Gnash  0.8.10
SWFMovieDefinition.h
Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
00003 //   Free Software Foundation, Inc
00004 // 
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 3 of the License, or
00008 // (at your option) any later version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019 // The SWFMovieDefinition is the 'root' definition of a SWF movie, including
00020 // movies loaded into another SWF file. Each self-contained SWF file has exactly
00021 // one SWFMovieDefinition.
00022 
00023 #ifndef GNASH_SWF_MOVIE_DEFINITION_H
00024 #define GNASH_SWF_MOVIE_DEFINITION_H
00025 
00026 #ifdef HAVE_CONFIG_H
00027 #include "gnashconfig.h" // for USE_SWFTREE
00028 #endif
00029 
00030 #include "movie_definition.h" // for inheritance
00031 #include "DefinitionTag.h" // for boost::intrusive_ptr visibility of dtor
00032 #include "StringPredicates.h" 
00033 #include "SWFRect.h"
00034 #include "GnashNumeric.h"
00035 #include "GnashAlgorithm.h"
00036 
00037 #include <boost/intrusive_ptr.hpp>
00038 #include <vector>
00039 #include <map>
00040 #include <set> 
00041 #include <string>
00042 #include <memory> 
00043 #include <boost/thread/thread.hpp>
00044 #include <boost/thread/condition.hpp>
00045 #include <boost/thread/barrier.hpp>
00046 #include <boost/scoped_ptr.hpp>
00047 
00048 // Forward declarations
00049 namespace gnash {
00050     namespace image {
00051         class JpegInput;
00052     }
00053     class IOChannel;
00054     class SWFMovieDefinition;
00055     class SWFStream;
00056     class movie_root;
00057     class MovieClip;
00058     class SWFMovie;
00059     class RunResources;
00060     class Font;
00061 }
00062 
00063 namespace gnash {
00064 
00066 class SWFMovieLoader
00067 {
00068 public:
00069 
00070     SWFMovieLoader(SWFMovieDefinition& md);
00071 
00072     ~SWFMovieLoader();
00073 
00075     //
00080     bool start();
00081 
00083     bool started() const;
00084 
00086     bool isSelfThread() const;
00087 
00088 private:
00089 
00090     SWFMovieDefinition& _movie_def;
00091 
00092     mutable boost::mutex _mutex;
00093     std::auto_ptr<boost::thread> _thread;
00094 
00095     // Barrier to ensure that _thread
00096     // is initialized before the loader thread
00097     // continues execution
00098     boost::barrier _barrier;
00099 
00101     static void execute(SWFMovieLoader& ml, SWFMovieDefinition* md);
00102 
00103 };
00104 
00106 //
00110 class CharacterDictionary
00111 {
00112 public:
00113 
00115     //
00118     typedef std::map<int, boost::intrusive_ptr<SWF::DefinitionTag> >
00119         CharacterContainer;
00120 
00121     typedef CharacterContainer::iterator CharacterIterator;
00122 
00123     typedef CharacterContainer::const_iterator CharacterConstIterator;
00124 
00126     //
00129     boost::intrusive_ptr<SWF::DefinitionTag> getDisplayObject(int id) const;
00130 
00132     //
00135     void addDisplayObject(int id, boost::intrusive_ptr<SWF::DefinitionTag> c);
00136       
00138     CharacterIterator begin() { return _map.begin(); }
00139 
00141     CharacterConstIterator begin() const { return _map.begin(); }
00142 
00144     CharacterIterator end() { return _map.end(); }
00145 
00147     CharacterConstIterator end() const { return _map.end(); }
00148 
00149     friend std::ostream& operator<<(std::ostream& o,
00150             const CharacterDictionary& cd);
00151 
00152 private:
00153 
00154     CharacterContainer _map;
00155 
00156 };
00157 
00158 
00160 //
00164 class SWFMovieDefinition : public movie_definition
00165 {
00166 public:
00167 
00169     //
00172     SWFMovieDefinition(const RunResources& runResources);
00173 
00174     ~SWFMovieDefinition();
00175 
00177     size_t get_frame_count() const {
00178         return m_frame_count;
00179     }
00180     
00182     float get_frame_rate() const {
00183         return m_frame_rate;
00184     }
00185     
00187     const SWFRect& get_frame_size() const {
00188         return m_frame_size;
00189     }
00190 
00191     size_t get_width_pixels() const {
00192         return std::ceil(twipsToPixels(m_frame_size.width()));
00193     }
00194 
00195     size_t get_height_pixels() const {
00196         return std::ceil(twipsToPixels(m_frame_size.height()));
00197     }
00198 
00200     void setAS3() {
00201         _as3 = true;
00202     }
00203     
00205     bool isAS3() const {
00206         return _as3;
00207     }
00208 
00210     //
00213     virtual int get_version() const { return m_version; }
00214 
00216     //
00224     virtual size_t get_loading_frame() const;
00225 
00227     //
00230     size_t get_bytes_loaded() const {
00231         boost::mutex::scoped_lock lock(_bytes_loaded_mutex);
00232         return _bytes_loaded;
00233     }
00234 
00236     size_t get_bytes_total() const {
00237         return m_file_length;
00238     }
00239 
00240     virtual void importResources(boost::intrusive_ptr<movie_definition> source,
00241             const Imports& imports);
00242 
00243     virtual void addDisplayObject(boost::uint16_t id, SWF::DefinitionTag* c);
00244 
00246     SWF::DefinitionTag* getDefinitionTag(boost::uint16_t id) const;
00247 
00248     // See dox in movie_definition
00249     //
00250     // locks _namedFramesMutex
00251     bool get_labeled_frame(const std::string& label, size_t& frame_number)
00252         const;
00253 
00254     void add_font(int font_id, boost::intrusive_ptr<Font> f);
00255 
00256     Font* get_font(int font_id) const;
00257 
00258     Font* get_font(const std::string& name, bool bold, bool italic) const;
00259 
00260     // See dox in movie_definition.h
00261     CachedBitmap* getBitmap(int DisplayObject_id) const;
00262 
00263     // See dox in movie_definition.h
00264     void addBitmap(int DisplayObject_id, boost::intrusive_ptr<CachedBitmap> im);
00265 
00266     // See dox in movie_definition.h
00267     sound_sample* get_sound_sample(int DisplayObject_id) const;
00268 
00269     // See dox in movie_definition.h
00270     virtual void add_sound_sample(int DisplayObject_id, sound_sample* sam);
00271 
00272     // See dox in movie_definition.h
00273     virtual void set_loading_sound_stream_id(int id) {
00274         m_loading_sound_stream = id;
00275     }
00276 
00277     // See dox in movie_definition.h
00278     int get_loading_sound_stream_id() const {
00279         return m_loading_sound_stream;
00280     }
00281 
00282     // See dox in movie_definition.h
00283     void addControlTag(boost::intrusive_ptr<SWF::ControlTag> tag) {
00284         assert(tag);
00285         boost::mutex::scoped_lock lock(_frames_loaded_mutex);
00286         m_playlist[_frames_loaded].push_back(tag);
00287     }
00288 
00289     // See dox in movie_definition.h
00290     //
00291     // locks _namedFramesMutex and _frames_loaded_mutex
00292     //
00293     void add_frame_name(const std::string& name);
00294 
00297     void set_jpeg_loader(std::auto_ptr<image::JpegInput> j_in);
00298 
00299     // See dox in movie_definition.h
00300     image::JpegInput* get_jpeg_loader() const {
00301         return m_jpeg_in.get();
00302     }
00303 
00304     virtual const PlayList* getPlaylist(size_t frame_number) const {
00305 
00306 #ifndef NDEBUG
00307         boost::mutex::scoped_lock lock(_frames_loaded_mutex);
00308         assert(frame_number <= _frames_loaded);
00309 #endif
00310 
00311         PlayListMap::const_iterator it = m_playlist.find(frame_number);
00312         if ( it == m_playlist.end() ) return NULL;
00313         else return &(it->second);
00314     }
00315 
00317     //
00325     bool readHeader(std::auto_ptr<IOChannel> in, const std::string& url);
00326 
00328     //
00334     bool completeLoad();
00335 
00339     bool ensure_frame_loaded(size_t framenum) const;
00340 
00342     //
00347     void read_all_swf();
00348 
00350     //
00358     Movie* createMovie(Global_as& gl, DisplayObject* parent = 0);
00359 
00360     virtual DisplayObject* createDisplayObject(Global_as&, DisplayObject*)
00361         const {
00362         return 0;
00363     }
00364 
00365     virtual const std::string& get_url() const { return _url; }
00366     
00368     //
00370     //
00375     boost::uint16_t exportID(const std::string& symbol) const;
00376     
00378     //
00380     //
00384     void registerExport(const std::string& symbol, boost::uint16_t id);
00385 
00386     
00387 #ifdef USE_SWFTREE
00388 
00389     // These methods attach the contents of the METADATA tag
00390     // to a movie_definition.
00391     virtual void storeDescriptiveMetadata(const std::string& data) {
00392         _metadata = data;
00393     }
00394 
00395     virtual const std::string& getDescriptiveMetadata() const {
00396         return _metadata;
00397     }    
00398 
00399 #endif
00400 
00401 private:
00402 
00403 #ifdef USE_SWFTREE
00404     // For storing descriptive metadata (information only)
00405     std::string _metadata;
00406 #endif
00407 
00409     CharacterDictionary    _dictionary;
00410 
00412     mutable boost::mutex _dictionaryMutex;
00413 
00414     typedef std::map<int, boost::intrusive_ptr<Font> > FontMap;
00415     FontMap m_fonts;
00416 
00417     typedef std::map<int, boost::intrusive_ptr<CachedBitmap> > Bitmaps;
00418     Bitmaps _bitmaps;
00419 
00420     typedef std::map<int, boost::intrusive_ptr<sound_sample> > SoundSampleMap;
00421     SoundSampleMap m_sound_samples;
00422 
00423     typedef std::map<size_t, PlayList> PlayListMap;
00424 
00426     PlayListMap m_playlist;
00427 
00429     typedef std::map<std::string, size_t, StringNoCaseLessThan> NamedFrameMap;
00430     NamedFrameMap _namedFrames;
00431 
00432     // Mutex protecting access to _namedFrames
00433     mutable boost::mutex _namedFramesMutex;
00434 
00436     typedef std::map<std::string, boost::uint16_t,
00437             StringNoCaseLessThan> Exports;
00438 
00440     Exports _exportTable;
00441 
00442     // Mutex protecting access to the export map.
00443     mutable boost::mutex _exportedResourcesMutex;
00444 
00447     typedef std::vector<boost::intrusive_ptr<movie_definition> > ImportVect;
00448     ImportVect m_import_source_movies;
00449 
00450     SWFRect    m_frame_size;
00451     float    m_frame_rate;
00452     size_t    m_frame_count;
00453     int    m_version;
00454 
00456     size_t    _frames_loaded;
00457 
00459     //
00463     mutable boost::mutex _frames_loaded_mutex;
00464 
00466     mutable boost::condition _frame_reached_condition;
00467 
00469     //
00472     mutable size_t _waiting_for_frame;
00473 
00475     unsigned long _bytes_loaded;
00476 
00478     //
00482     mutable boost::mutex _bytes_loaded_mutex;
00483 
00484     int m_loading_sound_stream;
00485 
00486     boost::uint32_t m_file_length;
00487 
00488     std::auto_ptr<image::JpegInput> m_jpeg_in;
00489 
00490     std::string _url;
00491 
00493     boost::scoped_ptr<SWFStream> _str;
00494 
00495     std::auto_ptr<IOChannel> _in;
00496 
00498     size_t _swf_end_pos;
00499 
00501     SWFMovieLoader _loader;
00502 
00510     virtual void incrementLoadedFrames();
00511 
00513     //
00515     void setBytesLoaded(unsigned long bytes)
00516     {
00517         boost::mutex::scoped_lock lock(_bytes_loaded_mutex);
00518         _bytes_loaded=bytes;
00519     }
00520 
00522     bool _loadingCanceled;
00523 
00525     std::set< boost::intrusive_ptr<movie_definition> > _importSources;
00526 
00527 private:
00528 
00531     //
00535     const RunResources& _runResources;
00536 
00537     bool _as3;
00538 
00539 };
00540 
00541 } // namespace gnash
00542 
00543 #endif