mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 799344 - Flatten nsBultinDecoderStateMachine and nsDecoderStateMachine into a single class. r=roc
This commit is contained in:
parent
3b143c4c58
commit
dc33e1da54
@ -158,7 +158,7 @@ nsDASHDecoder::~nsDASHDecoder()
|
||||
MOZ_COUNT_DTOR(nsDASHDecoder);
|
||||
}
|
||||
|
||||
nsDecoderStateMachine*
|
||||
nsBuiltinDecoderStateMachine*
|
||||
nsDASHDecoder::CreateStateMachine()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
|
||||
// Creates a single state machine for all stream decoders.
|
||||
// Called from Load on the main thread only.
|
||||
nsDecoderStateMachine* CreateStateMachine();
|
||||
nsBuiltinDecoderStateMachine* CreateStateMachine();
|
||||
|
||||
// Loads the MPD from the network and subsequently loads the media streams.
|
||||
// Called from the main thread only.
|
||||
|
@ -31,7 +31,7 @@ extern PRLogModuleInfo* gBuiltinDecoderLog;
|
||||
#define LOG1(msg)
|
||||
#endif
|
||||
|
||||
nsDecoderStateMachine*
|
||||
nsBuiltinDecoderStateMachine*
|
||||
nsDASHRepDecoder::CreateStateMachine()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
@ -40,7 +40,7 @@ nsDASHRepDecoder::CreateStateMachine()
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDASHRepDecoder::SetStateMachine(nsDecoderStateMachine* aSM)
|
||||
nsDASHRepDecoder::SetStateMachine(nsBuiltinDecoderStateMachine* aSM)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
mDecoderStateMachine = aSM;
|
||||
|
@ -53,12 +53,12 @@ public:
|
||||
|
||||
// Called by the main decoder at creation time; points to the main state
|
||||
// machine managed by the main decoder. Called on the main thread only.
|
||||
nsresult SetStateMachine(nsDecoderStateMachine* aSM);
|
||||
nsresult SetStateMachine(nsBuiltinDecoderStateMachine* aSM);
|
||||
|
||||
private:
|
||||
// Overridden to return the ptr set by SetStateMachine. Called on the main
|
||||
// thread only.
|
||||
nsDecoderStateMachine* CreateStateMachine();
|
||||
nsBuiltinDecoderStateMachine* CreateStateMachine();
|
||||
|
||||
public:
|
||||
// Called by nsDASHDecoder at creation time; points to the media resource
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "nsGStreamerReader.h"
|
||||
#include "nsGStreamerDecoder.h"
|
||||
|
||||
nsDecoderStateMachine* nsGStreamerDecoder::CreateStateMachine()
|
||||
nsBuiltinDecoderStateMachine* nsGStreamerDecoder::CreateStateMachine()
|
||||
{
|
||||
return new nsBuiltinDecoderStateMachine(this, new nsGStreamerReader(this));
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class nsGStreamerDecoder : public nsBuiltinDecoder
|
||||
{
|
||||
public:
|
||||
virtual nsMediaDecoder* Clone() { return new nsGStreamerDecoder(); }
|
||||
virtual nsDecoderStateMachine* CreateStateMachine();
|
||||
virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -4,6 +4,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsBuiltinDecoder.h"
|
||||
#include <limits>
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsAudioStream.h"
|
||||
@ -12,7 +13,6 @@
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsTArray.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "nsBuiltinDecoder.h"
|
||||
#include "nsBuiltinDecoderStateMachine.h"
|
||||
#include "nsTimeRanges.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -29,7 +29,7 @@ PRLogModuleInfo* gBuiltinDecoderLog;
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsBuiltinDecoder, nsIObserver)
|
||||
|
||||
void nsBuiltinDecoder::Pause()
|
||||
void nsBuiltinDecoder::Pause()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
@ -253,7 +253,7 @@ bool nsBuiltinDecoder::Init(nsHTMLMediaElement* aElement)
|
||||
void nsBuiltinDecoder::Shutdown()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
|
||||
|
||||
if (mShuttingDown)
|
||||
return;
|
||||
|
||||
@ -350,7 +350,7 @@ nsresult nsBuiltinDecoder::InitializeStateMachine(nsMediaDecoder* aCloneDonor)
|
||||
mDecoderStateMachine->SetDuration(mDuration);
|
||||
mDecoderStateMachine->SetVolume(mInitialVolume);
|
||||
mDecoderStateMachine->SetAudioCaptured(mInitialAudioCaptured);
|
||||
|
||||
|
||||
if (mFrameBufferLength > 0) {
|
||||
// The valid mFrameBufferLength value was specified earlier
|
||||
mDecoderStateMachine->SetFrameBufferLength(mFrameBufferLength);
|
||||
@ -744,7 +744,7 @@ nsBuiltinDecoder::GetStatistics()
|
||||
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
if (mResource) {
|
||||
result.mDownloadRate =
|
||||
result.mDownloadRate =
|
||||
mResource->GetDownloadRate(&result.mDownloadRateReliable);
|
||||
result.mDownloadPosition =
|
||||
mResource->GetCachedDataEnd(mDecoderPosition);
|
||||
@ -809,7 +809,7 @@ void nsBuiltinDecoder::NotifySuspendedStatusChanged()
|
||||
return;
|
||||
MediaResource* activeStream;
|
||||
bool suspended = mResource->IsSuspendedByCache(&activeStream);
|
||||
|
||||
|
||||
if (mElement) {
|
||||
if (suspended) {
|
||||
// If this is an autoplay element, we need to kick off its autoplaying
|
||||
@ -818,7 +818,7 @@ void nsBuiltinDecoder::NotifySuspendedStatusChanged()
|
||||
}
|
||||
mElement->NotifySuspendedByCache(suspended);
|
||||
UpdateReadyStateForData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsBuiltinDecoder::NotifyBytesDownloaded()
|
||||
@ -989,7 +989,7 @@ void nsBuiltinDecoder::SeekingStarted()
|
||||
|
||||
void nsBuiltinDecoder::ChangeState(PlayState aState)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
|
||||
if (mNextState == aState) {
|
||||
@ -1211,3 +1211,56 @@ void nsBuiltinDecoder::NotifyAudioAvailableListener()
|
||||
mDecoderStateMachine->NotifyAudioAvailableListener();
|
||||
}
|
||||
}
|
||||
|
||||
bool nsBuiltinDecoder::OnDecodeThread() const {
|
||||
return mDecoderStateMachine->OnDecodeThread();
|
||||
}
|
||||
|
||||
ReentrantMonitor& nsBuiltinDecoder::GetReentrantMonitor() {
|
||||
return mReentrantMonitor.GetReentrantMonitor();
|
||||
}
|
||||
|
||||
// Constructs the time ranges representing what segments of the media
|
||||
// are buffered and playable.
|
||||
nsresult nsBuiltinDecoder::GetBuffered(nsTimeRanges* aBuffered) {
|
||||
if (mDecoderStateMachine) {
|
||||
return mDecoderStateMachine->GetBuffered(aBuffered);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int64_t nsBuiltinDecoder::VideoQueueMemoryInUse() {
|
||||
if (mDecoderStateMachine) {
|
||||
return mDecoderStateMachine->VideoQueueMemoryInUse();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t nsBuiltinDecoder::AudioQueueMemoryInUse() {
|
||||
if (mDecoderStateMachine) {
|
||||
return mDecoderStateMachine->AudioQueueMemoryInUse();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nsBuiltinDecoder::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) {
|
||||
if (mDecoderStateMachine) {
|
||||
mDecoderStateMachine->NotifyDataArrived(aBuffer, aLength, aOffset);
|
||||
}
|
||||
}
|
||||
|
||||
void nsBuiltinDecoder::UpdatePlaybackPosition(int64_t aTime)
|
||||
{
|
||||
mDecoderStateMachine->UpdatePlaybackPosition(aTime);
|
||||
}
|
||||
|
||||
// Provide access to the state machine object
|
||||
nsBuiltinDecoderStateMachine* nsBuiltinDecoder::GetStateMachine() {
|
||||
return mDecoderStateMachine;
|
||||
}
|
||||
|
||||
// Drop reference to state machine. Only called during shutdown dance.
|
||||
void nsBuiltinDecoder::ReleaseStateMachine() {
|
||||
mDecoderStateMachine = nullptr;
|
||||
}
|
||||
|
||||
|
@ -13,10 +13,9 @@ to the hardware. This thread is not created until playback starts, but
|
||||
currently is not destroyed when paused, only when playback ends.
|
||||
|
||||
The decoder owns the resources for downloading the media file, and the
|
||||
high level state. It holds an owning reference to the state machine
|
||||
(a subclass of nsDecoderStateMachine; nsBuiltinDecoderStateMachine) that
|
||||
high level state. It holds an owning reference to the state machine that
|
||||
owns all the resources related to decoding data, and manages the low level
|
||||
decoding operations and A/V sync.
|
||||
decoding operations and A/V sync.
|
||||
|
||||
Each state machine runs on the shared state machine thread. Every time some
|
||||
action is required for a state machine, it is scheduled to run on the shared
|
||||
@ -35,7 +34,7 @@ The player states are the states requested by the client through the
|
||||
DOM API. They represent the desired state of the player, while the
|
||||
decoder's state represents the actual state of the decoder.
|
||||
|
||||
The high level state of the player is maintained via a PlayState value.
|
||||
The high level state of the player is maintained via a PlayState value.
|
||||
It can have the following states:
|
||||
|
||||
START
|
||||
@ -60,7 +59,7 @@ machine object to cause it to behave as required by the play state.
|
||||
State transitions will likely schedule the state machine to run to
|
||||
affect the change.
|
||||
|
||||
An implementation of the nsDecoderStateMachine class is the event
|
||||
An implementation of the nsBuiltinDecoderStateMachine class is the event
|
||||
that gets dispatched to the state machine thread. Each time the event is run,
|
||||
the state machine must cycle the state machine once, and then return.
|
||||
|
||||
@ -91,7 +90,7 @@ SHUTDOWN
|
||||
The following result in state transitions.
|
||||
|
||||
Shutdown()
|
||||
Clean up any resources the nsDecoderStateMachine owns.
|
||||
Clean up any resources the nsBuiltinDecoderStateMachine owns.
|
||||
Play()
|
||||
Start decoding and playback of media data.
|
||||
Buffer
|
||||
@ -127,7 +126,7 @@ DECODING | | | | |
|
||||
------------>-----|
|
||||
|
||||
The following represents the states that the nsBuiltinDecoder object
|
||||
can be in, and the valid states the nsDecoderStateMachine can be in at that
|
||||
can be in, and the valid states the nsBuiltinDecoderStateMachine can be in at that
|
||||
time:
|
||||
|
||||
player LOADING decoder DECODING_METADATA
|
||||
@ -141,7 +140,7 @@ The general sequence of events is:
|
||||
|
||||
1) The video element calls Load on nsMediaDecoder. This creates the
|
||||
state machine and starts the channel for downloading the
|
||||
file. It instantiates and schedules the nsDecoderStateMachine. The
|
||||
file. It instantiates and schedules the nsBuiltinDecoderStateMachine. The
|
||||
high level LOADING state is entered, which results in the decode
|
||||
thread being created and starting to decode metadata. These are
|
||||
the headers that give the video size, framerate, etc. Load() returns
|
||||
@ -205,133 +204,12 @@ class Image;
|
||||
typedef mozilla::layers::Image Image;
|
||||
|
||||
class nsAudioStream;
|
||||
class nsBuiltinDecoderStateMachine;
|
||||
|
||||
static inline bool IsCurrentThread(nsIThread* aThread) {
|
||||
return NS_GetCurrentThread() == aThread;
|
||||
}
|
||||
|
||||
// Decoder backends must implement this class to perform the codec
|
||||
// specific parts of decoding the video/audio format.
|
||||
class nsDecoderStateMachine : public nsRunnable
|
||||
{
|
||||
public:
|
||||
// Enumeration for the valid decoding states
|
||||
enum State {
|
||||
DECODER_STATE_DECODING_METADATA,
|
||||
DECODER_STATE_DECODING,
|
||||
DECODER_STATE_SEEKING,
|
||||
DECODER_STATE_BUFFERING,
|
||||
DECODER_STATE_COMPLETED,
|
||||
DECODER_STATE_SHUTDOWN
|
||||
};
|
||||
|
||||
// Initializes the state machine, returns NS_OK on success, or
|
||||
// NS_ERROR_FAILURE on failure.
|
||||
virtual nsresult Init(nsDecoderStateMachine* aCloneDonor) = 0;
|
||||
|
||||
// Return the current decode state. The decoder monitor must be
|
||||
// obtained before calling this.
|
||||
virtual State GetState() = 0;
|
||||
|
||||
// Set the audio volume. The decoder monitor must be obtained before
|
||||
// calling this.
|
||||
virtual void SetVolume(double aVolume) = 0;
|
||||
virtual void SetAudioCaptured(bool aCapture) = 0;
|
||||
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
// True if the state machine has shutdown, or is in the process of
|
||||
// shutting down. The decoder monitor must be obtained before calling this.
|
||||
virtual bool IsShutdown() = 0;
|
||||
|
||||
// Called from the main thread to get the duration. The decoder monitor
|
||||
// must be obtained before calling this. It is in units of microseconds.
|
||||
virtual int64_t GetDuration() = 0;
|
||||
|
||||
// Called from the main thread to set the duration of the media resource
|
||||
// if it is able to be obtained via HTTP headers. Called from the
|
||||
// state machine thread to set the duration if it is obtained from the
|
||||
// media metadata. The decoder monitor must be obtained before calling this.
|
||||
// aDuration is in microseconds.
|
||||
virtual void SetDuration(int64_t aDuration) = 0;
|
||||
|
||||
// Called while decoding metadata to set the end time of the media
|
||||
// resource. The decoder monitor must be obtained before calling this.
|
||||
// aEndTime is in microseconds.
|
||||
virtual void SetEndTime(int64_t aEndTime) = 0;
|
||||
|
||||
// Set the media fragment end time. aEndTime is in microseconds.
|
||||
virtual void SetFragmentEndTime(int64_t aEndTime) = 0;
|
||||
|
||||
// Functions used by assertions to ensure we're calling things
|
||||
// on the appropriate threads.
|
||||
virtual bool OnDecodeThread() const = 0;
|
||||
|
||||
// Returns true if the current thread is the state machine thread.
|
||||
virtual bool OnStateMachineThread() const = 0;
|
||||
|
||||
virtual nsHTMLMediaElement::NextFrameStatus GetNextFrameStatus() = 0;
|
||||
|
||||
// Cause state transitions. These methods obtain the decoder monitor
|
||||
// to synchronise the change of state, and to notify other threads
|
||||
// that the state has changed.
|
||||
virtual void Play() = 0;
|
||||
|
||||
// Seeks to aTime in seconds
|
||||
virtual void Seek(double aTime) = 0;
|
||||
|
||||
// Returns the current playback position in seconds.
|
||||
// Called from the main thread to get the current frame time. The decoder
|
||||
// monitor must be obtained before calling this.
|
||||
virtual double GetCurrentTime() const = 0;
|
||||
|
||||
// Clear the flag indicating that a playback position change event
|
||||
// is currently queued. This is called from the main thread and must
|
||||
// be called with the decode monitor held.
|
||||
virtual void ClearPositionChangeFlag() = 0;
|
||||
|
||||
// Called from the main thread to set whether the media resource can
|
||||
// seek into unbuffered ranges. The decoder monitor must be obtained
|
||||
// before calling this.
|
||||
virtual void SetSeekable(bool aSeekable) = 0;
|
||||
|
||||
// Returns true if the media resource can seek into unbuffered ranges,
|
||||
// as set by SetSeekable(). The decoder monitor must be obtained before
|
||||
// calling this.
|
||||
virtual bool IsSeekable() = 0;
|
||||
|
||||
// Update the playback position. This can result in a timeupdate event
|
||||
// and an invalidate of the frame being dispatched asynchronously if
|
||||
// there is no such event currently queued.
|
||||
// Only called on the decoder thread. Must be called with
|
||||
// the decode monitor held.
|
||||
virtual void UpdatePlaybackPosition(int64_t aTime) = 0;
|
||||
|
||||
virtual nsresult GetBuffered(nsTimeRanges* aBuffered) = 0;
|
||||
|
||||
// Return true if the media is seekable using only buffered ranges.
|
||||
virtual bool IsSeekableInBufferedRanges() = 0;
|
||||
|
||||
virtual int64_t VideoQueueMemoryInUse() = 0;
|
||||
virtual int64_t AudioQueueMemoryInUse() = 0;
|
||||
|
||||
virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) = 0;
|
||||
|
||||
// Causes the state machine to switch to buffering state, and to
|
||||
// immediately stop playback and buffer downloaded data. Must be called
|
||||
// with the decode monitor held. Called on the state machine thread and
|
||||
// the main thread.
|
||||
virtual void StartBuffering() = 0;
|
||||
|
||||
// Sets the current size of the framebuffer used in MozAudioAvailable events.
|
||||
// Called on the state machine thread and the main thread.
|
||||
virtual void SetFrameBufferLength(uint32_t aLength) = 0;
|
||||
|
||||
// Called when a "MozAudioAvailable" event listener is added to the media
|
||||
// element. Called on the main thread.
|
||||
virtual void NotifyAudioAvailableListener() = 0;
|
||||
};
|
||||
|
||||
class nsBuiltinDecoder : public nsMediaDecoder
|
||||
{
|
||||
public:
|
||||
@ -354,13 +232,13 @@ public:
|
||||
|
||||
nsBuiltinDecoder();
|
||||
~nsBuiltinDecoder();
|
||||
|
||||
|
||||
virtual bool Init(nsHTMLMediaElement* aElement);
|
||||
|
||||
// This method must be called by the owning object before that
|
||||
// object disposes of this decoder object.
|
||||
virtual void Shutdown();
|
||||
|
||||
|
||||
virtual double GetCurrentTime();
|
||||
|
||||
virtual nsresult Load(MediaResource* aResource,
|
||||
@ -371,7 +249,7 @@ public:
|
||||
nsresult OpenResource(MediaResource* aResource,
|
||||
nsIStreamListener** aStreamListener);
|
||||
|
||||
virtual nsDecoderStateMachine* CreateStateMachine() = 0;
|
||||
virtual nsBuiltinDecoderStateMachine* CreateStateMachine() = 0;
|
||||
|
||||
// Initialize state machine and schedule it.
|
||||
nsresult InitializeStateMachine(nsMediaDecoder* aCloneDonor);
|
||||
@ -402,7 +280,7 @@ public:
|
||||
~DecodedStreamData();
|
||||
|
||||
// The following group of fields are protected by the decoder's monitor
|
||||
// and can be read or written on any thread.
|
||||
// and can be read or written on any thread.
|
||||
int64_t mLastAudioPacketTime; // microseconds
|
||||
int64_t mLastAudioPacketEndTime; // microseconds
|
||||
// Count of audio frames written to the stream
|
||||
@ -562,44 +440,21 @@ public:
|
||||
|
||||
virtual bool OnStateMachineThread() const;
|
||||
|
||||
virtual bool OnDecodeThread() const {
|
||||
return mDecoderStateMachine->OnDecodeThread();
|
||||
}
|
||||
virtual bool OnDecodeThread() const;
|
||||
|
||||
// Returns the monitor for other threads to synchronise access to
|
||||
// state.
|
||||
virtual ReentrantMonitor& GetReentrantMonitor() {
|
||||
return mReentrantMonitor.GetReentrantMonitor();
|
||||
}
|
||||
virtual ReentrantMonitor& GetReentrantMonitor();
|
||||
|
||||
// Constructs the time ranges representing what segments of the media
|
||||
// are buffered and playable.
|
||||
virtual nsresult GetBuffered(nsTimeRanges* aBuffered) {
|
||||
if (mDecoderStateMachine) {
|
||||
return mDecoderStateMachine->GetBuffered(aBuffered);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
virtual nsresult GetBuffered(nsTimeRanges* aBuffered);
|
||||
|
||||
virtual int64_t VideoQueueMemoryInUse() {
|
||||
if (mDecoderStateMachine) {
|
||||
return mDecoderStateMachine->VideoQueueMemoryInUse();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
virtual int64_t VideoQueueMemoryInUse();
|
||||
|
||||
virtual int64_t AudioQueueMemoryInUse() {
|
||||
if (mDecoderStateMachine) {
|
||||
return mDecoderStateMachine->AudioQueueMemoryInUse();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
virtual int64_t AudioQueueMemoryInUse();
|
||||
|
||||
virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset) {
|
||||
if (mDecoderStateMachine) {
|
||||
mDecoderStateMachine->NotifyDataArrived(aBuffer, aLength, aOffset);
|
||||
}
|
||||
}
|
||||
virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
|
||||
|
||||
// Sets the length of the framebuffer used in MozAudioAvailable events.
|
||||
// The new size must be between 512 and 16384.
|
||||
@ -628,15 +483,11 @@ public:
|
||||
double ComputePlaybackRate(bool* aReliable);
|
||||
|
||||
// Make the decoder state machine update the playback position. Called by
|
||||
// the reader on the decoder thread (Assertions for this checked by
|
||||
// the reader on the decoder thread (Assertions for this checked by
|
||||
// mDecoderStateMachine). This must be called with the decode monitor
|
||||
// held.
|
||||
void UpdatePlaybackPosition(int64_t aTime)
|
||||
{
|
||||
mDecoderStateMachine->UpdatePlaybackPosition(aTime);
|
||||
}
|
||||
|
||||
/******
|
||||
void UpdatePlaybackPosition(int64_t aTime);
|
||||
/******
|
||||
* The following methods must only be called on the main
|
||||
* thread.
|
||||
******/
|
||||
@ -701,10 +552,10 @@ public:
|
||||
void UpdatePlaybackOffset(int64_t aOffset);
|
||||
|
||||
// Provide access to the state machine object
|
||||
nsDecoderStateMachine* GetStateMachine() { return mDecoderStateMachine; }
|
||||
nsBuiltinDecoderStateMachine* GetStateMachine();
|
||||
|
||||
// Drop reference to state machine. Only called during shutdown dance.
|
||||
virtual void ReleaseStateMachine() { mDecoderStateMachine = nullptr; }
|
||||
virtual void ReleaseStateMachine();
|
||||
|
||||
// Called when a "MozAudioAvailable" event listener is added to the media
|
||||
// element. Called on the main thread.
|
||||
@ -774,7 +625,7 @@ public:
|
||||
// is synchronised on a monitor. The lifetime of this object is
|
||||
// after mPlayState is LOADING and before mPlayState is SHUTDOWN. It
|
||||
// is safe to access it during this period.
|
||||
nsCOMPtr<nsDecoderStateMachine> mDecoderStateMachine;
|
||||
nsCOMPtr<nsBuiltinDecoderStateMachine> mDecoderStateMachine;
|
||||
|
||||
// Media data resource.
|
||||
nsAutoPtr<MediaResource> mResource;
|
||||
|
@ -1215,7 +1215,7 @@ uint32_t nsBuiltinDecoderStateMachine::PlayFromAudioQueue(uint64_t aFrameOffset,
|
||||
return frames;
|
||||
}
|
||||
|
||||
nsresult nsBuiltinDecoderStateMachine::Init(nsDecoderStateMachine* aCloneDonor)
|
||||
nsresult nsBuiltinDecoderStateMachine::Init(nsBuiltinDecoderStateMachine* aCloneDonor)
|
||||
{
|
||||
nsBuiltinDecoderReader* cloneReader = nullptr;
|
||||
if (aCloneDonor) {
|
||||
|
@ -78,7 +78,6 @@ hardware (via nsAudioStream and libsydneyaudio).
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsBuiltinDecoder.h"
|
||||
#include "nsBuiltinDecoderReader.h"
|
||||
#include "nsAudioAvailableEventManager.h"
|
||||
#include "nsHTMLMediaElement.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
@ -86,6 +85,9 @@ hardware (via nsAudioStream and libsydneyaudio).
|
||||
#include "AudioSegment.h"
|
||||
#include "VideoSegment.h"
|
||||
|
||||
|
||||
class nsBuiltinDecoderReader;
|
||||
|
||||
/*
|
||||
The state machine class. This manages the decoding and seeking in the
|
||||
nsBuiltinDecoderReader on the decode thread, and A/V sync on the shared
|
||||
@ -98,7 +100,7 @@ hardware (via nsAudioStream and libsydneyaudio).
|
||||
|
||||
See nsBuiltinDecoder.h for more details.
|
||||
*/
|
||||
class nsBuiltinDecoderStateMachine : public nsDecoderStateMachine
|
||||
class nsBuiltinDecoderStateMachine : public nsRunnable
|
||||
{
|
||||
public:
|
||||
typedef mozilla::ReentrantMonitor ReentrantMonitor;
|
||||
@ -114,29 +116,91 @@ public:
|
||||
~nsBuiltinDecoderStateMachine();
|
||||
|
||||
// nsDecoderStateMachine interface
|
||||
virtual nsresult Init(nsDecoderStateMachine* aCloneDonor);
|
||||
State GetState()
|
||||
{
|
||||
virtual nsresult Init(nsBuiltinDecoderStateMachine* aCloneDonor);
|
||||
|
||||
// Enumeration for the valid decoding states
|
||||
enum State {
|
||||
DECODER_STATE_DECODING_METADATA,
|
||||
DECODER_STATE_DECODING,
|
||||
DECODER_STATE_SEEKING,
|
||||
DECODER_STATE_BUFFERING,
|
||||
DECODER_STATE_COMPLETED,
|
||||
DECODER_STATE_SHUTDOWN
|
||||
};
|
||||
|
||||
State GetState() {
|
||||
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
return mState;
|
||||
}
|
||||
|
||||
// Set the audio volume. The decoder monitor must be obtained before
|
||||
// calling this.
|
||||
virtual void SetVolume(double aVolume);
|
||||
virtual void SetAudioCaptured(bool aCapture);
|
||||
virtual void Shutdown();
|
||||
|
||||
// Called from the main thread to get the duration. The decoder monitor
|
||||
// must be obtained before calling this. It is in units of microseconds.
|
||||
virtual int64_t GetDuration();
|
||||
|
||||
// Called from the main thread to set the duration of the media resource
|
||||
// if it is able to be obtained via HTTP headers. Called from the
|
||||
// state machine thread to set the duration if it is obtained from the
|
||||
// media metadata. The decoder monitor must be obtained before calling this.
|
||||
// aDuration is in microseconds.
|
||||
virtual void SetDuration(int64_t aDuration);
|
||||
|
||||
// Called while decoding metadata to set the end time of the media
|
||||
// resource. The decoder monitor must be obtained before calling this.
|
||||
// aEndTime is in microseconds.
|
||||
void SetEndTime(int64_t aEndTime);
|
||||
|
||||
// Functions used by assertions to ensure we're calling things
|
||||
// on the appropriate threads.
|
||||
virtual bool OnDecodeThread() const {
|
||||
return IsCurrentThread(mDecodeThread);
|
||||
}
|
||||
bool OnStateMachineThread() const;
|
||||
bool OnAudioThread() const {
|
||||
return IsCurrentThread(mAudioThread);
|
||||
}
|
||||
|
||||
virtual nsHTMLMediaElement::NextFrameStatus GetNextFrameStatus();
|
||||
|
||||
// Cause state transitions. These methods obtain the decoder monitor
|
||||
// to synchronise the change of state, and to notify other threads
|
||||
// that the state has changed.
|
||||
virtual void Play();
|
||||
|
||||
// Seeks to aTime in seconds.
|
||||
virtual void Seek(double aTime);
|
||||
|
||||
// Returns the current playback position in seconds.
|
||||
// Called from the main thread to get the current frame time. The decoder
|
||||
// monitor must be obtained before calling this.
|
||||
virtual double GetCurrentTime() const;
|
||||
|
||||
// Clear the flag indicating that a playback position change event
|
||||
// is currently queued. This is called from the main thread and must
|
||||
// be called with the decode monitor held.
|
||||
virtual void ClearPositionChangeFlag();
|
||||
|
||||
// Called from the main thread to set whether the media resource can
|
||||
// seek into unbuffered ranges. The decoder monitor must be obtained
|
||||
// before calling this.
|
||||
virtual void SetSeekable(bool aSeekable);
|
||||
|
||||
// Update the playback position. This can result in a timeupdate event
|
||||
// and an invalidate of the frame being dispatched asynchronously if
|
||||
// there is no such event currently queued.
|
||||
// Only called on the decoder thread. Must be called with
|
||||
// the decode monitor held.
|
||||
virtual void UpdatePlaybackPosition(int64_t aTime);
|
||||
|
||||
// Causes the state machine to switch to buffering state, and to
|
||||
// immediately stop playback and buffer downloaded data. Must be called
|
||||
// with the decode monitor held. Called on the state machine thread and
|
||||
// the main thread.
|
||||
virtual void StartBuffering();
|
||||
|
||||
// State machine thread run function. Defers to RunStateMachine().
|
||||
@ -163,24 +227,16 @@ public:
|
||||
bool IsBuffering() const {
|
||||
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
return mState == nsBuiltinDecoderStateMachine::DECODER_STATE_BUFFERING;
|
||||
return mState == DECODER_STATE_BUFFERING;
|
||||
}
|
||||
|
||||
// Must be called with the decode monitor held.
|
||||
bool IsSeeking() const {
|
||||
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
return mState == nsBuiltinDecoderStateMachine::DECODER_STATE_SEEKING;
|
||||
return mState == DECODER_STATE_SEEKING;
|
||||
}
|
||||
|
||||
// Functions used by assertions to ensure we're calling things
|
||||
// on the appropriate threads.
|
||||
bool OnAudioThread() const {
|
||||
return IsCurrentThread(mAudioThread);
|
||||
}
|
||||
|
||||
bool OnStateMachineThread() const;
|
||||
|
||||
nsresult GetBuffered(nsTimeRanges* aBuffered);
|
||||
|
||||
int64_t VideoQueueMemoryInUse() {
|
||||
@ -209,6 +265,7 @@ public:
|
||||
return mSeekable;
|
||||
}
|
||||
|
||||
// Return true if the media is seekable using only buffered ranges.
|
||||
bool IsSeekableInBufferedRanges() {
|
||||
if (mReader) {
|
||||
return mReader->IsSeekableInBufferedRanges();
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "nsOggReader.h"
|
||||
#include "nsOggDecoder.h"
|
||||
|
||||
nsDecoderStateMachine* nsOggDecoder::CreateStateMachine()
|
||||
nsBuiltinDecoderStateMachine* nsOggDecoder::CreateStateMachine()
|
||||
{
|
||||
return new nsBuiltinDecoderStateMachine(this, new nsOggReader(this));
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
}
|
||||
return new nsOggDecoder();
|
||||
}
|
||||
virtual nsDecoderStateMachine* CreateStateMachine();
|
||||
virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -336,7 +336,7 @@ nsresult nsOggReader::ReadMetadata(nsVideoInfo* aInfo,
|
||||
|
||||
MediaResource* resource = mDecoder->GetResource();
|
||||
if (mDecoder->GetStateMachine()->GetDuration() == -1 &&
|
||||
mDecoder->GetStateMachine()->GetState() != nsDecoderStateMachine::DECODER_STATE_SHUTDOWN &&
|
||||
!mDecoder->GetStateMachine()->IsShutdown() &&
|
||||
resource->GetLength() >= 0 &&
|
||||
mDecoder->GetStateMachine()->IsSeekable())
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ nsMediaDecoder* nsMediaOmxDecoder::Clone()
|
||||
return new nsMediaOmxDecoder();
|
||||
}
|
||||
|
||||
nsDecoderStateMachine* nsMediaOmxDecoder::CreateStateMachine()
|
||||
nsBuiltinDecoderStateMachine* nsMediaOmxDecoder::CreateStateMachine()
|
||||
{
|
||||
return new nsBuiltinDecoderStateMachine(this, new nsMediaOmxReader(this));
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
~nsMediaOmxDecoder();
|
||||
|
||||
virtual nsMediaDecoder* Clone();
|
||||
virtual nsDecoderStateMachine* CreateStateMachine();
|
||||
virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "nsMediaOmxReader.h"
|
||||
|
||||
#include "nsBuiltinDecoderStateMachine.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsTimeRanges.h"
|
||||
#include "MediaResource.h"
|
||||
|
@ -12,7 +12,7 @@ nsMediaPluginDecoder::nsMediaPluginDecoder(const nsACString& aType) : mType(aTyp
|
||||
{
|
||||
}
|
||||
|
||||
nsDecoderStateMachine* nsMediaPluginDecoder::CreateStateMachine()
|
||||
nsBuiltinDecoderStateMachine* nsMediaPluginDecoder::CreateStateMachine()
|
||||
{
|
||||
return new nsBuiltinDecoderStateMachine(this, new nsMediaPluginReader(this));
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
}
|
||||
|
||||
virtual nsMediaDecoder* Clone() { return new nsMediaPluginDecoder(mType); }
|
||||
virtual nsDecoderStateMachine* CreateStateMachine();
|
||||
virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -3,13 +3,14 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "nsMediaPluginReader.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsTimeRanges.h"
|
||||
#include "MediaResource.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "nsMediaPluginReader.h"
|
||||
#include "nsMediaPluginDecoder.h"
|
||||
#include "nsMediaPluginHost.h"
|
||||
#include "nsBuiltinDecoderStateMachine.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nsRawReader.h"
|
||||
#include "nsRawDecoder.h"
|
||||
|
||||
nsDecoderStateMachine* nsRawDecoder::CreateStateMachine()
|
||||
nsBuiltinDecoderStateMachine* nsRawDecoder::CreateStateMachine()
|
||||
{
|
||||
return new nsBuiltinDecoderStateMachine(this, new nsRawReader(this), true);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
}
|
||||
return new nsRawDecoder();
|
||||
}
|
||||
virtual nsDecoderStateMachine* CreateStateMachine();
|
||||
virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "nsWaveReader.h"
|
||||
#include "nsWaveDecoder.h"
|
||||
|
||||
nsDecoderStateMachine* nsWaveDecoder::CreateStateMachine()
|
||||
nsBuiltinDecoderStateMachine* nsWaveDecoder::CreateStateMachine()
|
||||
{
|
||||
return new nsBuiltinDecoderStateMachine(this, new nsWaveReader(this));
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
}
|
||||
return new nsWaveDecoder();
|
||||
}
|
||||
virtual nsDecoderStateMachine* CreateStateMachine();
|
||||
virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "MediaResource.h"
|
||||
#include "nsWaveReader.h"
|
||||
#include "nsTimeRanges.h"
|
||||
#include "nsBuiltinDecoderStateMachine.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
#include "mozilla/StandardInteger.h"
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "nsWebMReader.h"
|
||||
#include "nsWebMDecoder.h"
|
||||
|
||||
nsDecoderStateMachine* nsWebMDecoder::CreateStateMachine()
|
||||
nsBuiltinDecoderStateMachine* nsWebMDecoder::CreateStateMachine()
|
||||
{
|
||||
return new nsBuiltinDecoderStateMachine(this, new nsWebMReader(this));
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
}
|
||||
return new nsWebMDecoder();
|
||||
}
|
||||
virtual nsDecoderStateMachine* CreateStateMachine();
|
||||
virtual nsBuiltinDecoderStateMachine* CreateStateMachine();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user