• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

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 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         FLASH,
00065 
00067         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         DSOEXPORT boost::uint64_t getBufferTime() const
00476         {
00477                 boost::mutex::scoped_lock lock(_bufferTimeMutex);
00478                 return _bufferTime;
00479         }
00480 
00482         //
00486         DSOEXPORT void setBufferTime(boost::uint64_t t)
00487         {
00488                 boost::mutex::scoped_lock lock(_bufferTimeMutex);
00489                 _bufferTime=t;
00490         }
00491 
00493         //
00497         DSOEXPORT bool nextFrameTimestamp(boost::uint64_t& ts) const;
00498 
00500         //
00504         DSOEXPORT bool nextVideoFrameTimestamp(boost::uint64_t& ts) const;
00505 
00507         //
00513         DSOEXPORT std::auto_ptr<EncodedVideoFrame> nextVideoFrame();
00514 
00516         //
00520         DSOEXPORT bool nextAudioFrameTimestamp(boost::uint64_t& ts) const;
00521 
00523         //
00529         DSOEXPORT std::auto_ptr<EncodedAudioFrame> nextAudioFrame();
00530 
00532         //
00536         VideoInfo* getVideoInfo() { return _videoInfo.get(); }
00537 
00539         //
00543         AudioInfo* getAudioInfo() { return _audioInfo.get(); }
00544 
00546         //
00552         bool parsingCompleted() const { return _parsingComplete; }
00553 
00555         //
00562         virtual bool indexingCompleted() const { return true; }
00563 
00565         virtual boost::uint64_t getBytesLoaded() const { return 0; }
00566 
00568         boost::uint64_t getBytesTotal() const
00569         {
00570                 return _stream->size();
00571         }
00572 
00574         //
00582         virtual bool parseNextChunk()=0;
00583 
00585     //
00590     //
00593     virtual void fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts);
00594 
00595 protected:
00596 
00598 
00600         std::auto_ptr<VideoInfo> _videoInfo;
00601 
00603         std::auto_ptr<AudioInfo> _audioInfo;
00604 
00606         bool _parsingComplete;
00607 
00609         boost::uint64_t _bytesLoaded;
00610 
00612 
00614         void startParserThread();
00615 
00617         //
00623         void stopParserThread();
00624 
00626         void clearBuffers();
00627 
00629         //
00632         void pushEncodedAudioFrame(std::auto_ptr<EncodedAudioFrame> frame);
00633 
00635         //
00638         void pushEncodedVideoFrame(std::auto_ptr<EncodedVideoFrame> frame);
00639 
00641         //
00644         const EncodedVideoFrame* peekNextVideoFrame() const;
00645 
00647         //
00650         const EncodedAudioFrame* peekNextAudioFrame() const;
00651 
00653         std::auto_ptr<IOChannel> _stream;
00654         mutable boost::mutex _streamMutex;
00655 
00656         static void parserLoopStarter(MediaParser* mp)
00657         {
00658                 mp->parserLoop();
00659         }
00660 
00669         void parserLoop();
00670 
00671         bool parserThreadKillRequested() const
00672         {
00673                 boost::mutex::scoped_lock lock(_parserThreadKillRequestMutex);
00674                 return _parserThreadKillRequested;
00675         }
00676 
00677         boost::uint64_t _bufferTime;
00678         mutable boost::mutex _bufferTimeMutex;
00679 
00680         std::auto_ptr<boost::thread> _parserThread;
00681         boost::barrier _parserThreadStartBarrier;
00682         mutable boost::mutex _parserThreadKillRequestMutex;
00683         bool _parserThreadKillRequested;
00684         boost::condition _parserThreadWakeup;
00685 
00691         void waitIfNeeded(boost::mutex::scoped_lock& qMutexLock);
00692 
00693         void wakeupParserThread();
00694 
00696         mutable boost::mutex _qMutex;
00697 
00698 
00700         mutable boost::mutex _bytesLoadedMutex;
00701 
00703         //
00709         bool bufferFull() const;
00710 
00714         bool _seekRequest;
00715 private:
00716 
00717         typedef std::deque<EncodedVideoFrame*> VideoFrames;
00718         typedef std::deque<EncodedAudioFrame*> AudioFrames;
00719 
00721         //
00724         VideoFrames _videoFrames;
00725 
00727         //
00730         AudioFrames _audioFrames;
00731 
00732         void requestParserThreadKill()
00733         {
00734                 boost::mutex::scoped_lock lock(_parserThreadKillRequestMutex);
00735                 _parserThreadKillRequested=true;
00736                 _parserThreadWakeup.notify_all();
00737         }
00738 
00740         boost::uint64_t audioBufferLength() const;
00741 
00743         boost::uint64_t videoBufferLength() const;
00744 
00746         boost::uint64_t getBufferLengthNoLock() const;
00747         
00748 };
00749 
00750 
00751 } // gnash.media namespace 
00752 } // namespace gnash
00753 
00754 #endif // __MEDIAPARSER_H__

Generated on Fri Mar 16 2012 15:46:11 for Gnash by  doxygen 1.7.1