1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/MediaDecoderReader.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,181 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 +#if !defined(MediaDecoderReader_h_) 1.10 +#define MediaDecoderReader_h_ 1.11 + 1.12 +#include "AbstractMediaDecoder.h" 1.13 +#include "MediaInfo.h" 1.14 +#include "MediaData.h" 1.15 +#include "MediaQueue.h" 1.16 +#include "AudioCompactor.h" 1.17 + 1.18 +namespace mozilla { 1.19 + 1.20 +namespace dom { 1.21 +class TimeRanges; 1.22 +} 1.23 + 1.24 +// Encapsulates the decoding and reading of media data. Reading can only be 1.25 +// done on the decode thread. Never hold the decoder monitor when 1.26 +// calling into this class. Unless otherwise specified, methods and fields of 1.27 +// this class can only be accessed on the decode thread. 1.28 +class MediaDecoderReader { 1.29 +public: 1.30 + MediaDecoderReader(AbstractMediaDecoder* aDecoder); 1.31 + virtual ~MediaDecoderReader(); 1.32 + 1.33 + // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE 1.34 + // on failure. 1.35 + virtual nsresult Init(MediaDecoderReader* aCloneDonor) = 0; 1.36 + 1.37 + // True if this reader is waiting media resource allocation 1.38 + virtual bool IsWaitingMediaResources() { return false; } 1.39 + // True when this reader need to become dormant state 1.40 + virtual bool IsDormantNeeded() { return false; } 1.41 + // Release media resources they should be released in dormant state 1.42 + virtual void ReleaseMediaResources() {}; 1.43 + // Release the decoder during shutdown 1.44 + virtual void ReleaseDecoder() {}; 1.45 + 1.46 + // Resets all state related to decoding, emptying all buffers etc. 1.47 + virtual nsresult ResetDecode(); 1.48 + 1.49 + // Decodes an unspecified amount of audio data, enqueuing the audio data 1.50 + // in mAudioQueue. Returns true when there's more audio to decode, 1.51 + // false if the audio is finished, end of file has been reached, 1.52 + // or an un-recoverable read error has occured. 1.53 + virtual bool DecodeAudioData() = 0; 1.54 + 1.55 + // Reads and decodes one video frame. Packets with a timestamp less 1.56 + // than aTimeThreshold will be decoded (unless they're not keyframes 1.57 + // and aKeyframeSkip is true), but will not be added to the queue. 1.58 + virtual bool DecodeVideoFrame(bool &aKeyframeSkip, 1.59 + int64_t aTimeThreshold) = 0; 1.60 + 1.61 + virtual bool HasAudio() = 0; 1.62 + virtual bool HasVideo() = 0; 1.63 + 1.64 + // Read header data for all bitstreams in the file. Fills aInfo with 1.65 + // the data required to present the media, and optionally fills *aTags 1.66 + // with tag metadata from the file. 1.67 + // Returns NS_OK on success, or NS_ERROR_FAILURE on failure. 1.68 + virtual nsresult ReadMetadata(MediaInfo* aInfo, 1.69 + MetadataTags** aTags) = 0; 1.70 + 1.71 + // Stores the presentation time of the first frame we'd be able to play if 1.72 + // we started playback at the current position. Returns the first video 1.73 + // frame, if we have video. 1.74 + virtual VideoData* FindStartTime(int64_t& aOutStartTime); 1.75 + 1.76 + // Moves the decode head to aTime microseconds. aStartTime and aEndTime 1.77 + // denote the start and end times of the media in usecs, and aCurrentTime 1.78 + // is the current playback position in microseconds. 1.79 + virtual nsresult Seek(int64_t aTime, 1.80 + int64_t aStartTime, 1.81 + int64_t aEndTime, 1.82 + int64_t aCurrentTime) = 0; 1.83 + 1.84 + // Called to move the reader into idle/active state. When the reader is 1.85 + // created it is assumed to be active (i.e. not idle). When the media 1.86 + // element is paused and we don't need to decode any more data, the state 1.87 + // machine calls SetIdle() to inform the reader that its decoder won't be 1.88 + // needed for a while. When we need to decode data again, the state machine 1.89 + // calls SetActive() to activate the decoder. The reader can use these 1.90 + // notifications to enter/exit a low power state when the decoder isn't 1.91 + // needed, if desired. This is most useful on mobile. 1.92 + virtual void SetIdle() { } 1.93 + virtual void SetActive() { } 1.94 + 1.95 + // Tell the reader that the data decoded are not for direct playback, so it 1.96 + // can accept more files, in particular those which have more channels than 1.97 + // available in the audio output. 1.98 + void SetIgnoreAudioOutputFormat() 1.99 + { 1.100 + mIgnoreAudioOutputFormat = true; 1.101 + } 1.102 + 1.103 +protected: 1.104 + // Queue of audio frames. This queue is threadsafe, and is accessed from 1.105 + // the audio, decoder, state machine, and main threads. 1.106 + MediaQueue<AudioData> mAudioQueue; 1.107 + 1.108 + // Queue of video frames. This queue is threadsafe, and is accessed from 1.109 + // the decoder, state machine, and main threads. 1.110 + MediaQueue<VideoData> mVideoQueue; 1.111 + 1.112 + // An adapter to the audio queue which first copies data to buffers with 1.113 + // minimal allocation slop and then pushes them to the queue. This is 1.114 + // useful for decoders working with formats that give awkward numbers of 1.115 + // frames such as mp3. 1.116 + AudioCompactor mAudioCompactor; 1.117 + 1.118 +public: 1.119 + // Populates aBuffered with the time ranges which are buffered. aStartTime 1.120 + // must be the presentation time of the first frame in the media, e.g. 1.121 + // the media time corresponding to playback time/position 0. This function 1.122 + // is called on the main, decode, and state machine threads. 1.123 + // 1.124 + // This base implementation in MediaDecoderReader estimates the time ranges 1.125 + // buffered by interpolating the cached byte ranges with the duration 1.126 + // of the media. Reader subclasses should override this method if they 1.127 + // can quickly calculate the buffered ranges more accurately. 1.128 + // 1.129 + // The primary advantage of this implementation in the reader base class 1.130 + // is that it's a fast approximation, which does not perform any I/O. 1.131 + // 1.132 + // The OggReader relies on this base implementation not performing I/O, 1.133 + // since in FirefoxOS we can't do I/O on the main thread, where this is 1.134 + // called. 1.135 + virtual nsresult GetBuffered(dom::TimeRanges* aBuffered, 1.136 + int64_t aStartTime); 1.137 + 1.138 + // Returns the number of bytes of memory allocated by structures/frames in 1.139 + // the video queue. 1.140 + size_t SizeOfVideoQueueInBytes() const; 1.141 + 1.142 + // Returns the number of bytes of memory allocated by structures/frames in 1.143 + // the audio queue. 1.144 + size_t SizeOfAudioQueueInBytes() const; 1.145 + 1.146 + // Only used by WebMReader and MediaOmxReader for now, so stub here rather 1.147 + // than in every reader than inherits from MediaDecoderReader. 1.148 + virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) {} 1.149 + 1.150 + virtual MediaQueue<AudioData>& AudioQueue() { return mAudioQueue; } 1.151 + virtual MediaQueue<VideoData>& VideoQueue() { return mVideoQueue; } 1.152 + 1.153 + // Returns a pointer to the decoder. 1.154 + AbstractMediaDecoder* GetDecoder() { 1.155 + return mDecoder; 1.156 + } 1.157 + 1.158 + AudioData* DecodeToFirstAudioData(); 1.159 + VideoData* DecodeToFirstVideoData(); 1.160 + 1.161 + // Decodes samples until we reach frames required to play at time aTarget 1.162 + // (usecs). This also trims the samples to start exactly at aTarget, 1.163 + // by discarding audio samples and adjusting start times of video frames. 1.164 + nsresult DecodeToTarget(int64_t aTarget); 1.165 + 1.166 + MediaInfo GetMediaInfo() { return mInfo; } 1.167 + 1.168 +protected: 1.169 + 1.170 + // Reference to the owning decoder object. 1.171 + AbstractMediaDecoder* mDecoder; 1.172 + 1.173 + // Stores presentation info required for playback. 1.174 + MediaInfo mInfo; 1.175 + 1.176 + // Whether we should accept media that we know we can't play 1.177 + // directly, because they have a number of channel higher than 1.178 + // what we support. 1.179 + bool mIgnoreAudioOutputFormat; 1.180 +}; 1.181 + 1.182 +} // namespace mozilla 1.183 + 1.184 +#endif