[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r9646: Drop the unused half of NetCo
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r9646: Drop the unused half of NetConnection so that it's clear how the class |
Date: |
Thu, 28 Aug 2008 12:45:45 +0200 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 9646
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Thu 2008-08-28 12:45:45 +0200
message:
Drop the unused half of NetConnection so that it's clear how the class
works and what it's for. Some minor cleanups to logging and code. Use smart
pointers when it's useful.
Allocate a SwsContext for each instance of the VideoDecoderFfmpeg class
so that newer versions of Ffmpeg can decode more than one NetStream
simultaneously. Make sure it's freed on destruction. The ifdefs make the
code a bit messier, but that's ffmpeg's fault for changing its API.
modified:
libcore/DisplayList.cpp
libcore/asobj/NetConnection.cpp
libcore/asobj/NetConnection.h
libcore/asobj/NetStreamFfmpeg.cpp
libcore/asobj/Sound.cpp
libcore/asobj/Sound.h
libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
libmedia/ffmpeg/VideoDecoderFfmpeg.h
------------------------------------------------------------
revno: 9644.1.1
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Wed 2008-08-27 12:57:49 +0200
message:
Make logging tidier. Don't use string::size() when we want
!string::empty().
Use auto_ptr to make sure AMFQueue is deleted.
Drop members such as eof(), getBytesLoaded(), seek() etc.
modified:
libcore/asobj/NetConnection.cpp
libcore/asobj/NetConnection.h
------------------------------------------------------------
revno: 9644.1.2
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Wed 2008-08-27 13:07:07 +0200
message:
Drop NetConnection::openConnection as it's unused and duplicates URL
checking code.
Also remove old, commented-out calls to it.
modified:
libcore/asobj/NetConnection.cpp
libcore/asobj/NetConnection.h
libcore/asobj/NetStreamFfmpeg.cpp
libcore/asobj/Sound.cpp
libcore/asobj/Sound.h
------------------------------------------------------------
revno: 9644.1.3
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Wed 2008-08-27 13:27:47 +0200
message:
Drop _loader member.
modified:
libcore/asobj/NetConnection.h
------------------------------------------------------------
revno: 9644.1.4
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Wed 2008-08-27 15:50:54 +0200
message:
Drop some c_str() members.
modified:
libcore/DisplayList.cpp
------------------------------------------------------------
revno: 9644.1.5
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2008-08-28 10:32:06 +0200
message:
Ensure the SwsContext struct is freed on exit and not static, so that it
can be used in imageConvertRGB from different threads.
Make imageConvertRGB non-static so that it can access the _swsContext
member.
At present it's not used outside the class, so it doesn't need to be
static.
If this changes, it needs a small redesign.
modified:
libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
libmedia/ffmpeg/VideoDecoderFfmpeg.h
------------------------------------------------------------
revno: 9644.1.6
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2008-08-28 11:54:06 +0200
message:
ifdefs for different ffmpeg version.
modified:
libmedia/ffmpeg/VideoDecoderFfmpeg.cpp
libmedia/ffmpeg/VideoDecoderFfmpeg.h
=== modified file 'libcore/DisplayList.cpp'
--- a/libcore/DisplayList.cpp 2008-08-18 23:53:04 +0000
+++ b/libcore/DisplayList.cpp 2008-08-27 13:50:54 +0000
@@ -465,7 +465,7 @@
{
IF_VERBOSE_ASCODING_ERRORS(
log_aserror("%s.swapDepth(%d) : ignored call with target depth less then
%d",
- ch1->getTarget().c_str(), newdepth, character::staticDepthOffset);
+ ch1->getTarget(), newdepth, character::staticDepthOffset);
);
return;
}
@@ -727,7 +727,7 @@
const DisplayItem& dobj = *it;
log_debug(_("Item %d at depth %d (char id %d, name %s, type %s)"),
num, dobj->get_depth(), dobj->get_id(),
- dobj->get_name().c_str(), typeName(*dobj).c_str());
+ dobj->get_name(), typeName(*dobj));
num++;
}
}
=== modified file 'libcore/asobj/NetConnection.cpp'
--- a/libcore/asobj/NetConnection.cpp 2008-08-25 10:16:16 +0000
+++ b/libcore/asobj/NetConnection.cpp 2008-08-27 11:07:07 +0000
@@ -24,7 +24,6 @@
#include <iostream>
#include <string>
-#include <new>
#include <boost/scoped_ptr.hpp>
#include "NetConnection.h"
@@ -38,8 +37,6 @@
#include "URLAccessManager.h"
#include "URL.h"
-#include "FLVParser.h"
-
// for NetConnection.call()
#include "VM.h"
#include "array.h"
@@ -53,89 +50,21 @@
namespace gnash {
static as_value netconnection_new(const fn_call& fn);
-//static as_object* getNetConnectionInterface();
/// \class NetConnection
/// \brief Opens a local connection through which you can play
/// back video (FLV) files from an HTTP address or from the local file
/// system, using curl.
-
-
NetConnection::NetConnection()
:
as_object(getNetConnectionInterface()),
- call_queue(0)
+ _callQueue(0)
{
attachProperties();
}
/*public*/
-bool NetConnection::openConnection(const std::string& url)
-{
- // if already running there is no need to setup things again
- if ( _loader.get() ) {
- log_debug("NetConnection::openConnection() called when already connected
to a stream. Checking if the existing connection can be used.");
- std::string newurl;
- if (_prefixUrl.size() > 0) {
- newurl += _prefixUrl + "/" + url;
- } else {
- newurl += url;
- }
- if (newurl.compare(_completeUrl) == 0) {
- return true;
- } else {
- return false;
- }
- }
-
- if ( _prefixUrl.size() > 0 ) {
- _completeUrl += _prefixUrl + "/" + url;
- } else {
- _completeUrl += url;
- }
-
- URL uri( _completeUrl, get_base_url() );
-
- std::string uriStr( uri.str() );
- assert( uriStr.find( "://" ) != std::string::npos );
-
- // Check if we're allowed to open url
-#if 1 // done by getStream I guess...
- if ( ! URLAccessManager::allow( uri ) ) {
- log_security( _("Gnash is not allowed to open this url: %s"),
uriStr.c_str() );
- return false;
- }
-#endif
-
- log_security( _("Connecting to movie: %s"), uriStr );
-
- StreamProvider& streamProvider = StreamProvider::getDefaultInstance();
- _loader.reset( streamProvider.getStream( uri ) );
-
- if ( ! _loader.get() ) {
- log_error( _("Gnash could not open this url: %s"), uriStr );
- _loader.reset();
-
- return false;
- }
-
- log_debug( _("Connection established to movie: %s"), uriStr );
-
- return true;
-}
-
-
-/*public*/
-bool
-NetConnection::eof()
-{
- if (!_loader.get()) return true; // @@ correct ?
- return _loader->eof();
-}
-
-
-/*public*/
std::string NetConnection::validateURL(const std::string& url)
{
std::string completeUrl;
@@ -156,11 +85,11 @@
// Check if we're allowed to open url
if (!URLAccessManager::allow(uri)) {
- log_security(_("Gnash is not allowed to open this url: %s"),
uriStr.c_str());
+ log_security(_("Gnash is not allowed to open this url: %s"),
uriStr);
return "";
}
- log_debug(_("Connection to movie: %s"), uriStr.c_str());
+ log_debug(_("Connection to movie: %s"), uriStr);
return uriStr;
}
@@ -180,74 +109,6 @@
}
-/*public*/
-size_t
-NetConnection::read( void *dst, size_t bytes )
-{
- if ( ! _loader.get() ) {
- return 0;
- }
-
- return _loader->read( dst, bytes );
-}
-
-
-/*public*/
-bool
-NetConnection::seek( size_t pos )
-{
- if ( ! _loader.get() ) {
- return false;
- }
-
- return ! _loader->seek( pos );
-}
-
-
-/*public*/
-/// TODO: drop
-size_t
-NetConnection::tell()
-{
- if (!_loader.get()) return 0; // @@ correct ?
- return _loader->tell();
-}
-
-
-/*public*/
-/// TODO: drop
-long
-NetConnection::getBytesLoaded()
-{
- if (!_loader.get()) return 0; // @@ correct ?
- return _loader->tell(); // getBytesLoaded();
-}
-
-
-/*public*/
-/// TODO: drop
-long
-NetConnection::getBytesTotal()
-{
- if (!_loader.get()) return 0; // @@ correct ?
- return _loader->size(); // getBytesTotal();
-}
-
-
-/*public*/
-/// TODO: drop
-bool
-NetConnection::loadCompleted()
-{
- if ( ! _loader.get() ) {
- return false;
- }
-
- // is the below correct ?
- return _loader->eof(); // completed();
-}
-
-
/// \brief callback to instantiate a new NetConnection object.
/// \param fn the parameters from the Flash movie
/// \return nothing from the function call.
@@ -312,7 +173,7 @@
if ( fn.nargs > 1 )
{
std::stringstream ss; fn.dump_args(ss);
- log_unimpl("NetConnection.connect(%s): args after the first are
not supported", ss.str().c_str());
+ log_unimpl("NetConnection.connect(%s): args after the first are
not supported", ss.str());
}
@@ -554,8 +415,7 @@
log_debug("have connection");
int read = connection->readNonBlocking(reply.data() +
reply_end, NCCALLREPLYMAX - reply_end);
if(read > 0) {
- log_debug("read '%1%' bytes:", read);
- log_debug(_(hexify(reply.data() + reply_end,
read, false).c_str()));
+ log_debug("read '%1%' bytes: %2%", read,
hexify(reply.data() + reply_end, read, false));
reply_end += read;
}
@@ -735,8 +595,7 @@
// set the "number of bodies" header
(reinterpret_cast<boost::uint16_t*>(postdata.data() +
4))[0] = htons(queued_count);
std::string
postdata_str(reinterpret_cast<char*>(postdata.data()), postdata.size());
- log_debug("NetConnection.call(): encoded args from %1%
calls:", queued_count);
- log_debug("%s", hexify(postdata.data(),
postdata.size(), false));
+ log_debug("NetConnection.call(): encoded args from %1%
calls: %2%", queued_count, hexify(postdata.data(), postdata.size(), false));
queued_count = 0;
connection.reset(
StreamProvider::getDefaultInstance().getStream(url, postdata_str) );
postdata.resize(6);
@@ -754,7 +613,7 @@
{
boost::intrusive_ptr<NetConnection> ptr =
ensureType<NetConnection>(fn.this_ptr);
// FIXME check if it's possible for the URL of a NetConnection
to change between call()s
- ptr->call_queue->tick();
+ ptr->_callQueue->tick();
return as_value();
};
@@ -767,18 +626,22 @@
}
private:
- void start_ticking() {
-
- if(ticker) return;
-
- boost::intrusive_ptr<builtin_function> ticker_as = \
- new builtin_function(&AMFQueue::amfqueue_tick_wrapper);
+ void start_ticking()
+ {
+
+ if (ticker) return;
+
+ boost::intrusive_ptr<builtin_function> ticker_as =
+ new builtin_function(&AMFQueue::amfqueue_tick_wrapper);
+
std::auto_ptr<Timer> timer(new Timer);
unsigned long delayMS = 50; // FIXME crank up to 50 or so
timer->setInterval(*ticker_as, delayMS, &_nc);
ticker = _nc.getVM().getRoot().add_interval_timer(timer, true);
}
- void push_amf(const SimpleBuffer &amf) {
+
+ void push_amf(const SimpleBuffer &amf)
+ {
GNASH_REPORT_FUNCTION;
postdata.append(amf.data(), amf.size());
@@ -786,23 +649,29 @@
start_ticking();
}
- void stop_ticking() {
- if(!ticker) return;
+
+ void stop_ticking()
+ {
+ if (!ticker) return;
_nc.getVM().getRoot().clear_interval_timer(ticker);
ticker=0;
}
+
void push_callback(const std::string& id,
boost::intrusive_ptr<as_object> callback) {
callbacks.insert(std::pair<std::string,
boost::intrusive_ptr<as_object> >(id, callback));
}
- boost::intrusive_ptr<as_object> pop_callback(std::string id) {
+
+ boost::intrusive_ptr<as_object> pop_callback(std::string id)
+ {
CallbacksMap::iterator it = callbacks.find(id);
- if(it != callbacks.end()) {
+ if (it != callbacks.end()) {
boost::intrusive_ptr<as_object> callback = it->second;
//boost::intrusive_ptr<as_object> callback;
//callback = it.second;
callbacks.erase(it);
return callback;
- } else {
+ }
+ else {
return 0;
}
}
@@ -837,10 +706,13 @@
// TODO: arg(1) is the response object. let it know when data comes back
boost::intrusive_ptr<as_object> asCallback = 0;
if(fn.nargs > 1) {
+
if(fn.arg(1).is_object()) {
asCallback = (fn.arg(1).to_object());
- } else {
- IF_VERBOSE_ASCODING_ERRORS(
+ }
+
+ else {
+ IF_VERBOSE_ASCODING_ERRORS(
std::stringstream ss; fn.dump_args(ss);
log_aserror("NetConnection::call(%s): second argument
must be an object", ss.str());
);
@@ -860,11 +732,14 @@
// client id (result number) as counted string
// the convention seems to be / followed by a unique (ascending) number
- call_number += 1;
- // TODO is there a better way to do this number->string conversion?
- std::string call_number_str((boost::format("/%1%") %
call_number).str());
- buf->appendNetworkShort(call_number_str.size());
- buf->append(call_number_str.c_str(), call_number_str.size());
+ ++call_number;
+
+ std::ostringstream os;
+ os << "/" << call_number;
+ const std::string callNumberString = os.str();
+
+ buf->appendNetworkShort(callNumberString.size());
+ buf->append(callNumberString.c_str(), callNumberString.size());
size_t total_size_offset = buf->size();
buf->append("\000\000\000\000", 4); // total size to be filled in later
@@ -873,9 +748,11 @@
// encode array of arguments to remote method
buf->appendByte(Element::STRICT_ARRAY_AMF0);
buf->appendNetworkLong(fn.nargs - 2);
- if(fn.nargs > 2) {
- for(unsigned int i = 2; i < fn.nargs; ++i) {
- if(fn.arg(i).is_string()) {
+ if (fn.nargs > 2) {
+
+ for (unsigned int i = 2; i < fn.nargs; ++i) {
+
+ if (fn.arg(i).is_string()) {
buf->appendByte(Element::STRING_AMF0);
std::string str = fn.arg(i).to_string();
buf->appendNetworkShort(str.size());
@@ -884,7 +761,9 @@
//} else if(fn.arg(i).is_function()) {
// as_function f = fn.arg(i).to_function();
// tmp = AMF::encodefunction(f);
- } else if(fn.arg(i).is_number()) {
+ }
+
+ else if(fn.arg(i).is_number()) {
double d = fn.arg(i).to_number();
buf->appendByte(Element::NUMBER_AMF0);
swapBytes(&d, 8); // this actually only swapps
on little-endian machines
@@ -893,7 +772,9 @@
//} else if(fn.arg(i).is_object()) {
// boost::intrusive_ptr<as_object> o =
fn.arg(i).to_object();
// tmp = AMF::encodeObject(o);
- } else {
+ }
+
+ else {
log_error(_("NetConnection.call(): unknown
argument type"));
buf->appendByte(Element::UNDEFINED_AMF0);
}
@@ -904,26 +785,27 @@
*(reinterpret_cast<uint32_t*>(buf->data() + total_size_offset)) =
htonl(buf->size() - 4 - total_size_offset);
- log_debug(_("NetConnection.call(): encoded args: "));
- log_debug("%s", hexify(buf->data(), buf->size(), false));
+ log_debug(_("NetConnection.call(): encoded args: %s"),
hexify(buf->data(), buf->size(), false));
// FIXME check that ptr->_prefixURL is valid
URL url(ptr->validateURL(std::string()));
// FIXME check if it's possible for the URL of a NetConnection to
change between call()s
- if(ptr->call_queue == 0) {
- ptr->call_queue = new AMFQueue(*ptr, url);
+ if (! ptr->_callQueue.get()) {
+ ptr->_callQueue.reset(new AMFQueue(*ptr, url));
}
- if(asCallback) {
+ if (asCallback) {
//boost::intrusive_ptr<as_object>
intrusive_callback(asCallback);
log_debug("calling enqueue with callback");
- ptr->call_queue->enqueue(*buf, call_number_str, asCallback);
+ ptr->_callQueue->enqueue(*buf, callNumberString, asCallback);
//? delete asCallback;
- } else {
+ }
+
+ else {
log_debug("calling enqueue without callback");
- ptr->call_queue->enqueue(*buf);
+ ptr->_callQueue->enqueue(*buf);
}
log_debug("called enqueue");
@@ -1041,13 +923,12 @@
// here to have AMFQueue definition available
NetConnection::~NetConnection()
{
- delete call_queue;
}
void
NetConnection::markReachableResources() const
{
- if ( call_queue ) call_queue->markReachableResources();
+ if ( _callQueue.get() ) _callQueue->markReachableResources();
markAsObjectReachable();
}
=== modified file 'libcore/asobj/NetConnection.h'
--- a/libcore/asobj/NetConnection.h 2008-08-18 23:53:04 +0000
+++ b/libcore/asobj/NetConnection.h 2008-08-27 11:27:47 +0000
@@ -16,17 +16,10 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#ifndef __NETCONNECTION_H__
-#define __NETCONNECTION_H__
+#ifndef GNASH_NETCONNECTION_H
+#define GNASH_NETCONNECTION_H
#include "IOChannel.h"
-
-#include <stdexcept>
-#include <cstdio>
-#include <cerrno>
-#include <sys/types.h>
-#include <sys/stat.h>
-
#include <string>
// TODO: port to new AS architecture
@@ -74,87 +67,6 @@
/// Register the "NetConnection" constructor to the given global object
static void registerConstructor(as_object& global);
- /// Open a connection to stream FLV files.
- //
- /// If already connected an error is raised and false
- /// is returned. Otherwise, a connection is attempted
- /// using a separate thread that starts loading data
- /// caching it.
- ///
- /// @param url
- /// An url portion to append to the base url (???)
- ///
- /// @return true on success, false on error.
- ///
- /// @note Older Flash movies can only take a NULL value as
- /// the parameter, which therefor only connects to the localhost using
- /// RTMP. Newer Flash movies have a parameter to connect which is a
- /// URL string like rtmp://foobar.com/videos/bar.flv
- ///
- bool openConnection(const std::string& url);
-
- /// Put read pointer at given position
- //
- /// If the position has not been loaded yet
- /// this call blocks. If not connected false
- /// is returned w/out blocking.
- ///
- bool seek(size_t pos);
-
- /// Read 'bytes' bytes into the given buffer.
- //
- /// If not enough bytes have been loaded yet
- /// this call blocks. If not connected false
- /// is returned w/out blocking.
- ///
- /// Return number of actually read bytes
- ///
- /// TODO: drop
- ///
- size_t read(void *dst, size_t bytes);
-
- /// Return true if EOF has been reached
- //
- /// This call never blocks.
- /// If not connected, true is returned (is this correct behaviour?)
- ///
- bool eof();
-
- /// Report global position within the file
- //
- /// This call never blocks.
- /// If not connected, 0 is returned (is this correct behaviour?)
- ///
- /// TODO: drop
- ///
- size_t tell();
-
- /// Returns the number of bytes cached
- //
- /// This call never blocks.
- /// If not connected, 0 is returned (is this correct behaviour?)
- ///
- /// TODO: drop
- ///
- long getBytesLoaded();
-
- /// Returns the total size of the file
- //
- /// This call never blocks.
- /// If not connected, 0 is returned (is this correct behaviour?)
- ///
- /// TODO: drop
- ///
- long getBytesTotal();
-
- /// Returns whether the load is complete
- //
- /// This call never blocks.
- ///
- /// TODO: drop
- ///
- bool loadCompleted();
-
protected:
/// Mark responders associated with remoting calls
@@ -163,7 +75,7 @@
private:
friend class AMFQueue;
- AMFQueue *call_queue;
+ std::auto_ptr<AMFQueue> _callQueue;
/// Extend the URL to be used for playing
void addToURL(const std::string& url);
@@ -174,12 +86,6 @@
/// the complete url of the file
std::string _completeUrl;
- /// The file/stream loader thread and interface
- //
- /// TODO: drop
- ///
- std::auto_ptr<IOChannel> _loader;
-
/// Attach ActionScript instance properties
void attachProperties();
=== modified file 'libcore/asobj/NetStreamFfmpeg.cpp'
--- a/libcore/asobj/NetStreamFfmpeg.cpp 2008-08-18 23:53:04 +0000
+++ b/libcore/asobj/NetStreamFfmpeg.cpp 2008-08-27 11:07:07 +0000
@@ -45,14 +45,6 @@
#include <boost/scoped_array.hpp>
#include <algorithm> // std::min
-
-#if defined(_WIN32) || defined(WIN32)
-# include <windows.h> // for sleep()
-# define usleep(x) Sleep(x/1000)
-#else
-# include "unistd.h" // for usleep()
-#endif
-
/// Define this to add debugging prints for locking
//#define GNASH_DEBUG_THREADS
=== modified file 'libcore/asobj/Sound.cpp'
--- a/libcore/asobj/Sound.cpp 2008-08-25 10:16:16 +0000
+++ b/libcore/asobj/Sound.cpp 2008-08-27 11:07:07 +0000
@@ -179,10 +179,6 @@
log_error(_("%s: This sound already has a connection? (We try
to handle this by overriding the old one...)"), __FUNCTION__);
}
externalURL = file;
-#if 0
- connection = new NetConnection();
- connection->openConnection(externalURL);
-#endif
}
void
=== modified file 'libcore/asobj/Sound.h'
--- a/libcore/asobj/Sound.h 2008-06-19 17:21:13 +0000
+++ b/libcore/asobj/Sound.h 2008-08-27 11:07:07 +0000
@@ -16,8 +16,8 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-#ifndef __SOUND_H__
-#define __SOUND_H__
+#ifndef GNASH_ASOBJ_SOUND_H
+#define GNASH_ASOBJ_SOUND_H
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
=== modified file 'libmedia/ffmpeg/VideoDecoderFfmpeg.cpp'
--- a/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp 2008-08-19 06:57:35 +0000
+++ b/libmedia/ffmpeg/VideoDecoderFfmpeg.cpp 2008-08-28 09:54:06 +0000
@@ -40,7 +40,32 @@
namespace gnash {
namespace media {
-
+
+#ifdef HAVE_SWSCALE_H
+/// A wrapper round an SwsContext that ensures it's
+/// freed on destruction.
+class SwsContextWrapper
+{
+public:
+
+ SwsContextWrapper(SwsContext* context)
+ :
+ _context(context)
+ {}
+
+ ~SwsContextWrapper()
+ {
+ sws_freeContext(_context);
+ }
+
+ SwsContext* getContext() { return _context; }
+
+private:
+ SwsContext* _context;
+
+};
+#endif
+
VideoDecoderFfmpeg::VideoDecoderFfmpeg(videoCodecType format, int width, int
height)
:
_videoCodec(NULL),
@@ -128,7 +153,7 @@
}
}
-AVPicture /*static*/
+AVPicture
VideoDecoderFfmpeg::convertRGB24(AVCodecContext* srcCtx,
const AVFrame& srcFrame)
{
@@ -150,25 +175,37 @@
img_convert(&picture, PIX_FMT_RGB24, (AVPicture*) &srcFrame,
srcCtx->pix_fmt, width, height);
#else
- // FIXME: this will live forever ...
- static struct SwsContext* context = NULL;
- if (!context) {
+ // Check whether the context wrapper exists
+ // already.
+ if (!_swsContext.get()) {
// FIXME: this leads to wrong results (read: segfaults) if this method
// is called from two unrelated video contexts, for example from
// a NetStreamFfmpeg and an embedded video context. Or two
// separate instances of one of the former two.
- context = sws_getContext(width, height, srcCtx->pix_fmt,
- width, height, PIX_FMT_RGB24,
- SWS_FAST_BILINEAR, NULL, NULL, NULL);
+ _swsContext.reset(
+ new SwsContextWrapper(
+ sws_getContext(width, height, srcCtx->pix_fmt,
+ width, height, PIX_FMT_RGB24,
+ SWS_FAST_BILINEAR, NULL, NULL, NULL)
+ ));
- if (!context) {
+ // Check that the context was assigned.
+ if (!_swsContext->getContext()) {
delete [] buffer;
+
+ // This means we will try to assign the
+ // context again next time.
+ _swsContext.reset();
return picture;
}
}
- int rv = sws_scale(context, const_cast<uint8_t**>(srcFrame.data),
+ // Is it possible for the context to be reset
+ // to NULL once it's been created?
+ assert(_swsContext->getContext());
+
+ int rv = sws_scale(_swsContext->getContext(),
const_cast<uint8_t**>(srcFrame.data),
const_cast<int*>(srcFrame.linesize), 0, height, picture.data,
picture.linesize);
=== modified file 'libmedia/ffmpeg/VideoDecoderFfmpeg.h'
--- a/libmedia/ffmpeg/VideoDecoderFfmpeg.h 2008-08-18 23:53:04 +0000
+++ b/libmedia/ffmpeg/VideoDecoderFfmpeg.h 2008-08-28 09:54:06 +0000
@@ -1,6 +1,6 @@
// VideoDecoderFfmpeg.h: Video decoding using the FFMPEG library.
//
-// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008 Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -9,12 +9,12 @@
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
#ifndef GNASH_VIDEODECODERFFMPEG_H
@@ -41,60 +41,82 @@
}
#endif
+
+#if defined(HAVE_LIBSWSCALE_SWSCALE_H) || defined(HAVE_FFMPEG_SWSCALE_H)
+# define HAVE_SWSCALE_H 1
+#endif
+
+
namespace gnash {
namespace media {
+/// Forward declarations
+#ifdef HAVE_SWSCALE_H
+class SwsContextWrapper;
+#endif
+
class VideoDecoderFfmpeg : public VideoDecoder {
-
+
public:
- DSOEXPORT VideoDecoderFfmpeg(videoCodecType format, int width, int height);
-
- DSOEXPORT VideoDecoderFfmpeg(VideoInfo& info);
-
- DSOEXPORT ~VideoDecoderFfmpeg();
-
- void push(const EncodedVideoFrame& buffer);
-
- std::auto_ptr<image::ImageBase> pop();
-
- bool peek();
-
-
- /// \brief converts an video frame from (almost) any type to RGB24.
- ///
- /// @param srcCtx The source context that was used to decode srcFrame.
- /// @param srcFrame the source frame to be converted.
- /// @return an AVPicture containing the converted image. Please be advised
- /// that the RGB data pointer is stored in AVPicture::data[0]. The
- /// caller owns that pointer, which must be freed with delete [].
- /// It is advised to wrap the pointer in a boost::scoped_array.
- /// If conversion fails, AVPicture::data[0] will be NULL.
- DSOEXPORT static AVPicture convertRGB24(AVCodecContext* srcCtx, const
AVFrame& srcFrame);
-
- /// Convert FLASH codec id to FFMPEG codec id
- //
- /// @return CODEC_ID_NONE for unsupported flash codecs
- ///
- DSOEXPORT static enum CodecID flashToFfmpegCodec(videoCodecType format);
+ DSOEXPORT VideoDecoderFfmpeg(videoCodecType format, int width, int height);
+
+ DSOEXPORT VideoDecoderFfmpeg(VideoInfo& info);
+
+ DSOEXPORT ~VideoDecoderFfmpeg();
+
+ void push(const EncodedVideoFrame& buffer);
+
+ std::auto_ptr<image::ImageBase> pop();
+
+ bool peek();
+
+
+ /// \brief converts an video frame from (almost) any type to RGB24.
+ ///
+ /// @param srcCtx The source context that was used to decode srcFrame.
+ /// @param srcFrame the source frame to be converted.
+ /// @return an AVPicture containing the converted image. Please be advised
+ /// that the RGB data pointer is stored in
AVPicture::data[0]. The
+ /// caller owns that pointer, which must be freed with
delete [].
+ /// It is advised to wrap the pointer in a
boost::scoped_array.
+ /// If conversion fails, AVPicture::data[0] will be NULL.
+ AVPicture convertRGB24(AVCodecContext* srcCtx, const AVFrame& srcFrame);
+
+ /// Convert FLASH codec id to FFMPEG codec id
+ //
+ /// @return CODEC_ID_NONE for unsupported flash codecs
+ ///
+ DSOEXPORT static enum CodecID flashToFfmpegCodec(videoCodecType format);
private:
- void init(enum CodecID format, int width, int height, boost::uint8_t*
extradata=0, int extradataSize=0);
-
- std::auto_ptr<image::ImageBase> decode(const boost::uint8_t* input,
boost::uint32_t input_size);
-
- std::auto_ptr<image::ImageBase> decode(const EncodedVideoFrame* vf)
- {
- return decode(vf->data(), vf->dataSize());
- }
-
- AVCodec* _videoCodec;
- AVCodecContext* _videoCodecCtx;
- std::vector<const EncodedVideoFrame*> _video_frames;
+ void init(enum CodecID format, int width, int height, boost::uint8_t*
extradata=0, int extradataSize=0);
+
+ std::auto_ptr<image::ImageBase> decode(const boost::uint8_t* input,
boost::uint32_t input_size);
+
+ std::auto_ptr<image::ImageBase> decode(const EncodedVideoFrame* vf)
+ {
+ return decode(vf->data(), vf->dataSize());
+ }
+
+ AVCodec* _videoCodec;
+ AVCodecContext* _videoCodecCtx;
+
+#if HAVE_SWSCALE_H
+ /// A pointer to a wrapper round an SwsContext
+ //
+ /// This is constructed with a SwsContext*, which
+ /// can be NULL, so it is important to check
+ /// not only that the wrapper exists, but also
+ /// the context inside it.
+ std::auto_ptr<SwsContextWrapper> _swsContext;
+#endif
+
+ std::vector<const EncodedVideoFrame*> _video_frames;
};
-
+
} // gnash.media namespace
} // gnash namespace
- [Gnash-commit] /srv/bzr/gnash/trunk r9646: Drop the unused half of NetConnection so that it's clear how the class,
Benjamin Wolsey <=