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.

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

mercurial