Gnash 0.8.9

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 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 #ifndef GNASH_MEDIAPARSER_H
00020 #define GNASH_MEDIAPARSER_H
00021 
00022 #include "IOChannel.h" // for inlines
00023 #include "dsodefs.h" // DSOEXPORT
00024 
00025 #include <boost/scoped_array.hpp>
00026 #include <boost/shared_ptr.hpp>
00027 #include <boost/thread/thread.hpp>
00028 #include <boost/thread/condition.hpp>
00029 #include <boost/thread/barrier.hpp>
00030 #include <memory>
00031 #include <deque>
00032 #include <map>
00033 #include <vector>
00034 #include <iosfwd> // for output operator forward declarations
00035 
00036 // Undefine this to load/parse media files in main thread
00037 #define LOAD_MEDIA_IN_A_SEPARATE_THREAD 1
00038 
00039 namespace gnash {
00040     class SimpleBuffer;
00041 }
00042 
00043 namespace gnash {
00044 namespace media {
00045 
00046 
00048 enum videoFrameType
00049 {
00051         KEY_FRAME = 1,
00052 
00054         INTER_FRAME = 2,
00055 
00057         DIS_INTER_FRAME = 3
00058 };
00059 
00061 enum codecType
00062 {
00064         CODEC_TYPE_FLASH,
00065 
00067         CODEC_TYPE_CUSTOM
00068 };
00069 
00071 enum videoCodecType
00072 {
00074         VIDEO_CODEC_H263 = 2,
00075 
00077         VIDEO_CODEC_SCREENVIDEO = 3,
00078 
00080         VIDEO_CODEC_VP6 = 4,
00081 
00083         VIDEO_CODEC_VP6A = 5,
00084 
00086         VIDEO_CODEC_SCREENVIDEO2 = 6,
00087 
00089         VIDEO_CODEC_H264 = 7
00090 
00091         // NOTE: if you add more elements here remember to
00092         //       also add them to the output operator!
00093 };
00094 
00095 DSOEXPORT std::ostream& operator<< (std::ostream& os, const videoCodecType& t);
00096 
00098 //
00115 enum audioCodecType
00116 {
00118         //
00128         AUDIO_CODEC_RAW = 0,    
00129 
00131     //
00141         AUDIO_CODEC_ADPCM = 1,
00142 
00144         //
00157         AUDIO_CODEC_MP3 = 2,
00158 
00160         AUDIO_CODEC_UNCOMPRESSED = 3,
00161 
00163     //
00167         AUDIO_CODEC_NELLYMOSER_8HZ_MONO = 5,
00168 
00170     //
00174         AUDIO_CODEC_NELLYMOSER = 6,
00175 
00177         AUDIO_CODEC_AAC = 10,
00178 
00180         AUDIO_CODEC_SPEEX = 11
00181 
00182         // NOTE: if you add more elements here remember to
00183         //       also add them to the output operator!
00184 };
00185 
00186 DSOEXPORT std::ostream& operator<< (std::ostream& os, const audioCodecType& t);
00187 
00189 //
00195 class AudioInfo
00196 {
00197 
00198 public:
00199 
00201     //
00226         AudioInfo(int codeci, boost::uint16_t sampleRatei,
00227             boost::uint16_t sampleSizei, bool stereoi,
00228             boost::uint64_t durationi, codecType typei)
00229                 :
00230         codec(codeci),
00231                 sampleRate(sampleRatei),
00232                 sampleSize(sampleSizei),
00233                 stereo(stereoi),
00234                 duration(durationi),
00235                 type(typei)
00236                 {
00237                 }
00238 
00240         //
00245         int codec;
00246 
00247         boost::uint16_t sampleRate;
00248 
00250         boost::uint16_t sampleSize;
00251 
00252         bool stereo;
00253 
00254         boost::uint64_t duration;
00255 
00256         codecType type;
00257 
00259     //
00263         class ExtraInfo {
00264         public:
00265                 virtual ~ExtraInfo() {}
00266         };
00267 
00269     //
00272         std::auto_ptr<ExtraInfo> extra;
00273 };
00274 
00276 //
00281 class VideoInfo
00282 {
00283 public:
00284 
00286     //
00313         VideoInfo(int codeci, boost::uint16_t widthi, boost::uint16_t heighti,
00314             boost::uint16_t frameRatei, boost::uint64_t durationi,
00315             codecType typei)
00316                 :
00317         codec(codeci),
00318                 width(widthi),
00319                 height(heighti),
00320                 frameRate(frameRatei),
00321                 duration(durationi),
00322                 type(typei)
00323         {
00324         }
00325 
00326         int codec;
00327         boost::uint16_t width;
00328         boost::uint16_t height;
00329         boost::uint16_t frameRate;
00330         boost::uint64_t duration;
00331         codecType type;
00332 
00334     //
00338         class ExtraInfo {
00339         public:
00340                 virtual ~ExtraInfo() {}
00341         };
00342 
00344     //
00347         std::auto_ptr<ExtraInfo> extra;
00348 };
00349 
00350 DSOEXPORT std::ostream& operator << (std::ostream& os, const VideoInfo& vi);
00351 
00352 
00353 class EncodedExtraData {
00354 
00355 public:
00356         virtual ~EncodedExtraData() {}
00357 
00358 };
00359 
00361 class EncodedVideoFrame
00362 {
00363 public:
00364 
00366         //
00379         EncodedVideoFrame(boost::uint8_t* data, boost::uint32_t size,
00380                         unsigned int frameNum,
00381                         boost::uint64_t timestamp=0)
00382                 :
00383                 _size(size),
00384                 _data(data),
00385                 _frameNum(frameNum),
00386                 _timestamp(timestamp)
00387         {}
00388 
00390         const boost::uint8_t* data() const { return _data.get(); }
00391 
00393         boost::uint32_t dataSize() const { return _size; }
00394 
00396         boost::uint64_t timestamp() const { return _timestamp; }
00397 
00399         unsigned frameNum() const { return _frameNum; }
00400 
00401         // FIXME: should have better encapsulation for this sort of stuff.
00402         std::auto_ptr<EncodedExtraData> extradata;
00403 private:
00404 
00405         boost::uint32_t _size;
00406         boost::scoped_array<boost::uint8_t> _data;
00407         unsigned int _frameNum;
00408         boost::uint64_t _timestamp;
00409 };
00410 
00412 class EncodedAudioFrame
00413 {
00414 public:
00415         boost::uint32_t dataSize;
00416         boost::scoped_array<boost::uint8_t> data;
00417         boost::uint64_t timestamp;
00418 
00419         // FIXME: should have better encapsulation for this sort of stuff.
00420         std::auto_ptr<EncodedExtraData> extradata;
00421 };
00422 
00424 //
00431 class MediaParser
00432 {
00433 public:
00434 
00436     //
00438     typedef std::multimap<boost::uint64_t, boost::shared_ptr<SimpleBuffer> >
00439         MetaTags;
00440     
00441     typedef std::vector<MetaTags::mapped_type> OrderedMetaTags;
00442         MediaParser(std::auto_ptr<IOChannel> stream);
00443 
00444         // Classes with virtual methods (virtual classes)
00445         // must have a virtual destructor, or the destructors
00446         // of subclasses will never be invoked, tipically resulting
00447         // in memory leaks..
00448         //
00449         virtual ~MediaParser();
00450 
00454         //
00461         virtual bool seek(boost::uint32_t& time)=0;
00462 
00464         //
00472         DSOEXPORT boost::uint64_t getBufferLength() const;
00473 
00475         //
00477         DSOEXPORT bool isBufferEmpty() const;
00478 
00480         DSOEXPORT boost::uint64_t getBufferTime() const
00481         {
00482                 boost::mutex::scoped_lock lock(_bufferTimeMutex);
00483                 return _bufferTime;
00484         }
00485 
00487         //
00491         DSOEXPORT void setBufferTime(boost::uint64_t t)
00492         {
00493                 boost::mutex::scoped_lock lock(_bufferTimeMutex);
00494                 _bufferTime=t;
00495         }
00496 
00498         //
00504         DSOEXPORT bool nextFrameTimestamp(boost::uint64_t& ts) const;
00505 
00507         //
00513         DSOEXPORT bool nextVideoFrameTimestamp(boost::uint64_t& ts) const;
00514 
00516         //
00522         DSOEXPORT std::auto_ptr<EncodedVideoFrame> nextVideoFrame();
00523 
00525         //
00531         DSOEXPORT bool nextAudioFrameTimestamp(boost::uint64_t& ts) const;
00532 
00534         //
00540         DSOEXPORT std::auto_ptr<EncodedAudioFrame> nextAudioFrame();
00541 
00543         //
00547         VideoInfo* getVideoInfo() { return _videoInfo.get(); }
00548 
00550         //
00554         AudioInfo* getAudioInfo() { return _audioInfo.get(); }
00555 
00557         //
00563         bool parsingCompleted() const { return _parsingComplete; }
00564 
00566         //
00573         virtual bool indexingCompleted() const { return true; }
00574 
00576         virtual boost::uint64_t getBytesLoaded() const { return 0; }
00577 
00579         boost::uint64_t getBytesTotal() const
00580         {
00581                 return _stream->size();
00582         }
00583 
00585         //
00593         virtual bool parseNextChunk()=0;
00594 
00596     //
00601     //
00604     virtual void fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts);
00605 
00606 protected:
00607 
00609 
00611         std::auto_ptr<VideoInfo> _videoInfo;
00612 
00614         std::auto_ptr<AudioInfo> _audioInfo;
00615 
00617         bool _parsingComplete;
00618 
00620         boost::uint64_t _bytesLoaded;
00621 
00623 
00625         void startParserThread();
00626 
00628         //
00634         void stopParserThread();
00635 
00637         void clearBuffers();
00638 
00640         //
00643         void pushEncodedAudioFrame(std::auto_ptr<EncodedAudioFrame> frame);
00644 
00646         //
00649         void pushEncodedVideoFrame(std::auto_ptr<EncodedVideoFrame> frame);
00650 
00652         std::auto_ptr<IOChannel> _stream;
00653         mutable boost::mutex _streamMutex;
00654 
00655         static void parserLoopStarter(MediaParser* mp)
00656         {
00657                 mp->parserLoop();
00658         }
00659 
00668         void parserLoop();
00669 
00670         bool parserThreadKillRequested() const
00671         {
00672                 boost::mutex::scoped_lock lock(_parserThreadKillRequestMutex);
00673                 return _parserThreadKillRequested;
00674         }
00675 
00676         boost::uint64_t _bufferTime;
00677         mutable boost::mutex _bufferTimeMutex;
00678 
00679         std::auto_ptr<boost::thread> _parserThread;
00680         boost::barrier _parserThreadStartBarrier;
00681         mutable boost::mutex _parserThreadKillRequestMutex;
00682         bool _parserThreadKillRequested;
00683         boost::condition _parserThreadWakeup;
00684 
00690         void waitIfNeeded(boost::mutex::scoped_lock& qMutexLock);
00691 
00692         void wakeupParserThread();
00693 
00695         mutable boost::mutex _qMutex;
00696 
00697 
00699         mutable boost::mutex _bytesLoadedMutex;
00700 
00702         //
00708         bool bufferFull() const;
00709 
00713         bool _seekRequest;
00714 
00715 private:
00716 
00717         typedef std::deque<EncodedVideoFrame*> VideoFrames;
00718         typedef std::deque<EncodedAudioFrame*> AudioFrames;
00719 
00721         //
00726         const EncodedVideoFrame* peekNextVideoFrame() const;
00727 
00729         //
00734         const EncodedAudioFrame* peekNextAudioFrame() const;
00735 
00736 
00738         //
00741         VideoFrames _videoFrames;
00742 
00744         //
00747         AudioFrames _audioFrames;
00748 
00749         void requestParserThreadKill()
00750         {
00751                 boost::mutex::scoped_lock lock(_parserThreadKillRequestMutex);
00752                 _parserThreadKillRequested=true;
00753                 _parserThreadWakeup.notify_all();
00754         }
00755 
00757         boost::uint64_t audioBufferLength() const;
00758 
00760         boost::uint64_t videoBufferLength() const;
00761 
00763         boost::uint64_t getBufferLengthNoLock() const;
00764         
00765 };
00766 
00767 
00768 } // gnash.media namespace 
00769 } // namespace gnash
00770 
00771 #endif // __MEDIAPARSER_H__