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 
98 
99  // NOTE: if you add more elements here remember to
100  // also add them to the output operator!
101 };
102 
103 DSOEXPORT std::ostream& operator<< (std::ostream& os, const videoCodecType& t);
104 
106 //
124 {
126  //
137 
139  //
150 
152  //
166 
169 
171  //
176 
178  //
183 
186 
189 
190  // NOTE: if you add more elements here remember to
191  // also add them to the output operator!
192 };
193 
194 DSOEXPORT std::ostream& operator<< (std::ostream& os, const audioCodecType& t);
195 
197 //
204 {
205 
206 public:
207 
209  //
234  AudioInfo(int codeci, boost::uint16_t sampleRatei,
235  boost::uint16_t sampleSizei, bool stereoi,
236  boost::uint64_t durationi, codecType typei)
237  :
238  codec(codeci),
239  sampleRate(sampleRatei),
240  sampleSize(sampleSizei),
241  stereo(stereoi),
242  duration(durationi),
243  type(typei)
244  {
245  }
246 
248  //
253  int codec;
254 
255  boost::uint16_t sampleRate;
256 
258  boost::uint16_t sampleSize;
259 
260  bool stereo;
261 
262  boost::uint64_t duration;
263 
265 
267  //
271  class ExtraInfo {
272  public:
273  virtual ~ExtraInfo() {}
274  };
275 
277  //
280  std::auto_ptr<ExtraInfo> extra;
281 };
282 
284 //
290 {
291 public:
292 
294  //
321  VideoInfo(int codeci, boost::uint16_t widthi, boost::uint16_t heighti,
322  boost::uint16_t frameRatei, boost::uint64_t durationi,
323  codecType typei)
324  :
325  codec(codeci),
326  width(widthi),
327  height(heighti),
328  frameRate(frameRatei),
329  duration(durationi),
330  type(typei)
331  {
332  }
333 
334  int codec;
335  boost::uint16_t width;
336  boost::uint16_t height;
337  boost::uint16_t frameRate;
338  boost::uint64_t duration;
340 
342  //
346  class ExtraInfo {
347  public:
348  virtual ~ExtraInfo() {}
349  };
350 
352  //
355  std::auto_ptr<ExtraInfo> extra;
356 };
357 
358 DSOEXPORT std::ostream& operator << (std::ostream& os, const VideoInfo& vi);
359 
360 
362 
363 public:
364  virtual ~EncodedExtraData() {}
365 
366 };
367 
370 {
371 public:
372 
374  //
387  EncodedVideoFrame(boost::uint8_t* data, boost::uint32_t size,
388  unsigned int frameNum,
389  boost::uint64_t timestamp=0)
390  :
391  _size(size),
392  _data(data),
393  _frameNum(frameNum),
394  _timestamp(timestamp)
395  {}
396 
398  const boost::uint8_t* data() const { return _data.get(); }
399 
401  boost::uint32_t dataSize() const { return _size; }
402 
404  boost::uint64_t timestamp() const { return _timestamp; }
405 
407  unsigned frameNum() const { return _frameNum; }
408 
409  // FIXME: should have better encapsulation for this sort of stuff.
410  std::auto_ptr<EncodedExtraData> extradata;
411 private:
412 
413  boost::uint32_t _size;
414  boost::scoped_array<boost::uint8_t> _data;
415  unsigned int _frameNum;
416  boost::uint64_t _timestamp;
417 };
418 
421 {
422 public:
423  boost::uint32_t dataSize;
424  boost::scoped_array<boost::uint8_t> data;
425  boost::uint64_t timestamp;
426 
427  // FIXME: should have better encapsulation for this sort of stuff.
428  std::auto_ptr<EncodedExtraData> extradata;
429 };
430 
432 //
440 {
441 public:
442 
444  //
446  typedef std::multimap<boost::uint64_t, boost::shared_ptr<SimpleBuffer> >
448 
449  typedef std::vector<MetaTags::mapped_type> OrderedMetaTags;
450  MediaParser(std::auto_ptr<IOChannel> stream);
451 
452  // Classes with virtual methods (virtual classes)
453  // must have a virtual destructor, or the destructors
454  // of subclasses will never be invoked, tipically resulting
455  // in memory leaks..
456  //
457  virtual ~MediaParser();
458 
462  //
469  virtual bool seek(boost::uint32_t& time)=0;
470 
472  //
480  DSOEXPORT boost::uint64_t getBufferLength() const;
481 
483  //
485  DSOEXPORT bool isBufferEmpty() const;
486 
488  DSOEXPORT boost::uint64_t getBufferTime() const
489  {
490  boost::mutex::scoped_lock lock(_bufferTimeMutex);
491  return _bufferTime;
492  }
493 
495  //
499  DSOEXPORT void setBufferTime(boost::uint64_t t)
500  {
501  boost::mutex::scoped_lock lock(_bufferTimeMutex);
502  _bufferTime=t;
503  }
504 
506  //
512  DSOEXPORT bool nextFrameTimestamp(boost::uint64_t& ts) const;
513 
515  //
521  DSOEXPORT bool nextVideoFrameTimestamp(boost::uint64_t& ts) const;
522 
524  //
530  DSOEXPORT std::auto_ptr<EncodedVideoFrame> nextVideoFrame();
531 
533  //
539  DSOEXPORT bool nextAudioFrameTimestamp(boost::uint64_t& ts) const;
540 
542  //
548  DSOEXPORT std::auto_ptr<EncodedAudioFrame> nextAudioFrame();
549 
551  //
555  VideoInfo* getVideoInfo() { return _videoInfo.get(); }
556 
558  //
562  AudioInfo* getAudioInfo() { return _audioInfo.get(); }
563 
565  //
571  bool parsingCompleted() const { return _parsingComplete; }
572 
574  //
581  virtual bool indexingCompleted() const { return true; }
582 
584  virtual boost::uint64_t getBytesLoaded() const { return 0; }
585 
587  boost::uint64_t getBytesTotal() const
588  {
589  return _stream->size();
590  }
591 
593  //
601  virtual bool parseNextChunk()=0;
602 
604  //
609  //
612  virtual void fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts);
613 
615  //
617  virtual boost::optional<Id3Info> getId3Info() const;
618 
619 protected:
620 
622 
624  std::auto_ptr<VideoInfo> _videoInfo;
625 
627  std::auto_ptr<AudioInfo> _audioInfo;
628 
631 
633  boost::uint64_t _bytesLoaded;
634 
636 
638  void startParserThread();
639 
641  //
647  void stopParserThread();
648 
650  void clearBuffers();
651 
653  //
656  void pushEncodedAudioFrame(std::auto_ptr<EncodedAudioFrame> frame);
657 
659  //
662  void pushEncodedVideoFrame(std::auto_ptr<EncodedVideoFrame> frame);
663 
665  std::auto_ptr<IOChannel> _stream;
666  mutable boost::mutex _streamMutex;
667 
669  {
670  mp->parserLoop();
671  }
672 
681  void parserLoop();
682 
684  {
685  boost::mutex::scoped_lock lock(_parserThreadKillRequestMutex);
687  }
688 
689  boost::uint64_t _bufferTime;
690  mutable boost::mutex _bufferTimeMutex;
691 
692  std::auto_ptr<boost::thread> _parserThread;
694  mutable boost::mutex _parserThreadKillRequestMutex;
696  boost::condition _parserThreadWakeup;
697 
703  void waitIfNeeded(boost::mutex::scoped_lock& qMutexLock);
704 
705  void wakeupParserThread();
706 
708  mutable boost::mutex _qMutex;
709 
711  mutable boost::mutex _bytesLoadedMutex;
712 
714  //
720  bool bufferFull() const;
721 
726 
727 private:
728 
729  typedef std::deque<EncodedVideoFrame*> VideoFrames;
730  typedef std::deque<EncodedAudioFrame*> AudioFrames;
731 
733  //
738  const EncodedVideoFrame* peekNextVideoFrame() const;
739 
741  //
746  const EncodedAudioFrame* peekNextAudioFrame() const;
747 
748 
750  //
753  VideoFrames _videoFrames;
754 
756  //
759  AudioFrames _audioFrames;
760 
761  void requestParserThreadKill()
762  {
763  boost::mutex::scoped_lock lock(_parserThreadKillRequestMutex);
765  _parserThreadWakeup.notify_all();
766  }
767 
769  boost::uint64_t audioBufferLength() const;
770 
772  boost::uint64_t videoBufferLength() const;
773 
775  boost::uint64_t getBufferLengthNoLock() const;
776 
777 };
778 
779 
780 } // gnash.media namespace
781 } // namespace gnash
782 
783 #endif // __MEDIAPARSER_H__