Gnash  0.8.11dev
MediaParser.h
Go to the documentation of this file.
1 // MediaParser.h: Base class for media parsers
2 //
3 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
4 // Free Software Foundation, Inc.
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 
20 #ifndef GNASH_MEDIAPARSER_H
21 #define GNASH_MEDIAPARSER_H
22 
23 #include <boost/scoped_array.hpp>
24 #include <boost/shared_ptr.hpp>
25 #include <boost/thread/thread.hpp>
26 #include <boost/thread/condition.hpp>
27 #include <boost/thread/barrier.hpp>
28 #include <memory>
29 #include <deque>
30 #include <map>
31 #include <vector>
32 #include <iosfwd> // for output operator forward declarations
33 #include <boost/optional.hpp>
34 
35 #include "IOChannel.h" // for inlines
36 #include "dsodefs.h" // DSOEXPORT
37 
38 // Undefine this to load/parse media files in main thread
39 #define LOAD_MEDIA_IN_A_SEPARATE_THREAD 1
40 
41 namespace gnash {
42  class SimpleBuffer;
43  namespace media {
44  struct Id3Info;
45  }
46 }
47 
48 namespace gnash {
49 namespace media {
50 
51 
54 {
56  KEY_FRAME = 1,
57 
60 
63 };
64 
67 {
70 
73 };
74 
77 {
80 
83 
86 
89 
92 
95 
96  // NOTE: if you add more elements here remember to
97  // also add them to the output operator!
98 };
99 
100 DSOEXPORT std::ostream& operator<< (std::ostream& os, const videoCodecType& t);
101 
103 //
121 {
123  //
134 
136  //
147 
149  //
163 
166 
168  //
173 
175  //
180 
183 
186 
187  // NOTE: if you add more elements here remember to
188  // also add them to the output operator!
189 };
190 
191 DSOEXPORT std::ostream& operator<< (std::ostream& os, const audioCodecType& t);
192 
194 //
201 {
202 
203 public:
204 
206  //
231  AudioInfo(int codeci, boost::uint16_t sampleRatei,
232  boost::uint16_t sampleSizei, bool stereoi,
233  boost::uint64_t durationi, codecType typei)
234  :
235  codec(codeci),
236  sampleRate(sampleRatei),
237  sampleSize(sampleSizei),
238  stereo(stereoi),
239  duration(durationi),
240  type(typei)
241  {
242  }
243 
245  //
250  int codec;
251 
252  boost::uint16_t sampleRate;
253 
255  boost::uint16_t sampleSize;
256 
257  bool stereo;
258 
259  boost::uint64_t duration;
260 
262 
264  //
268  class ExtraInfo {
269  public:
270  virtual ~ExtraInfo() {}
271  };
272 
274  //
277  std::auto_ptr<ExtraInfo> extra;
278 };
279 
281 //
287 {
288 public:
289 
291  //
318  VideoInfo(int codeci, boost::uint16_t widthi, boost::uint16_t heighti,
319  boost::uint16_t frameRatei, boost::uint64_t durationi,
320  codecType typei)
321  :
322  codec(codeci),
323  width(widthi),
324  height(heighti),
325  frameRate(frameRatei),
326  duration(durationi),
327  type(typei)
328  {
329  }
330 
331  int codec;
332  boost::uint16_t width;
333  boost::uint16_t height;
334  boost::uint16_t frameRate;
335  boost::uint64_t duration;
337 
339  //
343  class ExtraInfo {
344  public:
345  virtual ~ExtraInfo() {}
346  };
347 
349  //
352  std::auto_ptr<ExtraInfo> extra;
353 };
354 
355 DSOEXPORT std::ostream& operator << (std::ostream& os, const VideoInfo& vi);
356 
357 
359 
360 public:
361  virtual ~EncodedExtraData() {}
362 
363 };
364 
367 {
368 public:
369 
371  //
384  EncodedVideoFrame(boost::uint8_t* data, boost::uint32_t size,
385  unsigned int frameNum,
386  boost::uint64_t timestamp=0)
387  :
388  _size(size),
389  _data(data),
390  _frameNum(frameNum),
391  _timestamp(timestamp)
392  {}
393 
395  const boost::uint8_t* data() const { return _data.get(); }
396 
398  boost::uint32_t dataSize() const { return _size; }
399 
401  boost::uint64_t timestamp() const { return _timestamp; }
402 
404  unsigned frameNum() const { return _frameNum; }
405 
406  // FIXME: should have better encapsulation for this sort of stuff.
407  std::auto_ptr<EncodedExtraData> extradata;
408 private:
409 
410  boost::uint32_t _size;
411  boost::scoped_array<boost::uint8_t> _data;
412  unsigned int _frameNum;
413  boost::uint64_t _timestamp;
414 };
415 
418 {
419 public:
420  boost::uint32_t dataSize;
421  boost::scoped_array<boost::uint8_t> data;
422  boost::uint64_t timestamp;
423 
424  // FIXME: should have better encapsulation for this sort of stuff.
425  std::auto_ptr<EncodedExtraData> extradata;
426 };
427 
429 //
437 {
438 public:
439 
441  //
443  typedef std::multimap<boost::uint64_t, boost::shared_ptr<SimpleBuffer> >
445 
446  typedef std::vector<MetaTags::mapped_type> OrderedMetaTags;
447  MediaParser(std::auto_ptr<IOChannel> stream);
448 
449  // Classes with virtual methods (virtual classes)
450  // must have a virtual destructor, or the destructors
451  // of subclasses will never be invoked, tipically resulting
452  // in memory leaks..
453  //
454  virtual ~MediaParser();
455 
459  //
466  virtual bool seek(boost::uint32_t& time)=0;
467 
469  //
477  DSOEXPORT boost::uint64_t getBufferLength() const;
478 
480  //
482  DSOEXPORT bool isBufferEmpty() const;
483 
485  DSOEXPORT boost::uint64_t getBufferTime() const
486  {
487  boost::mutex::scoped_lock lock(_bufferTimeMutex);
488  return _bufferTime;
489  }
490 
492  //
496  DSOEXPORT void setBufferTime(boost::uint64_t t)
497  {
498  boost::mutex::scoped_lock lock(_bufferTimeMutex);
499  _bufferTime=t;
500  }
501 
503  //
509  DSOEXPORT bool nextFrameTimestamp(boost::uint64_t& ts) const;
510 
512  //
518  DSOEXPORT bool nextVideoFrameTimestamp(boost::uint64_t& ts) const;
519 
521  //
527  DSOEXPORT std::auto_ptr<EncodedVideoFrame> nextVideoFrame();
528 
530  //
536  DSOEXPORT bool nextAudioFrameTimestamp(boost::uint64_t& ts) const;
537 
539  //
545  DSOEXPORT std::auto_ptr<EncodedAudioFrame> nextAudioFrame();
546 
548  //
552  VideoInfo* getVideoInfo() { return _videoInfo.get(); }
553 
555  //
559  AudioInfo* getAudioInfo() { return _audioInfo.get(); }
560 
562  //
568  bool parsingCompleted() const { return _parsingComplete; }
569 
571  //
578  virtual bool indexingCompleted() const { return true; }
579 
581  virtual boost::uint64_t getBytesLoaded() const { return 0; }
582 
584  boost::uint64_t getBytesTotal() const
585  {
586  return _stream->size();
587  }
588 
590  //
598  virtual bool parseNextChunk()=0;
599 
601  //
606  //
609  virtual void fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts);
610 
612  //
614  virtual boost::optional<Id3Info> getId3Info() const;
615 
616 protected:
617 
619 
621  std::auto_ptr<VideoInfo> _videoInfo;
622 
624  std::auto_ptr<AudioInfo> _audioInfo;
625 
628 
630  boost::uint64_t _bytesLoaded;
631 
633 
635  void startParserThread();
636 
638  //
644  void stopParserThread();
645 
647  void clearBuffers();
648 
650  //
653  void pushEncodedAudioFrame(std::auto_ptr<EncodedAudioFrame> frame);
654 
656  //
659  void pushEncodedVideoFrame(std::auto_ptr<EncodedVideoFrame> frame);
660 
662  std::auto_ptr<IOChannel> _stream;
663  mutable boost::mutex _streamMutex;
664 
666  {
667  mp->parserLoop();
668  }
669 
678  void parserLoop();
679 
681  {
682  boost::mutex::scoped_lock lock(_parserThreadKillRequestMutex);
684  }
685 
686  boost::uint64_t _bufferTime;
687  mutable boost::mutex _bufferTimeMutex;
688 
689  std::auto_ptr<boost::thread> _parserThread;
691  mutable boost::mutex _parserThreadKillRequestMutex;
693  boost::condition _parserThreadWakeup;
694 
700  void waitIfNeeded(boost::mutex::scoped_lock& qMutexLock);
701 
702  void wakeupParserThread();
703 
705  mutable boost::mutex _qMutex;
706 
708  mutable boost::mutex _bytesLoadedMutex;
709 
711  //
717  bool bufferFull() const;
718 
723 
724 private:
725 
726  typedef std::deque<EncodedVideoFrame*> VideoFrames;
727  typedef std::deque<EncodedAudioFrame*> AudioFrames;
728 
730  //
735  const EncodedVideoFrame* peekNextVideoFrame() const;
736 
738  //
743  const EncodedAudioFrame* peekNextAudioFrame() const;
744 
745 
747  //
750  VideoFrames _videoFrames;
751 
753  //
756  AudioFrames _audioFrames;
757 
758  void requestParserThreadKill()
759  {
760  boost::mutex::scoped_lock lock(_parserThreadKillRequestMutex);
762  _parserThreadWakeup.notify_all();
763  }
764 
766  boost::uint64_t audioBufferLength() const;
767 
769  boost::uint64_t videoBufferLength() const;
770 
772  boost::uint64_t getBufferLengthNoLock() const;
773 
774 };
775 
776 
777 } // gnash.media namespace
778 } // namespace gnash
779 
780 #endif // __MEDIAPARSER_H__