00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef GNASH_MEDIAPARSER_H
00020 #define GNASH_MEDIAPARSER_H
00021
00022 #include "IOChannel.h"
00023 #include "dsodefs.h"
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>
00035
00036
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
00092
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
00183
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
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
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
00445
00446
00447
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 }
00752 }
00753
00754 #endif // __MEDIAPARSER_H__