2016-03-03 05:57:11 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
|
|
|
/* 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/. */
|
|
|
|
|
|
|
|
#include "Benchmark.h"
|
2017-06-20 18:56:55 +03:00
|
|
|
|
2016-03-09 07:34:50 +03:00
|
|
|
#include "BufferMediaResource.h"
|
|
|
|
#include "MediaData.h"
|
2016-03-03 05:57:11 +03:00
|
|
|
#include "PDMFactory.h"
|
2017-06-20 18:28:34 +03:00
|
|
|
#include "VideoUtils.h"
|
2016-03-03 05:57:11 +03:00
|
|
|
#include "WebMDemuxer.h"
|
2017-01-31 22:43:07 +03:00
|
|
|
#include "gfxPrefs.h"
|
2016-11-29 08:03:36 +03:00
|
|
|
#include "mozilla/AbstractThread.h"
|
2016-03-03 05:57:11 +03:00
|
|
|
#include "mozilla/Preferences.h"
|
2017-06-20 18:28:34 +03:00
|
|
|
#include "mozilla/SharedThreadPool.h"
|
2018-06-22 17:00:25 +03:00
|
|
|
#include "mozilla/StaticMutex.h"
|
|
|
|
#include "mozilla/StaticPrefs.h"
|
2017-08-30 06:38:56 +03:00
|
|
|
#include "mozilla/SystemGroup.h"
|
2017-06-20 18:28:34 +03:00
|
|
|
#include "mozilla/TaskQueue.h"
|
2016-03-03 06:23:19 +03:00
|
|
|
#include "mozilla/Telemetry.h"
|
2016-03-17 09:20:21 +03:00
|
|
|
#include "mozilla/dom/ContentChild.h"
|
2017-01-31 22:43:07 +03:00
|
|
|
#include "mozilla/gfx/gfxVars.h"
|
2016-03-03 05:57:11 +03:00
|
|
|
|
2017-01-26 03:59:20 +03:00
|
|
|
#ifndef MOZ_WIDGET_ANDROID
|
|
|
|
#include "WebMSample.h"
|
|
|
|
#endif
|
|
|
|
|
2017-06-20 18:28:34 +03:00
|
|
|
using namespace mozilla::gfx;
|
|
|
|
|
2016-03-03 05:57:11 +03:00
|
|
|
namespace mozilla {
|
|
|
|
|
2016-04-13 05:44:29 +03:00
|
|
|
// Update this version number to force re-running the benchmark. Such as when
|
|
|
|
// an improvement to FFVP9 or LIBVPX is deemed worthwhile.
|
2018-07-12 11:28:41 +03:00
|
|
|
const uint32_t VP9Benchmark::sBenchmarkVersionID = 4;
|
2016-04-13 05:44:29 +03:00
|
|
|
|
2016-03-09 07:34:50 +03:00
|
|
|
const char* VP9Benchmark::sBenchmarkFpsPref = "media.benchmark.vp9.fps";
|
2016-04-13 05:44:29 +03:00
|
|
|
const char* VP9Benchmark::sBenchmarkFpsVersionCheck = "media.benchmark.vp9.versioncheck";
|
2016-03-09 07:34:50 +03:00
|
|
|
bool VP9Benchmark::sHasRunTest = false;
|
2016-03-03 05:57:11 +03:00
|
|
|
|
2016-04-19 10:36:19 +03:00
|
|
|
// static
|
2016-03-03 05:57:11 +03:00
|
|
|
bool
|
2018-07-12 11:28:41 +03:00
|
|
|
VP9Benchmark::IsVP9DecodeFast(bool aDefault)
|
2016-03-03 05:57:11 +03:00
|
|
|
{
|
2018-07-12 11:28:41 +03:00
|
|
|
// Disable VP9 estimizer on Mac, see bug 1400787.
|
|
|
|
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_APPLEMEDIA)
|
2016-10-26 12:08:21 +03:00
|
|
|
return false;
|
2016-04-20 18:09:49 +03:00
|
|
|
#else
|
2018-06-22 17:00:25 +03:00
|
|
|
static StaticMutex sMutex;
|
|
|
|
uint32_t decodeFps = StaticPrefs::MediaBenchmarkVp9Fps();
|
|
|
|
uint32_t hadRecentUpdate = StaticPrefs::MediaBenchmarkVp9Versioncheck();
|
|
|
|
bool needBenchmark;
|
|
|
|
{
|
|
|
|
StaticMutexAutoLock lock(sMutex);
|
|
|
|
needBenchmark = !sHasRunTest &&
|
|
|
|
(decodeFps == 0 || hadRecentUpdate != sBenchmarkVersionID);
|
2016-03-03 05:57:11 +03:00
|
|
|
sHasRunTest = true;
|
2018-06-22 17:00:25 +03:00
|
|
|
}
|
2016-03-03 05:57:11 +03:00
|
|
|
|
2018-06-22 17:00:25 +03:00
|
|
|
if (needBenchmark) {
|
2017-06-26 16:39:16 +03:00
|
|
|
RefPtr<WebMDemuxer> demuxer = new WebMDemuxer(
|
2017-08-24 12:04:59 +03:00
|
|
|
new BufferMediaResource(sWebMSample, sizeof(sWebMSample)));
|
2018-06-22 17:00:25 +03:00
|
|
|
RefPtr<Benchmark> estimiser = new Benchmark(
|
|
|
|
demuxer,
|
|
|
|
{ StaticPrefs::MediaBenchmarkFrames(), // frames to measure
|
|
|
|
1, // start benchmarking after decoding this frame.
|
|
|
|
8, // loop after decoding that many frames.
|
|
|
|
TimeDuration::FromMilliseconds(StaticPrefs::MediaBenchmarkTimeout()) });
|
2016-03-09 07:34:50 +03:00
|
|
|
estimiser->Run()->Then(
|
2018-06-22 17:00:25 +03:00
|
|
|
AbstractThread::MainThread(),
|
|
|
|
__func__,
|
2016-03-09 07:34:50 +03:00
|
|
|
[](uint32_t aDecodeFps) {
|
2016-03-17 09:20:21 +03:00
|
|
|
if (XRE_IsContentProcess()) {
|
|
|
|
dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
|
|
|
|
if (contentChild) {
|
|
|
|
contentChild->SendNotifyBenchmarkResult(NS_LITERAL_STRING("VP9"),
|
|
|
|
aDecodeFps);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Preferences::SetUint(sBenchmarkFpsPref, aDecodeFps);
|
2016-04-13 05:44:29 +03:00
|
|
|
Preferences::SetUint(sBenchmarkFpsVersionCheck, sBenchmarkVersionID);
|
2016-03-17 09:20:21 +03:00
|
|
|
}
|
2018-06-22 17:00:25 +03:00
|
|
|
Telemetry::Accumulate(Telemetry::HistogramID::VIDEO_VP9_BENCHMARK_FPS,
|
|
|
|
aDecodeFps);
|
2016-03-09 07:34:50 +03:00
|
|
|
},
|
2018-06-22 17:00:25 +03:00
|
|
|
[]() {});
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
|
|
|
|
2018-06-22 17:00:25 +03:00
|
|
|
if (decodeFps == 0) {
|
2018-07-03 19:32:09 +03:00
|
|
|
return aDefault;
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
|
|
|
|
2018-06-22 17:00:25 +03:00
|
|
|
return decodeFps >= StaticPrefs::MediaBenchmarkVp9Threshold();
|
2018-07-12 11:28:41 +03:00
|
|
|
#endif
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
|
|
|
|
2016-03-09 07:34:50 +03:00
|
|
|
Benchmark::Benchmark(MediaDataDemuxer* aDemuxer, const Parameters& aParameters)
|
2018-06-22 19:38:29 +03:00
|
|
|
: QueueObject(new TaskQueue(GetMediaThreadPool(MediaThreadType::PLAYBACK),
|
|
|
|
"Benchmark::QueueObject"))
|
2016-03-09 07:34:50 +03:00
|
|
|
, mParameters(aParameters)
|
2016-03-03 05:57:11 +03:00
|
|
|
, mKeepAliveUntilComplete(this)
|
2016-03-09 07:34:50 +03:00
|
|
|
, mPlaybackState(this, aDemuxer)
|
2016-03-03 05:57:11 +03:00
|
|
|
{
|
2016-03-09 07:34:50 +03:00
|
|
|
MOZ_COUNT_CTOR(Benchmark);
|
|
|
|
}
|
2016-03-03 05:57:11 +03:00
|
|
|
|
2016-03-09 07:34:50 +03:00
|
|
|
Benchmark::~Benchmark()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(Benchmark);
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<Benchmark::BenchmarkPromise>
|
|
|
|
Benchmark::Run()
|
|
|
|
{
|
2016-03-03 05:57:11 +03:00
|
|
|
RefPtr<Benchmark> self = this;
|
2018-06-22 19:38:29 +03:00
|
|
|
return InvokeAsync(Thread(), __func__, [self] {
|
|
|
|
RefPtr<BenchmarkPromise> p = self->mPromise.Ensure(__func__);
|
|
|
|
self->mPlaybackState.Dispatch(NS_NewRunnableFunction(
|
|
|
|
"Benchmark::Run", [self]() { self->mPlaybackState.DemuxSamples(); }));
|
|
|
|
return p;
|
|
|
|
});
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-09 07:34:50 +03:00
|
|
|
Benchmark::ReturnResult(uint32_t aDecodeFps)
|
2016-03-03 05:57:11 +03:00
|
|
|
{
|
2016-03-09 13:38:49 +03:00
|
|
|
MOZ_ASSERT(OnThread());
|
2016-03-03 05:57:11 +03:00
|
|
|
|
2016-03-09 07:34:50 +03:00
|
|
|
mPromise.ResolveIfExists(aDecodeFps, __func__);
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
|
|
|
|
2018-03-29 23:11:06 +03:00
|
|
|
void
|
|
|
|
Benchmark::ReturnError(const MediaResult& aError)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(OnThread());
|
|
|
|
|
|
|
|
mPromise.RejectIfExists(aError, __func__);
|
|
|
|
}
|
|
|
|
|
2016-03-03 05:57:11 +03:00
|
|
|
void
|
|
|
|
Benchmark::Dispose()
|
|
|
|
{
|
2016-03-09 13:38:49 +03:00
|
|
|
MOZ_ASSERT(OnThread());
|
2016-03-03 05:57:11 +03:00
|
|
|
|
|
|
|
mKeepAliveUntilComplete = nullptr;
|
|
|
|
}
|
|
|
|
|
2016-03-09 13:38:49 +03:00
|
|
|
void
|
|
|
|
Benchmark::Init()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2017-01-31 22:43:07 +03:00
|
|
|
gfxVars::Initialize();
|
|
|
|
gfxPrefs::GetSingleton();
|
2016-03-09 13:38:49 +03:00
|
|
|
}
|
|
|
|
|
2018-06-22 19:38:29 +03:00
|
|
|
BenchmarkPlayback::BenchmarkPlayback(Benchmark* aGlobalState,
|
2016-03-09 07:34:50 +03:00
|
|
|
MediaDataDemuxer* aDemuxer)
|
2017-04-25 09:57:55 +03:00
|
|
|
: QueueObject(new TaskQueue(
|
|
|
|
GetMediaThreadPool(MediaThreadType::PLAYBACK),
|
|
|
|
"BenchmarkPlayback::QueueObject"))
|
2018-06-22 19:38:29 +03:00
|
|
|
, mGlobalState(aGlobalState)
|
2017-04-25 09:57:55 +03:00
|
|
|
, mDecoderTaskQueue(new TaskQueue(
|
|
|
|
GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER),
|
|
|
|
"BenchmarkPlayback::mDecoderTaskQueue"))
|
2016-03-09 07:34:50 +03:00
|
|
|
, mDemuxer(aDemuxer)
|
|
|
|
, mSampleIndex(0)
|
|
|
|
, mFrameCount(0)
|
|
|
|
, mFinished(false)
|
2017-01-26 15:56:46 +03:00
|
|
|
, mDrained(false)
|
2016-03-03 05:57:11 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BenchmarkPlayback::DemuxSamples()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(OnThread());
|
|
|
|
|
2018-06-22 19:38:29 +03:00
|
|
|
RefPtr<Benchmark> ref(mGlobalState);
|
2016-03-09 07:34:50 +03:00
|
|
|
mDemuxer->Init()->Then(
|
2016-03-03 05:57:11 +03:00
|
|
|
Thread(), __func__,
|
2016-03-09 07:34:50 +03:00
|
|
|
[this, ref](nsresult aResult) {
|
2016-03-03 05:57:11 +03:00
|
|
|
MOZ_ASSERT(OnThread());
|
2018-03-27 15:07:12 +03:00
|
|
|
if (mDemuxer->GetNumberTracks(TrackInfo::kVideoTrack)) {
|
|
|
|
mTrackDemuxer =
|
|
|
|
mDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
|
|
|
|
} else if (mDemuxer->GetNumberTracks(TrackInfo::kAudioTrack)) {
|
|
|
|
mTrackDemuxer =
|
|
|
|
mDemuxer->GetTrackDemuxer(TrackInfo::kAudioTrack, 0);
|
|
|
|
}
|
2016-03-09 07:34:50 +03:00
|
|
|
if (!mTrackDemuxer) {
|
2018-03-29 23:11:06 +03:00
|
|
|
Error(MediaResult(NS_ERROR_FAILURE, "Can't create track demuxer"));
|
2016-03-11 00:37:09 +03:00
|
|
|
return;
|
2016-03-09 07:34:50 +03:00
|
|
|
}
|
|
|
|
DemuxNextSample();
|
2016-03-03 05:57:11 +03:00
|
|
|
},
|
2018-03-29 23:11:06 +03:00
|
|
|
[this, ref](const MediaResult& aError) { Error(aError); });
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-09 07:34:50 +03:00
|
|
|
BenchmarkPlayback::DemuxNextSample()
|
2016-03-03 05:57:11 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(OnThread());
|
|
|
|
|
2018-06-22 19:38:29 +03:00
|
|
|
RefPtr<Benchmark> ref(mGlobalState);
|
2016-03-09 07:34:50 +03:00
|
|
|
RefPtr<MediaTrackDemuxer::SamplesPromise> promise = mTrackDemuxer->GetSamples();
|
|
|
|
promise->Then(
|
|
|
|
Thread(), __func__,
|
|
|
|
[this, ref](RefPtr<MediaTrackDemuxer::SamplesHolder> aHolder) {
|
2018-05-30 22:15:35 +03:00
|
|
|
mSamples.AppendElements(std::move(aHolder->mSamples));
|
2017-09-04 12:27:43 +03:00
|
|
|
if (ref->mParameters.mStopAtFrame &&
|
2018-06-22 17:00:25 +03:00
|
|
|
mSamples.Length() == ref->mParameters.mStopAtFrame.ref()) {
|
2018-05-30 22:15:35 +03:00
|
|
|
InitDecoder(std::move(*mTrackDemuxer->GetInfo()));
|
2016-03-09 07:34:50 +03:00
|
|
|
} else {
|
2017-06-12 22:34:10 +03:00
|
|
|
Dispatch(NS_NewRunnableFunction("BenchmarkPlayback::DemuxNextSample",
|
|
|
|
[this, ref]() { DemuxNextSample(); }));
|
2016-03-09 07:34:50 +03:00
|
|
|
}
|
|
|
|
},
|
2016-09-12 05:22:20 +03:00
|
|
|
[this, ref](const MediaResult& aError) {
|
|
|
|
switch (aError.Code()) {
|
|
|
|
case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
|
2018-05-30 22:15:35 +03:00
|
|
|
InitDecoder(std::move(*mTrackDemuxer->GetInfo()));
|
2016-03-09 07:34:50 +03:00
|
|
|
break;
|
|
|
|
default:
|
2018-03-29 23:11:06 +03:00
|
|
|
Error(aError);
|
|
|
|
break;
|
2016-03-09 07:34:50 +03:00
|
|
|
}
|
|
|
|
});
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-03-09 07:34:50 +03:00
|
|
|
BenchmarkPlayback::InitDecoder(TrackInfo&& aInfo)
|
2016-03-03 05:57:11 +03:00
|
|
|
{
|
2016-03-09 07:34:50 +03:00
|
|
|
MOZ_ASSERT(OnThread());
|
2016-03-03 05:57:11 +03:00
|
|
|
|
|
|
|
RefPtr<PDMFactory> platform = new PDMFactory();
|
2017-01-26 15:56:46 +03:00
|
|
|
mDecoder = platform->CreateDecoder({ aInfo, mDecoderTaskQueue });
|
2016-03-09 07:34:50 +03:00
|
|
|
if (!mDecoder) {
|
2018-03-29 23:11:06 +03:00
|
|
|
Error(MediaResult(NS_ERROR_FAILURE, "Failed to create decoder"));
|
2016-03-09 07:34:50 +03:00
|
|
|
return;
|
|
|
|
}
|
2018-06-22 19:38:29 +03:00
|
|
|
RefPtr<Benchmark> ref(mGlobalState);
|
2016-03-03 05:57:11 +03:00
|
|
|
mDecoder->Init()->Then(
|
2016-03-09 13:14:01 +03:00
|
|
|
Thread(), __func__,
|
2018-03-29 23:11:06 +03:00
|
|
|
[this, ref](TrackInfo::TrackType aTrackType) { InputExhausted(); },
|
|
|
|
[this, ref](const MediaResult& aError) { Error(aError); });
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BenchmarkPlayback::FinalizeShutdown()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(OnThread());
|
|
|
|
|
|
|
|
MOZ_ASSERT(!mDecoder, "mDecoder must have been shutdown already");
|
|
|
|
mDecoderTaskQueue->BeginShutdown();
|
|
|
|
mDecoderTaskQueue->AwaitShutdownAndIdle();
|
|
|
|
mDecoderTaskQueue = nullptr;
|
|
|
|
|
|
|
|
if (mTrackDemuxer) {
|
|
|
|
mTrackDemuxer->Reset();
|
|
|
|
mTrackDemuxer->BreakCycles();
|
|
|
|
mTrackDemuxer = nullptr;
|
|
|
|
}
|
|
|
|
mDemuxer = nullptr;
|
|
|
|
|
2018-06-22 19:38:29 +03:00
|
|
|
RefPtr<Benchmark> ref(mGlobalState);
|
2018-03-29 23:11:06 +03:00
|
|
|
Thread()->AsTaskQueue()->BeginShutdown()->Then(
|
|
|
|
ref->Thread(), __func__,
|
|
|
|
[ref]() { ref->Dispose(); },
|
|
|
|
[]() { MOZ_CRASH("not reached"); });
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2018-06-22 19:38:29 +03:00
|
|
|
BenchmarkPlayback::GlobalShutdown()
|
2016-03-03 05:57:11 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(OnThread());
|
|
|
|
|
2018-03-30 12:00:50 +03:00
|
|
|
MOZ_ASSERT(!mFinished, "We've already shutdown");
|
|
|
|
|
2016-03-11 00:37:09 +03:00
|
|
|
mFinished = true;
|
|
|
|
|
2016-03-09 07:34:50 +03:00
|
|
|
if (mDecoder) {
|
2018-06-22 19:38:29 +03:00
|
|
|
RefPtr<Benchmark> ref(mGlobalState);
|
2017-01-26 15:56:46 +03:00
|
|
|
mDecoder->Flush()->Then(
|
|
|
|
Thread(), __func__,
|
|
|
|
[ref, this]() {
|
|
|
|
mDecoder->Shutdown()->Then(
|
|
|
|
Thread(), __func__,
|
|
|
|
[ref, this]() {
|
2018-03-29 23:11:06 +03:00
|
|
|
FinalizeShutdown();
|
2017-01-26 15:56:46 +03:00
|
|
|
},
|
|
|
|
[]() { MOZ_CRASH("not reached"); });
|
|
|
|
mDecoder = nullptr;
|
|
|
|
},
|
|
|
|
[]() { MOZ_CRASH("not reached"); });
|
2018-03-29 23:11:06 +03:00
|
|
|
} else {
|
|
|
|
FinalizeShutdown();
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-01-26 15:56:46 +03:00
|
|
|
BenchmarkPlayback::Output(const MediaDataDecoder::DecodedData& aResults)
|
2016-03-09 07:34:50 +03:00
|
|
|
{
|
2017-01-26 15:56:46 +03:00
|
|
|
MOZ_ASSERT(OnThread());
|
2018-03-30 12:00:50 +03:00
|
|
|
MOZ_ASSERT(!mFinished);
|
|
|
|
|
2018-06-22 19:38:29 +03:00
|
|
|
RefPtr<Benchmark> ref(mGlobalState);
|
2017-01-26 15:56:46 +03:00
|
|
|
mFrameCount += aResults.Length();
|
|
|
|
if (!mDecodeStartTime && mFrameCount >= ref->mParameters.mStartupFrame) {
|
|
|
|
mDecodeStartTime = Some(TimeStamp::Now());
|
|
|
|
}
|
|
|
|
TimeStamp now = TimeStamp::Now();
|
2018-06-22 17:00:25 +03:00
|
|
|
uint32_t frames = mFrameCount - ref->mParameters.mStartupFrame;
|
2017-01-26 15:56:46 +03:00
|
|
|
TimeDuration elapsedTime = now - mDecodeStartTime.refOr(now);
|
2018-06-22 17:00:25 +03:00
|
|
|
if (((frames == ref->mParameters.mFramesToMeasure) &&
|
|
|
|
mFrameCount > ref->mParameters.mStartupFrame && frames > 0) ||
|
2018-03-30 12:00:50 +03:00
|
|
|
elapsedTime >= ref->mParameters.mTimeout || mDrained) {
|
2016-03-09 07:34:50 +03:00
|
|
|
uint32_t decodeFps = frames / elapsedTime.ToSeconds();
|
2018-06-22 19:38:29 +03:00
|
|
|
GlobalShutdown();
|
2017-06-12 22:34:10 +03:00
|
|
|
ref->Dispatch(
|
|
|
|
NS_NewRunnableFunction("BenchmarkPlayback::Output", [ref, decodeFps]() {
|
|
|
|
ref->ReturnResult(decodeFps);
|
|
|
|
}));
|
2017-01-26 15:56:46 +03:00
|
|
|
}
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
|
|
|
|
2018-03-29 23:11:06 +03:00
|
|
|
void
|
|
|
|
BenchmarkPlayback::Error(const MediaResult& aError)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(OnThread());
|
|
|
|
|
2018-06-22 19:38:29 +03:00
|
|
|
RefPtr<Benchmark> ref(mGlobalState);
|
|
|
|
GlobalShutdown();
|
2018-03-29 23:11:06 +03:00
|
|
|
ref->Dispatch(NS_NewRunnableFunction(
|
|
|
|
"BenchmarkPlayback::Error",
|
|
|
|
[ref, aError]() { ref->ReturnError(aError); }));
|
|
|
|
}
|
|
|
|
|
2017-01-26 15:56:46 +03:00
|
|
|
void
|
|
|
|
BenchmarkPlayback::InputExhausted()
|
2016-03-03 05:57:11 +03:00
|
|
|
{
|
2017-01-26 15:56:46 +03:00
|
|
|
MOZ_ASSERT(OnThread());
|
2018-03-30 12:00:50 +03:00
|
|
|
MOZ_ASSERT(!mFinished);
|
|
|
|
|
|
|
|
if (mSampleIndex >= mSamples.Length()) {
|
|
|
|
Error(MediaResult(NS_ERROR_FAILURE, "Nothing left to decode"));
|
2017-01-26 15:56:46 +03:00
|
|
|
return;
|
|
|
|
}
|
2018-03-30 12:00:50 +03:00
|
|
|
|
|
|
|
RefPtr<MediaRawData> sample = mSamples[mSampleIndex];
|
2018-06-22 19:38:29 +03:00
|
|
|
RefPtr<Benchmark> ref(mGlobalState);
|
2018-03-30 12:00:50 +03:00
|
|
|
RefPtr<MediaDataDecoder::DecodePromise> p = mDecoder->Decode(sample);
|
|
|
|
|
2017-01-26 15:56:46 +03:00
|
|
|
mSampleIndex++;
|
2018-03-30 12:00:50 +03:00
|
|
|
if (mSampleIndex == mSamples.Length() && !ref->mParameters.mStopAtFrame) {
|
|
|
|
// Complete current frame decode then drain if still necessary.
|
|
|
|
p->Then(Thread(), __func__,
|
|
|
|
[ref, this](const MediaDataDecoder::DecodedData& aResults) {
|
|
|
|
Output(aResults);
|
|
|
|
if (!mFinished) {
|
|
|
|
mDecoder->Drain()->Then(
|
|
|
|
Thread(), __func__,
|
|
|
|
[ref, this](const MediaDataDecoder::DecodedData& aResults) {
|
|
|
|
mDrained = true;
|
|
|
|
Output(aResults);
|
|
|
|
MOZ_ASSERT(mFinished, "We must be done now");
|
|
|
|
},
|
|
|
|
[ref, this](const MediaResult& aError) { Error(aError); });
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[ref, this](const MediaResult& aError) { Error(aError); });
|
|
|
|
} else {
|
|
|
|
if (mSampleIndex == mSamples.Length() && ref->mParameters.mStopAtFrame) {
|
2017-01-26 15:56:46 +03:00
|
|
|
mSampleIndex = 0;
|
|
|
|
}
|
2018-03-30 12:00:50 +03:00
|
|
|
// Continue decoding
|
|
|
|
p->Then(Thread(), __func__,
|
|
|
|
[ref, this](const MediaDataDecoder::DecodedData& aResults) {
|
|
|
|
Output(aResults);
|
|
|
|
if (!mFinished) {
|
|
|
|
InputExhausted();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[ref, this](const MediaResult& aError) { Error(aError); });
|
2017-01-26 15:56:46 +03:00
|
|
|
}
|
2016-03-03 05:57:11 +03:00
|
|
|
}
|
2016-03-09 07:34:50 +03:00
|
|
|
|
2017-01-26 15:56:46 +03:00
|
|
|
} // namespace mozilla
|