LCOV - code coverage report
Current view: directory - content/media - nsBuiltinDecoder.h (source / functions) Found Hit Coverage
Test: app.info Lines: 28 0 0.0 %
Date: 2012-06-02 Functions: 14 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* vim:set ts=2 sw=2 sts=2 et cindent: */
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Mozilla code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is the Mozilla Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2007
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *  Chris Double <chris.double@double.co.nz>
      24                 :  *  Chris Pearce <chris@pearce.org.nz>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : /*
      40                 : Each video element based on nsBuiltinDecoder has a state machine to manage
      41                 : its play state and keep the current frame up to date. All state machines
      42                 : share time in a single shared thread. Each decoder also has one thread
      43                 : dedicated to decoding audio and video data. This thread is shutdown when
      44                 : playback is paused. Each decoder also has a thread to push decoded audio
      45                 : to the hardware. This thread is not created until playback starts, but
      46                 : currently is not destroyed when paused, only when playback ends.
      47                 : 
      48                 : The decoder owns the resources for downloading the media file, and the
      49                 : high level state. It holds an owning reference to the state machine
      50                 : (a subclass of nsDecoderStateMachine; nsBuiltinDecoderStateMachine) that
      51                 : owns all the resources related to decoding data, and manages the low level
      52                 : decoding operations and A/V sync. 
      53                 : 
      54                 : Each state machine runs on the shared state machine thread. Every time some
      55                 : action is required for a state machine, it is scheduled to run on the shared
      56                 : the state machine thread. The state machine runs one "cycle" on the state
      57                 : machine thread, and then returns. If necessary, it will schedule itself to
      58                 : run again in future. While running this cycle, it must not block the
      59                 : thread, as other state machines' events may need to run. State shared
      60                 : between a state machine's threads is synchronised via the monitor owned
      61                 : by its nsBuiltinDecoder object.
      62                 : 
      63                 : The Main thread controls the decode state machine by setting the value
      64                 : of a mPlayState variable and notifying on the monitor based on the
      65                 : high level player actions required (Seek, Pause, Play, etc).
      66                 : 
      67                 : The player states are the states requested by the client through the
      68                 : DOM API.  They represent the desired state of the player, while the
      69                 : decoder's state represents the actual state of the decoder.
      70                 : 
      71                 : The high level state of the player is maintained via a PlayState value. 
      72                 : It can have the following states:
      73                 : 
      74                 : START
      75                 :   The decoder has been initialized but has no resource loaded.
      76                 : PAUSED
      77                 :   A request via the API has been received to pause playback.
      78                 : LOADING
      79                 :   A request via the API has been received to load a resource.
      80                 : PLAYING
      81                 :   A request via the API has been received to start playback.
      82                 : SEEKING
      83                 :   A request via the API has been received to start seeking.
      84                 : COMPLETED
      85                 :   Playback has completed.
      86                 : SHUTDOWN
      87                 :   The decoder is about to be destroyed.
      88                 : 
      89                 : State transition occurs when the Media Element calls the Play, Seek,
      90                 : etc methods on the nsBuiltinDecoder object. When the transition
      91                 : occurs nsBuiltinDecoder then calls the methods on the decoder state
      92                 : machine object to cause it to behave as required by the play state.
      93                 : State transitions will likely schedule the state machine to run to
      94                 : affect the change.
      95                 : 
      96                 : An implementation of the nsDecoderStateMachine class is the event
      97                 : that gets dispatched to the state machine thread. Each time the event is run,
      98                 : the state machine must cycle the state machine once, and then return.
      99                 : 
     100                 : The state machine has the following states:
     101                 : 
     102                 : DECODING_METADATA
     103                 :   The media headers are being loaded, and things like framerate, etc are
     104                 :   being determined, and the first frame of audio/video data is being decoded.
     105                 : DECODING
     106                 :   The decode has started. If the PlayState is PLAYING, the decode thread
     107                 :   should be alive and decoding video and audio frame, the audio thread
     108                 :   should be playing audio, and the state machine should run periodically
     109                 :   to update the video frames being displayed.
     110                 : SEEKING
     111                 :   A seek operation is in progress. The decode thread should be seeking.
     112                 : BUFFERING
     113                 :   Decoding is paused while data is buffered for smooth playback. If playback
     114                 :   is paused (PlayState transitions to PAUSED) we'll destory the decode thread.
     115                 : COMPLETED
     116                 :   The resource has completed decoding, but possibly not finished playback.
     117                 :   The decode thread will be destroyed. Once playback finished, the audio
     118                 :   thread will also be destroyed.
     119                 : SHUTDOWN
     120                 :   The decoder object and its state machine are about to be destroyed.
     121                 :   Once the last state machine has been destroyed, the shared state machine
     122                 :   thread will also be destroyed. It will be recreated later if needed.
     123                 : 
     124                 : The following result in state transitions.
     125                 : 
     126                 : Shutdown()
     127                 :   Clean up any resources the nsDecoderStateMachine owns.
     128                 : Play()
     129                 :   Start decoding and playback of media data.
     130                 : Buffer
     131                 :   This is not user initiated. It occurs when the
     132                 :   available data in the stream drops below a certain point.
     133                 : Complete
     134                 :   This is not user initiated. It occurs when the
     135                 :   stream is completely decoded.
     136                 : Seek(double)
     137                 :   Seek to the time position given in the resource.
     138                 : 
     139                 : A state transition diagram:
     140                 : 
     141                 : DECODING_METADATA
     142                 :   |      |
     143                 :   v      | Shutdown()
     144                 :   |      |
     145                 :   v      -->-------------------->--------------------------|
     146                 :   |---------------->----->------------------------|        v
     147                 : DECODING             |          |  |              |        |
     148                 :   ^                  v Seek(t)  |  |              |        |
     149                 :   |         Play()   |          v  |              |        |
     150                 :   ^-----------<----SEEKING      |  v Complete     v        v
     151                 :   |                  |          |  |              |        |
     152                 :   |                  |          |  COMPLETED    SHUTDOWN-<-|
     153                 :   ^                  ^          |  |Shutdown()    |
     154                 :   |                  |          |  >-------->-----^
     155                 :   |          Play()  |Seek(t)   |Buffer()         |
     156                 :   -----------<--------<-------BUFFERING           |
     157                 :                                 |                 ^
     158                 :                                 v Shutdown()      |
     159                 :                                 |                 |
     160                 :                                 ------------>-----|
     161                 : 
     162                 : The following represents the states that the nsBuiltinDecoder object
     163                 : can be in, and the valid states the nsDecoderStateMachine can be in at that
     164                 : time:
     165                 : 
     166                 : player LOADING   decoder DECODING_METADATA
     167                 : player PLAYING   decoder DECODING, BUFFERING, SEEKING, COMPLETED
     168                 : player PAUSED    decoder DECODING, BUFFERING, SEEKING, COMPLETED
     169                 : player SEEKING   decoder SEEKING
     170                 : player COMPLETED decoder SHUTDOWN
     171                 : player SHUTDOWN  decoder SHUTDOWN
     172                 : 
     173                 : The general sequence of events is:
     174                 : 
     175                 : 1) The video element calls Load on nsMediaDecoder. This creates the
     176                 :    state machine and starts the channel for downloading the
     177                 :    file. It instantiates and schedules the nsDecoderStateMachine. The
     178                 :    high level LOADING state is entered, which results in the decode
     179                 :    thread being created and starting to decode metadata. These are
     180                 :    the headers that give the video size, framerate, etc. Load() returns
     181                 :    immediately to the calling video element.
     182                 : 
     183                 : 2) When the metadata has been loaded by the decode thread, the state machine
     184                 :    will call a method on the video element object to inform it that this
     185                 :    step is done, so it can do the things required by the video specification
     186                 :    at this stage. The decode thread then continues to decode the first frame
     187                 :    of data.
     188                 : 
     189                 : 3) When the first frame of data has been successfully decoded the state
     190                 :    machine calls a method on the video element object to inform it that
     191                 :    this step has been done, once again so it can do the required things
     192                 :    by the video specification at this stage.
     193                 : 
     194                 :    This results in the high level state changing to PLAYING or PAUSED
     195                 :    depending on any user action that may have occurred.
     196                 : 
     197                 :    While the play state is PLAYING, the decode thread will decode
     198                 :    data, and the audio thread will push audio data to the hardware to
     199                 :    be played. The state machine will run periodically on the shared
     200                 :    state machine thread to ensure video frames are played at the 
     201                 :    correct time; i.e. the state machine manages A/V sync.
     202                 : 
     203                 : The Shutdown method on nsBuiltinDecoder closes the download channel, and
     204                 : signals to the state machine that it should shutdown. The state machine
     205                 : shuts down asynchronously, and will release the owning reference to the
     206                 : state machine once its threads are shutdown.
     207                 : 
     208                 : The owning object of a nsBuiltinDecoder object *MUST* call Shutdown when
     209                 : destroying the nsBuiltinDecoder object.
     210                 : 
     211                 : */
     212                 : #if !defined(nsBuiltinDecoder_h_)
     213                 : #define nsBuiltinDecoder_h_
     214                 : 
     215                 : #include "nsMediaDecoder.h"
     216                 : 
     217                 : #include "nsISupports.h"
     218                 : #include "nsCOMPtr.h"
     219                 : #include "nsIThread.h"
     220                 : #include "nsIChannel.h"
     221                 : #include "nsIObserver.h"
     222                 : #include "nsIFrame.h"
     223                 : #include "nsAutoPtr.h"
     224                 : #include "nsSize.h"
     225                 : #include "prlog.h"
     226                 : #include "gfxContext.h"
     227                 : #include "gfxRect.h"
     228                 : #include "MediaResource.h"
     229                 : #include "nsMediaDecoder.h"
     230                 : #include "nsHTMLMediaElement.h"
     231                 : #include "mozilla/ReentrantMonitor.h"
     232                 : 
     233                 : class nsAudioStream;
     234                 : 
     235               0 : static inline bool IsCurrentThread(nsIThread* aThread) {
     236               0 :   return NS_GetCurrentThread() == aThread;
     237                 : }
     238                 : 
     239                 : // Decoder backends must implement this class to perform the codec
     240                 : // specific parts of decoding the video/audio format.
     241                 : class nsDecoderStateMachine : public nsRunnable
     242               0 : {
     243                 : public:
     244                 :   // Enumeration for the valid decoding states
     245                 :   enum State {
     246                 :     DECODER_STATE_DECODING_METADATA,
     247                 :     DECODER_STATE_DECODING,
     248                 :     DECODER_STATE_SEEKING,
     249                 :     DECODER_STATE_BUFFERING,
     250                 :     DECODER_STATE_COMPLETED,
     251                 :     DECODER_STATE_SHUTDOWN
     252                 :   };
     253                 : 
     254                 :   // Initializes the state machine, returns NS_OK on success, or
     255                 :   // NS_ERROR_FAILURE on failure.
     256                 :   virtual nsresult Init(nsDecoderStateMachine* aCloneDonor) = 0;
     257                 : 
     258                 :   // Return the current decode state. The decoder monitor must be
     259                 :   // obtained before calling this.
     260                 :   virtual State GetState() = 0;
     261                 : 
     262                 :   // Set the audio volume. The decoder monitor must be obtained before
     263                 :   // calling this.
     264                 :   virtual void SetVolume(double aVolume) = 0;
     265                 : 
     266                 :   virtual void Shutdown() = 0;
     267                 : 
     268                 :   // Called from the main thread to get the duration. The decoder monitor
     269                 :   // must be obtained before calling this. It is in units of microseconds.
     270                 :   virtual PRInt64 GetDuration() = 0;
     271                 : 
     272                 :   // Called from the main thread to set the duration of the media resource
     273                 :   // if it is able to be obtained via HTTP headers. Called from the 
     274                 :   // state machine thread to set the duration if it is obtained from the
     275                 :   // media metadata. The decoder monitor must be obtained before calling this.
     276                 :   // aDuration is in microseconds.
     277                 :   virtual void SetDuration(PRInt64 aDuration) = 0;
     278                 : 
     279                 :   // Called while decoding metadata to set the end time of the media
     280                 :   // resource. The decoder monitor must be obtained before calling this.
     281                 :   // aEndTime is in microseconds.
     282                 :   virtual void SetEndTime(PRInt64 aEndTime) = 0;
     283                 : 
     284                 :   // Set the media fragment end time. aEndTime is in microseconds.
     285                 :   virtual void SetFragmentEndTime(PRInt64 aEndTime) = 0;
     286                 : 
     287                 :   // Functions used by assertions to ensure we're calling things
     288                 :   // on the appropriate threads.
     289                 :   virtual bool OnDecodeThread() const = 0;
     290                 : 
     291                 :   // Returns true if the current thread is the state machine thread.
     292                 :   virtual bool OnStateMachineThread() const = 0;
     293                 : 
     294                 :   virtual nsHTMLMediaElement::NextFrameStatus GetNextFrameStatus() = 0;
     295                 : 
     296                 :   // Cause state transitions. These methods obtain the decoder monitor
     297                 :   // to synchronise the change of state, and to notify other threads
     298                 :   // that the state has changed.
     299                 :   virtual void Play() = 0;
     300                 : 
     301                 :   // Seeks to aTime in seconds
     302                 :   virtual void Seek(double aTime) = 0;
     303                 : 
     304                 :   // Returns the current playback position in seconds.
     305                 :   // Called from the main thread to get the current frame time. The decoder
     306                 :   // monitor must be obtained before calling this.
     307                 :   virtual double GetCurrentTime() const = 0;
     308                 : 
     309                 :   // Clear the flag indicating that a playback position change event
     310                 :   // is currently queued. This is called from the main thread and must
     311                 :   // be called with the decode monitor held.
     312                 :   virtual void ClearPositionChangeFlag() = 0;
     313                 : 
     314                 :   // Called from the main thread to set whether the media resource can
     315                 :   // seek into unbuffered ranges. The decoder monitor must be obtained
     316                 :   // before calling this.
     317                 :   virtual void SetSeekable(bool aSeekable) = 0;
     318                 : 
     319                 :   // Returns true if the media resource can seek into unbuffered ranges,
     320                 :   // as set by SetSeekable(). The decoder monitor must be obtained before
     321                 :   // calling this.
     322                 :   virtual bool IsSeekable() = 0;
     323                 : 
     324                 :   // Update the playback position. This can result in a timeupdate event
     325                 :   // and an invalidate of the frame being dispatched asynchronously if
     326                 :   // there is no such event currently queued.
     327                 :   // Only called on the decoder thread. Must be called with
     328                 :   // the decode monitor held.
     329                 :   virtual void UpdatePlaybackPosition(PRInt64 aTime) = 0;
     330                 : 
     331                 :   virtual nsresult GetBuffered(nsTimeRanges* aBuffered) = 0;
     332                 : 
     333                 :   virtual PRInt64 VideoQueueMemoryInUse() = 0;
     334                 :   virtual PRInt64 AudioQueueMemoryInUse() = 0;
     335                 : 
     336                 :   virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset) = 0;
     337                 : 
     338                 :   // Causes the state machine to switch to buffering state, and to
     339                 :   // immediately stop playback and buffer downloaded data. Must be called
     340                 :   // with the decode monitor held. Called on the state machine thread and
     341                 :   // the main thread.
     342                 :   virtual void StartBuffering() = 0;
     343                 : 
     344                 :   // Sets the current size of the framebuffer used in MozAudioAvailable events.
     345                 :   // Called on the state machine thread and the main thread.
     346                 :   virtual void SetFrameBufferLength(PRUint32 aLength) = 0;
     347                 : 
     348                 :   // Called when a "MozAudioAvailable" event listener is added to the media
     349                 :   // element. Called on the main thread.
     350                 :   virtual void NotifyAudioAvailableListener() = 0;
     351                 : };
     352                 : 
     353                 : class nsBuiltinDecoder : public nsMediaDecoder
     354                 : {
     355                 : public:
     356                 :   typedef mozilla::MediaChannelStatistics MediaChannelStatistics;
     357                 : 
     358                 :   NS_DECL_ISUPPORTS
     359                 :   NS_DECL_NSIOBSERVER
     360                 : 
     361                 :   // Enumeration for the valid play states (see mPlayState)
     362                 :   enum PlayState {
     363                 :     PLAY_STATE_START,
     364                 :     PLAY_STATE_LOADING,
     365                 :     PLAY_STATE_PAUSED,
     366                 :     PLAY_STATE_PLAYING,
     367                 :     PLAY_STATE_SEEKING,
     368                 :     PLAY_STATE_ENDED,
     369                 :     PLAY_STATE_SHUTDOWN
     370                 :   };
     371                 : 
     372                 :   nsBuiltinDecoder();
     373                 :   ~nsBuiltinDecoder();
     374                 :   
     375                 :   virtual bool Init(nsHTMLMediaElement* aElement);
     376                 : 
     377                 :   // This method must be called by the owning object before that
     378                 :   // object disposes of this decoder object.
     379                 :   virtual void Shutdown();
     380                 :   
     381                 :   virtual double GetCurrentTime();
     382                 : 
     383                 :   virtual nsresult Load(MediaResource* aResource,
     384                 :                         nsIStreamListener** aListener,
     385                 :                         nsMediaDecoder* aCloneDonor);
     386                 : 
     387                 :   virtual nsDecoderStateMachine* CreateStateMachine() = 0;
     388                 : 
     389                 :   // Start playback of a video. 'Load' must have previously been
     390                 :   // called.
     391                 :   virtual nsresult Play();
     392                 : 
     393                 :   // Seek to the time position in (seconds) from the start of the video.
     394                 :   virtual nsresult Seek(double aTime);
     395                 : 
     396                 :   virtual nsresult PlaybackRateChanged();
     397                 : 
     398                 :   virtual void Pause();
     399                 :   virtual void SetVolume(double aVolume);
     400                 :   virtual double GetDuration();
     401                 : 
     402                 :   virtual void SetInfinite(bool aInfinite);
     403                 :   virtual bool IsInfinite();
     404                 : 
     405               0 :   virtual MediaResource* GetResource() { return mResource; }
     406                 :   virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
     407                 : 
     408                 :   virtual void NotifySuspendedStatusChanged();
     409                 :   virtual void NotifyBytesDownloaded();
     410                 :   virtual void NotifyDownloadEnded(nsresult aStatus);
     411                 :   // Called by the decode thread to keep track of the number of bytes read
     412                 :   // from the resource.
     413                 :   void NotifyBytesConsumed(PRInt64 aBytes);
     414                 : 
     415                 :   // Called when the video file has completed downloading.
     416                 :   // Call on the main thread only.
     417                 :   void ResourceLoaded();
     418                 : 
     419                 :   // Called if the media file encounters a network error.
     420                 :   // Call on the main thread only.
     421                 :   virtual void NetworkError();
     422                 : 
     423                 :   // Call from any thread safely. Return true if we are currently
     424                 :   // seeking in the media resource.
     425                 :   virtual bool IsSeeking() const;
     426                 : 
     427                 :   // Return true if the decoder has reached the end of playback.
     428                 :   // Call on the main thread only.
     429                 :   virtual bool IsEnded() const;
     430                 : 
     431                 :   // Set the duration of the media resource in units of seconds.
     432                 :   // This is called via a channel listener if it can pick up the duration
     433                 :   // from a content header. Must be called from the main thread only.
     434                 :   virtual void SetDuration(double aDuration);
     435                 : 
     436                 :   // Set a flag indicating whether seeking is supported
     437                 :   virtual void SetSeekable(bool aSeekable);
     438                 : 
     439                 :   // Return true if seeking is supported.
     440                 :   virtual bool IsSeekable();
     441                 : 
     442                 :   virtual nsresult GetSeekable(nsTimeRanges* aSeekable);
     443                 : 
     444                 :   // Set the end time of the media resource. When playback reaches
     445                 :   // this point the media pauses. aTime is in seconds.
     446                 :   virtual void SetEndTime(double aTime);
     447                 : 
     448                 :   virtual Statistics GetStatistics();
     449                 : 
     450                 :   // Suspend any media downloads that are in progress. Called by the
     451                 :   // media element when it is sent to the bfcache. Call on the main
     452                 :   // thread only.
     453                 :   virtual void Suspend();
     454                 : 
     455                 :   // Resume any media downloads that have been suspended. Called by the
     456                 :   // media element when it is restored from the bfcache. Call on the
     457                 :   // main thread only.
     458                 :   virtual void Resume(bool aForceBuffering);
     459                 : 
     460                 :   // Tells our MediaResource to put all loads in the background.
     461                 :   virtual void MoveLoadsToBackground();
     462                 : 
     463                 :   void AudioAvailable(float* aFrameBuffer, PRUint32 aFrameBufferLength, float aTime);
     464                 : 
     465                 :   // Called by the state machine to notify the decoder that the duration
     466                 :   // has changed.
     467                 :   void DurationChanged();
     468                 : 
     469                 :   bool OnStateMachineThread() const;
     470                 : 
     471               0 :   bool OnDecodeThread() const {
     472               0 :     return mDecoderStateMachine->OnDecodeThread();
     473                 :   }
     474                 : 
     475                 :   // Returns the monitor for other threads to synchronise access to
     476                 :   // state.
     477               0 :   ReentrantMonitor& GetReentrantMonitor() { 
     478               0 :     return mReentrantMonitor; 
     479                 :   }
     480                 : 
     481                 :   // Constructs the time ranges representing what segments of the media
     482                 :   // are buffered and playable.
     483               0 :   virtual nsresult GetBuffered(nsTimeRanges* aBuffered) {
     484               0 :     if (mDecoderStateMachine) {
     485               0 :       return mDecoderStateMachine->GetBuffered(aBuffered);
     486                 :     }
     487               0 :     return NS_ERROR_FAILURE;
     488                 :   }
     489                 : 
     490               0 :   virtual PRInt64 VideoQueueMemoryInUse() {
     491               0 :     if (mDecoderStateMachine) {
     492               0 :       return mDecoderStateMachine->VideoQueueMemoryInUse();
     493                 :     }
     494               0 :     return 0;
     495                 :   }
     496                 : 
     497               0 :   virtual PRInt64 AudioQueueMemoryInUse() {
     498               0 :     if (mDecoderStateMachine) {
     499               0 :       return mDecoderStateMachine->AudioQueueMemoryInUse();
     500                 :     }
     501               0 :     return 0;
     502                 :   }
     503                 : 
     504               0 :   virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset) {
     505               0 :     if (mDecoderStateMachine) {
     506               0 :       mDecoderStateMachine->NotifyDataArrived(aBuffer, aLength, aOffset);
     507                 :     }
     508               0 :   }
     509                 : 
     510                 :   // Sets the length of the framebuffer used in MozAudioAvailable events.
     511                 :   // The new size must be between 512 and 16384.
     512                 :   virtual nsresult RequestFrameBufferLength(PRUint32 aLength);
     513                 : 
     514                 :   // Return the current state. Can be called on any thread. If called from
     515                 :   // a non-main thread, the decoder monitor must be held.
     516               0 :   PlayState GetState() {
     517               0 :     return mPlayState;
     518                 :   }
     519                 : 
     520                 :   // Stop updating the bytes downloaded for progress notifications. Called
     521                 :   // when seeking to prevent wild changes to the progress notification.
     522                 :   // Must be called with the decoder monitor held.
     523                 :   void StopProgressUpdates();
     524                 : 
     525                 :   // Allow updating the bytes downloaded for progress notifications. Must
     526                 :   // be called with the decoder monitor held.
     527                 :   void StartProgressUpdates();
     528                 : 
     529                 :   // Something has changed that could affect the computed playback rate,
     530                 :   // so recompute it. The monitor must be held.
     531                 :   void UpdatePlaybackRate();
     532                 : 
     533                 :   // The actual playback rate computation. The monitor must be held.
     534                 :   double ComputePlaybackRate(bool* aReliable);
     535                 : 
     536                 :   // Make the decoder state machine update the playback position. Called by
     537                 :   // the reader on the decoder thread (Assertions for this checked by 
     538                 :   // mDecoderStateMachine). This must be called with the decode monitor
     539                 :   // held.
     540                 :   void UpdatePlaybackPosition(PRInt64 aTime)
     541                 :   {
     542                 :     mDecoderStateMachine->UpdatePlaybackPosition(aTime);
     543                 :   }
     544                 : 
     545                 :   /****** 
     546                 :    * The following methods must only be called on the main
     547                 :    * thread.
     548                 :    ******/
     549                 : 
     550                 :   // Change to a new play state. This updates the mState variable and
     551                 :   // notifies any thread blocking on this object's monitor of the
     552                 :   // change. Call on the main thread only.
     553                 :   void ChangeState(PlayState aState);
     554                 : 
     555                 :   // Called when the metadata from the media file has been read.
     556                 :   // Call on the main thread only.
     557                 :   void MetadataLoaded(PRUint32 aChannels,
     558                 :                       PRUint32 aRate);
     559                 : 
     560                 :   // Called when the first frame has been loaded.
     561                 :   // Call on the main thread only.
     562                 :   void FirstFrameLoaded();
     563                 : 
     564                 :   // Called when the video has completed playing.
     565                 :   // Call on the main thread only.
     566                 :   void PlaybackEnded();
     567                 : 
     568                 :   // Seeking has stopped. Inform the element on the main
     569                 :   // thread.
     570                 :   void SeekingStopped();
     571                 : 
     572                 :   // Seeking has stopped at the end of the resource. Inform the element on the main
     573                 :   // thread.
     574                 :   void SeekingStoppedAtEnd();
     575                 : 
     576                 :   // Seeking has started. Inform the element on the main
     577                 :   // thread.
     578                 :   void SeekingStarted();
     579                 : 
     580                 :   // Called when the backend has changed the current playback
     581                 :   // position. It dispatches a timeupdate event and invalidates the frame.
     582                 :   // This must be called on the main thread only.
     583                 :   void PlaybackPositionChanged();
     584                 : 
     585                 :   // Calls mElement->UpdateReadyStateForData, telling it which state we have
     586                 :   // entered.  Main thread only.
     587                 :   void NextFrameUnavailableBuffering();
     588                 :   void NextFrameAvailable();
     589                 :   void NextFrameUnavailable();
     590                 : 
     591                 :   // Calls mElement->UpdateReadyStateForData, telling it whether we have
     592                 :   // data for the next frame and if we're buffering. Main thread only.
     593                 :   void UpdateReadyStateForData();
     594                 : 
     595                 :   // Find the end of the cached data starting at the current decoder
     596                 :   // position.
     597                 :   PRInt64 GetDownloadPosition();
     598                 : 
     599                 :   // Updates the approximate byte offset which playback has reached. This is
     600                 :   // used to calculate the readyState transitions.
     601                 :   void UpdatePlaybackOffset(PRInt64 aOffset);
     602                 : 
     603                 :   // Provide access to the state machine object
     604                 :   nsDecoderStateMachine* GetStateMachine() { return mDecoderStateMachine; }
     605                 : 
     606                 :   // Return the current decode state. The decoder monitor must be
     607                 :   // obtained before calling this.
     608               0 :   nsDecoderStateMachine::State GetDecodeState() { return mDecoderStateMachine->GetState(); }
     609                 : 
     610                 :   // Drop reference to state machine.  Only called during shutdown dance.
     611               0 :   void ReleaseStateMachine() { mDecoderStateMachine = nsnull; }
     612                 : 
     613                 :    // Called when a "MozAudioAvailable" event listener is added to the media
     614                 :    // element. Called on the main thread.
     615                 :    virtual void NotifyAudioAvailableListener();
     616                 : 
     617                 :   // Notifies the element that decoding has failed.
     618                 :   void DecodeError();
     619                 : 
     620                 :   // Schedules the state machine to run one cycle on the shared state
     621                 :   // machine thread. Main thread only.
     622                 :   nsresult ScheduleStateMachineThread();
     623                 : 
     624                 :   /******
     625                 :    * The following members should be accessed with the decoder lock held.
     626                 :    ******/
     627                 : 
     628                 :   // Current decoding position in the stream. This is where the decoder
     629                 :   // is up to consuming the stream. This is not adjusted during decoder
     630                 :   // seek operations, but it's updated at the end when we start playing
     631                 :   // back again.
     632                 :   PRInt64 mDecoderPosition;
     633                 :   // Current playback position in the stream. This is (approximately)
     634                 :   // where we're up to playing back the stream. This is not adjusted
     635                 :   // during decoder seek operations, but it's updated at the end when we
     636                 :   // start playing back again.
     637                 :   PRInt64 mPlaybackPosition;
     638                 :   // Data needed to estimate playback data rate. The timeline used for
     639                 :   // this estimate is "decode time" (where the "current time" is the
     640                 :   // time of the last decoded video frame).
     641                 :   MediaChannelStatistics mPlaybackStatistics;
     642                 : 
     643                 :   // The current playback position of the media resource in units of
     644                 :   // seconds. This is updated approximately at the framerate of the
     645                 :   // video (if it is a video) or the callback period of the audio.
     646                 :   // It is read and written from the main thread only.
     647                 :   double mCurrentTime;
     648                 : 
     649                 :   // Volume that playback should start at.  0.0 = muted. 1.0 = full
     650                 :   // volume.  Readable/Writeable from the main thread.
     651                 :   double mInitialVolume;
     652                 : 
     653                 :   // Position to seek to when the seek notification is received by the
     654                 :   // decode thread. Written by the main thread and read via the
     655                 :   // decode thread. Synchronised using mReentrantMonitor. If the
     656                 :   // value is negative then no seek has been requested. When a seek is
     657                 :   // started this is reset to negative.
     658                 :   double mRequestedSeekTime;
     659                 : 
     660                 :   // Duration of the media resource. Set to -1 if unknown.
     661                 :   // Set when the metadata is loaded. Accessed on the main thread
     662                 :   // only.
     663                 :   PRInt64 mDuration;
     664                 : 
     665                 :   // True if the media resource is seekable (server supports byte range
     666                 :   // requests).
     667                 :   bool mSeekable;
     668                 : 
     669                 :   /******
     670                 :    * The following member variables can be accessed from any thread.
     671                 :    ******/
     672                 : 
     673                 :   // The state machine object for handling the decoding. It is safe to
     674                 :   // call methods of this object from other threads. Its internal data
     675                 :   // is synchronised on a monitor. The lifetime of this object is
     676                 :   // after mPlayState is LOADING and before mPlayState is SHUTDOWN. It
     677                 :   // is safe to access it during this period.
     678                 :   nsCOMPtr<nsDecoderStateMachine> mDecoderStateMachine;
     679                 : 
     680                 :   // Media data resource.
     681                 :   nsAutoPtr<MediaResource> mResource;
     682                 : 
     683                 :   // ReentrantMonitor for detecting when the video play state changes. A call
     684                 :   // to Wait on this monitor will block the thread until the next
     685                 :   // state change.
     686                 :   ReentrantMonitor mReentrantMonitor;
     687                 : 
     688                 :   // Set to one of the valid play states. It is protected by the
     689                 :   // monitor mReentrantMonitor. This monitor must be acquired when reading or
     690                 :   // writing the state. Any change to the state on the main thread
     691                 :   // must call NotifyAll on the monitor so the decode thread can wake up.
     692                 :   PlayState mPlayState;
     693                 : 
     694                 :   // The state to change to after a seek or load operation. It must only
     695                 :   // be changed from the main thread. The decoder monitor must be acquired
     696                 :   // when writing to the state, or when reading from a non-main thread.
     697                 :   // Any change to the state must call NotifyAll on the monitor.
     698                 :   PlayState mNextState; 
     699                 : 
     700                 :   // True when we have fully loaded the resource and reported that
     701                 :   // to the element (i.e. reached NETWORK_LOADED state).
     702                 :   // Accessed on the main thread only.
     703                 :   bool mResourceLoaded;
     704                 : 
     705                 :   // True when seeking or otherwise moving the play position around in
     706                 :   // such a manner that progress event data is inaccurate. This is set
     707                 :   // during seek and duration operations to prevent the progress indicator
     708                 :   // from jumping around. Read/Write from any thread. Must have decode monitor
     709                 :   // locked before accessing.
     710                 :   bool mIgnoreProgressData;
     711                 : 
     712                 :   // True if the stream is infinite (e.g. a webradio).
     713                 :   bool mInfiniteStream;
     714                 : };
     715                 : 
     716                 : #endif

Generated by: LCOV version 1.7