00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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>
00033 #include <boost/optional.hpp>
00034
00035 #include "IOChannel.h"
00036 #include "dsodefs.h"
00037
00038
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
00097
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
00188
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
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
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
00450
00451
00452
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 }
00778 }
00779
00780 #endif // __MEDIAPARSER_H__