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:
JW Wang 2017-08-07 13:23:43 +08:00
Родитель e5f016de87
Коммит 6ab3fdad07
4 изменённых файлов: 166 добавлений и 137 удалений

Просмотреть файл

@ -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