[Top][All Lists]
[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);
- [Gnash-commit] gnash ChangeLog server/movie_def_impl.cpp serve...,
Sandro Santilli <=