Gnash  0.8.10
MediaParser.h
Go to the documentation of this file.
00001 // MediaParser.h: Base class for media parsers
00002 // 
00003 //   Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
00004 //   Free Software Foundation, Inc.
00005 // 
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 3 of the License, or
00009 // (at your option) any later version.
00010 // 
00011 // This program is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with this program; if not, write to the Free Software
00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019 
00020 #ifndef GNASH_MEDIAPARSER_H
00021 #define GNASH_MEDIAPARSER_H
00022 
00023 #include <boost/scoped_array.hpp>
00024 #include <boost/shared_ptr.hpp>
00025 #include <boost/thread/thread.hpp>
00026 #include <boost/thread/condition.hpp>
00027 #include <boost/thread/barrier.hpp>
00028 #include <memory>
00029 #include <deque>
00030 #include <map>
00031 #include <vector>
00032 #include <iosfwd> // for output operator forward declarations
00033 #include <boost/optional.hpp>
00034 
00035 #include "IOChannel.h" // for inlines
00036 #include "dsodefs.h" // DSOEXPORT
00037 
00038 // Undefine this to load/parse media files in main thread
00039 #define LOAD_MEDIA_IN_A_SEPARATE_THREAD 1
00040 
00041 namespace gnash {
00042     class SimpleBuffer;
00043     namespace media {
00044         struct Id3Info;
00045     }
00046 }
00047 
00048 namespace gnash {
00049 namespace media {
00050 
00051 
00053 enum videoFrameType
00054 {
00056         KEY_FRAME = 1,
00057 
00059         INTER_FRAME = 2,
00060 
00062         DIS_INTER_FRAME = 3
00063 };
00064 
00066 enum codecType
00067 {
00069         CODEC_TYPE_FLASH,
00070 
00072         CODEC_TYPE_CUSTOM
00073 };
00074 
00076 enum videoCodecType
00077 {
00079         VIDEO_CODEC_H263 = 2,
00080 
00082         VIDEO_CODEC_SCREENVIDEO = 3,
00083 
00085         VIDEO_CODEC_VP6 = 4,
00086 
00088         VIDEO_CODEC_VP6A = 5,
00089 
00091         VIDEO_CODEC_SCREENVIDEO2 = 6,
00092 
00094         VIDEO_CODEC_H264 = 7
00095 
00096         // NOTE: if you add more elements here remember to
00097         //       also add them to the output operator!
00098 };
00099 
00100 DSOEXPORT std::ostream& operator<< (std::ostream& os, const videoCodecType& t);
00101 
00103 //
00120 enum audioCodecType
00121 {
00123         //
00133         AUDIO_CODEC_RAW = 0,    
00134 
00136     //
00146         AUDIO_CODEC_ADPCM = 1,
00147 
00149         //
00162         AUDIO_CODEC_MP3 = 2,
00163 
00165         AUDIO_CODEC_UNCOMPRESSED = 3,
00166 
00168     //
00172         AUDIO_CODEC_NELLYMOSER_8HZ_MONO = 5,
00173 
00175     //
00179         AUDIO_CODEC_NELLYMOSER = 6,
00180 
00182         AUDIO_CODEC_AAC = 10,
00183 
00185         AUDIO_CODEC_SPEEX = 11
00186 
00187         // NOTE: if you add more elements here remember to
00188         //       also add them to the output operator!
00189 };
00190 
00191 DSOEXPORT std::ostream& operator<< (std::ostream& os, const audioCodecType& t);
00192 
00194 //
00200 class AudioInfo
00201 {
00202 
00203 public:
00204 
00206     //
00231         AudioInfo(int codeci, boost::uint16_t sampleRatei,
00232             boost::uint16_t sampleSizei, bool stereoi,
00233             boost::uint64_t durationi, codecType typei)
00234                 :
00235         codec(codeci),
00236                 sampleRate(sampleRatei),
00237                 sampleSize(sampleSizei),
00238                 stereo(stereoi),
00239                 duration(durationi),
00240                 type(typei)
00241                 {
00242                 }
00243 
00245         //
00250         int codec;
00251 
00252         boost::uint16_t sampleRate;
00253 
00255         boost::uint16_t sampleSize;
00256 
00257         bool stereo;
00258 
00259         boost::uint64_t duration;
00260 
00261         codecType type;
00262 
00264     //
00268         class ExtraInfo {
00269         public:
00270                 virtual ~ExtraInfo() {}
00271         };
00272 
00274     //
00277         std::auto_ptr<ExtraInfo> extra;
00278 };
00279 
00281 //
00286 class VideoInfo
00287 {
00288 public:
00289 
00291     //
00318         VideoInfo(int codeci, boost::uint16_t widthi, boost::uint16_t heighti,
00319             boost::uint16_t frameRatei, boost::uint64_t durationi,
00320             codecType typei)
00321                 :
00322         codec(codeci),
00323                 width(widthi),
00324                 height(heighti),
00325                 frameRate(frameRatei),
00326                 duration(durationi),
00327                 type(typei)
00328         {
00329         }
00330 
00331         int codec;
00332         boost::uint16_t width;
00333         boost::uint16_t height;
00334         boost::uint16_t frameRate;
00335         boost::uint64_t duration;
00336         codecType type;
00337 
00339     //
00343         class ExtraInfo {
00344         public:
00345                 virtual ~ExtraInfo() {}
00346         };
00347 
00349     //
00352         std::auto_ptr<ExtraInfo> extra;
00353 };
00354 
00355 DSOEXPORT std::ostream& operator << (std::ostream& os, const VideoInfo& vi);
00356 
00357 
00358 class EncodedExtraData {
00359 
00360 public:
00361         virtual ~EncodedExtraData() {}
00362 
00363 };
00364 
00366 class EncodedVideoFrame
00367 {
00368 public:
00369 
00371         //
00384         EncodedVideoFrame(boost::uint8_t* data, boost::uint32_t size,
00385                         unsigned int frameNum,
00386                         boost::uint64_t timestamp=0)
00387                 :
00388                 _size(size),
00389                 _data(data),
00390                 _frameNum(frameNum),
00391                 _timestamp(timestamp)
00392         {}
00393 
00395         const boost::uint8_t* data() const { return _data.get(); }
00396 
00398         boost::uint32_t dataSize() const { return _size; }
00399 
00401         boost::uint64_t timestamp() const { return _timestamp; }
00402 
00404         unsigned frameNum() const { return _frameNum; }
00405 
00406         // FIXME: should have better encapsulation for this sort of stuff.
00407         std::auto_ptr<EncodedExtraData> extradata;
00408 private:
00409 
00410         boost::uint32_t _size;
00411         boost::scoped_array<boost::uint8_t> _data;
00412         unsigned int _frameNum;
00413         boost::uint64_t _timestamp;
00414 };
00415 
00417 class EncodedAudioFrame
00418 {
00419 public:
00420         boost::uint32_t dataSize;
00421         boost::scoped_array<boost::uint8_t> data;
00422         boost::uint64_t timestamp;
00423 
00424         // FIXME: should have better encapsulation for this sort of stuff.
00425         std::auto_ptr<EncodedExtraData> extradata;
00426 };
00427 
00429 //
00436 class MediaParser
00437 {
00438 public:
00439 
00441     //
00443     typedef std::multimap<boost::uint64_t, boost::shared_ptr<SimpleBuffer> >
00444         MetaTags;
00445     
00446     typedef std::vector<MetaTags::mapped_type> OrderedMetaTags;
00447         MediaParser(std::auto_ptr<IOChannel> stream);
00448 
00449         // Classes with virtual methods (virtual classes)
00450         // must have a virtual destructor, or the destructors
00451         // of subclasses will never be invoked, tipically resulting
00452         // in memory leaks..
00453         //
00454         virtual ~MediaParser();
00455 
00459         //
00466         virtual bool seek(boost::uint32_t& time)=0;
00467 
00469         //
00477         DSOEXPORT boost::uint64_t getBufferLength() const;
00478 
00480         //
00482         DSOEXPORT bool isBufferEmpty() const;
00483 
00485         DSOEXPORT boost::uint64_t getBufferTime() const
00486         {
00487                 boost::mutex::scoped_lock lock(_bufferTimeMutex);
00488                 return _bufferTime;
00489         }
00490 
00492         //
00496         DSOEXPORT void setBufferTime(boost::uint64_t t)
00497         {
00498                 boost::mutex::scoped_lock lock(_bufferTimeMutex);
00499                 _bufferTime=t;
00500         }
00501 
00503         //
00509         DSOEXPORT bool nextFrameTimestamp(boost::uint64_t& ts) const;
00510 
00512         //
00518         DSOEXPORT bool nextVideoFrameTimestamp(boost::uint64_t& ts) const;
00519 
00521         //
00527         DSOEXPORT std::auto_ptr<EncodedVideoFrame> nextVideoFrame();
00528 
00530         //
00536         DSOEXPORT bool nextAudioFrameTimestamp(boost::uint64_t& ts) const;
00537 
00539         //
00545         DSOEXPORT std::auto_ptr<EncodedAudioFrame> nextAudioFrame();
00546 
00548         //
00552         VideoInfo* getVideoInfo() { return _videoInfo.get(); }
00553 
00555         //
00559         AudioInfo* getAudioInfo() { return _audioInfo.get(); }
00560 
00562         //
00568         bool parsingCompleted() const { return _parsingComplete; }
00569 
00571         //
00578         virtual bool indexingCompleted() const { return true; }
00579 
00581         virtual boost::uint64_t getBytesLoaded() const { return 0; }
00582 
00584         boost::uint64_t getBytesTotal() const
00585         {
00586                 return _stream->size();
00587         }
00588 
00590         //
00598         virtual bool parseNextChunk()=0;
00599 
00601     //
00606     //
00609     virtual void fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts);
00610 
00612     //
00614     virtual boost::optional<Id3Info> getId3Info() const;
00615 
00616 protected:
00617 
00619 
00621         std::auto_ptr<VideoInfo> _videoInfo;
00622 
00624         std::auto_ptr<AudioInfo> _audioInfo;
00625 
00627         bool _parsingComplete;
00628 
00630         boost::uint64_t _bytesLoaded;
00631 
00633 
00635         void startParserThread();
00636 
00638         //
00644         void stopParserThread();
00645 
00647         void clearBuffers();
00648 
00650         //
00653         void pushEncodedAudioFrame(std::auto_ptr<EncodedAudioFrame> frame);
00654 
00656         //
00659         void pushEncodedVideoFrame(std::auto_ptr<EncodedVideoFrame> frame);
00660 
00662         std::auto_ptr<IOChannel> _stream;
00663         mutable boost::mutex _streamMutex;
00664 
00665         static void parserLoopStarter(MediaParser* mp)
00666         {
00667                 mp->parserLoop();
00668         }
00669 
00678         void parserLoop();
00679 
00680         bool parserThreadKillRequested() const
00681         {
00682                 boost::mutex::scoped_lock lock(_parserThreadKillRequestMutex);
00683                 return _parserThreadKillRequested;
00684         }
00685 
00686         boost::uint64_t _bufferTime;
00687         mutable boost::mutex _bufferTimeMutex;
00688 
00689         std::auto_ptr<boost::thread> _parserThread;
00690         boost::barrier _parserThreadStartBarrier;
00691         mutable boost::mutex _parserThreadKillRequestMutex;
00692         bool _parserThreadKillRequested;
00693         boost::condition _parserThreadWakeup;
00694 
00700         void waitIfNeeded(boost::mutex::scoped_lock& qMutexLock);
00701 
00702         void wakeupParserThread();
00703 
00705         mutable boost::mutex _qMutex;
00706 
00708         mutable boost::mutex _bytesLoadedMutex;
00709 
00711         //
00717         bool bufferFull() const;
00718 
00722         bool _seekRequest;
00723 
00724 private:
00725 
00726         typedef std::deque<EncodedVideoFrame*> VideoFrames;
00727         typedef std::deque<EncodedAudioFrame*> AudioFrames;
00728 
00730         //
00735         const EncodedVideoFrame* peekNextVideoFrame() const;
00736 
00738         //
00743         const EncodedAudioFrame* peekNextAudioFrame() const;
00744 
00745 
00747         //
00750         VideoFrames _videoFrames;
00751 
00753         //
00756         AudioFrames _audioFrames;
00757 
00758         void requestParserThreadKill()
00759         {
00760                 boost::mutex::scoped_lock lock(_parserThreadKillRequestMutex);
00761                 _parserThreadKillRequested=true;
00762                 _parserThreadWakeup.notify_all();
00763         }
00764 
00766         boost::uint64_t audioBufferLength() const;
00767 
00769         boost::uint64_t videoBufferLength() const;
00770 
00772         boost::uint64_t getBufferLengthNoLock() const;
00773         
00774 };
00775 
00776 
00777 } // gnash.media namespace 
00778 } // namespace gnash
00779 
00780 #endif // __MEDIAPARSER_H__