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

mercurial