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 /* vim:set ts=2 sw=2 sts=2 et cindent: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #if !defined(RtspMediaResource_h_)
7 #define RtspMediaResource_h_
9 #include "MediaResource.h"
11 namespace mozilla {
13 class RtspTrackBuffer;
15 /* RtspMediaResource
16 * RtspMediaResource provides an interface to deliver and control RTSP media
17 * data to RtspDecoder.
18 *
19 * RTSP Flow Start vs HTTP Flow Start:
20 * For HTTP (and files stored on disk), once the channel is created and response
21 * data is available, HTMLMediaElement::MediaLoadListener::OnStartRequest is
22 * called. (Note, this is an asynchronous call following channel->AsyncOpen).
23 * The decoder and MediaResource are set up to talk to each other:
24 * InitializeDecoderForChannel and FinishDecoderSetup.
25 * RtspMediaResource is different from this, in that FinishDecoderSetup is
26 * postponed until after the initial connection with the server is made.
27 * RtspController, owned by RtspMediaResource, provides the interface to setup
28 * the connection, and calls RtspMediaResource::Listener::OnConnected
29 * (from nsIStreamingProtocolListener). FinishDecoderSetup is then called to
30 * connect RtspMediaResource with RtspDecoder and allow HTMLMediaElement to
31 * request playback etc.
32 *
33 * Playback:
34 * When the user presses play/pause, HTMLMediaElement::Play/::Pause is called,
35 * subsequently making calls to the decoder state machine. Upon these state
36 * changes, the decoder is told to start reading and decoding data. This causes
37 * the nsIStreamingMediaController object to send play/pause commands to the
38 * server.
39 * Data is then delivered to the host and eventually written to the
40 * RtspTrackBuffer objects. Note that RtspMediaResource does not know about the
41 * play or pause state. It only knows about the data written into its buffers.
42 *
43 * Data Structures and Flow:
44 * Unlike HTTP, RTSP provides separate streams for audio and video.
45 * As such, it creates two RtspTrackBuffer objects for the audio and video data.
46 * Data is read using the function ReadFrameFromTrack. These buffer objects are
47 * ring buffers, implying that data from the network may be discarded if the
48 * decoder cannot read at a high enough rate.
49 *
50 * Data is delivered via RtspMediaResource::Listener::OnMediaDataAvailable.
51 * This Listener implements nsIStreamingProtocolListener, and writes the data to
52 * the appropriate RtspTrackBuffer. The decoder then reads the data by calling
53 * RtspMediaResource::ReadFrameFromTrack. Note that the decoder and decode
54 * thread will be blocked until data is available in one of the two buffers.
55 *
56 * Seeking:
57 * Since the frame data received after seek is not continuous with existing
58 * frames in RtspTrackBuffer, the buffer must be cleared. If we don't clear the
59 * old frame data in RtspTrackBuffer, the decoder's behavior will be
60 * unpredictable. So we add |mFrameType| in RtspTrackBuffer to do this:
61 * When we are seeking, the mFrameType flag is set, and RtspTrackBuffer will
62 * drop the incoming data until the RTSP server completes the seek operation.
63 * Note: seeking for RTSP is carried out based on sending the seek time to the
64 * server, unlike HTTP in which the seek time is converted to a byte offset.
65 * Thus, RtspMediaResource has a SeekTime function which should be called
66 * instead of Seek.
67 * */
68 class RtspMediaResource : public BaseMediaResource
69 {
70 public:
71 RtspMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI,
72 const nsACString& aContentType);
73 virtual ~RtspMediaResource();
75 // The following methods can be called on any thread.
77 // Get the RtspMediaResource pointer if this MediaResource is a
78 // RtspMediaResource. For calling Rtsp specific functions.
79 virtual RtspMediaResource* GetRtspPointer() MOZ_OVERRIDE MOZ_FINAL {
80 return this;
81 }
83 // Returns the nsIStreamingProtocolController in the RtspMediaResource.
84 // RtspMediaExtractor: request it to get mime type for creating decoder.
85 // RtspOmxDecoder: request it to send play/pause commands to RTSP server.
86 // The lifetime of mMediaStreamController is controlled by RtspMediaResource
87 // because the RtspMediaExtractor and RtspOmxDecoder won't hold the reference.
88 nsIStreamingProtocolController* GetMediaStreamController() {
89 return mMediaStreamController;
90 }
92 virtual bool IsRealTime() MOZ_OVERRIDE {
93 return mRealTime;
94 }
96 // The following methods can be called on any thread except main thread.
98 // Read data from track.
99 // Parameters:
100 // aToBuffer, aToBufferSize: buffer pointer and buffer size.
101 // aReadCount: output actual read bytes.
102 // aFrameTime: output frame time stamp.
103 // aFrameSize: actual data size in track.
104 nsresult ReadFrameFromTrack(uint8_t* aBuffer, uint32_t aBufferSize,
105 uint32_t aTrackIdx, uint32_t& aBytes,
106 uint64_t& aTime, uint32_t& aFrameSize);
108 // Seek to the given time offset
109 nsresult SeekTime(int64_t aOffset);
111 // dummy
112 virtual nsresult ReadAt(int64_t aOffset, char* aBuffer,
113 uint32_t aCount, uint32_t* aBytes) MOZ_OVERRIDE{
114 return NS_ERROR_FAILURE;
115 }
116 // dummy
117 virtual void SetReadMode(MediaCacheStream::ReadMode aMode) MOZ_OVERRIDE {}
118 // dummy
119 virtual void SetPlaybackRate(uint32_t aBytesPerSecond) MOZ_OVERRIDE {}
120 // dummy
121 virtual nsresult Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
122 MOZ_OVERRIDE {
123 return NS_OK;
124 }
125 // dummy
126 virtual nsresult Seek(int32_t aWhence, int64_t aOffset) MOZ_OVERRIDE {
127 return NS_OK;
128 }
129 // dummy
130 virtual void StartSeekingForMetadata() MOZ_OVERRIDE {}
131 // dummy
132 virtual void EndSeekingForMetadata() MOZ_OVERRIDE {}
133 // dummy
134 virtual int64_t Tell() MOZ_OVERRIDE { return 0; }
136 // Any thread
137 virtual void Pin() MOZ_OVERRIDE {}
138 virtual void Unpin() MOZ_OVERRIDE {}
140 // dummy
141 virtual bool IsSuspendedByCache() MOZ_OVERRIDE { return false; }
143 virtual bool IsSuspended() MOZ_OVERRIDE { return false; }
144 virtual bool IsTransportSeekable() MOZ_OVERRIDE { return true; }
145 // dummy
146 virtual double GetDownloadRate(bool* aIsReliable) MOZ_OVERRIDE { return 0; }
148 virtual int64_t GetLength() MOZ_OVERRIDE {
149 if (mRealTime) {
150 return -1;
151 }
152 return 0;
153 }
155 // dummy
156 virtual int64_t GetNextCachedData(int64_t aOffset) MOZ_OVERRIDE { return 0; }
157 // dummy
158 virtual int64_t GetCachedDataEnd(int64_t aOffset) MOZ_OVERRIDE { return 0; }
159 // dummy
160 virtual bool IsDataCachedToEndOfResource(int64_t aOffset) MOZ_OVERRIDE {
161 return false;
162 }
163 // dummy
164 nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) MOZ_OVERRIDE {
165 return NS_ERROR_FAILURE;
166 }
168 // The following methods can be called on main thread only.
170 virtual nsresult Open(nsIStreamListener** aStreamListener) MOZ_OVERRIDE;
171 virtual nsresult Close() MOZ_OVERRIDE;
172 virtual void Suspend(bool aCloseImmediately) MOZ_OVERRIDE;
173 virtual void Resume() MOZ_OVERRIDE;
174 virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() MOZ_OVERRIDE;
175 virtual bool CanClone() MOZ_OVERRIDE {
176 return false;
177 }
178 virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder)
179 MOZ_OVERRIDE {
180 return nullptr;
181 }
182 // dummy
183 virtual nsresult ReadFromCache(char* aBuffer, int64_t aOffset,
184 uint32_t aCount) MOZ_OVERRIDE {
185 return NS_ERROR_FAILURE;
186 }
188 virtual size_t SizeOfExcludingThis(
189 MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
191 virtual size_t SizeOfIncludingThis(
192 MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE {
193 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
194 }
196 // Listener implements nsIStreamingProtocolListener as
197 // mMediaStreamController's callback function.
198 // It holds RtspMediaResource reference to notify the connection status and
199 // data arrival. The Revoke function releases the reference when
200 // RtspMediaResource::OnDisconnected is called.
201 class Listener MOZ_FINAL : public nsIInterfaceRequestor,
202 public nsIStreamingProtocolListener
203 {
204 public:
205 Listener(RtspMediaResource* aResource) : mResource(aResource) {}
206 ~Listener() {}
208 NS_DECL_ISUPPORTS
209 NS_DECL_NSIINTERFACEREQUESTOR
210 NS_DECL_NSISTREAMINGPROTOCOLLISTENER
212 void Revoke();
214 private:
215 nsRefPtr<RtspMediaResource> mResource;
216 };
217 friend class Listener;
219 protected:
220 // Main thread access only.
221 // These are called on the main thread by Listener.
222 NS_DECL_NSISTREAMINGPROTOCOLLISTENER
224 nsRefPtr<Listener> mListener;
226 private:
227 bool IsVideoEnabled();
228 bool IsVideo(uint8_t tracks, nsIStreamingProtocolMetaData *meta);
229 // These two members are created at |RtspMediaResource::OnConnected|.
230 nsCOMPtr<nsIStreamingProtocolController> mMediaStreamController;
231 nsTArray<nsAutoPtr<RtspTrackBuffer>> mTrackBuffer;
233 // A flag that indicates the |RtspMediaResource::OnConnected| has already been
234 // called.
235 bool mIsConnected;
236 // live stream
237 bool mRealTime;
238 };
240 } // namespace mozilla
242 #endif