Bug 1530996 - Use the new storage mechanism to save the current playback benchmark. r=jya

Create an event in MediaFormatReader the will signal to the HTMLMediaElement to initiate a new storing according to the latest VideoInfo. Also when the application is shutting down, trigger a new storing early enough, before all the events are disconnected.

Differential Revision: https://phabricator.services.mozilla.com/D38316

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alex Chronopoulos 2019-08-06 09:25:45 +00:00
parent db7dd624ec
commit dae984b098
7 changed files with 73 additions and 2 deletions

View File

@ -7,6 +7,7 @@
#include "MediaDecoder.h"
#include "DOMMediaStream.h"
#include "DecoderBenchmark.h"
#include "ImageContainer.h"
#include "Layers.h"
#include "MediaDecoderStateMachine.h"
@ -287,6 +288,7 @@ MediaDecoder::MediaDecoder(MediaDecoderInit& aInit)
mOwner(aInit.mOwner),
mAbstractMainThread(aInit.mOwner->AbstractMainThread()),
mFrameStats(new FrameStatistics()),
mDecoderBenchmark(new DecoderBenchmark()),
mVideoFrameContainer(aInit.mOwner->GetVideoFrameContainer()),
mMinimizePreroll(aInit.mMinimizePreroll),
mFiredMetadataLoaded(false),
@ -368,6 +370,7 @@ void MediaDecoder::Shutdown() {
mOnWaitingForKey.Disconnect();
mOnDecodeWarning.Disconnect();
mOnNextFrameStatus.Disconnect();
mOnStoreDecoderBenchmark.Disconnect();
mDecoderStateMachine->BeginShutdown()->Then(
mAbstractMainThread, __func__, this, &MediaDecoder::FinishShutdown,
@ -500,6 +503,29 @@ void MediaDecoder::OnNextFrameStatus(
}
}
void MediaDecoder::OnStoreDecoderBenchmark(const VideoInfo& aInfo) {
MOZ_ASSERT(NS_IsMainThread());
int32_t videoFrameRate = aInfo.GetFrameRate().ref();
if (mFrameStats && videoFrameRate) {
DecoderBenchmarkInfo benchmarkInfo{
aInfo.mMimeType,
aInfo.mDisplay.width,
aInfo.mDisplay.height,
videoFrameRate,
BitDepthForColorDepth(aInfo.mColorDepth),
};
LOG("Store benchmark: Video width=%d, height=%d, frameRate=%d, content "
"type = %s\n",
benchmarkInfo.mWidth, benchmarkInfo.mHeight, benchmarkInfo.mFrameRate,
benchmarkInfo.mContentType.BeginReading());
mDecoderBenchmark->Store(benchmarkInfo, mFrameStats);
}
}
void MediaDecoder::FinishShutdown() {
MOZ_ASSERT(NS_IsMainThread());
SetStateMachine(nullptr);
@ -545,6 +571,9 @@ void MediaDecoder::SetStateMachineParameters() {
mAbstractMainThread, this, &MediaDecoder::OnMediaNotSeekable);
mOnNextFrameStatus = mDecoderStateMachine->OnNextFrameStatus().Connect(
mAbstractMainThread, this, &MediaDecoder::OnNextFrameStatus);
mOnStoreDecoderBenchmark = mReader->OnStoreDecoderBenchmark().Connect(
mAbstractMainThread, this,
&MediaDecoder::OnStoreDecoderBenchmark);
mOnEncrypted = mReader->OnEncrypted().Connect(
mAbstractMainThread, GetOwner(), &MediaDecoderOwner::DispatchEncrypted);

View File

@ -42,6 +42,7 @@ class MediaMemoryInfo;
class AbstractThread;
class DOMMediaStream;
class DecoderBenchmark;
class FrameStatistics;
class VideoFrameContainer;
class MediaFormatReader;
@ -475,6 +476,8 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
void OnNextFrameStatus(MediaDecoderOwner::NextFrameStatus);
void OnStoreDecoderBenchmark(const VideoInfo& aInfo);
void FinishShutdown();
void ConnectMirrors(MediaDecoderStateMachine* aObject);
@ -517,6 +520,9 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
// Counters related to decode and presentation of frames.
const RefPtr<FrameStatistics> mFrameStats;
// Store a benchmark of the decoder based on FrameStatistics.
RefPtr<DecoderBenchmark> mDecoderBenchmark;
RefPtr<VideoFrameContainer> mVideoFrameContainer;
// True if the decoder has been directed to minimize its preroll before
@ -576,6 +582,7 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
MediaEventListener mOnWaitingForKey;
MediaEventListener mOnDecodeWarning;
MediaEventListener mOnNextFrameStatus;
MediaEventListener mOnStoreDecoderBenchmark;
// True if we have suspended video decoding.
bool mIsVideoDecodingSuspended = false;

View File

@ -894,10 +894,21 @@ void MediaFormatReader::ShutdownDecoder(TrackType aTrack) {
auto& decoder = GetDecoderData(aTrack);
// Flush the decoder if necessary.
decoder.Flush();
// Shut down the decoder if any.
decoder.ShutdownDecoder();
}
void MediaFormatReader::NotifyDecoderBenchmarkStore() {
MOZ_ASSERT(OnTaskQueue());
auto& decoder = GetDecoderData(TrackInfo::kVideoTrack);
if (decoder.GetCurrentInfo() && decoder.GetCurrentInfo()->GetAsVideoInfo()) {
VideoInfo info = *(decoder.GetCurrentInfo()->GetAsVideoInfo());
info.SetFrameRate(static_cast<int32_t>(ceil(decoder.mMeanRate.Mean())));
mOnStoreDecoderBenchmark.Notify(std::move(info));
}
}
RefPtr<ShutdownPromise> MediaFormatReader::TearDownDecoders() {
if (mAudio.mTaskQueue) {
mAudio.mTaskQueue->BeginShutdown();
@ -1838,6 +1849,11 @@ void MediaFormatReader::HandleDemuxedSamples(
LOG("%s stream id has changed from:%d to:%d.", TrackTypeToStr(aTrack),
decoder.mLastStreamSourceID, info->GetID());
if (aTrack == TrackInfo::kVideoTrack) {
// We are about to create a new decoder thus the benchmark,
// up to this point, is stored.
NotifyDecoderBenchmarkStore();
}
decoder.mNextStreamSourceID.reset();
decoder.mLastStreamSourceID = info->GetID();
decoder.mInfo = info;
@ -2111,6 +2127,10 @@ void MediaFormatReader::Update(TrackType aTrack) {
} else if (decoder.HasCompletedDrain()) {
if (decoder.mDemuxEOS) {
LOG("Rejecting %s promise: EOS", TrackTypeToStr(aTrack));
if (aTrack == TrackInfo::kVideoTrack) {
// End of video, store the benchmark of the decoder.
NotifyDecoderBenchmarkStore();
}
decoder.RejectPromise(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
} else if (decoder.mWaitingForData) {
if (decoder.mDrainState == DrainState::DrainCompleted &&

View File

@ -232,6 +232,10 @@ class MediaFormatReader final
MediaEventSource<MediaResult>& OnDecodeWarning() { return mOnDecodeWarning; }
MediaEventSource<VideoInfo>& OnStoreDecoderBenchmark() {
return mOnStoreDecoderBenchmark;
}
private:
~MediaFormatReader();
@ -306,6 +310,11 @@ class MediaFormatReader final
size_t SizeOfQueue(TrackType aTrack);
// Fire a new OnStoreDecoderBenchmark event that will create new
// storage of the decoder benchmark.
// This is called only on TaskQueue.
void NotifyDecoderBenchmarkStore();
RefPtr<PDMFactory> mPlatform;
RefPtr<PDMFactory> mEncryptedPlatform;
@ -775,6 +784,8 @@ class MediaFormatReader final
MediaEventProducer<MediaResult> mOnDecodeWarning;
MediaEventProducer<VideoInfo> mOnStoreDecoderBenchmark;
RefPtr<FrameStatistics> mFrameStats;
// Used in bug 1393399 for telemetry.

View File

@ -253,6 +253,9 @@ class VideoInfo : public TrackInfo {
// bits etc)
gfx::ColorRange mColorRange = gfx::ColorRange::LIMITED;
Maybe<int32_t> GetFrameRate() const { return mFrameRate; }
void SetFrameRate(int32_t aRate) { mFrameRate = Some(aRate); }
private:
// mImage may be cropped; currently only used with the WebM container.
// A negative width or height indicate that no cropping is to occur.
@ -260,6 +263,8 @@ class VideoInfo : public TrackInfo {
// Indicates whether or not frames may contain alpha information.
bool mAlphaPresent = false;
Maybe<int32_t> mFrameRate;
};
class AudioInfo : public TrackInfo {

View File

@ -7,7 +7,7 @@
#include "DOMMediaStream.h"
#include "MediaStreamError.h"
#include "MediaStreamGraph.h"
#include "MediaStreamGraphImpl.h"
#include "MediaStreamListener.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/dom/Promise.h"

View File

@ -25,7 +25,6 @@ struct DecoderBenchmarkInfo final {
class DecoderBenchmark final {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecoderBenchmark)
DecoderBenchmark() = default;
public:
void Store(const DecoderBenchmarkInfo& aBenchInfo,