Bug 1203374. Part 1 - extract the code of computing canplaythrough so it is reusable. r=jya.

1. extract MediaDecoder::Statistics to its own file.
2. sort out include orders of MediaDecoderStateMachine.cpp
This commit is contained in:
JW Wang 2015-09-10 16:37:26 +08:00
parent adb367a821
commit cd1fe7e8c2
5 changed files with 119 additions and 95 deletions

View File

@ -37,14 +37,6 @@ static const int DEFAULT_HEURISTIC_DORMANT_TIMEOUT_MSECS = 60000;
namespace mozilla {
// Number of estimated seconds worth of data we need to have buffered
// ahead of the current playback position before we allow the media decoder
// to report that it can play through the entire media without the decode
// catching up with the download. Having this margin make the
// MediaDecoder::CanPlayThrough() calculation more stable in the case of
// fluctuating bitrates.
static const int64_t CAN_PLAY_THROUGH_MARGIN = 1;
// The amount of instability we tollerate in calls to
// MediaDecoder::UpdateEstimatedMediaDuration(); changes of duration
// less than this are ignored, as they're assumed to be the result of
@ -821,10 +813,10 @@ void MediaDecoder::PlaybackEnded()
}
}
MediaDecoder::Statistics
MediaStatistics
MediaDecoder::GetStatistics()
{
Statistics result;
MediaStatistics result;
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
if (mResource) {
@ -1372,40 +1364,11 @@ void MediaDecoder::UnpinForSeek()
resource->Unpin();
}
bool MediaDecoder::CanPlayThrough()
bool
MediaDecoder::CanPlayThrough()
{
Statistics stats = GetStatistics();
NS_ENSURE_TRUE(mDecoderStateMachine, false);
if (mDecoderStateMachine->IsRealTime() ||
(stats.mTotalBytes < 0 && stats.mDownloadRateReliable) ||
(stats.mTotalBytes >= 0 && stats.mTotalBytes == stats.mDownloadPosition)) {
return true;
}
if (!stats.mDownloadRateReliable || !stats.mPlaybackRateReliable) {
return false;
}
int64_t bytesToDownload = stats.mTotalBytes - stats.mDownloadPosition;
int64_t bytesToPlayback = stats.mTotalBytes - stats.mPlaybackPosition;
double timeToDownload = bytesToDownload / stats.mDownloadRate;
double timeToPlay = bytesToPlayback / stats.mPlaybackRate;
if (timeToDownload > timeToPlay) {
// Estimated time to download is greater than the estimated time to play.
// We probably can't play through without having to stop to buffer.
return false;
}
// Estimated time to download is less than the estimated time to play.
// We can probably play through without having to buffer, but ensure that
// we've got a reasonable amount of data buffered after the current
// playback position, so that if the bitrate of the media fluctuates, or if
// our download rate or decode rate estimation is otherwise inaccurate,
// we don't suddenly discover that we need to buffer. This is particularly
// required near the start of the media, when not much data is downloaded.
int64_t readAheadMargin =
static_cast<int64_t>(stats.mPlaybackRate * CAN_PLAY_THROUGH_MARGIN);
return stats.mDownloadPosition > stats.mPlaybackPosition + readAheadMargin;
return mDecoderStateMachine->IsRealTime() || GetStatistics().CanPlayThrough();
}
#ifdef MOZ_EME

View File

@ -207,6 +207,7 @@ destroying the MediaDecoder object.
#include "MediaEventSource.h"
#include "MediaMetadataManager.h"
#include "MediaResource.h"
#include "MediaStatistics.h"
#include "MediaStreamGraph.h"
#include "TimeUnits.h"
@ -716,37 +717,11 @@ public:
static bool IsAppleMP3Enabled();
#endif
struct Statistics {
// Estimate of the current playback rate (bytes/second).
double mPlaybackRate;
// Estimate of the current download rate (bytes/second). This
// ignores time that the channel was paused by Gecko.
double mDownloadRate;
// Total length of media stream in bytes; -1 if not known
int64_t mTotalBytes;
// Current position of the download, in bytes. This is the offset of
// the first uncached byte after the decoder position.
int64_t mDownloadPosition;
// Current position of decoding, in bytes (how much of the stream
// has been consumed)
int64_t mDecoderPosition;
// Current position of playback, in bytes
int64_t mPlaybackPosition;
// If false, then mDownloadRate cannot be considered a reliable
// estimate (probably because the download has only been running
// a short time).
bool mDownloadRateReliable;
// If false, then mPlaybackRate cannot be considered a reliable
// estimate (probably because playback has only been running
// a short time).
bool mPlaybackRateReliable;
};
// 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.
virtual Statistics GetStatistics();
MediaStatistics GetStatistics();
// Frame decoding/painting related performance counters.
// Threadsafe.

View File

@ -9,40 +9,43 @@
#include "mmsystem.h"
#endif
#include "mozilla/DebugOnly.h"
#include <algorithm>
#include <stdint.h>
#include "MediaDecoderStateMachine.h"
#include "MediaTimer.h"
#include "gfx2DGlue.h"
#include "mediasink/DecodedAudioDataSink.h"
#include "mediasink/AudioSinkWrapper.h"
#include "mediasink/DecodedStream.h"
#include "nsTArray.h"
#include "MediaDecoder.h"
#include "MediaDecoderReader.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Logging.h"
#include "mozilla/mozalloc.h"
#include "VideoUtils.h"
#include "TimeUnits.h"
#include "nsDeque.h"
#include "AudioSegment.h"
#include "VideoSegment.h"
#include "ImageContainer.h"
#include "nsComponentManagerUtils.h"
#include "nsITimer.h"
#include "nsContentUtils.h"
#include "MediaShutdownManager.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/Preferences.h"
#include "mozilla/SharedThreadPool.h"
#include "mozilla/TaskQueue.h"
#include "nsIEventTarget.h"
#include "prenv.h"
#include "mozilla/Preferences.h"
#include "gfx2DGlue.h"
#include "nsPrintfCString.h"
#include "DOMMediaStream.h"
#include "mozilla/Logging.h"
#include <algorithm>
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
#include "nsIEventTarget.h"
#include "nsITimer.h"
#include "nsPrintfCString.h"
#include "nsTArray.h"
#include "nsDeque.h"
#include "prenv.h"
#include "AudioSegment.h"
#include "DOMMediaStream.h"
#include "ImageContainer.h"
#include "MediaDecoder.h"
#include "MediaDecoderReader.h"
#include "MediaDecoderStateMachine.h"
#include "MediaShutdownManager.h"
#include "MediaStatistics.h"
#include "MediaTimer.h"
#include "TimeUnits.h"
#include "VideoSegment.h"
#include "VideoUtils.h"
namespace mozilla {
@ -2822,7 +2825,7 @@ void MediaDecoderStateMachine::StartBuffering()
SetState(DECODER_STATE_BUFFERING);
DECODER_LOG("Changed state from DECODING to BUFFERING, decoded for %.3lfs",
decodeDuration.ToSeconds());
MediaDecoder::Statistics stats = mDecoder->GetStatistics();
MediaStatistics stats = mDecoder->GetStatistics();
DECODER_LOG("Playback rate: %.1lfKB/s%s download rate: %.1lfKB/s%s",
stats.mPlaybackRate/1024, stats.mPlaybackRateReliable ? "" : " (unreliable)",
stats.mDownloadRate/1024, stats.mDownloadRateReliable ? "" : " (unreliable)");

View File

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef MediaStatistics_h_
#define MediaStatistics_h_
namespace mozilla {
struct MediaStatistics {
// Estimate of the current playback rate (bytes/second).
double mPlaybackRate;
// Estimate of the current download rate (bytes/second). This
// ignores time that the channel was paused by Gecko.
double mDownloadRate;
// Total length of media stream in bytes; -1 if not known
int64_t mTotalBytes;
// Current position of the download, in bytes. This is the offset of
// the first uncached byte after the decoder position.
int64_t mDownloadPosition;
// Current position of decoding, in bytes (how much of the stream
// has been consumed)
int64_t mDecoderPosition;
// Current position of playback, in bytes
int64_t mPlaybackPosition;
// If false, then mDownloadRate cannot be considered a reliable
// estimate (probably because the download has only been running
// a short time).
bool mDownloadRateReliable;
// If false, then mPlaybackRate cannot be considered a reliable
// estimate (probably because playback has only been running
// a short time).
bool mPlaybackRateReliable;
bool CanPlayThrough()
{
// Number of estimated seconds worth of data we need to have buffered
// ahead of the current playback position before we allow the media decoder
// to report that it can play through the entire media without the decode
// catching up with the download. Having this margin make the
// CanPlayThrough() calculation more stable in the case of
// fluctuating bitrates.
static const int64_t CAN_PLAY_THROUGH_MARGIN = 1;
if ((mTotalBytes < 0 && mDownloadRateReliable) ||
(mTotalBytes >= 0 && mTotalBytes == mDownloadPosition)) {
return true;
}
if (!mDownloadRateReliable || !mPlaybackRateReliable) {
return false;
}
int64_t bytesToDownload = mTotalBytes - mDownloadPosition;
int64_t bytesToPlayback = mTotalBytes - mPlaybackPosition;
double timeToDownload = bytesToDownload / mDownloadRate;
double timeToPlay = bytesToPlayback / mPlaybackRate;
if (timeToDownload > timeToPlay) {
// Estimated time to download is greater than the estimated time to play.
// We probably can't play through without having to stop to buffer.
return false;
}
// Estimated time to download is less than the estimated time to play.
// We can probably play through without having to buffer, but ensure that
// we've got a reasonable amount of data buffered after the current
// playback position, so that if the bitrate of the media fluctuates, or if
// our download rate or decode rate estimation is otherwise inaccurate,
// we don't suddenly discover that we need to buffer. This is particularly
// required near the start of the media, when not much data is downloaded.
int64_t readAheadMargin =
static_cast<int64_t>(mPlaybackRate * CAN_PLAY_THROUGH_MARGIN);
return mDownloadPosition > mPlaybackPosition + readAheadMargin;
}
};
} // namespace mozilla
#endif // MediaStatistics_h_

View File

@ -129,6 +129,7 @@ EXPORTS += [
'MediaRecorder.h',
'MediaResource.h',
'MediaSegment.h',
'MediaStatistics.h',
'MediaStreamGraph.h',
'MediaTimer.h',
'MediaTrack.h',