1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/RtspMediaResource.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,243 @@ 1.4 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#if !defined(RtspMediaResource_h_) 1.10 +#define RtspMediaResource_h_ 1.11 + 1.12 +#include "MediaResource.h" 1.13 + 1.14 +namespace mozilla { 1.15 + 1.16 +class RtspTrackBuffer; 1.17 + 1.18 +/* RtspMediaResource 1.19 + * RtspMediaResource provides an interface to deliver and control RTSP media 1.20 + * data to RtspDecoder. 1.21 + * 1.22 + * RTSP Flow Start vs HTTP Flow Start: 1.23 + * For HTTP (and files stored on disk), once the channel is created and response 1.24 + * data is available, HTMLMediaElement::MediaLoadListener::OnStartRequest is 1.25 + * called. (Note, this is an asynchronous call following channel->AsyncOpen). 1.26 + * The decoder and MediaResource are set up to talk to each other: 1.27 + * InitializeDecoderForChannel and FinishDecoderSetup. 1.28 + * RtspMediaResource is different from this, in that FinishDecoderSetup is 1.29 + * postponed until after the initial connection with the server is made. 1.30 + * RtspController, owned by RtspMediaResource, provides the interface to setup 1.31 + * the connection, and calls RtspMediaResource::Listener::OnConnected 1.32 + * (from nsIStreamingProtocolListener). FinishDecoderSetup is then called to 1.33 + * connect RtspMediaResource with RtspDecoder and allow HTMLMediaElement to 1.34 + * request playback etc. 1.35 + * 1.36 + * Playback: 1.37 + * When the user presses play/pause, HTMLMediaElement::Play/::Pause is called, 1.38 + * subsequently making calls to the decoder state machine. Upon these state 1.39 + * changes, the decoder is told to start reading and decoding data. This causes 1.40 + * the nsIStreamingMediaController object to send play/pause commands to the 1.41 + * server. 1.42 + * Data is then delivered to the host and eventually written to the 1.43 + * RtspTrackBuffer objects. Note that RtspMediaResource does not know about the 1.44 + * play or pause state. It only knows about the data written into its buffers. 1.45 + * 1.46 + * Data Structures and Flow: 1.47 + * Unlike HTTP, RTSP provides separate streams for audio and video. 1.48 + * As such, it creates two RtspTrackBuffer objects for the audio and video data. 1.49 + * Data is read using the function ReadFrameFromTrack. These buffer objects are 1.50 + * ring buffers, implying that data from the network may be discarded if the 1.51 + * decoder cannot read at a high enough rate. 1.52 + * 1.53 + * Data is delivered via RtspMediaResource::Listener::OnMediaDataAvailable. 1.54 + * This Listener implements nsIStreamingProtocolListener, and writes the data to 1.55 + * the appropriate RtspTrackBuffer. The decoder then reads the data by calling 1.56 + * RtspMediaResource::ReadFrameFromTrack. Note that the decoder and decode 1.57 + * thread will be blocked until data is available in one of the two buffers. 1.58 + * 1.59 + * Seeking: 1.60 + * Since the frame data received after seek is not continuous with existing 1.61 + * frames in RtspTrackBuffer, the buffer must be cleared. If we don't clear the 1.62 + * old frame data in RtspTrackBuffer, the decoder's behavior will be 1.63 + * unpredictable. So we add |mFrameType| in RtspTrackBuffer to do this: 1.64 + * When we are seeking, the mFrameType flag is set, and RtspTrackBuffer will 1.65 + * drop the incoming data until the RTSP server completes the seek operation. 1.66 + * Note: seeking for RTSP is carried out based on sending the seek time to the 1.67 + * server, unlike HTTP in which the seek time is converted to a byte offset. 1.68 + * Thus, RtspMediaResource has a SeekTime function which should be called 1.69 + * instead of Seek. 1.70 + * */ 1.71 +class RtspMediaResource : public BaseMediaResource 1.72 +{ 1.73 +public: 1.74 + RtspMediaResource(MediaDecoder* aDecoder, nsIChannel* aChannel, nsIURI* aURI, 1.75 + const nsACString& aContentType); 1.76 + virtual ~RtspMediaResource(); 1.77 + 1.78 + // The following methods can be called on any thread. 1.79 + 1.80 + // Get the RtspMediaResource pointer if this MediaResource is a 1.81 + // RtspMediaResource. For calling Rtsp specific functions. 1.82 + virtual RtspMediaResource* GetRtspPointer() MOZ_OVERRIDE MOZ_FINAL { 1.83 + return this; 1.84 + } 1.85 + 1.86 + // Returns the nsIStreamingProtocolController in the RtspMediaResource. 1.87 + // RtspMediaExtractor: request it to get mime type for creating decoder. 1.88 + // RtspOmxDecoder: request it to send play/pause commands to RTSP server. 1.89 + // The lifetime of mMediaStreamController is controlled by RtspMediaResource 1.90 + // because the RtspMediaExtractor and RtspOmxDecoder won't hold the reference. 1.91 + nsIStreamingProtocolController* GetMediaStreamController() { 1.92 + return mMediaStreamController; 1.93 + } 1.94 + 1.95 + virtual bool IsRealTime() MOZ_OVERRIDE { 1.96 + return mRealTime; 1.97 + } 1.98 + 1.99 + // The following methods can be called on any thread except main thread. 1.100 + 1.101 + // Read data from track. 1.102 + // Parameters: 1.103 + // aToBuffer, aToBufferSize: buffer pointer and buffer size. 1.104 + // aReadCount: output actual read bytes. 1.105 + // aFrameTime: output frame time stamp. 1.106 + // aFrameSize: actual data size in track. 1.107 + nsresult ReadFrameFromTrack(uint8_t* aBuffer, uint32_t aBufferSize, 1.108 + uint32_t aTrackIdx, uint32_t& aBytes, 1.109 + uint64_t& aTime, uint32_t& aFrameSize); 1.110 + 1.111 + // Seek to the given time offset 1.112 + nsresult SeekTime(int64_t aOffset); 1.113 + 1.114 + // dummy 1.115 + virtual nsresult ReadAt(int64_t aOffset, char* aBuffer, 1.116 + uint32_t aCount, uint32_t* aBytes) MOZ_OVERRIDE{ 1.117 + return NS_ERROR_FAILURE; 1.118 + } 1.119 + // dummy 1.120 + virtual void SetReadMode(MediaCacheStream::ReadMode aMode) MOZ_OVERRIDE {} 1.121 + // dummy 1.122 + virtual void SetPlaybackRate(uint32_t aBytesPerSecond) MOZ_OVERRIDE {} 1.123 + // dummy 1.124 + virtual nsresult Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes) 1.125 + MOZ_OVERRIDE { 1.126 + return NS_OK; 1.127 + } 1.128 + // dummy 1.129 + virtual nsresult Seek(int32_t aWhence, int64_t aOffset) MOZ_OVERRIDE { 1.130 + return NS_OK; 1.131 + } 1.132 + // dummy 1.133 + virtual void StartSeekingForMetadata() MOZ_OVERRIDE {} 1.134 + // dummy 1.135 + virtual void EndSeekingForMetadata() MOZ_OVERRIDE {} 1.136 + // dummy 1.137 + virtual int64_t Tell() MOZ_OVERRIDE { return 0; } 1.138 + 1.139 + // Any thread 1.140 + virtual void Pin() MOZ_OVERRIDE {} 1.141 + virtual void Unpin() MOZ_OVERRIDE {} 1.142 + 1.143 + // dummy 1.144 + virtual bool IsSuspendedByCache() MOZ_OVERRIDE { return false; } 1.145 + 1.146 + virtual bool IsSuspended() MOZ_OVERRIDE { return false; } 1.147 + virtual bool IsTransportSeekable() MOZ_OVERRIDE { return true; } 1.148 + // dummy 1.149 + virtual double GetDownloadRate(bool* aIsReliable) MOZ_OVERRIDE { return 0; } 1.150 + 1.151 + virtual int64_t GetLength() MOZ_OVERRIDE { 1.152 + if (mRealTime) { 1.153 + return -1; 1.154 + } 1.155 + return 0; 1.156 + } 1.157 + 1.158 + // dummy 1.159 + virtual int64_t GetNextCachedData(int64_t aOffset) MOZ_OVERRIDE { return 0; } 1.160 + // dummy 1.161 + virtual int64_t GetCachedDataEnd(int64_t aOffset) MOZ_OVERRIDE { return 0; } 1.162 + // dummy 1.163 + virtual bool IsDataCachedToEndOfResource(int64_t aOffset) MOZ_OVERRIDE { 1.164 + return false; 1.165 + } 1.166 + // dummy 1.167 + nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) MOZ_OVERRIDE { 1.168 + return NS_ERROR_FAILURE; 1.169 + } 1.170 + 1.171 + // The following methods can be called on main thread only. 1.172 + 1.173 + virtual nsresult Open(nsIStreamListener** aStreamListener) MOZ_OVERRIDE; 1.174 + virtual nsresult Close() MOZ_OVERRIDE; 1.175 + virtual void Suspend(bool aCloseImmediately) MOZ_OVERRIDE; 1.176 + virtual void Resume() MOZ_OVERRIDE; 1.177 + virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() MOZ_OVERRIDE; 1.178 + virtual bool CanClone() MOZ_OVERRIDE { 1.179 + return false; 1.180 + } 1.181 + virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder) 1.182 + MOZ_OVERRIDE { 1.183 + return nullptr; 1.184 + } 1.185 + // dummy 1.186 + virtual nsresult ReadFromCache(char* aBuffer, int64_t aOffset, 1.187 + uint32_t aCount) MOZ_OVERRIDE { 1.188 + return NS_ERROR_FAILURE; 1.189 + } 1.190 + 1.191 + virtual size_t SizeOfExcludingThis( 1.192 + MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE; 1.193 + 1.194 + virtual size_t SizeOfIncludingThis( 1.195 + MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE { 1.196 + return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); 1.197 + } 1.198 + 1.199 + // Listener implements nsIStreamingProtocolListener as 1.200 + // mMediaStreamController's callback function. 1.201 + // It holds RtspMediaResource reference to notify the connection status and 1.202 + // data arrival. The Revoke function releases the reference when 1.203 + // RtspMediaResource::OnDisconnected is called. 1.204 + class Listener MOZ_FINAL : public nsIInterfaceRequestor, 1.205 + public nsIStreamingProtocolListener 1.206 + { 1.207 + public: 1.208 + Listener(RtspMediaResource* aResource) : mResource(aResource) {} 1.209 + ~Listener() {} 1.210 + 1.211 + NS_DECL_ISUPPORTS 1.212 + NS_DECL_NSIINTERFACEREQUESTOR 1.213 + NS_DECL_NSISTREAMINGPROTOCOLLISTENER 1.214 + 1.215 + void Revoke(); 1.216 + 1.217 + private: 1.218 + nsRefPtr<RtspMediaResource> mResource; 1.219 + }; 1.220 + friend class Listener; 1.221 + 1.222 +protected: 1.223 + // Main thread access only. 1.224 + // These are called on the main thread by Listener. 1.225 + NS_DECL_NSISTREAMINGPROTOCOLLISTENER 1.226 + 1.227 + nsRefPtr<Listener> mListener; 1.228 + 1.229 +private: 1.230 + bool IsVideoEnabled(); 1.231 + bool IsVideo(uint8_t tracks, nsIStreamingProtocolMetaData *meta); 1.232 + // These two members are created at |RtspMediaResource::OnConnected|. 1.233 + nsCOMPtr<nsIStreamingProtocolController> mMediaStreamController; 1.234 + nsTArray<nsAutoPtr<RtspTrackBuffer>> mTrackBuffer; 1.235 + 1.236 + // A flag that indicates the |RtspMediaResource::OnConnected| has already been 1.237 + // called. 1.238 + bool mIsConnected; 1.239 + // live stream 1.240 + bool mRealTime; 1.241 +}; 1.242 + 1.243 +} // namespace mozilla 1.244 + 1.245 +#endif 1.246 +