2008-07-30 10:50:14 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2011-07-12 07:39:39 +04:00
|
|
|
|
2012-11-14 23:46:40 +04:00
|
|
|
#if !defined(MediaDecoder_h_)
|
|
|
|
#define MediaDecoder_h_
|
2008-07-30 10:50:14 +04:00
|
|
|
|
2015-09-07 06:39:46 +03:00
|
|
|
#ifdef MOZ_EME
|
|
|
|
#include "mozilla/CDMProxy.h"
|
|
|
|
#endif
|
|
|
|
|
2015-08-21 01:10:33 +03:00
|
|
|
#include "mozilla/Atomics.h"
|
2015-07-16 21:52:43 +03:00
|
|
|
#include "mozilla/MozPromise.h"
|
|
|
|
#include "mozilla/ReentrantMonitor.h"
|
|
|
|
#include "mozilla/StateMirroring.h"
|
|
|
|
#include "mozilla/StateWatching.h"
|
|
|
|
|
|
|
|
#include "mozilla/dom/AudioChannelBinding.h"
|
|
|
|
|
2015-09-07 06:39:46 +03:00
|
|
|
#include "necko-config.h"
|
|
|
|
#include "nsAutoPtr.h"
|
2008-07-30 10:50:14 +04:00
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsIObserver.h"
|
2015-09-07 06:39:46 +03:00
|
|
|
#include "nsISupports.h"
|
2015-01-28 17:31:31 +03:00
|
|
|
#include "nsITimer.h"
|
2015-09-07 06:39:46 +03:00
|
|
|
|
|
|
|
#include "AbstractMediaDecoder.h"
|
2015-04-01 04:44:36 +03:00
|
|
|
#include "MediaDecoderOwner.h"
|
2015-09-07 06:38:34 +03:00
|
|
|
#include "MediaEventSource.h"
|
2015-09-07 06:39:46 +03:00
|
|
|
#include "MediaMetadataManager.h"
|
|
|
|
#include "MediaResource.h"
|
2015-10-27 05:28:26 +03:00
|
|
|
#include "MediaResourceCallback.h"
|
2015-09-10 11:37:26 +03:00
|
|
|
#include "MediaStatistics.h"
|
2012-11-14 23:45:13 +04:00
|
|
|
#include "MediaStreamGraph.h"
|
2015-05-18 09:15:47 +03:00
|
|
|
#include "TimeUnits.h"
|
2016-02-01 07:05:25 +03:00
|
|
|
#include "SeekTarget.h"
|
2008-07-30 10:50:14 +04:00
|
|
|
|
2012-11-14 23:45:33 +04:00
|
|
|
class nsIStreamListener;
|
|
|
|
class nsIPrincipal;
|
|
|
|
|
2012-08-19 23:33:25 +04:00
|
|
|
namespace mozilla {
|
|
|
|
|
2016-06-09 22:27:39 +03:00
|
|
|
namespace dom {
|
|
|
|
class Promise;
|
|
|
|
}
|
|
|
|
|
2012-11-14 23:45:33 +04:00
|
|
|
class VideoFrameContainer;
|
2012-11-14 23:46:40 +04:00
|
|
|
class MediaDecoderStateMachine;
|
2012-11-14 23:45:13 +04:00
|
|
|
|
2015-12-01 04:34:02 +03:00
|
|
|
enum class MediaEventType : int8_t;
|
|
|
|
|
2013-01-02 21:26:08 +04:00
|
|
|
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
|
|
|
|
// GetTickCount() and conflicts with MediaDecoder::GetCurrentTime implementation.
|
|
|
|
#ifdef GetCurrentTime
|
|
|
|
#undef GetCurrentTime
|
|
|
|
#endif
|
|
|
|
|
2015-11-16 02:50:55 +03:00
|
|
|
class MediaDecoder : public AbstractMediaDecoder
|
2010-04-27 12:53:44 +04:00
|
|
|
{
|
2012-02-15 08:35:01 +04:00
|
|
|
public:
|
2015-03-03 03:46:32 +03:00
|
|
|
struct SeekResolveValue {
|
|
|
|
SeekResolveValue(bool aAtEnd, MediaDecoderEventVisibility aEventVisibility)
|
|
|
|
: mAtEnd(aAtEnd), mEventVisibility(aEventVisibility) {}
|
|
|
|
bool mAtEnd;
|
|
|
|
MediaDecoderEventVisibility mEventVisibility;
|
|
|
|
};
|
|
|
|
|
2015-11-16 02:50:55 +03:00
|
|
|
// Used to register with MediaResource to receive notifications which will
|
|
|
|
// be forwarded to MediaDecoder.
|
|
|
|
class ResourceCallback : public MediaResourceCallback {
|
2016-08-01 09:39:39 +03:00
|
|
|
// Throttle calls to MediaDecoder::NotifyDataArrived()
|
|
|
|
// to be at most once per 500ms.
|
|
|
|
static const uint32_t sDelay = 500;
|
|
|
|
|
2015-11-16 02:50:55 +03:00
|
|
|
public:
|
|
|
|
// Start to receive notifications from ResourceCallback.
|
|
|
|
void Connect(MediaDecoder* aDecoder);
|
|
|
|
// Called upon shutdown to stop receiving notifications.
|
|
|
|
void Disconnect();
|
|
|
|
|
|
|
|
private:
|
|
|
|
/* MediaResourceCallback functions */
|
|
|
|
MediaDecoderOwner* GetMediaOwner() const override;
|
|
|
|
void SetInfinite(bool aInfinite) override;
|
|
|
|
void SetMediaSeekable(bool aMediaSeekable) override;
|
|
|
|
void NotifyNetworkError() override;
|
|
|
|
void NotifyDecodeError() override;
|
|
|
|
void NotifyDataArrived() override;
|
|
|
|
void NotifyBytesDownloaded() override;
|
|
|
|
void NotifyDataEnded(nsresult aStatus) override;
|
|
|
|
void NotifyPrincipalChanged() override;
|
|
|
|
void NotifySuspendedStatusChanged() override;
|
|
|
|
void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) override;
|
|
|
|
|
2016-08-01 09:39:39 +03:00
|
|
|
static void TimerCallback(nsITimer* aTimer, void* aClosure);
|
|
|
|
|
2015-11-16 02:50:55 +03:00
|
|
|
// The decoder to send notifications. Main-thread only.
|
|
|
|
MediaDecoder* mDecoder = nullptr;
|
2016-08-01 09:39:39 +03:00
|
|
|
nsCOMPtr<nsITimer> mTimer;
|
|
|
|
bool mTimerArmed = false;
|
2015-11-16 02:50:55 +03:00
|
|
|
};
|
|
|
|
|
2015-07-16 21:06:49 +03:00
|
|
|
typedef MozPromise<SeekResolveValue, bool /* aIgnored */, /* IsExclusive = */ true> SeekPromise;
|
2013-12-02 01:09:06 +04:00
|
|
|
|
2013-07-19 06:21:19 +04:00
|
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
2008-07-30 10:50:14 +04:00
|
|
|
|
2008-10-19 11:39:21 +04:00
|
|
|
// Enumeration for the valid play states (see mPlayState)
|
|
|
|
enum PlayState {
|
|
|
|
PLAY_STATE_START,
|
|
|
|
PLAY_STATE_LOADING,
|
|
|
|
PLAY_STATE_PAUSED,
|
|
|
|
PLAY_STATE_PLAYING,
|
|
|
|
PLAY_STATE_ENDED,
|
|
|
|
PLAY_STATE_SHUTDOWN
|
|
|
|
};
|
|
|
|
|
2015-04-07 20:59:44 +03:00
|
|
|
// Must be called exactly once, on the main thread, during startup.
|
|
|
|
static void InitStatics();
|
|
|
|
|
2015-10-15 06:36:21 +03:00
|
|
|
explicit MediaDecoder(MediaDecoderOwner* aOwner);
|
2012-11-07 02:33:02 +04:00
|
|
|
|
2015-11-16 02:50:55 +03:00
|
|
|
// Return a callback object used to register with MediaResource to receive
|
|
|
|
// notifications.
|
|
|
|
MediaResourceCallback* GetResourceCallback() const;
|
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Create a new decoder of the same type as this one.
|
|
|
|
// Subclasses must implement this.
|
2015-10-15 06:37:47 +03:00
|
|
|
virtual MediaDecoder* Clone(MediaDecoderOwner* aOwner) = 0;
|
2012-11-14 23:45:13 +04:00
|
|
|
// Create a new state machine to run this decoder.
|
|
|
|
// Subclasses must implement this.
|
2012-11-14 23:46:40 +04:00
|
|
|
virtual MediaDecoderStateMachine* CreateStateMachine() = 0;
|
2012-11-14 23:45:13 +04:00
|
|
|
|
|
|
|
// Cleanup internal data structures. Must be called on the main
|
|
|
|
// thread by the owning object before that object disposes of this object.
|
2016-05-04 11:13:25 +03:00
|
|
|
virtual void Shutdown();
|
2012-11-07 02:33:02 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Start downloading the media. Decode the downloaded data up to the
|
|
|
|
// point of the first frame of data.
|
|
|
|
// This is called at most once per decoder, after Init().
|
2015-10-14 06:46:27 +03:00
|
|
|
virtual nsresult Load(nsIStreamListener** aListener);
|
2008-07-30 10:50:14 +04:00
|
|
|
|
2013-07-24 13:55:23 +04:00
|
|
|
// Called in |Load| to open mResource.
|
|
|
|
nsresult OpenResource(nsIStreamListener** aStreamListener);
|
2012-09-18 00:45:38 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Called if the media file encounters a network error.
|
2015-11-16 02:50:55 +03:00
|
|
|
void NetworkError();
|
2012-11-14 23:45:13 +04:00
|
|
|
|
|
|
|
// Get the current MediaResource being used. Its URI will be returned
|
|
|
|
// by currentSrc. Returns what was passed to Load(), if Load() has been called.
|
2013-05-03 02:59:18 +04:00
|
|
|
// Note: The MediaResource is refcounted, but it outlives the MediaDecoder,
|
|
|
|
// so it's OK to use the reference returned by this function without
|
|
|
|
// refcounting, *unless* you need to store and use the reference after the
|
|
|
|
// MediaDecoder has been destroyed. You might need to do this if you're
|
|
|
|
// wrapping the MediaResource in some kind of byte stream interface to be
|
|
|
|
// passed to a platform decoder.
|
2015-03-21 19:28:04 +03:00
|
|
|
MediaResource* GetResource() const final override
|
2012-11-19 19:11:21 +04:00
|
|
|
{
|
|
|
|
return mResource;
|
|
|
|
}
|
2013-07-24 13:55:23 +04:00
|
|
|
void SetResource(MediaResource* aResource)
|
|
|
|
{
|
2015-07-01 00:39:41 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2013-07-24 13:55:23 +04:00
|
|
|
mResource = aResource;
|
|
|
|
}
|
2012-11-14 23:45:13 +04:00
|
|
|
|
|
|
|
// Return the principal of the current URI being played or downloaded.
|
|
|
|
virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
|
|
|
|
|
|
|
|
// Return the time position in the video stream being
|
|
|
|
// played measured in seconds.
|
|
|
|
virtual double GetCurrentTime();
|
|
|
|
|
|
|
|
// Seek to the time position in (seconds) from the start of the video.
|
2014-04-01 07:39:04 +04:00
|
|
|
// If aDoFastSeek is true, we'll seek to the sync point/keyframe preceeding
|
|
|
|
// the seek target.
|
2016-06-09 22:27:39 +03:00
|
|
|
virtual nsresult Seek(double aTime, SeekTarget::Type aSeekType,
|
|
|
|
dom::Promise* aPromise = nullptr);
|
2012-11-14 23:45:13 +04:00
|
|
|
|
2012-09-18 00:45:38 +04:00
|
|
|
// Initialize state machine and schedule it.
|
2015-10-14 06:46:27 +03:00
|
|
|
nsresult InitializeStateMachine();
|
2012-09-18 00:45:38 +04:00
|
|
|
|
2008-07-30 10:50:14 +04:00
|
|
|
// Start playback of a video. 'Load' must have previously been
|
|
|
|
// called.
|
2008-10-30 08:20:08 +03:00
|
|
|
virtual nsresult Play();
|
2008-07-30 10:50:14 +04:00
|
|
|
|
2015-01-22 07:01:12 +03:00
|
|
|
// Notify activity of the decoder owner is changed.
|
|
|
|
// Based on the activity, dormant state is updated.
|
2013-06-10 16:22:05 +04:00
|
|
|
// Dormant state is a state to free all scarce media resources
|
|
|
|
// (like hw video codec), did not decoding and stay dormant.
|
|
|
|
// It is used to share scarece media resources in system.
|
2016-04-12 08:48:06 +03:00
|
|
|
virtual void NotifyOwnerActivityChanged(bool aIsVisible);
|
2013-06-10 16:22:05 +04:00
|
|
|
|
2015-01-28 17:31:31 +03:00
|
|
|
void UpdateDormantState(bool aDormantTimeout, bool aActivity);
|
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Pause video playback.
|
2008-10-30 08:20:08 +03:00
|
|
|
virtual void Pause();
|
2012-11-14 23:45:13 +04:00
|
|
|
// Adjust the speed of the playback, optionally with pitch correction,
|
2011-01-17 06:03:00 +03:00
|
|
|
virtual void SetVolume(double aVolume);
|
2012-04-30 07:12:42 +04:00
|
|
|
|
2014-04-08 19:29:07 +04:00
|
|
|
virtual void SetPlaybackRate(double aPlaybackRate);
|
2012-11-22 14:38:28 +04:00
|
|
|
void SetPreservesPitch(bool aPreservesPitch);
|
|
|
|
|
2014-04-01 07:43:57 +04:00
|
|
|
// Directs the decoder to not preroll extra samples until the media is
|
|
|
|
// played. This reduces the memory overhead of media elements that may
|
|
|
|
// not be played. Note that seeking also doesn't cause us start prerolling.
|
|
|
|
void SetMinimizePrerollUntilPlaybackStarts();
|
|
|
|
|
2012-07-31 16:17:22 +04:00
|
|
|
// All MediaStream-related data is protected by mReentrantMonitor.
|
2012-11-14 23:46:40 +04:00
|
|
|
// We have at most one DecodedStreamData per MediaDecoder. Its stream
|
2012-07-31 16:17:22 +04:00
|
|
|
// is used as the input for each ProcessedMediaStream created by calls to
|
|
|
|
// captureStream(UntilEnded). Seeking creates a new source stream, as does
|
|
|
|
// replaying after the input as ended. In the latter case, the new source is
|
|
|
|
// not connected to streams created by captureStreamUntilEnded.
|
2012-08-21 08:06:46 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Add an output stream. All decoder output will be sent to the stream.
|
|
|
|
// The stream is initially blocked. The decoder is responsible for unblocking
|
|
|
|
// it while it is playing back.
|
2012-07-31 16:17:22 +04:00
|
|
|
virtual void AddOutputStream(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
|
2015-07-24 15:28:17 +03:00
|
|
|
// Remove an output stream added with AddOutputStream.
|
|
|
|
virtual void RemoveOutputStream(MediaStream* aStream);
|
2012-04-30 07:12:42 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Return the duration of the video in seconds.
|
2011-01-17 06:03:00 +03:00
|
|
|
virtual double GetDuration();
|
2008-07-30 10:50:14 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Return true if the stream is infinite (see SetInfinite).
|
2016-07-13 11:35:37 +03:00
|
|
|
bool IsInfinite() const;
|
2008-07-30 10:50:14 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Called by MediaResource when some data has been received.
|
|
|
|
// Call on the main thread only.
|
2015-11-16 02:50:55 +03:00
|
|
|
virtual void NotifyBytesDownloaded();
|
2012-11-14 23:45:13 +04:00
|
|
|
|
|
|
|
// Called as data arrives on the stream and is read into the cache. Called
|
|
|
|
// on the main thread only.
|
2015-11-23 05:26:49 +03:00
|
|
|
void NotifyDataArrived();
|
2012-11-14 23:45:13 +04:00
|
|
|
|
2012-05-15 09:57:17 +04:00
|
|
|
// Return true if we are currently seeking in the media resource.
|
|
|
|
// Call on the main thread only.
|
2016-07-13 11:35:37 +03:00
|
|
|
bool IsSeeking() const;
|
2008-07-30 10:50:14 +04:00
|
|
|
|
2016-08-01 10:22:32 +03:00
|
|
|
// Return true if the decoder has reached the end of playback.
|
|
|
|
bool IsEnded() const;
|
2008-12-14 21:02:54 +03:00
|
|
|
|
2016-02-08 07:28:15 +03:00
|
|
|
// Return true if the MediaDecoderOwner's error attribute is not null.
|
2016-07-28 12:21:09 +03:00
|
|
|
// Must be called before Shutdown().
|
2016-02-08 07:28:15 +03:00
|
|
|
bool OwnerHasError() const;
|
|
|
|
|
2016-06-29 02:42:07 +03:00
|
|
|
already_AddRefed<GMPCrashHelper> GetCrashHelper() override;
|
|
|
|
|
2015-06-17 02:11:06 +03:00
|
|
|
protected:
|
2013-09-10 04:45:33 +04:00
|
|
|
// Updates the media duration. This is called while the media is being
|
|
|
|
// played, calls before the media has reached loaded metadata are ignored.
|
|
|
|
// The duration is assumed to be an estimate, and so a degree of
|
|
|
|
// instability is expected; if the incoming duration is not significantly
|
|
|
|
// different from the existing duration, the change request is ignored.
|
|
|
|
// If the incoming duration is significantly different, the duration is
|
|
|
|
// changed, this causes a durationchanged event to fire to the media
|
|
|
|
// element.
|
2015-03-21 19:28:04 +03:00
|
|
|
void UpdateEstimatedMediaDuration(int64_t aDuration) override;
|
2015-11-23 05:26:49 +03:00
|
|
|
|
2015-06-17 02:11:06 +03:00
|
|
|
public:
|
2016-02-04 07:31:21 +03:00
|
|
|
// Set a flag indicating whether random seeking is supported
|
2015-12-02 10:42:32 +03:00
|
|
|
void SetMediaSeekable(bool aMediaSeekable);
|
2016-02-04 07:31:21 +03:00
|
|
|
// Set a flag indicating whether seeking is supported only in buffered ranges
|
|
|
|
void SetMediaSeekableOnlyInBufferedRanges(bool aMediaSeekableOnlyInBufferedRanges);
|
2014-06-23 14:08:34 +04:00
|
|
|
|
2016-02-04 07:31:21 +03:00
|
|
|
// Returns true if this media supports random seeking. False for example with
|
|
|
|
// chained ogg files.
|
2015-11-23 05:26:49 +03:00
|
|
|
bool IsMediaSeekable();
|
2016-02-04 07:31:21 +03:00
|
|
|
// Returns true if this media supports seeking only in buffered ranges. True
|
|
|
|
// for example in WebMs with no cues
|
|
|
|
bool IsMediaSeekableOnlyInBufferedRanges();
|
2012-11-30 17:17:54 +04:00
|
|
|
// Returns true if seeking is supported on a transport level (e.g. the server
|
|
|
|
// supports range requests, we are playing a file, etc.).
|
2015-11-23 05:26:49 +03:00
|
|
|
bool IsTransportSeekable();
|
2011-08-09 14:10:48 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Return the time ranges that can be seeked into.
|
2015-05-18 09:15:47 +03:00
|
|
|
virtual media::TimeIntervals GetSeekable();
|
2008-11-10 04:38:02 +03:00
|
|
|
|
2011-08-25 03:42:23 +04:00
|
|
|
// Set the end time of the media resource. When playback reaches
|
|
|
|
// this point the media pauses. aTime is in seconds.
|
2012-11-19 19:11:21 +04:00
|
|
|
virtual void SetFragmentEndTime(double aTime);
|
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Invalidate the frame.
|
|
|
|
void Invalidate();
|
2013-10-02 07:05:34 +04:00
|
|
|
void InvalidateWithFlags(uint32_t aFlags);
|
2009-02-05 11:02:21 +03:00
|
|
|
|
2009-01-22 02:54:40 +03:00
|
|
|
// Suspend any media downloads that are in progress. Called by the
|
2012-11-14 23:45:13 +04:00
|
|
|
// media element when it is sent to the bfcache, or when we need
|
|
|
|
// to throttle the download. Call on the main thread only. This can
|
|
|
|
// be called multiple times, there's an internal "suspend count".
|
2009-01-22 02:54:40 +03:00
|
|
|
virtual void Suspend();
|
|
|
|
|
|
|
|
// Resume any media downloads that have been suspended. Called by the
|
2012-11-14 23:45:13 +04:00
|
|
|
// media element when it is restored from the bfcache, or when we need
|
|
|
|
// to stop throttling the download. Call on the main thread only.
|
|
|
|
// The download will only actually resume once as many Resume calls
|
2016-01-12 03:04:32 +03:00
|
|
|
// have been made as Suspend calls.
|
|
|
|
virtual void Resume();
|
2009-01-22 02:54:40 +03:00
|
|
|
|
2014-12-23 04:16:05 +03:00
|
|
|
// Moves any existing channel loads into or out of background. Background
|
|
|
|
// loads don't block the load event. This is called when we stop or restart
|
|
|
|
// delaying the load event. This also determines whether any new loads
|
|
|
|
// initiated (for example to seek) will be in the background. This calls
|
|
|
|
// SetLoadInBackground() on mResource.
|
|
|
|
void SetLoadInBackground(bool aLoadInBackground);
|
2009-04-10 05:28:24 +04:00
|
|
|
|
2015-09-22 08:57:36 +03:00
|
|
|
MediaDecoderStateMachine* GetStateMachine() const;
|
2015-04-02 20:49:01 +03:00
|
|
|
void SetStateMachine(MediaDecoderStateMachine* aStateMachine);
|
|
|
|
|
2010-08-05 11:40:35 +04:00
|
|
|
// Constructs the time ranges representing what segments of the media
|
|
|
|
// are buffered and playable.
|
2015-05-18 09:15:47 +03:00
|
|
|
virtual media::TimeIntervals GetBuffered();
|
2010-08-05 11:40:35 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Returns the size, in bytes, of the heap memory used by the currently
|
|
|
|
// queued decoded video and audio data.
|
2014-03-20 01:33:12 +04:00
|
|
|
size_t SizeOfVideoQueue();
|
2014-01-23 07:14:45 +04:00
|
|
|
size_t SizeOfAudioQueue();
|
2011-07-22 07:17:23 +04:00
|
|
|
|
2015-08-21 01:10:33 +03:00
|
|
|
// Helper struct for accumulating resource sizes that need to be measured
|
|
|
|
// asynchronously. Once all references are dropped the callback will be
|
|
|
|
// invoked.
|
|
|
|
struct ResourceSizes
|
|
|
|
{
|
|
|
|
typedef MozPromise<size_t, size_t, true> SizeOfPromise;
|
|
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ResourceSizes)
|
|
|
|
explicit ResourceSizes(MallocSizeOf aMallocSizeOf)
|
|
|
|
: mMallocSizeOf(aMallocSizeOf)
|
|
|
|
, mByteSize(0)
|
|
|
|
, mCallback()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
mozilla::MallocSizeOf mMallocSizeOf;
|
|
|
|
mozilla::Atomic<size_t> mByteSize;
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<SizeOfPromise> Promise()
|
2015-08-21 01:10:33 +03:00
|
|
|
{
|
|
|
|
return mCallback.Ensure(__func__);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
~ResourceSizes()
|
|
|
|
{
|
|
|
|
mCallback.ResolveIfExists(mByteSize, __func__);
|
|
|
|
}
|
|
|
|
|
|
|
|
MozPromiseHolder<SizeOfPromise> mCallback;
|
|
|
|
};
|
|
|
|
|
|
|
|
virtual void AddSizeOfResources(ResourceSizes* aSizes);
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
VideoFrameContainer* GetVideoFrameContainer() final override
|
2012-11-19 19:11:21 +04:00
|
|
|
{
|
|
|
|
return mVideoFrameContainer;
|
|
|
|
}
|
2015-03-21 19:28:04 +03:00
|
|
|
layers::ImageContainer* GetImageContainer() override;
|
2010-09-13 12:45:50 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Fire timeupdate events if needed according to the time constraints
|
|
|
|
// outlined in the specification.
|
|
|
|
void FireTimeUpdate();
|
|
|
|
|
2009-04-01 04:52:56 +04:00
|
|
|
// Something has changed that could affect the computed playback rate,
|
|
|
|
// so recompute it. The monitor must be held.
|
2012-12-13 23:42:45 +04:00
|
|
|
virtual void UpdatePlaybackRate();
|
|
|
|
|
2009-04-01 04:52:56 +04:00
|
|
|
// The actual playback rate computation. The monitor must be held.
|
2015-09-15 05:04:50 +03:00
|
|
|
void ComputePlaybackRate();
|
2009-04-01 04:52:56 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Returns true if we can play the entire media through without stopping
|
|
|
|
// to buffer, given the current download and playback rates.
|
2015-12-02 07:09:47 +03:00
|
|
|
virtual bool CanPlayThrough();
|
2012-11-14 23:45:13 +04:00
|
|
|
|
2014-04-10 21:39:20 +04:00
|
|
|
void SetAudioChannel(dom::AudioChannel aChannel) { mAudioChannel = aChannel; }
|
|
|
|
dom::AudioChannel GetAudioChannel() { return mAudioChannel; }
|
2012-11-16 07:25:26 +04:00
|
|
|
|
2016-04-12 08:48:06 +03:00
|
|
|
// Called from HTMLMediaElement when owner document activity changes
|
|
|
|
virtual void SetElementVisibility(bool aIsVisible);
|
|
|
|
|
2016-08-25 05:10:05 +03:00
|
|
|
// Force override the visible state to hidden.
|
|
|
|
// Called from HTMLMediaElement when testing of video decode suspend from mochitests.
|
|
|
|
void SetForcedHidden(bool aForcedHidden);
|
|
|
|
|
2012-11-07 02:33:02 +04:00
|
|
|
/******
|
2008-07-30 10:50:14 +04:00
|
|
|
* The following methods must only be called on the main
|
|
|
|
* thread.
|
|
|
|
******/
|
|
|
|
|
2008-11-18 11:19:32 +03:00
|
|
|
// Change to a new play state. This updates the mState variable and
|
|
|
|
// notifies any thread blocking on this object's monitor of the
|
|
|
|
// change. Call on the main thread only.
|
2014-04-08 19:29:07 +04:00
|
|
|
virtual void ChangeState(PlayState aState);
|
2008-11-18 11:19:32 +03:00
|
|
|
|
2014-07-04 07:55:06 +04:00
|
|
|
// Called from MetadataLoaded(). Creates audio tracks and adds them to its
|
|
|
|
// owner's audio track list, and implies to video tracks respectively.
|
|
|
|
// Call on the main thread only.
|
|
|
|
void ConstructMediaTracks();
|
|
|
|
|
|
|
|
// Removes all audio tracks and video tracks that are previously added into
|
|
|
|
// the track list. Call on the main thread only.
|
2015-09-07 06:39:16 +03:00
|
|
|
void RemoveMediaTracks();
|
2014-07-04 07:55:06 +04:00
|
|
|
|
2008-07-30 10:50:14 +04:00
|
|
|
// Called when the video has completed playing.
|
|
|
|
// Call on the main thread only.
|
2008-10-19 11:39:21 +04:00
|
|
|
void PlaybackEnded();
|
2008-07-30 10:50:14 +04:00
|
|
|
|
2016-06-09 22:27:39 +03:00
|
|
|
void OnSeekRejected();
|
2015-04-16 00:00:41 +03:00
|
|
|
void OnSeekResolved(SeekResolveValue aVal);
|
2009-05-31 14:02:17 +04:00
|
|
|
|
2015-07-20 09:34:18 +03:00
|
|
|
void SeekingChanged()
|
|
|
|
{
|
|
|
|
// Stop updating the bytes downloaded for progress notifications when
|
|
|
|
// seeking to prevent wild changes to the progress notification.
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
mIgnoreProgressData = mLogicallySeeking;
|
|
|
|
}
|
|
|
|
|
2016-08-03 12:18:54 +03:00
|
|
|
// Seeking has started. Inform the element on the main thread.
|
|
|
|
void SeekingStarted();
|
2008-10-19 11:39:21 +04:00
|
|
|
|
2016-04-18 13:57:47 +03:00
|
|
|
void UpdateLogicalPositionInternal(MediaDecoderEventVisibility aEventVisibility);
|
2015-07-01 00:39:41 +03:00
|
|
|
void UpdateLogicalPosition()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2016-07-28 09:43:50 +03:00
|
|
|
MOZ_ASSERT(!IsShutdown());
|
2016-04-18 13:57:47 +03:00
|
|
|
// Per spec, offical position remains stable during pause and seek.
|
|
|
|
if (mPlayState == PLAY_STATE_PAUSED || IsSeeking()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
UpdateLogicalPositionInternal(MediaDecoderEventVisibility::Observable);
|
2015-07-01 00:39:41 +03:00
|
|
|
}
|
2008-10-23 12:02:18 +04:00
|
|
|
|
2009-04-01 04:52:56 +04:00
|
|
|
// Find the end of the cached data starting at the current decoder
|
|
|
|
// position.
|
2012-08-22 19:56:38 +04:00
|
|
|
int64_t GetDownloadPosition();
|
2009-04-01 04:52:56 +04:00
|
|
|
|
2009-09-22 04:08:13 +04:00
|
|
|
// Notifies the element that decoding has failed.
|
2016-09-10 17:51:13 +03:00
|
|
|
void DecodeError(const MediaResult& aError);
|
2009-09-22 04:08:13 +04:00
|
|
|
|
2013-07-24 13:55:23 +04:00
|
|
|
// Indicate whether the media is same-origin with the element.
|
|
|
|
void UpdateSameOriginStatus(bool aSameOrigin);
|
|
|
|
|
2016-07-28 12:21:09 +03:00
|
|
|
MediaDecoderOwner* GetOwner() const override;
|
2013-05-04 14:12:41 +04:00
|
|
|
|
2014-08-08 06:44:04 +04:00
|
|
|
#ifdef MOZ_EME
|
2015-10-18 08:24:48 +03:00
|
|
|
typedef MozPromise<RefPtr<CDMProxy>, bool /* aIgnored */, /* IsExclusive = */ true> CDMProxyPromise;
|
2015-09-27 13:39:37 +03:00
|
|
|
|
|
|
|
// Resolved when a CDMProxy is available and the capabilities are known or
|
|
|
|
// rejected when this decoder is about to shut down.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<CDMProxyPromise> RequestCDMProxy() const;
|
2015-09-27 13:39:37 +03:00
|
|
|
|
2015-09-27 13:59:08 +03:00
|
|
|
void SetCDMProxy(CDMProxy* aProxy);
|
2014-08-08 06:44:04 +04:00
|
|
|
#endif
|
2014-07-30 10:53:34 +04:00
|
|
|
|
2015-11-25 02:52:48 +03:00
|
|
|
void EnsureTelemetryReported();
|
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
static bool IsOggEnabled();
|
|
|
|
static bool IsOpusEnabled();
|
|
|
|
static bool IsWaveEnabled();
|
|
|
|
static bool IsWebMEnabled();
|
2015-12-12 21:49:07 +03:00
|
|
|
|
2013-05-03 01:21:22 +04:00
|
|
|
#ifdef MOZ_OMX_DECODER
|
2012-11-14 23:45:13 +04:00
|
|
|
static bool IsOmxEnabled();
|
|
|
|
#endif
|
|
|
|
|
2014-07-17 05:32:56 +04:00
|
|
|
#ifdef MOZ_ANDROID_OMX
|
2016-03-10 01:45:27 +03:00
|
|
|
static bool IsAndroidMediaPluginEnabled();
|
2012-11-14 23:45:13 +04:00
|
|
|
#endif
|
|
|
|
|
2012-12-18 12:49:58 +04:00
|
|
|
#ifdef MOZ_WMF
|
|
|
|
static bool IsWMFEnabled();
|
|
|
|
#endif
|
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Return statistics. This is used for progress events and other things.
|
|
|
|
// This can be called from any thread. It's only a snapshot of the
|
|
|
|
// current state, since other threads might be changing the state
|
|
|
|
// at any time.
|
2015-09-10 11:37:26 +03:00
|
|
|
MediaStatistics GetStatistics();
|
2012-11-14 23:45:13 +04:00
|
|
|
|
|
|
|
// Return the frame decode/paint related statistics.
|
2015-12-03 10:59:30 +03:00
|
|
|
FrameStatistics& GetFrameStatistics() { return *mFrameStats; }
|
2012-11-14 23:45:13 +04:00
|
|
|
|
2012-11-19 19:11:21 +04:00
|
|
|
// Increments the parsed and decoded frame counters by the passed in counts.
|
|
|
|
// Can be called on any thread.
|
2016-07-18 03:41:40 +03:00
|
|
|
virtual void NotifyDecodedFrames(const FrameStatisticsData& aStats) override
|
2012-11-19 19:11:21 +04:00
|
|
|
{
|
2016-07-18 03:41:40 +03:00
|
|
|
GetFrameStatistics().NotifyDecodedFrames(aStats);
|
2012-11-19 19:11:21 +04:00
|
|
|
}
|
|
|
|
|
2015-04-29 05:02:31 +03:00
|
|
|
void UpdateReadyState()
|
|
|
|
{
|
2015-10-19 08:55:38 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2016-07-27 05:59:23 +03:00
|
|
|
MOZ_ASSERT(!IsShutdown());
|
|
|
|
mOwner->UpdateReadyState();
|
2015-04-29 05:02:31 +03:00
|
|
|
}
|
2015-03-19 05:01:12 +03:00
|
|
|
|
2015-04-01 04:44:36 +03:00
|
|
|
virtual MediaDecoderOwner::NextFrameStatus NextFrameStatus() { return mNextFrameStatus; }
|
2015-12-02 03:50:21 +03:00
|
|
|
virtual MediaDecoderOwner::NextFrameStatus NextFrameBufferedStatus();
|
2015-04-01 04:44:36 +03:00
|
|
|
|
2016-01-18 07:34:07 +03:00
|
|
|
// Returns a string describing the state of the media player internal
|
|
|
|
// data. Used for debugging purposes.
|
|
|
|
virtual void GetMozDebugReaderData(nsAString& aString) {}
|
|
|
|
|
2016-04-22 09:18:26 +03:00
|
|
|
virtual void DumpDebugInfo();
|
|
|
|
|
2013-11-18 08:22:47 +04:00
|
|
|
protected:
|
2014-06-24 20:36:43 +04:00
|
|
|
virtual ~MediaDecoder();
|
2015-11-23 05:35:18 +03:00
|
|
|
|
|
|
|
// Called when the first audio and/or video from the media file has been loaded
|
|
|
|
// by the state machine. Call on the main thread only.
|
|
|
|
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
|
|
|
|
MediaDecoderEventVisibility aEventVisibility);
|
|
|
|
|
2014-08-05 18:55:02 +04:00
|
|
|
void SetStateMachineParameters();
|
2014-06-24 20:36:43 +04:00
|
|
|
|
2015-01-28 17:31:31 +03:00
|
|
|
static void DormantTimerExpired(nsITimer *aTimer, void *aClosure);
|
|
|
|
|
|
|
|
// Start a timer for heuristic dormant.
|
|
|
|
void StartDormantTimer();
|
|
|
|
|
|
|
|
// Cancel a timer for heuristic dormant.
|
|
|
|
void CancelDormantTimer();
|
|
|
|
|
2016-07-13 11:45:30 +03:00
|
|
|
bool IsShutdown() const;
|
|
|
|
|
2015-06-10 01:31:46 +03:00
|
|
|
// Called by the state machine to notify the decoder that the duration
|
|
|
|
// has changed.
|
|
|
|
void DurationChanged();
|
|
|
|
|
2015-04-29 05:02:31 +03:00
|
|
|
// State-watching manager.
|
|
|
|
WatchManager<MediaDecoder> mWatchManager;
|
2015-03-19 05:01:12 +03:00
|
|
|
|
2015-06-30 00:27:16 +03:00
|
|
|
// Used by the ogg decoder to watch mStateMachineIsShutdown.
|
|
|
|
virtual void ShutdownBitChanged() {}
|
|
|
|
|
2015-07-17 08:00:26 +03:00
|
|
|
double ExplicitDuration() { return mExplicitDuration.Ref().ref(); }
|
|
|
|
|
|
|
|
void SetExplicitDuration(double aValue)
|
|
|
|
{
|
2016-07-28 11:54:53 +03:00
|
|
|
MOZ_ASSERT(!IsShutdown());
|
2015-07-17 08:00:26 +03:00
|
|
|
mExplicitDuration.Set(Some(aValue));
|
|
|
|
|
|
|
|
// We Invoke DurationChanged explicitly, rather than using a watcher, so
|
|
|
|
// that it takes effect immediately, rather than at the end of the current task.
|
|
|
|
DurationChanged();
|
|
|
|
}
|
2015-04-01 04:44:36 +03:00
|
|
|
|
2008-07-30 10:50:14 +04:00
|
|
|
/******
|
2009-02-05 11:02:21 +03:00
|
|
|
* The following members should be accessed with the decoder lock held.
|
2008-07-30 10:50:14 +04:00
|
|
|
******/
|
2009-02-05 11:02:21 +03:00
|
|
|
|
2015-06-30 01:01:50 +03:00
|
|
|
// Whether the decoder implementation supports dormant mode.
|
|
|
|
bool mDormantSupported;
|
|
|
|
|
2015-05-08 03:04:22 +03:00
|
|
|
// The logical playback position of the media resource in units of
|
|
|
|
// seconds. This corresponds to the "official position" in HTML5. Note that
|
|
|
|
// we need to store this as a double, rather than an int64_t (like
|
|
|
|
// mCurrentPosition), so that |v.currentTime = foo; v.currentTime == foo|
|
|
|
|
// returns true without being affected by rounding errors.
|
|
|
|
double mLogicalPosition;
|
|
|
|
|
|
|
|
// The current playback position of the underlying playback infrastructure.
|
|
|
|
// This corresponds to the "current position" in HTML5.
|
|
|
|
// We allow omx subclasses to substitute an alternative current position for
|
|
|
|
// usage with the audio offload player.
|
|
|
|
virtual int64_t CurrentPosition() { return mCurrentPosition; }
|
2008-10-23 12:02:18 +04:00
|
|
|
|
2015-06-09 21:40:03 +03:00
|
|
|
// Official duration of the media resource as observed by script.
|
|
|
|
double mDuration;
|
2008-11-10 04:38:02 +03:00
|
|
|
|
2008-07-30 10:50:14 +04:00
|
|
|
/******
|
|
|
|
* The following member variables can be accessed from any thread.
|
|
|
|
******/
|
|
|
|
|
2015-04-02 20:49:01 +03:00
|
|
|
// Media data resource.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<MediaResource> mResource;
|
2015-04-02 20:49:01 +03:00
|
|
|
|
2015-12-02 03:50:21 +03:00
|
|
|
// Amount of buffered data ahead of current time required to consider that
|
|
|
|
// the next frame is available.
|
|
|
|
// An arbitrary value of 250ms is used.
|
|
|
|
static const int DEFAULT_NEXT_FRAME_AVAILABLE_BUFFERED = 250000;
|
|
|
|
|
2015-04-02 20:49:01 +03:00
|
|
|
private:
|
2015-11-23 05:35:18 +03:00
|
|
|
// Called when the metadata from the media file has been loaded by the
|
|
|
|
// state machine. Call on the main thread only.
|
|
|
|
void MetadataLoaded(nsAutoPtr<MediaInfo> aInfo,
|
|
|
|
nsAutoPtr<MetadataTags> aTags,
|
|
|
|
MediaDecoderEventVisibility aEventVisibility);
|
|
|
|
|
2015-11-18 04:00:56 +03:00
|
|
|
MediaEventSource<void>*
|
|
|
|
DataArrivedEvent() override { return &mDataArrivedEvent; }
|
|
|
|
|
2015-12-01 04:34:02 +03:00
|
|
|
void OnPlaybackEvent(MediaEventType aEvent);
|
2016-09-10 17:51:13 +03:00
|
|
|
void OnPlaybackErrorEvent(const MediaResult& aError);
|
2015-11-30 08:06:19 +03:00
|
|
|
|
2015-12-02 10:42:32 +03:00
|
|
|
void OnMediaNotSeekable()
|
|
|
|
{
|
|
|
|
SetMediaSeekable(false);
|
|
|
|
}
|
|
|
|
|
2016-05-04 11:13:25 +03:00
|
|
|
void FinishShutdown();
|
2015-12-03 10:59:44 +03:00
|
|
|
|
2016-07-15 10:35:41 +03:00
|
|
|
void ConnectMirrors(MediaDecoderStateMachine* aObject);
|
|
|
|
void DisconnectMirrors();
|
|
|
|
|
2015-11-18 04:00:56 +03:00
|
|
|
MediaEventProducer<void> mDataArrivedEvent;
|
|
|
|
|
2010-04-02 07:03:07 +04:00
|
|
|
// The state machine object for handling the decoding. It is safe to
|
|
|
|
// call methods of this object from other threads. Its internal data
|
|
|
|
// 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.
|
2015-04-02 20:49:01 +03:00
|
|
|
//
|
|
|
|
// Explicitly prievate to force access via accessors.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<MediaDecoderStateMachine> mDecoderStateMachine;
|
2010-04-02 07:03:07 +04:00
|
|
|
|
2015-11-16 02:50:55 +03:00
|
|
|
RefPtr<ResourceCallback> mResourceCallback;
|
|
|
|
|
2014-08-08 06:44:04 +04:00
|
|
|
#ifdef MOZ_EME
|
2015-09-27 13:39:37 +03:00
|
|
|
MozPromiseHolder<CDMProxyPromise> mCDMProxyPromiseHolder;
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<CDMProxyPromise> mCDMProxyPromise;
|
2014-08-08 06:44:04 +04:00
|
|
|
#endif
|
2014-07-30 10:53:34 +04:00
|
|
|
|
2015-04-25 06:35:06 +03:00
|
|
|
protected:
|
2016-06-09 22:27:39 +03:00
|
|
|
// The promise resolving/rejection is queued as a "micro-task" which will be
|
|
|
|
// handled immediately after the current JS task and before any pending JS
|
|
|
|
// tasks.
|
|
|
|
// At the time we are going to resolve/reject a promise, the "seeking" event
|
|
|
|
// task should already be queued but might yet be processed, so we queue one
|
|
|
|
// more task to file the promise resolving/rejection micro-tasks
|
|
|
|
// asynchronously to make sure that the micro-tasks are processed after the
|
|
|
|
// "seeking" event task.
|
|
|
|
void AsyncResolveSeekDOMPromiseIfExists();
|
|
|
|
void AsyncRejectSeekDOMPromiseIfExists();
|
|
|
|
void DiscardOngoingSeekIfExists();
|
|
|
|
virtual void CallSeek(const SeekTarget& aTarget, dom::Promise* aPromise);
|
2013-09-04 15:13:06 +04:00
|
|
|
|
2015-07-14 03:17:07 +03:00
|
|
|
// Returns true if heuristic dormant is supported.
|
|
|
|
bool IsHeuristicDormantSupported() const;
|
|
|
|
|
2015-07-16 21:06:49 +03:00
|
|
|
MozPromiseRequestHolder<SeekPromise> mSeekRequest;
|
2016-06-09 22:27:39 +03:00
|
|
|
RefPtr<dom::Promise> mSeekDOMPromise;
|
2015-03-03 03:46:32 +03:00
|
|
|
|
2009-01-15 23:26:51 +03:00
|
|
|
// True when seeking or otherwise moving the play position around in
|
|
|
|
// such a manner that progress event data is inaccurate. This is set
|
2009-02-05 11:02:21 +03:00
|
|
|
// during seek and duration operations to prevent the progress indicator
|
2015-07-20 09:34:18 +03:00
|
|
|
// from jumping around. Read/Write on the main thread only.
|
2011-09-29 10:19:26 +04:00
|
|
|
bool mIgnoreProgressData;
|
2011-08-01 22:11:20 +04:00
|
|
|
|
2011-09-30 03:34:37 +04:00
|
|
|
// True if the stream is infinite (e.g. a webradio).
|
2011-09-29 10:19:26 +04:00
|
|
|
bool mInfiniteStream;
|
2012-07-31 16:17:22 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// Ensures our media stream has been pinned.
|
|
|
|
void PinForSeek();
|
|
|
|
|
|
|
|
// Ensures our media stream has been unpinned.
|
|
|
|
void UnpinForSeek();
|
|
|
|
|
2015-03-05 04:32:54 +03:00
|
|
|
const char* PlayStateStr();
|
|
|
|
|
2015-09-07 06:38:34 +03:00
|
|
|
void OnMetadataUpdate(TimedMetadata&& aMetadata);
|
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// This should only ever be accessed from the main thread.
|
2016-07-29 09:44:22 +03:00
|
|
|
// It is set in the constructor and cleared in Shutdown when the element goes
|
|
|
|
// away. The decoder does not add a reference the element.
|
|
|
|
MediaDecoderOwner* mOwner;
|
2012-11-14 23:45:13 +04:00
|
|
|
|
|
|
|
// Counters related to decode and presentation of frames.
|
2015-12-03 10:59:30 +03:00
|
|
|
const RefPtr<FrameStatistics> mFrameStats;
|
2012-11-14 23:45:13 +04:00
|
|
|
|
2016-05-22 16:39:55 +03:00
|
|
|
RefPtr<VideoFrameContainer> mVideoFrameContainer;
|
2012-11-14 23:45:13 +04:00
|
|
|
|
2012-12-13 23:42:45 +04:00
|
|
|
// Data needed to estimate playback data rate. The timeline used for
|
|
|
|
// this estimate is "decode time" (where the "current time" is the
|
|
|
|
// time of the last decoded video frame).
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<MediaChannelStatistics> mPlaybackStatistics;
|
2012-12-13 23:42:45 +04:00
|
|
|
|
2012-11-14 23:45:13 +04:00
|
|
|
// True when our media stream has been pinned. We pin the stream
|
|
|
|
// while seeking.
|
|
|
|
bool mPinnedForSeek;
|
|
|
|
|
2012-11-22 14:38:28 +04:00
|
|
|
// True if the playback is paused because the playback rate member is 0.0.
|
|
|
|
bool mPausedForPlaybackRateNull;
|
|
|
|
|
2012-11-16 07:25:26 +04:00
|
|
|
// Be assigned from media element during the initialization and pass to
|
|
|
|
// AudioStream Class.
|
2014-04-10 21:39:20 +04:00
|
|
|
dom::AudioChannel mAudioChannel;
|
2014-04-01 07:43:57 +04:00
|
|
|
|
|
|
|
// True if the decoder has been directed to minimize its preroll before
|
|
|
|
// playback starts. After the first time playback starts, we don't attempt
|
|
|
|
// to minimize preroll, as we assume the user is likely to keep playing,
|
|
|
|
// or play the media again.
|
|
|
|
bool mMinimizePreroll;
|
2014-07-04 07:55:06 +04:00
|
|
|
|
|
|
|
// True if audio tracks and video tracks are constructed and added into the
|
|
|
|
// track list, false if all tracks are removed from the track list.
|
|
|
|
bool mMediaTracksConstructed;
|
|
|
|
|
2015-06-10 01:16:27 +03:00
|
|
|
// True if we've already fired metadataloaded.
|
|
|
|
bool mFiredMetadataLoaded;
|
|
|
|
|
2014-07-04 07:55:06 +04:00
|
|
|
// Stores media info, including info of audio tracks and video tracks, should
|
|
|
|
// only be accessed from main thread.
|
|
|
|
nsAutoPtr<MediaInfo> mInfo;
|
2015-01-22 07:01:12 +03:00
|
|
|
|
2016-08-25 05:10:05 +03:00
|
|
|
// Tracks the visiblity status from HTMLMediaElement
|
|
|
|
bool mElementVisible;
|
|
|
|
|
|
|
|
// If true, forces the decoder to be considered hidden.
|
|
|
|
bool mForcedHidden;
|
|
|
|
|
2015-01-22 07:01:12 +03:00
|
|
|
// True if MediaDecoder is in dormant state.
|
|
|
|
bool mIsDormant;
|
2015-01-28 17:31:31 +03:00
|
|
|
|
|
|
|
// True if heuristic dormant is supported.
|
|
|
|
const bool mIsHeuristicDormantSupported;
|
|
|
|
|
|
|
|
// Timeout ms of heuristic dormant timer.
|
|
|
|
const int mHeuristicDormantTimeout;
|
|
|
|
|
|
|
|
// True if MediaDecoder is in dormant by heuristic.
|
|
|
|
bool mIsHeuristicDormant;
|
|
|
|
|
|
|
|
// Timer to schedule updating dormant state.
|
|
|
|
nsCOMPtr<nsITimer> mDormantTimer;
|
2015-07-17 08:00:26 +03:00
|
|
|
|
2015-09-07 06:38:34 +03:00
|
|
|
// A listener to receive metadata updates from MDSM.
|
|
|
|
MediaEventListener mTimedMetadataListener;
|
|
|
|
|
2015-11-23 05:35:18 +03:00
|
|
|
MediaEventListener mMetadataLoadedListener;
|
|
|
|
MediaEventListener mFirstFrameLoadedListener;
|
|
|
|
|
2015-12-01 04:34:02 +03:00
|
|
|
MediaEventListener mOnPlaybackEvent;
|
2016-09-10 17:51:13 +03:00
|
|
|
MediaEventListener mOnPlaybackErrorEvent;
|
2015-12-02 10:42:32 +03:00
|
|
|
MediaEventListener mOnMediaNotSeekable;
|
2015-11-30 08:06:19 +03:00
|
|
|
|
2015-07-17 08:00:26 +03:00
|
|
|
protected:
|
|
|
|
// Whether the state machine is shut down.
|
|
|
|
Mirror<bool> mStateMachineIsShutdown;
|
|
|
|
|
|
|
|
// Buffered range, mirrored from the reader.
|
|
|
|
Mirror<media::TimeIntervals> mBuffered;
|
|
|
|
|
|
|
|
// NextFrameStatus, mirrored from the state machine.
|
|
|
|
Mirror<MediaDecoderOwner::NextFrameStatus> mNextFrameStatus;
|
|
|
|
|
|
|
|
// NB: Don't use mCurrentPosition directly, but rather CurrentPosition().
|
|
|
|
Mirror<int64_t> mCurrentPosition;
|
|
|
|
|
|
|
|
// Duration of the media resource according to the state machine.
|
|
|
|
Mirror<media::NullableTimeUnit> mStateMachineDuration;
|
|
|
|
|
2015-09-15 08:51:12 +03:00
|
|
|
// Current playback position in the stream. This is (approximately)
|
|
|
|
// where we're up to playing back the stream. This is not adjusted
|
|
|
|
// during decoder seek operations, but it's updated at the end when we
|
|
|
|
// start playing back again.
|
|
|
|
Mirror<int64_t> mPlaybackPosition;
|
|
|
|
|
2016-04-12 10:00:29 +03:00
|
|
|
// Used to distinguish whether the audio is producing sound.
|
2016-01-21 05:27:38 +03:00
|
|
|
Mirror<bool> mIsAudioDataAudible;
|
|
|
|
|
2015-07-17 08:00:26 +03:00
|
|
|
// Volume of playback. 0.0 = muted. 1.0 = full volume.
|
|
|
|
Canonical<double> mVolume;
|
|
|
|
|
|
|
|
// PlaybackRate and pitch preservation status we should start at.
|
2016-09-21 13:11:00 +03:00
|
|
|
double mPlaybackRate = 1;
|
2015-07-17 08:00:26 +03:00
|
|
|
|
|
|
|
Canonical<bool> mPreservesPitch;
|
|
|
|
|
|
|
|
// Media duration according to the demuxer's current estimate.
|
|
|
|
// Note that it's quite bizarre for this to live on the main thread - it would
|
|
|
|
// make much more sense for this to be owned by the demuxer's task queue. But
|
|
|
|
// currently this is only every changed in NotifyDataArrived, which runs on
|
|
|
|
// the main thread. That will need to be cleaned up at some point.
|
|
|
|
Canonical<media::NullableTimeUnit> mEstimatedDuration;
|
|
|
|
|
|
|
|
// Media duration set explicitly by JS. At present, this is only ever present
|
|
|
|
// for MSE.
|
|
|
|
Canonical<Maybe<double>> mExplicitDuration;
|
|
|
|
|
|
|
|
// Set to one of the valid play states.
|
|
|
|
// This can only be changed on the main thread while holding the decoder
|
|
|
|
// monitor. Thus, it can be safely read while holding the decoder monitor
|
|
|
|
// OR on the main thread.
|
|
|
|
Canonical<PlayState> mPlayState;
|
|
|
|
|
|
|
|
// This can only be changed on the main thread while holding the decoder
|
|
|
|
// monitor. Thus, it can be safely read while holding the decoder monitor
|
|
|
|
// OR on the main thread.
|
|
|
|
Canonical<PlayState> mNextState;
|
|
|
|
|
|
|
|
// True if the decoder is seeking.
|
|
|
|
Canonical<bool> mLogicallySeeking;
|
|
|
|
|
2015-08-06 13:05:30 +03:00
|
|
|
// True if the media is same-origin with the element. Data can only be
|
|
|
|
// passed to MediaStreams when this is true.
|
|
|
|
Canonical<bool> mSameOriginMedia;
|
|
|
|
|
2016-02-02 08:14:13 +03:00
|
|
|
// An identifier for the principal of the media. Used to track when
|
|
|
|
// main-thread induced principal changes get reflected on MSG thread.
|
|
|
|
Canonical<PrincipalHandle> mMediaPrincipalHandle;
|
|
|
|
|
2015-09-15 05:04:50 +03:00
|
|
|
// Estimate of the current playback rate (bytes/second).
|
|
|
|
Canonical<double> mPlaybackBytesPerSecond;
|
|
|
|
|
|
|
|
// True if mPlaybackBytesPerSecond is a reliable estimate.
|
|
|
|
Canonical<bool> mPlaybackRateReliable;
|
|
|
|
|
|
|
|
// Current decoding position in the stream. This is where the decoder
|
|
|
|
// is up to consuming the stream. This is not adjusted during decoder
|
|
|
|
// seek operations, but it's updated at the end when we start playing
|
|
|
|
// back again.
|
|
|
|
Canonical<int64_t> mDecoderPosition;
|
|
|
|
|
2015-09-21 08:49:01 +03:00
|
|
|
// True if the media is seekable (i.e. supports random access).
|
|
|
|
Canonical<bool> mMediaSeekable;
|
|
|
|
|
2016-02-04 07:31:21 +03:00
|
|
|
// True if the media is only seekable within its buffered ranges.
|
|
|
|
Canonical<bool> mMediaSeekableOnlyInBufferedRanges;
|
|
|
|
|
2016-04-12 10:00:29 +03:00
|
|
|
// True if the decoder is visible.
|
|
|
|
Canonical<bool> mIsVisible;
|
2016-04-12 08:20:15 +03:00
|
|
|
|
2015-07-17 08:00:26 +03:00
|
|
|
public:
|
|
|
|
AbstractCanonical<media::NullableTimeUnit>* CanonicalDurationOrNull() override;
|
|
|
|
AbstractCanonical<double>* CanonicalVolume() {
|
|
|
|
return &mVolume;
|
|
|
|
}
|
|
|
|
AbstractCanonical<bool>* CanonicalPreservesPitch() {
|
|
|
|
return &mPreservesPitch;
|
|
|
|
}
|
|
|
|
AbstractCanonical<media::NullableTimeUnit>* CanonicalEstimatedDuration() {
|
|
|
|
return &mEstimatedDuration;
|
|
|
|
}
|
2016-08-26 10:30:50 +03:00
|
|
|
AbstractCanonical<Maybe<double>>* CanonicalExplicitDuration() {
|
|
|
|
return &mExplicitDuration;
|
|
|
|
}
|
2015-07-17 08:00:26 +03:00
|
|
|
AbstractCanonical<PlayState>* CanonicalPlayState() {
|
|
|
|
return &mPlayState;
|
|
|
|
}
|
|
|
|
AbstractCanonical<PlayState>* CanonicalNextPlayState() {
|
|
|
|
return &mNextState;
|
|
|
|
}
|
|
|
|
AbstractCanonical<bool>* CanonicalLogicallySeeking() {
|
|
|
|
return &mLogicallySeeking;
|
|
|
|
}
|
2015-08-06 13:05:30 +03:00
|
|
|
AbstractCanonical<bool>* CanonicalSameOriginMedia() {
|
|
|
|
return &mSameOriginMedia;
|
|
|
|
}
|
2016-02-02 08:14:13 +03:00
|
|
|
AbstractCanonical<PrincipalHandle>* CanonicalMediaPrincipalHandle() {
|
|
|
|
return &mMediaPrincipalHandle;
|
|
|
|
}
|
2015-09-15 05:04:50 +03:00
|
|
|
AbstractCanonical<double>* CanonicalPlaybackBytesPerSecond() {
|
|
|
|
return &mPlaybackBytesPerSecond;
|
|
|
|
}
|
|
|
|
AbstractCanonical<bool>* CanonicalPlaybackRateReliable() {
|
|
|
|
return &mPlaybackRateReliable;
|
|
|
|
}
|
|
|
|
AbstractCanonical<int64_t>* CanonicalDecoderPosition() {
|
|
|
|
return &mDecoderPosition;
|
|
|
|
}
|
2015-09-21 08:49:01 +03:00
|
|
|
AbstractCanonical<bool>* CanonicalMediaSeekable() {
|
|
|
|
return &mMediaSeekable;
|
|
|
|
}
|
2016-02-04 07:31:21 +03:00
|
|
|
AbstractCanonical<bool>* CanonicalMediaSeekableOnlyInBufferedRanges() {
|
|
|
|
return &mMediaSeekableOnlyInBufferedRanges;
|
|
|
|
}
|
2016-04-12 10:00:29 +03:00
|
|
|
AbstractCanonical<bool>* CanonicalIsVisible() {
|
|
|
|
return &mIsVisible;
|
|
|
|
}
|
2015-10-27 05:28:26 +03:00
|
|
|
|
|
|
|
private:
|
2016-01-21 05:27:38 +03:00
|
|
|
// Notify owner when the audible state changed
|
|
|
|
void NotifyAudibleStateChanged();
|
|
|
|
|
2015-11-16 02:50:55 +03:00
|
|
|
/* Functions called by ResourceCallback */
|
|
|
|
|
|
|
|
// A media stream is assumed to be infinite if the metadata doesn't
|
|
|
|
// contain the duration, and range requests are not supported, and
|
|
|
|
// no headers give a hint of a possible duration (Content-Length,
|
|
|
|
// Content-Duration, and variants), and we cannot seek in the media
|
|
|
|
// stream to determine the duration.
|
|
|
|
//
|
|
|
|
// When the media stream ends, we can know the duration, thus the stream is
|
|
|
|
// no longer considered to be infinite.
|
|
|
|
void SetInfinite(bool aInfinite);
|
|
|
|
|
|
|
|
// Called by MediaResource when the principal of the resource has
|
|
|
|
// changed. Called on main thread only.
|
|
|
|
void NotifyPrincipalChanged();
|
|
|
|
|
|
|
|
// Called by MediaResource when the "cache suspended" status changes.
|
|
|
|
// If MediaResource::IsSuspendedByCache returns true, then the decoder
|
|
|
|
// should stop buffering or otherwise waiting for download progress and
|
|
|
|
// start consuming data, if possible, because the cache is full.
|
|
|
|
void NotifySuspendedStatusChanged();
|
|
|
|
|
|
|
|
// Called by the MediaResource to keep track of the number of bytes read
|
|
|
|
// from the resource. Called on the main by an event runner dispatched
|
|
|
|
// by the MediaResource read functions.
|
2015-11-23 05:26:49 +03:00
|
|
|
void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset);
|
2015-11-16 02:50:55 +03:00
|
|
|
|
|
|
|
// Called by nsChannelToPipeListener or MediaResource when the
|
|
|
|
// download has ended. Called on the main thread only. aStatus is
|
|
|
|
// the result from OnStopRequest.
|
|
|
|
void NotifyDownloadEnded(nsresult aStatus);
|
2015-12-01 04:34:02 +03:00
|
|
|
|
2015-11-25 02:52:48 +03:00
|
|
|
bool mTelemetryReported;
|
2008-07-30 10:50:14 +04:00
|
|
|
};
|
|
|
|
|
2012-11-14 23:45:33 +04:00
|
|
|
} // namespace mozilla
|
|
|
|
|
2008-07-30 10:50:14 +04:00
|
|
|
#endif
|