content/media/webm/WebMReader.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #if !defined(WebMReader_h_)
     7 #define WebMReader_h_
     9 #include <stdint.h>
    11 #include "nsDeque.h"
    12 #include "MediaDecoderReader.h"
    13 #include "nsAutoRef.h"
    14 #include "nestegg/nestegg.h"
    16 #define VPX_DONT_DEFINE_STDINT_TYPES
    17 #include "vpx/vpx_codec.h"
    19 #ifdef MOZ_TREMOR
    20 #include "tremor/ivorbiscodec.h"
    21 #else
    22 #include "vorbis/codec.h"
    23 #endif
    25 #ifdef MOZ_OPUS
    26 #include "OpusParser.h"
    27 #endif
    29 namespace mozilla {
    31 class WebMBufferedState;
    33 // Holds a nestegg_packet, and its file offset. This is needed so we
    34 // know the offset in the file we've played up to, in order to calculate
    35 // whether it's likely we can play through to the end without needing
    36 // to stop to buffer, given the current download rate.
    37 class NesteggPacketHolder {
    38 public:
    39   NesteggPacketHolder(nestegg_packet* aPacket, int64_t aOffset)
    40     : mPacket(aPacket), mOffset(aOffset)
    41   {
    42     MOZ_COUNT_CTOR(NesteggPacketHolder);
    43   }
    44   ~NesteggPacketHolder() {
    45     MOZ_COUNT_DTOR(NesteggPacketHolder);
    46     nestegg_free_packet(mPacket);
    47   }
    48   nestegg_packet* mPacket;
    49   // Offset in bytes. This is the offset of the end of the Block
    50   // which contains the packet.
    51   int64_t mOffset;
    52 private:
    53   // Copy constructor and assignment operator not implemented. Don't use them!
    54   NesteggPacketHolder(const NesteggPacketHolder &aOther);
    55   NesteggPacketHolder& operator= (NesteggPacketHolder const& aOther);
    56 };
    58 // Thread and type safe wrapper around nsDeque.
    59 class PacketQueueDeallocator : public nsDequeFunctor {
    60   virtual void* operator() (void* anObject) {
    61     delete static_cast<NesteggPacketHolder*>(anObject);
    62     return nullptr;
    63   }
    64 };
    66 // Typesafe queue for holding nestegg packets. It has
    67 // ownership of the items in the queue and will free them
    68 // when destroyed.
    69 class WebMPacketQueue : private nsDeque {
    70  public:
    71    WebMPacketQueue()
    72      : nsDeque(new PacketQueueDeallocator())
    73    {}
    75   ~WebMPacketQueue() {
    76     Reset();
    77   }
    79   inline int32_t GetSize() { 
    80     return nsDeque::GetSize();
    81   }
    83   inline void Push(NesteggPacketHolder* aItem) {
    84     NS_ASSERTION(aItem, "NULL pushed to WebMPacketQueue");
    85     nsDeque::Push(aItem);
    86   }
    88   inline void PushFront(NesteggPacketHolder* aItem) {
    89     NS_ASSERTION(aItem, "NULL pushed to WebMPacketQueue");
    90     nsDeque::PushFront(aItem);
    91   }
    93   inline NesteggPacketHolder* PopFront() {
    94     return static_cast<NesteggPacketHolder*>(nsDeque::PopFront());
    95   }
    97   void Reset() {
    98     while (GetSize() > 0) {
    99       delete PopFront();
   100     }
   101   }
   102 };
   104 class WebMReader : public MediaDecoderReader
   105 {
   106 public:
   107   WebMReader(AbstractMediaDecoder* aDecoder);
   108   ~WebMReader();
   110   virtual nsresult Init(MediaDecoderReader* aCloneDonor);
   111   virtual nsresult ResetDecode();
   112   virtual bool DecodeAudioData();
   114   // If the Theora granulepos has not been captured, it may read several packets
   115   // until one with a granulepos has been captured, to ensure that all packets
   116   // read have valid time info.  
   117   virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
   118                                   int64_t aTimeThreshold);
   120   virtual bool HasAudio()
   121   {
   122     NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   123     return mHasAudio;
   124   }
   126   virtual bool HasVideo()
   127   {
   128     NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   129     return mHasVideo;
   130   }
   132   virtual nsresult ReadMetadata(MediaInfo* aInfo,
   133                                 MetadataTags** aTags);
   134   virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
   135   virtual nsresult GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime);
   136   virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
   138 protected:
   139   // Value passed to NextPacket to determine if we are reading a video or an
   140   // audio packet.
   141   enum TrackType {
   142     VIDEO = 0,
   143     AUDIO = 1
   144   };
   146   // Read a packet from the nestegg file. Returns nullptr if all packets for
   147   // the particular track have been read. Pass VIDEO or AUDIO to indicate the
   148   // type of the packet we want to read.
   149   nsReturnRef<NesteggPacketHolder> NextPacket(TrackType aTrackType);
   151   // Pushes a packet to the front of the video packet queue.
   152   virtual void PushVideoPacket(NesteggPacketHolder* aItem);
   154   // Returns an initialized ogg packet with data obtained from the WebM container.
   155   ogg_packet InitOggPacket(unsigned char* aData,
   156                            size_t aLength,
   157                            bool aBOS,
   158                            bool aEOS,
   159                            int64_t aGranulepos);
   161 #ifdef MOZ_OPUS
   162   // Setup opus decoder
   163   bool InitOpusDecoder();
   164 #endif
   166   // Decode a nestegg packet of audio data. Push the audio data on the
   167   // audio queue. Returns true when there's more audio to decode,
   168   // false if the audio is finished, end of file has been reached,
   169   // or an un-recoverable read error has occured. The reader's monitor
   170   // must be held during this call. The caller is responsible for freeing
   171   // aPacket.
   172   bool DecodeAudioPacket(nestegg_packet* aPacket, int64_t aOffset);
   174   // Release context and set to null. Called when an error occurs during
   175   // reading metadata or destruction of the reader itself.
   176   void Cleanup();
   178 private:
   179   // libnestegg context for webm container. Access on state machine thread
   180   // or decoder thread only.
   181   nestegg* mContext;
   183   // VP8 decoder state
   184   vpx_codec_ctx_t mVPX;
   186   // Vorbis decoder state
   187   vorbis_info mVorbisInfo;
   188   vorbis_comment mVorbisComment;
   189   vorbis_dsp_state mVorbisDsp;
   190   vorbis_block mVorbisBlock;
   191   uint32_t mPacketCount;
   192   uint32_t mChannels;
   195 #ifdef MOZ_OPUS
   196   // Opus decoder state
   197   nsAutoPtr<OpusParser> mOpusParser;
   198   OpusMSDecoder *mOpusDecoder;
   199   int mSkip;        // Number of samples left to trim before playback.
   200   uint64_t mSeekPreroll; // Number of nanoseconds that must be discarded after seeking.
   201 #endif
   203   // Queue of video and audio packets that have been read but not decoded. These
   204   // must only be accessed from the state machine thread.
   205   WebMPacketQueue mVideoPackets;
   206   WebMPacketQueue mAudioPackets;
   208   // Index of video and audio track to play
   209   uint32_t mVideoTrack;
   210   uint32_t mAudioTrack;
   212   // Time in microseconds of the start of the first audio frame we've decoded.
   213   int64_t mAudioStartUsec;
   215   // Number of audio frames we've decoded since decoding began at mAudioStartMs.
   216   uint64_t mAudioFrames;
   218   // Number of microseconds that must be discarded from the start of the Stream.
   219   uint64_t mCodecDelay;
   221   // Parser state and computed offset-time mappings.  Shared by multiple
   222   // readers when decoder has been cloned.  Main thread only.
   223   nsRefPtr<WebMBufferedState> mBufferedState;
   225   // Size of the frame initially present in the stream. The picture region
   226   // is defined as a ratio relative to this.
   227   nsIntSize mInitialFrame;
   229   // Picture region, as relative to the initial frame size.
   230   nsIntRect mPicture;
   232   // Codec ID of audio track
   233   int mAudioCodec;
   234   // Codec ID of video track
   235   int mVideoCodec;
   237   // Booleans to indicate if we have audio and/or video data
   238   bool mHasVideo;
   239   bool mHasAudio;
   240 };
   242 } // namespace mozilla
   244 #endif

mercurial