Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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(MediaDecoderReader_h_)
7 #define MediaDecoderReader_h_
9 #include "AbstractMediaDecoder.h"
10 #include "MediaInfo.h"
11 #include "MediaData.h"
12 #include "MediaQueue.h"
13 #include "AudioCompactor.h"
15 namespace mozilla {
17 namespace dom {
18 class TimeRanges;
19 }
21 // Encapsulates the decoding and reading of media data. Reading can only be
22 // done on the decode thread. Never hold the decoder monitor when
23 // calling into this class. Unless otherwise specified, methods and fields of
24 // this class can only be accessed on the decode thread.
25 class MediaDecoderReader {
26 public:
27 MediaDecoderReader(AbstractMediaDecoder* aDecoder);
28 virtual ~MediaDecoderReader();
30 // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
31 // on failure.
32 virtual nsresult Init(MediaDecoderReader* aCloneDonor) = 0;
34 // True if this reader is waiting media resource allocation
35 virtual bool IsWaitingMediaResources() { return false; }
36 // True when this reader need to become dormant state
37 virtual bool IsDormantNeeded() { return false; }
38 // Release media resources they should be released in dormant state
39 virtual void ReleaseMediaResources() {};
40 // Release the decoder during shutdown
41 virtual void ReleaseDecoder() {};
43 // Resets all state related to decoding, emptying all buffers etc.
44 virtual nsresult ResetDecode();
46 // Decodes an unspecified amount of audio data, enqueuing the audio data
47 // in mAudioQueue. Returns true when there's more audio to decode,
48 // false if the audio is finished, end of file has been reached,
49 // or an un-recoverable read error has occured.
50 virtual bool DecodeAudioData() = 0;
52 // Reads and decodes one video frame. Packets with a timestamp less
53 // than aTimeThreshold will be decoded (unless they're not keyframes
54 // and aKeyframeSkip is true), but will not be added to the queue.
55 virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
56 int64_t aTimeThreshold) = 0;
58 virtual bool HasAudio() = 0;
59 virtual bool HasVideo() = 0;
61 // Read header data for all bitstreams in the file. Fills aInfo with
62 // the data required to present the media, and optionally fills *aTags
63 // with tag metadata from the file.
64 // Returns NS_OK on success, or NS_ERROR_FAILURE on failure.
65 virtual nsresult ReadMetadata(MediaInfo* aInfo,
66 MetadataTags** aTags) = 0;
68 // Stores the presentation time of the first frame we'd be able to play if
69 // we started playback at the current position. Returns the first video
70 // frame, if we have video.
71 virtual VideoData* FindStartTime(int64_t& aOutStartTime);
73 // Moves the decode head to aTime microseconds. aStartTime and aEndTime
74 // denote the start and end times of the media in usecs, and aCurrentTime
75 // is the current playback position in microseconds.
76 virtual nsresult Seek(int64_t aTime,
77 int64_t aStartTime,
78 int64_t aEndTime,
79 int64_t aCurrentTime) = 0;
81 // Called to move the reader into idle/active state. When the reader is
82 // created it is assumed to be active (i.e. not idle). When the media
83 // element is paused and we don't need to decode any more data, the state
84 // machine calls SetIdle() to inform the reader that its decoder won't be
85 // needed for a while. When we need to decode data again, the state machine
86 // calls SetActive() to activate the decoder. The reader can use these
87 // notifications to enter/exit a low power state when the decoder isn't
88 // needed, if desired. This is most useful on mobile.
89 virtual void SetIdle() { }
90 virtual void SetActive() { }
92 // Tell the reader that the data decoded are not for direct playback, so it
93 // can accept more files, in particular those which have more channels than
94 // available in the audio output.
95 void SetIgnoreAudioOutputFormat()
96 {
97 mIgnoreAudioOutputFormat = true;
98 }
100 protected:
101 // Queue of audio frames. This queue is threadsafe, and is accessed from
102 // the audio, decoder, state machine, and main threads.
103 MediaQueue<AudioData> mAudioQueue;
105 // Queue of video frames. This queue is threadsafe, and is accessed from
106 // the decoder, state machine, and main threads.
107 MediaQueue<VideoData> mVideoQueue;
109 // An adapter to the audio queue which first copies data to buffers with
110 // minimal allocation slop and then pushes them to the queue. This is
111 // useful for decoders working with formats that give awkward numbers of
112 // frames such as mp3.
113 AudioCompactor mAudioCompactor;
115 public:
116 // Populates aBuffered with the time ranges which are buffered. aStartTime
117 // must be the presentation time of the first frame in the media, e.g.
118 // the media time corresponding to playback time/position 0. This function
119 // is called on the main, decode, and state machine threads.
120 //
121 // This base implementation in MediaDecoderReader estimates the time ranges
122 // buffered by interpolating the cached byte ranges with the duration
123 // of the media. Reader subclasses should override this method if they
124 // can quickly calculate the buffered ranges more accurately.
125 //
126 // The primary advantage of this implementation in the reader base class
127 // is that it's a fast approximation, which does not perform any I/O.
128 //
129 // The OggReader relies on this base implementation not performing I/O,
130 // since in FirefoxOS we can't do I/O on the main thread, where this is
131 // called.
132 virtual nsresult GetBuffered(dom::TimeRanges* aBuffered,
133 int64_t aStartTime);
135 // Returns the number of bytes of memory allocated by structures/frames in
136 // the video queue.
137 size_t SizeOfVideoQueueInBytes() const;
139 // Returns the number of bytes of memory allocated by structures/frames in
140 // the audio queue.
141 size_t SizeOfAudioQueueInBytes() const;
143 // Only used by WebMReader and MediaOmxReader for now, so stub here rather
144 // than in every reader than inherits from MediaDecoderReader.
145 virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) {}
147 virtual MediaQueue<AudioData>& AudioQueue() { return mAudioQueue; }
148 virtual MediaQueue<VideoData>& VideoQueue() { return mVideoQueue; }
150 // Returns a pointer to the decoder.
151 AbstractMediaDecoder* GetDecoder() {
152 return mDecoder;
153 }
155 AudioData* DecodeToFirstAudioData();
156 VideoData* DecodeToFirstVideoData();
158 // Decodes samples until we reach frames required to play at time aTarget
159 // (usecs). This also trims the samples to start exactly at aTarget,
160 // by discarding audio samples and adjusting start times of video frames.
161 nsresult DecodeToTarget(int64_t aTarget);
163 MediaInfo GetMediaInfo() { return mInfo; }
165 protected:
167 // Reference to the owning decoder object.
168 AbstractMediaDecoder* mDecoder;
170 // Stores presentation info required for playback.
171 MediaInfo mInfo;
173 // Whether we should accept media that we know we can't play
174 // directly, because they have a number of channel higher than
175 // what we support.
176 bool mIgnoreAudioOutputFormat;
177 };
179 } // namespace mozilla
181 #endif