gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog server/movie_def_impl.cpp serve...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/movie_def_impl.cpp serve...
Date: Mon, 14 Aug 2006 23:16:58 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  06/08/14 23:16:58

Modified files:
        .              : ChangeLog 
        server         : movie_def_impl.cpp movie_def_impl.h 
                         movie_definition.h sprite_definition.h 
        server/swf     : tag_loaders.cpp 

Log message:
                * server/movie_def_impl.cpp, server/movie_def_impl.h,
                  server/movie_definition.h, server/sprite_definition.h,
                  server/swf/tag_loaders.cpp: initial implementation of
                  movie loading into a separate frame. Needs more cleanup
                  work, but the intro1.swf and elvis.swf seems to be both
                  playing nice.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.644&r2=1.645
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_def_impl.cpp?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_def_impl.h?cvsroot=gnash&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_definition.h?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_definition.h?cvsroot=gnash&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/tag_loaders.cpp?cvsroot=gnash&r1=1.25&r2=1.26

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.644
retrieving revision 1.645
diff -u -b -r1.644 -r1.645
--- ChangeLog   14 Aug 2006 21:58:54 -0000      1.644
+++ ChangeLog   14 Aug 2006 23:16:57 -0000      1.645
@@ -1,5 +1,14 @@
 2006-08-14 Sandro Santilli  <address@hidden>
 
+       * server/movie_def_impl.cpp, server/movie_def_impl.h,
+         server/movie_definition.h, server/sprite_definition.h,
+         server/swf/tag_loaders.cpp: initial implementation of
+         movie loading into a separate frame. Needs more cleanup
+         work, but the intro1.swf and elvis.swf seems to be both
+         playing nice.
+
+2006-08-14 Sandro Santilli  <address@hidden>
+
        * server/swf/tag_loaders.h, server/swf/tag_loaders.cpp:
          allow define_font_info_loader to be called for DEFINEFONTINFO2
          tag, updated doc.

Index: server/movie_def_impl.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/movie_def_impl.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/movie_def_impl.cpp   8 Aug 2006 09:50:54 -0000       1.19
+++ server/movie_def_impl.cpp   14 Aug 2006 23:16:57 -0000      1.20
@@ -66,7 +66,7 @@
 
 // If != 0 this is the number of frames to load at each iteration
 // of the main loop. Loading in chunks greatly speeds the process up
-#define FRAMELOAD_CHUNK 64
+#define FRAMELOAD_CHUNK 0
 
 // Debug frames load
 #undef DEBUG_FRAMES_LOAD
@@ -74,6 +74,65 @@
 namespace gnash
 {
 
+MovieLoader::MovieLoader(movie_def_impl& md)
+       :
+       waiting_for_frame(0),
+       _movie_def(md)
+{
+       pthread_cond_init(&frame_reached_condition, NULL);
+       pthread_mutex_init(&fake_mut, NULL);
+}
+
+MovieLoader::~MovieLoader()
+{
+       pthread_cond_destroy(&frame_reached_condition);
+       pthread_mutex_destroy(&fake_mut);
+}
+
+void*
+MovieLoader::execute(void* arg)
+{
+       movie_def_impl* md = static_cast<movie_def_impl*>(arg);
+       md->read_all_swf();
+       // maybe this frees all resources and that's bad !
+       pthread_exit(NULL);
+       return NULL;
+}
+
+bool
+MovieLoader::start()
+{
+       if ( pthread_create(&_thread, NULL, execute, &_movie_def) )
+       {
+               return false;
+       }
+
+       // should set some mutexes ?
+
+       return true;
+}
+
+void
+MovieLoader::signal_frame_loaded(size_t frameno)
+{
+       if ( waiting_for_frame &&
+               frameno >= waiting_for_frame )
+       {
+               pthread_cond_signal(&frame_reached_condition);
+       }
+}
+
+void
+MovieLoader::wait_for_frame(size_t framenum)
+{
+       assert(waiting_for_frame == 0);
+        waiting_for_frame = framenum;
+        pthread_cond_wait(&frame_reached_condition, &fake_mut);
+       waiting_for_frame = 0;
+}
+
+
+
 //
 // some utility stuff
 //
@@ -136,6 +195,22 @@
 // movie_def_impl
 //
 
+movie_def_impl::movie_def_impl(create_bitmaps_flag cbf,
+               create_font_shapes_flag cfs)
+       :
+       _tag_loaders(s_tag_loaders), // FIXME: use a class-static 
TagLoadersTable for movie_def_impl
+       m_create_bitmaps(cbf),
+       m_create_font_shapes(cfs),
+       m_frame_rate(30.0f),
+       m_frame_count(0u),
+       m_version(0),
+       m_loading_frame(0u),
+       _loaded_bytes(0u),
+       m_jpeg_in(0),
+       _loader(*this)
+{
+}
+
 movie_def_impl::~movie_def_impl()
 {
     // Release our playlist data.
@@ -156,7 +231,9 @@
                 }
         }}
 
-    assert(m_jpeg_in == NULL); // It's supposed to be cleaned up in read()
+       // It's supposed to be cleaned up in read()
+       // TODO: join with loader thread instead ?
+       //assert(m_jpeg_in.get() == NULL);
 }
 
 bool movie_def_impl::in_import_table(int character_id)
@@ -346,7 +423,7 @@
        bool    compressed = (header & 255) == 'C';
     
        IF_VERBOSE_PARSE(
-               log_parse("version = %d, file_length = %d\n",
+               log_parse("version = %d, file_length = %d",
                        m_version, m_file_length);
        );
 
@@ -360,7 +437,7 @@
 #endif
 
                IF_VERBOSE_PARSE(
-                       log_parse("file is compressed.\n");
+                       log_parse("file is compressed.");
                );
 
                original_in = in;
@@ -391,32 +468,26 @@
 
        IF_VERBOSE_PARSE(
                m_frame_size.print();
-               log_parse("frame rate = %f, frames = %d\n",
+               log_parse("frame rate = %f, frames = %d",
                        m_frame_rate, m_frame_count);
        );
 
-#if 0
-       size_t startup_frames = m_frame_count;
-#else
-       // Don't load any frame 
-       // Other parts of the code will need to call ensure_frame_loaded(#)
-       // whenever in need to access a new frame
-       size_t startup_frames = 1; // always load first frame (must try w/out)
-#endif
-       if ( startup_frames && ! ensure_frame_loaded(startup_frames) )
+       // Start the loading frame
+       if ( ! _loader.start() )
        {
-               log_error("Could not load to frame %u !", startup_frames);
-               return false;
+               log_error("Could not start loading thread");
        }
 
-       if (m_jpeg_in)
-        {
-            delete m_jpeg_in;
-            m_jpeg_in = NULL;
-        }
+       // Wait until 'startup_frames' have been loaded
+#if 1
+       size_t startup_frames = 1;
+#else
+       size_t startup_frames = m_frame_count;
+#endif
+       ensure_frame_loaded(startup_frames);
 
-// automatically deleted at movie_def_impl removal, can't delete here
-// as we will keep reading from it while playing
+// Can't delete here as we will keep reading from it while playing
+// FIXME: remove this at end of reading (or in destructor)
 #if 0
        if (original_in)
         {
@@ -429,128 +500,20 @@
 }
 
 
-// 0-based frame number
+// 1-based frame number
 bool
 movie_def_impl::ensure_frame_loaded(size_t framenum)
 {
-       assert(_str.get() != NULL);
-
-       // Don't ask me to load more then available frames !
-       // (this might be due to malformed SWF (header reporting
-       //  less frames then available - still, check for it should
-       //  be implemented in tag loaders (possibly action executors).
-       assert(framenum <= m_frame_count);
-
-       // We already loaded that frame...
-       // (could turn into an assertion directly)
-       if ( framenum <= m_loading_frame )
-       {
-               log_msg("Frame %u already loaded (we loaded %u/%u)",
-                       framenum, m_loading_frame, m_frame_count);
-
-               // we make this an assertion to catch callers
-               // that might check for this condition themself
-               // rather then rely on this function.
-               assert(0);
-
-               return true;
-       }
-#if DEBUG_FRAMES_LOAD
-       else
-       {
-               log_msg("Loading of frame %u requested (we are at %u/%u)",
-                       framenum, m_loading_frame, m_frame_count);
-       }
-#endif
+       if ( m_loading_frame >= framenum ) return true;
 
-       stream& str=*_str;
-       // when m_loading_frame is 1 we've read frame 1
-       while ( m_loading_frame < framenum )
-// (uint32_t) str.get_position() < _swf_end_pos)
-       {
-               SWF::tag_type tag_type = str.open_tag();
-
-               if (s_progress_function != NULL)
-                {
-                       s_progress_function((uint32_t)str.get_position(),
-                               _swf_end_pos);
-                }
-
-               SWF::TagLoadersTable::loader_function lf = NULL;
-               //log_parse("tag_type = %d\n", tag_type);
-               if (tag_type == SWF::SHOWFRAME)
-               {
-                       // show frame tag -- advance to the next frame.
+       // else, set condition and wait for it
+        log_msg("Waiting for frame %u to be loaded", framenum);
+       _loader.wait_for_frame(framenum);
+        log_msg("Condition reached (m_loading_frame=%u)", m_loading_frame);
 
-                       IF_VERBOSE_PARSE(
-                               log_parse("  show_frame\n");
-                       );
-
-                       ++m_loading_frame;
-#if DEBUG_FRAMES_LOAD
-                       log_msg("Loaded frame %u/%u",
-                               m_loading_frame, m_frame_count);
-#endif
-               }
-               else if (_tag_loaders.get(tag_type, &lf))
-                {
-                       // call the tag loader.  The tag loader should add
-                       // characters or tags to the movie data structure.
-                       (*lf)(&str, tag_type, this);
-               }
-               else
-               {
-                       // no tag loader for this tag type.
-                       IF_VERBOSE_PARSE(
-                               log_parse("*** no tag loader for type %d\n",
-                                       tag_type);
-                               dump_tag_bytes(&str);
-                       );
-               } 
-
-               str.close_tag();
-
-               if (tag_type == SWF::END)
-                {
-                       if ( m_loading_frame < framenum ) {
-                               log_warning("hit SWF::END before reaching "
-                                       "requested frame number %u",
-                                       framenum);
-                               _loaded_bytes = str.get_position();
-                               return false;
-                       }
-
-                       if ((unsigned int) str.get_position() != _swf_end_pos)
-                        {
-                               // Safety break, so we don't read past
-                               // the end of the  movie.
-                               log_warning("hit stream-end tag, "
-                                       "but not at the advertised SWF end; "
-                                       "stopping for safety.");
-                               break;
-                       }
-               }
-       }
-
-       size_t cur_pos = (size_t)str.get_position();
-       //assert( _loaded_bytes < cur_pos )
-       if ( cur_pos < _loaded_bytes )
-       {
-               log_warning("After load of frame %u:\n"
-                       " current stream position: %u\n"
-                       " _loaded_bytes=%u\n"
-                       "(some tag triggered a seek-back?!)",
-                       m_loading_frame,
-                       cur_pos,
-                       _loaded_bytes);
-       }
-       else
-       {
-               _loaded_bytes = cur_pos;
-       }
 
+       // TODO: return false on timeout 
        return true;
-
 }
 
 
@@ -801,6 +764,77 @@
 #endif
 }
 
+void
+movie_def_impl::read_all_swf()
+{
+       assert(_str.get() != NULL);
+
+       stream& str=*_str;
+
+       //size_t it=0;
+       while ( (uint32_t) str.get_position() < _swf_end_pos )
+       {
+               //log_msg("Loading thread iteration %u", it++);
+
+               SWF::tag_type tag_type = str.open_tag();
+
+               if (s_progress_function != NULL)
+                {
+                       s_progress_function((uint32_t)str.get_position(),
+                               _swf_end_pos);
+                }
+
+               SWF::TagLoadersTable::loader_function lf = NULL;
+               //log_parse("tag_type = %d\n", tag_type);
+               if (tag_type == SWF::SHOWFRAME)
+               {
+                       // show frame tag -- advance to the next frame.
+
+                       IF_VERBOSE_PARSE(
+                               log_parse("  show_frame\n");
+                       );
+
+                       ++m_loading_frame;
+
+                       // signal load of frame
+                       _loader.signal_frame_loaded(m_loading_frame);
+
+#if DEBUG_FRAMES_LOAD
+                       log_msg("Loaded frame %u/%u",
+                               m_loading_frame, m_frame_count);
+#endif
+               }
+               else if (_tag_loaders.get(tag_type, &lf))
+                {
+                       // call the tag loader.  The tag loader should add
+                       // characters or tags to the movie data structure.
+                       (*lf)(&str, tag_type, this);
+               }
+               else
+               {
+                       // no tag loader for this tag type.
+                               log_error("*** no tag loader for type %d 
(movie)",
+                                       tag_type);
+                               dump_tag_bytes(&str);
+               } 
+
+               str.close_tag();
+
+               if (tag_type == SWF::END)
+                {
+                       if ((unsigned int) str.get_position() != _swf_end_pos)
+                        {
+                               // Safety break, so we don't read past
+                               // the end of the  movie.
+                               log_warning("hit stream-end tag, "
+                                       "but not at the advertised SWF end; "
+                                       "stopping for safety.");
+                               break;
+                       }
+               }
+       }
+
+}
 
 } // namespace gnash
 

Index: server/movie_def_impl.h
===================================================================
RCS file: /sources/gnash/gnash/server/movie_def_impl.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- server/movie_def_impl.h     9 Aug 2006 01:59:06 -0000       1.17
+++ server/movie_def_impl.h     14 Aug 2006 23:16:57 -0000      1.18
@@ -54,6 +54,7 @@
 
 #include <map> // for CharacterDictionary
 #include <string>
+#include <memory> // for auto_ptr
 
 namespace gnash
 {
@@ -90,6 +91,52 @@
        }
 };
 
+/// \brief
+/// movie_def_impl helper class handling start and execution of
+/// an SWF loading thread
+///
+class MovieLoader
+{
+
+public:
+
+       MovieLoader(movie_def_impl& md);
+
+       ~MovieLoader();
+
+       /// Start loading thread.
+       //
+       /// The associated movie_def_impl instance
+       /// is expected to have already read the SWF
+       /// header and applied a zlib adapter if needed.
+       ///
+       bool start();
+
+       /// Wait for specified frame number (1-based) to be loaded
+       //
+       /// Block caller thread until frame is loaded.
+       ///
+       void wait_for_frame(size_t framenum);
+
+       /// Signal load of given frame number (if anyone waiting for it)
+       void signal_frame_loaded(size_t frameno);
+
+private:
+
+       size_t waiting_for_frame;
+
+       pthread_cond_t frame_reached_condition;
+
+       pthread_mutex_t fake_mut;
+
+       pthread_t _thread;
+
+       /// Entry point for the actual thread
+       static void *execute(void* arg);
+
+       movie_def_impl& _movie_def;
+};
+
 /// The Characters dictionary associated with each SWF file.
 //
 /// This is a set of Characters defined by define tags and
@@ -198,7 +245,7 @@
        uint32  m_file_length;
        size_t  _loaded_bytes;
 
-       jpeg::input*    m_jpeg_in;
+       std::auto_ptr<jpeg::input> m_jpeg_in;
 
        std::string _url;
 
@@ -211,21 +258,12 @@
        /// swf end position (as read from header)
        unsigned int _swf_end_pos;
 
+       /// asyncronous SWF loader and parser
+       MovieLoader _loader;
+
 public:
-       movie_def_impl(create_bitmaps_flag cbf,
-                       create_font_shapes_flag cfs)
-               :
-               _tag_loaders(s_tag_loaders), // FIXME: use a class-static 
TagLoadersTable for movie_def_impl
-               m_create_bitmaps(cbf),
-               m_create_font_shapes(cfs),
-               m_frame_rate(30.0f),
-               m_frame_count(0u),
-               m_version(0),
-               m_loading_frame(0u),
-               _loaded_bytes(0u),
-               m_jpeg_in(0)
-               {
-               }
+
+       movie_def_impl(create_bitmaps_flag cbf, create_font_shapes_flag cfs);
 
        ~movie_def_impl();
 
@@ -413,17 +451,20 @@
 
        /// Set an input object for later loading DefineBits
        /// images (JPEG images without the table info).
-       void    set_jpeg_loader(jpeg::input* j_in)
+       void    set_jpeg_loader(std::auto_ptr<jpeg::input> j_in)
        {
-           assert(m_jpeg_in == NULL);
+           assert(m_jpeg_in.get() == NULL);
            m_jpeg_in = j_in;
        }
 
        /// Get the jpeg input loader, to load a DefineBits
        /// image (one without table info).
+       //
+       /// NOTE: ownership is NOT transferred
+       ///
        jpeg::input*    get_jpeg_loader()
        {
-           return m_jpeg_in;
+           return m_jpeg_in.get();
        }
 
        virtual const std::vector<execute_tag*>& get_playlist(size_t 
frame_number)
@@ -461,6 +502,9 @@
        ///
        bool ensure_frame_loaded(size_t framenum);
 
+       /// Read and parse all the SWF stream (blocking until load is finished)
+       void read_all_swf();
+
        virtual void load_next_frame_chunk();
 
        /// Fill up *fonts with fonts that we own.

Index: server/movie_definition.h
===================================================================
RCS file: /sources/gnash/gnash/server/movie_definition.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- server/movie_definition.h   7 Aug 2006 20:43:38 -0000       1.10
+++ server/movie_definition.h   14 Aug 2006 23:16:57 -0000      1.11
@@ -72,6 +72,7 @@
 #include "tu_file.h"
 
 #include <string>
+#include <memory> // for auto_ptr
 
 namespace gnash
 {
@@ -213,7 +214,7 @@
 
        virtual void    add_frame_name(const char* name) = 0;
 
-       virtual void    set_jpeg_loader(jpeg::input* j_in) = 0;
+       virtual void    set_jpeg_loader(std::auto_ptr<jpeg::input> j_in) = 0;
 
        virtual jpeg::input*    get_jpeg_loader() = 0;
 

Index: server/sprite_definition.h
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_definition.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- server/sprite_definition.h  7 Aug 2006 20:43:38 -0000       1.15
+++ server/sprite_definition.h  14 Aug 2006 23:16:57 -0000      1.16
@@ -145,7 +145,7 @@
 
        virtual font* get_font(int id) { return m_movie_def->get_font(id); }
 
-       virtual void set_jpeg_loader(jpeg::input* /*j_in*/)
+       virtual void set_jpeg_loader(std::auto_ptr<jpeg::input> /*j_in*/)
        {
                assert(0);
        }
@@ -335,12 +335,17 @@
        ///
        virtual bool ensure_frame_loaded(size_t framenum)
        {
-               /// We load full sprite definitions at once, so
-               /// this function always returns true.
-               log_msg("sprite_definition: ensure_frame_loaded(%u) called (we 
are at %u", framenum, m_frame_count);
-               assert(framenum <= m_frame_count);
+               // TODO: return false on timeout 
+               while ( m_loading_frame < framenum )
+               {
+                       log_msg("sprite_definition: "
+                               "loading of frame %u requested "
+                               "(we are at %u/%u)",
+                               framenum, m_loading_frame, m_frame_count);
+                       // Could this ever happen ?
+                       assert(0);
+               }
                return true;
-               //return m_movie_def->ensure_frame_loaded(framenum);
        }
 
        virtual void load_next_frame_chunk()

Index: server/swf/tag_loaders.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/swf/tag_loaders.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- server/swf/tag_loaders.cpp  14 Aug 2006 21:58:54 -0000      1.25
+++ server/swf/tag_loaders.cpp  14 Aug 2006 23:16:58 -0000      1.26
@@ -196,7 +196,7 @@
        );
 
 #if TU_CONFIG_LINK_TO_JPEGLIB
-    jpeg::input* j_in = 
jpeg::input::create_swf_jpeg2_header_only(in->get_underlying_stream());
+    std::auto_ptr<jpeg::input> 
j_in(jpeg::input::create_swf_jpeg2_header_only(in->get_underlying_stream()));
     assert(j_in.get());
 
     m->set_jpeg_loader(j_in);




reply via email to

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