gnash-commit
[Top][All Lists]
Advanced

[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
 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]