content/media/RtspMediaResource.h

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

     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

mercurial