зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1388228. P5 - move some more members to ChannelMediaDecoder. r=gerald
Those members only make sense for ChannelMediaResource. MozReview-Commit-ID: 2z6WPQeJnIT --HG-- extra : rebase_source : 7f43635ee91c8fad1d6ad6f56788e880d54beab2
This commit is contained in:
Родитель
e5f016de87
Коммит
6ab3fdad07
|
@ -341,6 +341,133 @@ ChannelMediaDecoder::CanPlayThroughImpl()
|
|||
return GetStatistics().CanPlayThrough();
|
||||
}
|
||||
|
||||
void
|
||||
ChannelMediaDecoder::OnPlaybackEvent(MediaEventType aEvent)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MediaDecoder::OnPlaybackEvent(aEvent);
|
||||
switch (aEvent) {
|
||||
case MediaEventType::PlaybackStarted:
|
||||
mPlaybackStatistics.Start();
|
||||
break;
|
||||
case MediaEventType::PlaybackStopped:
|
||||
mPlaybackStatistics.Stop();
|
||||
ComputePlaybackRate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChannelMediaDecoder::DurationChanged()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AbstractThread::AutoEnter context(AbstractMainThread());
|
||||
MediaDecoder::DurationChanged();
|
||||
// Duration has changed so we should recompute playback rate
|
||||
UpdatePlaybackRate();
|
||||
}
|
||||
|
||||
void
|
||||
ChannelMediaDecoder::DownloadProgressed()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AbstractThread::AutoEnter context(AbstractMainThread());
|
||||
MediaDecoder::DownloadProgressed();
|
||||
UpdatePlaybackRate();
|
||||
mResource->ThrottleReadahead(ShouldThrottleDownload());
|
||||
}
|
||||
|
||||
void
|
||||
ChannelMediaDecoder::ComputePlaybackRate()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mResource);
|
||||
|
||||
int64_t length = mResource->GetLength();
|
||||
if (mozilla::IsFinite<double>(mDuration) && mDuration > 0 && length >= 0) {
|
||||
mPlaybackRateReliable = true;
|
||||
mPlaybackBytesPerSecond = length / mDuration;
|
||||
return;
|
||||
}
|
||||
|
||||
bool reliable = false;
|
||||
mPlaybackBytesPerSecond = mPlaybackStatistics.GetRateAtLastStop(&reliable);
|
||||
mPlaybackRateReliable = reliable;
|
||||
}
|
||||
|
||||
void
|
||||
ChannelMediaDecoder::UpdatePlaybackRate()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mResource);
|
||||
|
||||
ComputePlaybackRate();
|
||||
uint32_t rate = mPlaybackBytesPerSecond;
|
||||
|
||||
if (mPlaybackRateReliable) {
|
||||
// Avoid passing a zero rate
|
||||
rate = std::max(rate, 1u);
|
||||
} else {
|
||||
// Set a minimum rate of 10,000 bytes per second ... sometimes we just
|
||||
// don't have good data
|
||||
rate = std::max(rate, 10000u);
|
||||
}
|
||||
|
||||
mResource->SetPlaybackRate(rate);
|
||||
}
|
||||
|
||||
MediaStatistics
|
||||
ChannelMediaDecoder::GetStatistics()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mResource);
|
||||
|
||||
MediaStatistics result;
|
||||
result.mDownloadRate =
|
||||
mResource->GetDownloadRate(&result.mDownloadRateReliable);
|
||||
result.mDownloadPosition = mResource->GetCachedDataEnd(mDecoderPosition);
|
||||
result.mTotalBytes = mResource->GetLength();
|
||||
result.mPlaybackRate = mPlaybackBytesPerSecond;
|
||||
result.mPlaybackRateReliable = mPlaybackRateReliable;
|
||||
result.mDecoderPosition = mDecoderPosition;
|
||||
result.mPlaybackPosition = mPlaybackPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
ChannelMediaDecoder::ShouldThrottleDownload()
|
||||
{
|
||||
// We throttle the download if either the throttle override pref is set
|
||||
// (so that we can always throttle in Firefox on mobile) or if the download
|
||||
// is fast enough that there's no concern about playback being interrupted.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_TRUE(GetStateMachine(), false);
|
||||
|
||||
int64_t length = mResource->GetLength();
|
||||
if (length > 0 &&
|
||||
length <= int64_t(MediaPrefs::MediaMemoryCacheMaxSize()) * 1024) {
|
||||
// Don't throttle the download of small resources. This is to speed
|
||||
// up seeking, as seeks into unbuffered ranges would require starting
|
||||
// up a new HTTP transaction, which adds latency.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Preferences::GetBool("media.throttle-regardless-of-download-rate",
|
||||
false)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MediaStatistics stats = GetStatistics();
|
||||
if (!stats.mDownloadRateReliable || !stats.mPlaybackRateReliable) {
|
||||
return false;
|
||||
}
|
||||
uint32_t factor =
|
||||
std::max(2u, Preferences::GetUint("media.throttle-factor", 2));
|
||||
return stats.mDownloadRate > factor * stats.mPlaybackRate;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
// avoid redefined macro in unified build
|
||||
|
|
|
@ -54,6 +54,9 @@ class ChannelMediaDecoder : public MediaDecoder
|
|||
};
|
||||
|
||||
protected:
|
||||
void OnPlaybackEvent(MediaEventType aEvent) override;
|
||||
void DurationChanged() override;
|
||||
void DownloadProgressed() override;
|
||||
RefPtr<ResourceCallback> mResourceCallback;
|
||||
RefPtr<BaseMediaResource> mResource;
|
||||
|
||||
|
@ -93,6 +96,21 @@ private:
|
|||
|
||||
bool CanPlayThroughImpl() override final;
|
||||
|
||||
// The actual playback rate computation.
|
||||
void ComputePlaybackRate();
|
||||
|
||||
// Something has changed that could affect the computed playback rate,
|
||||
// so recompute it.
|
||||
void UpdatePlaybackRate();
|
||||
|
||||
// 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.
|
||||
MediaStatistics GetStatistics();
|
||||
|
||||
bool ShouldThrottleDownload();
|
||||
|
||||
WatchManager<ChannelMediaDecoder> mWatchManager;
|
||||
|
||||
// True when seeking or otherwise moving the play position around in
|
||||
|
@ -100,6 +118,17 @@ private:
|
|||
// during seek and duration operations to prevent the progress indicator
|
||||
// from jumping around. Read/Write on the main thread only.
|
||||
bool mIgnoreProgressData = false;
|
||||
|
||||
// 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).
|
||||
MediaChannelStatistics mPlaybackStatistics;
|
||||
|
||||
// Estimate of the current playback rate (bytes/second).
|
||||
double mPlaybackBytesPerSecond = 0;
|
||||
|
||||
// True if mPlaybackBytesPerSecond is a reliable estimate.
|
||||
bool mPlaybackRateReliable = true;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -517,13 +517,6 @@ void
|
|||
MediaDecoder::OnPlaybackEvent(MediaEventType aEvent)
|
||||
{
|
||||
switch (aEvent) {
|
||||
case MediaEventType::PlaybackStarted:
|
||||
mPlaybackStatistics.Start();
|
||||
break;
|
||||
case MediaEventType::PlaybackStopped:
|
||||
mPlaybackStatistics.Stop();
|
||||
ComputePlaybackRate();
|
||||
break;
|
||||
case MediaEventType::PlaybackEnded:
|
||||
PlaybackEnded();
|
||||
break;
|
||||
|
@ -550,6 +543,9 @@ MediaDecoder::OnPlaybackEvent(MediaEventType aEvent)
|
|||
break;
|
||||
case MediaEventType::VideoOnlySeekCompleted:
|
||||
GetOwner()->DispatchAsyncEvent(NS_LITERAL_STRING("mozvideoonlyseekcompleted"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -920,66 +916,6 @@ MediaDecoder::PlaybackEnded()
|
|||
GetOwner()->PlaybackEnded();
|
||||
}
|
||||
|
||||
MediaStatistics
|
||||
MediaDecoder::GetStatistics()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MediaResource* r = GetResource();
|
||||
MOZ_ASSERT(r);
|
||||
|
||||
MediaStatistics result;
|
||||
result.mDownloadRate =
|
||||
r->GetDownloadRate(&result.mDownloadRateReliable);
|
||||
result.mDownloadPosition = r->GetCachedDataEnd(mDecoderPosition);
|
||||
result.mTotalBytes = r->GetLength();
|
||||
result.mPlaybackRate = mPlaybackBytesPerSecond;
|
||||
result.mPlaybackRateReliable = mPlaybackRateReliable;
|
||||
result.mDecoderPosition = mDecoderPosition;
|
||||
result.mPlaybackPosition = mPlaybackPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoder::ComputePlaybackRate()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(GetResource());
|
||||
|
||||
int64_t length = GetResource()->GetLength();
|
||||
if (mozilla::IsFinite<double>(mDuration)
|
||||
&& mDuration > 0
|
||||
&& length >= 0) {
|
||||
mPlaybackRateReliable = true;
|
||||
mPlaybackBytesPerSecond = length / mDuration;
|
||||
return;
|
||||
}
|
||||
|
||||
bool reliable = false;
|
||||
mPlaybackBytesPerSecond = mPlaybackStatistics.GetRateAtLastStop(&reliable);
|
||||
mPlaybackRateReliable = reliable;
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoder::UpdatePlaybackRate()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(GetResource());
|
||||
|
||||
ComputePlaybackRate();
|
||||
uint32_t rate = mPlaybackBytesPerSecond;
|
||||
|
||||
if (mPlaybackRateReliable) {
|
||||
// Avoid passing a zero rate
|
||||
rate = std::max(rate, 1u);
|
||||
} else {
|
||||
// Set a minimum rate of 10,000 bytes per second ... sometimes we just
|
||||
// don't have good data
|
||||
rate = std::max(rate, 10000u);
|
||||
}
|
||||
|
||||
GetResource()->SetPlaybackRate(rate);
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoder::NotifySuspendedStatusChanged()
|
||||
{
|
||||
|
@ -992,47 +928,13 @@ MediaDecoder::NotifySuspendedStatusChanged()
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
MediaDecoder::ShouldThrottleDownload()
|
||||
{
|
||||
// We throttle the download if either the throttle override pref is set
|
||||
// (so that we can always throttle in Firefox on mobile) or if the download
|
||||
// is fast enough that there's no concern about playback being interrupted.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_TRUE(mDecoderStateMachine, false);
|
||||
|
||||
int64_t length = GetResource()->GetLength();
|
||||
if (length > 0 &&
|
||||
length <= int64_t(MediaPrefs::MediaMemoryCacheMaxSize()) * 1024) {
|
||||
// Don't throttle the download of small resources. This is to speed
|
||||
// up seeking, as seeks into unbuffered ranges would require starting
|
||||
// up a new HTTP transaction, which adds latency.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Preferences::GetBool("media.throttle-regardless-of-download-rate",
|
||||
false)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MediaStatistics stats = GetStatistics();
|
||||
if (!stats.mDownloadRateReliable || !stats.mPlaybackRateReliable) {
|
||||
return false;
|
||||
}
|
||||
uint32_t factor =
|
||||
std::max(2u, Preferences::GetUint("media.throttle-factor", 2));
|
||||
return stats.mDownloadRate > factor * stats.mPlaybackRate;
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoder::DownloadProgressed()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
|
||||
AbstractThread::AutoEnter context(AbstractMainThread());
|
||||
UpdatePlaybackRate();
|
||||
GetOwner()->DownloadProgressed();
|
||||
GetResource()->ThrottleReadahead(ShouldThrottleDownload());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1153,9 +1055,6 @@ MediaDecoder::DurationChanged()
|
|||
|
||||
LOG("Duration changed to %f", mDuration);
|
||||
|
||||
// Duration has changed so we should recompute playback rate
|
||||
UpdatePlaybackRate();
|
||||
|
||||
// See https://www.w3.org/Bugs/Public/show_bug.cgi?id=28822 for a discussion
|
||||
// of whether we should fire durationchange on explicit infinity.
|
||||
if (mFiredMetadataLoaded &&
|
||||
|
|
|
@ -306,13 +306,6 @@ private:
|
|||
// outlined in the specification.
|
||||
void FireTimeUpdate();
|
||||
|
||||
// Something has changed that could affect the computed playback rate,
|
||||
// so recompute it. The monitor must be held.
|
||||
virtual void UpdatePlaybackRate();
|
||||
|
||||
// The actual playback rate computation. The monitor must be held.
|
||||
void ComputePlaybackRate();
|
||||
|
||||
// Returns true if we can play the entire media through without stopping
|
||||
// to buffer, given the current download and playback rates.
|
||||
bool CanPlayThrough();
|
||||
|
@ -406,12 +399,6 @@ private:
|
|||
static bool IsWMFEnabled();
|
||||
#endif
|
||||
|
||||
// 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.
|
||||
MediaStatistics GetStatistics();
|
||||
|
||||
// Return the frame decode/paint related statistics.
|
||||
FrameStatistics& GetFrameStatistics() { return *mFrameStats; }
|
||||
|
||||
|
@ -449,9 +436,8 @@ protected:
|
|||
|
||||
bool IsShutdown() const;
|
||||
|
||||
// Called by the state machine to notify the decoder that the duration
|
||||
// has changed.
|
||||
void DurationChanged();
|
||||
// Called to notify the decoder that the duration has changed.
|
||||
virtual void DurationChanged();
|
||||
|
||||
// State-watching manager.
|
||||
WatchManager<MediaDecoder> mWatchManager;
|
||||
|
@ -468,6 +454,8 @@ protected:
|
|||
DurationChanged();
|
||||
}
|
||||
|
||||
virtual void OnPlaybackEvent(MediaEventType aEvent);
|
||||
|
||||
/******
|
||||
* The following members should be accessed with the decoder lock held.
|
||||
******/
|
||||
|
@ -517,7 +505,6 @@ private:
|
|||
// Called when the owner's activity changed.
|
||||
void NotifyCompositor();
|
||||
|
||||
void OnPlaybackEvent(MediaEventType aEvent);
|
||||
void OnPlaybackErrorEvent(const MediaResult& aError);
|
||||
|
||||
void OnDecoderDoctorEvent(DecoderDoctorEvent aEvent);
|
||||
|
@ -551,9 +538,9 @@ protected:
|
|||
void DiscardOngoingSeekIfExists();
|
||||
virtual void CallSeek(const SeekTarget& aTarget);
|
||||
|
||||
// Called to recompute playback rate and notify 'progress' event.
|
||||
// Call on the main thread only.
|
||||
void DownloadProgressed();
|
||||
// Called to notify fetching media data is in progress.
|
||||
// Called on the main thread only.
|
||||
virtual void DownloadProgressed();
|
||||
|
||||
// Called by MediaResource when the "cache suspended" status changes.
|
||||
// If MediaResource::IsSuspendedByCache returns true, then the decoder
|
||||
|
@ -577,8 +564,6 @@ protected:
|
|||
|
||||
void OnMetadataUpdate(TimedMetadata&& aMetadata);
|
||||
|
||||
bool ShouldThrottleDownload();
|
||||
|
||||
// This should only ever be accessed from the main thread.
|
||||
// It is set in the constructor and cleared in Shutdown when the element goes
|
||||
// away. The decoder does not add a reference the element.
|
||||
|
@ -592,11 +577,6 @@ protected:
|
|||
|
||||
RefPtr<VideoFrameContainer> mVideoFrameContainer;
|
||||
|
||||
// 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).
|
||||
MediaChannelStatistics mPlaybackStatistics;
|
||||
|
||||
// True when our media stream has been pinned. We pin the stream
|
||||
// while seeking.
|
||||
bool mPinnedForSeek;
|
||||
|
@ -758,12 +738,6 @@ private:
|
|||
bool mTelemetryReported;
|
||||
const MediaContainerType mContainerType;
|
||||
bool mCanPlayThrough = false;
|
||||
|
||||
// Estimate of the current playback rate (bytes/second).
|
||||
double mPlaybackBytesPerSecond = 0;
|
||||
|
||||
// True if mPlaybackBytesPerSecond is a reliable estimate.
|
||||
bool mPlaybackRateReliable = true;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
Загрузка…
Ссылка в новой задаче