mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 11:58:55 +00:00
Bug 1230265 - Add codec agnostic benchmark; r=kentuckyfriedtakahe
The Benchmark class is now taking a MediaDataDemuxer argument. Options allow to decode any videos and measure the decoding speed. MozReview-Commit-ID: C017I1cGqPL
This commit is contained in:
parent
c8300ee73e
commit
d5b11db943
@ -5,35 +5,51 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "Benchmark.h"
|
||||
#include "DecoderTraits.h"
|
||||
#include "BufferMediaResource.h"
|
||||
#include "MediaData.h"
|
||||
#include "PDMFactory.h"
|
||||
#include "WebMDemuxer.h"
|
||||
#include "BufferMediaResource.h"
|
||||
#include "WebMSample.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
const char* Benchmark::sBenchmarkFpsPref = "media.benchmark.fps";
|
||||
bool Benchmark::sHasRunTest = false;
|
||||
|
||||
const uint32_t BenchmarkDecoder::sStartupFrames = 1;
|
||||
const char* VP9Benchmark::sBenchmarkFpsPref = "media.benchmark.vp9.fps";
|
||||
bool VP9Benchmark::sHasRunTest = false;
|
||||
|
||||
bool
|
||||
Benchmark::IsVP9DecodeFast()
|
||||
VP9Benchmark::IsVP9DecodeFast()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!sHasRunTest) {
|
||||
bool hasPref = Preferences::HasUserValue(sBenchmarkFpsPref);
|
||||
|
||||
if (!sHasRunTest && !hasPref) {
|
||||
sHasRunTest = true;
|
||||
|
||||
if (!Preferences::HasUserValue(sBenchmarkFpsPref)) {
|
||||
RefPtr<Benchmark> estimiser = new Benchmark();
|
||||
}
|
||||
RefPtr<WebMDemuxer> demuxer =
|
||||
new WebMDemuxer(new BufferMediaResource(sWebMSample, sizeof(sWebMSample), nullptr,
|
||||
NS_LITERAL_CSTRING("video/webm")));
|
||||
RefPtr<Benchmark> estimiser =
|
||||
new Benchmark(demuxer,
|
||||
{
|
||||
Preferences::GetInt("media.benchmark.frames", 300), // frames to measure
|
||||
1, // start benchmarking after decoding this frame.
|
||||
8, // loop after decoding that many frames.
|
||||
TimeDuration::FromMilliseconds(
|
||||
Preferences::GetUint("media.benchmark.timeout", 1000))
|
||||
});
|
||||
estimiser->Run()->Then(
|
||||
AbstractThread::MainThread(), __func__,
|
||||
[](uint32_t aDecodeFps) {
|
||||
Preferences::SetUint(sBenchmarkFpsPref, aDecodeFps);
|
||||
Telemetry::Accumulate(Telemetry::ID::VIDEO_VP9_BENCHMARK_FPS, aDecodeFps);
|
||||
},
|
||||
[]() { });
|
||||
}
|
||||
|
||||
if (!Preferences::HasUserValue(sBenchmarkFpsPref)) {
|
||||
if (!hasPref) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -44,34 +60,37 @@ Benchmark::IsVP9DecodeFast()
|
||||
return decodeFps >= threshold;
|
||||
}
|
||||
|
||||
Benchmark::Benchmark()
|
||||
Benchmark::Benchmark(MediaDataDemuxer* aDemuxer, const Parameters& aParameters)
|
||||
: QueueObject(AbstractThread::MainThread())
|
||||
, mParameters(aParameters)
|
||||
, mKeepAliveUntilComplete(this)
|
||||
, mPlaybackState(this)
|
||||
, mPlaybackState(this, aDemuxer)
|
||||
{
|
||||
MOZ_COUNT_CTOR(Benchmark);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
Benchmark::~Benchmark()
|
||||
{
|
||||
MOZ_COUNT_DTOR(Benchmark);
|
||||
}
|
||||
|
||||
RefPtr<Benchmark::BenchmarkPromise>
|
||||
Benchmark::Run()
|
||||
{
|
||||
RefPtr<BenchmarkPromise> p = mPromise.Ensure(__func__);
|
||||
RefPtr<Benchmark> self = this;
|
||||
mPlaybackState.Dispatch(
|
||||
NS_NewRunnableFunction([self]() { self->mPlaybackState.DemuxSamples(); }));
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
Benchmark::SaveResult(uint32_t aDecodeFps)
|
||||
Benchmark::ReturnResult(uint32_t aDecodeFps)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
Preferences::SetUint(sBenchmarkFpsPref, aDecodeFps);
|
||||
Telemetry::Accumulate(Telemetry::ID::VIDEO_VP9_BENCHMARK_FPS, aDecodeFps);
|
||||
}
|
||||
|
||||
void
|
||||
Benchmark::Drain(RefPtr<MediaDataDecoder> aDecoder)
|
||||
{
|
||||
RefPtr<Benchmark> self = this;
|
||||
mPlaybackState.Dispatch(NS_NewRunnableFunction([self, aDecoder]() {
|
||||
self->mPlaybackState.Drain(aDecoder);
|
||||
}));
|
||||
mPromise.ResolveIfExists(aDecodeFps, __func__);
|
||||
}
|
||||
|
||||
void
|
||||
@ -79,22 +98,23 @@ Benchmark::Dispose()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mPlaybackState.Shutdown();
|
||||
mKeepAliveUntilComplete = nullptr;
|
||||
mPromise.RejectIfExists(false, __func__);
|
||||
}
|
||||
|
||||
bool
|
||||
Benchmark::IsOnPlaybackThread()
|
||||
{
|
||||
return mPlaybackState.OnThread();
|
||||
}
|
||||
|
||||
BenchmarkPlayback::BenchmarkPlayback(Benchmark* aMainThreadState)
|
||||
BenchmarkPlayback::BenchmarkPlayback(Benchmark* aMainThreadState,
|
||||
MediaDataDemuxer* aDemuxer)
|
||||
: QueueObject(new TaskQueue(GetMediaThreadPool(MediaThreadType::PLAYBACK)))
|
||||
, mMainThreadState(aMainThreadState)
|
||||
, mDecoderState(aMainThreadState, new FlushableTaskQueue(GetMediaThreadPool(
|
||||
MediaThreadType::PLATFORM_DECODER)))
|
||||
, mDecoderTaskQueue(new FlushableTaskQueue(GetMediaThreadPool(
|
||||
MediaThreadType::PLATFORM_DECODER)))
|
||||
, mDemuxer(aDemuxer)
|
||||
, mSampleIndex(0)
|
||||
, mFrameCount(0)
|
||||
, mFinished(false)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
PDMFactory::Init();
|
||||
}
|
||||
|
||||
void
|
||||
@ -102,151 +122,172 @@ BenchmarkPlayback::DemuxSamples()
|
||||
{
|
||||
MOZ_ASSERT(OnThread());
|
||||
|
||||
RefPtr<MediaDataDemuxer> demuxer = new WebMDemuxer(
|
||||
new BufferMediaResource(sWebMSample, sizeof(sWebMSample), nullptr,
|
||||
NS_LITERAL_CSTRING("video/webm")));
|
||||
RefPtr<Benchmark> ref = mMainThreadState;
|
||||
demuxer->Init()->Then(
|
||||
RefPtr<Benchmark> ref(mMainThreadState);
|
||||
mDemuxer->Init()->Then(
|
||||
Thread(), __func__,
|
||||
[this, ref, demuxer](nsresult aResult) {
|
||||
[this, ref](nsresult aResult) {
|
||||
MOZ_ASSERT(OnThread());
|
||||
RefPtr<MediaTrackDemuxer> track =
|
||||
demuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
|
||||
|
||||
RefPtr<MediaTrackDemuxer::SamplesPromise> promise = track->GetSamples(8);
|
||||
|
||||
promise->Then(
|
||||
ref->Thread(), __func__,
|
||||
[this, ref, track](RefPtr<MediaTrackDemuxer::SamplesHolder> aHolder) {
|
||||
mDecoderState.Init(Move(*track->GetInfo()), aHolder->mSamples);
|
||||
},
|
||||
[ref](DemuxerFailureReason aReason) { ref->Dispose(); });
|
||||
mTrackDemuxer =
|
||||
mDemuxer->GetTrackDemuxer(TrackInfo::kVideoTrack, 0);
|
||||
if (!mTrackDemuxer) {
|
||||
MainThreadShutdown();
|
||||
}
|
||||
DemuxNextSample();
|
||||
},
|
||||
[ref](DemuxerFailureReason aReason) { ref->Dispose(); });
|
||||
[this, ref](DemuxerFailureReason aReason) { MainThreadShutdown(); });
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkPlayback::Drain(RefPtr<MediaDataDecoder> aDecoder)
|
||||
BenchmarkPlayback::DemuxNextSample()
|
||||
{
|
||||
MOZ_ASSERT(OnThread());
|
||||
|
||||
aDecoder->Drain();
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkPlayback::Shutdown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mDecoderState.Thread()->AsTaskQueue()->BeginShutdown();
|
||||
Thread()->AsTaskQueue()->BeginShutdown();
|
||||
}
|
||||
|
||||
BenchmarkDecoder::BenchmarkDecoder(Benchmark* aMainThreadState,
|
||||
RefPtr<FlushableTaskQueue> aTaskQueue)
|
||||
: QueueObject(aTaskQueue)
|
||||
, mTaskQueue(aTaskQueue)
|
||||
, mMainThreadState(aMainThreadState)
|
||||
, mSampleIndex(0)
|
||||
, mFrameCount(0)
|
||||
, mFramesToMeasure(Preferences::GetUint("media.benchmark.frames", 300))
|
||||
, mTimeout(TimeDuration::FromMilliseconds(
|
||||
Preferences::GetUint("media.benchmark.timeout", 1000)))
|
||||
, mFinished(false)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkDecoder::Init(TrackInfo&& aInfo,
|
||||
nsTArray<RefPtr<MediaRawData> >& aSamples)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mSamples = aSamples;
|
||||
|
||||
RefPtr<PDMFactory> platform = new PDMFactory();
|
||||
platform->Init();
|
||||
|
||||
mDecoder = platform->CreateDecoder(aInfo, mTaskQueue, this);
|
||||
RefPtr<Benchmark> ref = mMainThreadState;
|
||||
mDecoder->Init()->Then(
|
||||
ref->Thread(), __func__,
|
||||
[this, ref, aSamples](TrackInfo::TrackType aTrackType) {
|
||||
Dispatch(NS_NewRunnableFunction([this, ref]() { InputExhausted(); }));
|
||||
RefPtr<Benchmark> ref(mMainThreadState);
|
||||
RefPtr<MediaTrackDemuxer::SamplesPromise> promise = mTrackDemuxer->GetSamples();
|
||||
promise->Then(
|
||||
Thread(), __func__,
|
||||
[this, ref](RefPtr<MediaTrackDemuxer::SamplesHolder> aHolder) {
|
||||
mSamples.AppendElements(Move(aHolder->mSamples));
|
||||
if (ref->mParameters.mStopAtFrame &&
|
||||
mSamples.Length() == (size_t)ref->mParameters.mStopAtFrame.ref()) {
|
||||
InitDecoder(Move(*mTrackDemuxer->GetInfo()));
|
||||
} else {
|
||||
Dispatch(NS_NewRunnableFunction([this, ref]() { DemuxNextSample(); }));
|
||||
}
|
||||
},
|
||||
[this, ref](MediaDataDecoder::DecoderFailureReason aReason) {
|
||||
ref->Dispose();
|
||||
[this, ref](DemuxerFailureReason aReason) {
|
||||
switch (aReason) {
|
||||
case DemuxerFailureReason::END_OF_STREAM:
|
||||
InitDecoder(Move(*mTrackDemuxer->GetInfo()));
|
||||
break;
|
||||
default:
|
||||
MainThreadShutdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkDecoder::MainThreadShutdown()
|
||||
BenchmarkPlayback::InitDecoder(TrackInfo&& aInfo)
|
||||
{
|
||||
MOZ_ASSERT(OnThread());
|
||||
|
||||
RefPtr<Benchmark> ref = mMainThreadState;
|
||||
ref->Dispatch(NS_NewRunnableFunction([ref]() { ref->Dispose(); }));
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkDecoder::Output(MediaData* aData)
|
||||
{
|
||||
MOZ_ASSERT(OnThread());
|
||||
|
||||
if (mFinished) {
|
||||
RefPtr<PDMFactory> platform = new PDMFactory();
|
||||
mDecoder = platform->CreateDecoder(aInfo, mDecoderTaskQueue, this);
|
||||
if (!mDecoder) {
|
||||
MainThreadShutdown();
|
||||
return;
|
||||
}
|
||||
mFrameCount++;
|
||||
if (mFrameCount == sStartupFrames) {
|
||||
mDecodeStartTime = TimeStamp::Now();
|
||||
RefPtr<Benchmark> ref(mMainThreadState);
|
||||
mDecoder->Init()->Then(
|
||||
ref->Thread(), __func__,
|
||||
[this, ref](TrackInfo::TrackType aTrackType) {
|
||||
Dispatch(NS_NewRunnableFunction([this, ref]() { InputExhausted(); }));
|
||||
},
|
||||
[this, ref](MediaDataDecoder::DecoderFailureReason aReason) {
|
||||
MainThreadShutdown();
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkPlayback::MainThreadShutdown()
|
||||
{
|
||||
MOZ_ASSERT(OnThread());
|
||||
|
||||
if (mDecoder) {
|
||||
mDecoder->Flush();
|
||||
mDecoder->Shutdown();
|
||||
mDecoder = nullptr;
|
||||
}
|
||||
uint32_t frames = mFrameCount - sStartupFrames;
|
||||
TimeDuration elapsedTime = TimeStamp::Now() - mDecodeStartTime;
|
||||
if (frames == mFramesToMeasure || elapsedTime >= mTimeout) {
|
||||
|
||||
mDecoderTaskQueue->BeginShutdown();
|
||||
mDecoderTaskQueue->AwaitShutdownAndIdle();
|
||||
mDecoderTaskQueue = nullptr;
|
||||
|
||||
if (mTrackDemuxer) {
|
||||
mTrackDemuxer->Reset();
|
||||
mTrackDemuxer->BreakCycles();
|
||||
mTrackDemuxer = nullptr;
|
||||
}
|
||||
|
||||
RefPtr<Benchmark> ref(mMainThreadState);
|
||||
Thread()->AsTaskQueue()->BeginShutdown()->Then(
|
||||
ref->Thread(), __func__,
|
||||
[ref]() { ref->Dispose(); },
|
||||
[]() { MOZ_CRASH("not reached"); });
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkPlayback::Output(MediaData* aData)
|
||||
{
|
||||
RefPtr<Benchmark> ref(mMainThreadState);
|
||||
Dispatch(NS_NewRunnableFunction([this, ref]() {
|
||||
mFrameCount++;
|
||||
if (mFrameCount == ref->mParameters.mStartupFrame) {
|
||||
mDecodeStartTime = TimeStamp::Now();
|
||||
}
|
||||
int32_t frames = mFrameCount - ref->mParameters.mStartupFrame;
|
||||
TimeDuration elapsedTime = TimeStamp::Now() - mDecodeStartTime;
|
||||
if (!mFinished &&
|
||||
(frames == ref->mParameters.mFramesToMeasure ||
|
||||
elapsedTime >= ref->mParameters.mTimeout)) {
|
||||
uint32_t decodeFps = frames / elapsedTime.ToSeconds();
|
||||
mFinished = true;
|
||||
MainThreadShutdown();
|
||||
ref->Dispatch(NS_NewRunnableFunction([ref, decodeFps]() {
|
||||
ref->ReturnResult(decodeFps);
|
||||
}));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkPlayback::Error()
|
||||
{
|
||||
RefPtr<Benchmark> ref(mMainThreadState);
|
||||
Dispatch(NS_NewRunnableFunction([this, ref]() { MainThreadShutdown(); }));
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkPlayback::InputExhausted()
|
||||
{
|
||||
RefPtr<Benchmark> ref(mMainThreadState);
|
||||
Dispatch(NS_NewRunnableFunction([this, ref]() {
|
||||
MOZ_ASSERT(OnThread());
|
||||
if (mFinished || mSampleIndex >= mSamples.Length()) {
|
||||
return;
|
||||
}
|
||||
mDecoder->Input(mSamples[mSampleIndex]);
|
||||
mSampleIndex++;
|
||||
if (mSampleIndex == mSamples.Length()) {
|
||||
if (ref->mParameters.mStopAtFrame) {
|
||||
mSampleIndex = 0;
|
||||
} else {
|
||||
mDecoder->Drain();
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkPlayback::DrainComplete()
|
||||
{
|
||||
RefPtr<Benchmark> ref(mMainThreadState);
|
||||
Dispatch(NS_NewRunnableFunction([this, ref]() {
|
||||
int32_t frames = mFrameCount - ref->mParameters.mStartupFrame;
|
||||
TimeDuration elapsedTime = TimeStamp::Now() - mDecodeStartTime;
|
||||
uint32_t decodeFps = frames / elapsedTime.ToSeconds();
|
||||
mFinished = true;
|
||||
|
||||
RefPtr<Benchmark> ref = mMainThreadState;
|
||||
RefPtr<MediaDataDecoder> decoder = mDecoder;
|
||||
ref->Dispatch(NS_NewRunnableFunction([ref, decoder, decodeFps]() {
|
||||
ref->Drain(decoder);
|
||||
ref->SaveResult(decodeFps);
|
||||
MainThreadShutdown();
|
||||
ref->Dispatch(NS_NewRunnableFunction([ref, decodeFps]() {
|
||||
ref->ReturnResult(decodeFps);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkDecoder::Error()
|
||||
{
|
||||
MOZ_ASSERT(OnThread());
|
||||
|
||||
MainThreadShutdown();
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkDecoder::InputExhausted()
|
||||
{
|
||||
MOZ_ASSERT(OnThread());
|
||||
|
||||
mDecoder->Input(mSamples[mSampleIndex]);
|
||||
mSampleIndex++;
|
||||
if (mSampleIndex == mSamples.Length()) {
|
||||
mSampleIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BenchmarkDecoder::DrainComplete()
|
||||
{
|
||||
MOZ_ASSERT(OnThread());
|
||||
|
||||
MainThreadShutdown();
|
||||
}));
|
||||
}
|
||||
|
||||
bool
|
||||
BenchmarkDecoder::OnReaderTaskQueue()
|
||||
BenchmarkPlayback::OnReaderTaskQueue()
|
||||
{
|
||||
return mMainThreadState->IsOnPlaybackThread();
|
||||
return OnThread();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,75 +7,100 @@
|
||||
#ifndef MOZILLA_BENCHMARK_H
|
||||
#define MOZILLA_BENCHMARK_H
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "MediaDataDemuxer.h"
|
||||
#include "QueueObject.h"
|
||||
#include "PlatformDecoderModule.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/TaskQueue.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class FlushableTaskQueue;
|
||||
class Benchmark;
|
||||
class BenchmarkPlayback;
|
||||
|
||||
class BenchmarkDecoder : public QueueObject, private MediaDataDecoderCallback
|
||||
class BenchmarkPlayback : public QueueObject, private MediaDataDecoderCallback
|
||||
{
|
||||
public:
|
||||
BenchmarkDecoder(Benchmark* aMainThreadState,
|
||||
RefPtr<FlushableTaskQueue> aTaskQueue);
|
||||
void Init(TrackInfo&& aInfo, nsTArray<RefPtr<MediaRawData>>& aSamples);
|
||||
|
||||
explicit BenchmarkPlayback(Benchmark* aMainThreadState, MediaDataDemuxer* aDemuxer);
|
||||
void DemuxSamples();
|
||||
void DemuxNextSample();
|
||||
void MainThreadShutdown();
|
||||
MediaRawData* PopNextSample();
|
||||
void InitDecoder(TrackInfo&& aInfo);
|
||||
|
||||
// MediaDataDecoderCallback
|
||||
// Those methods are called on the MediaDataDecoder's task queue.
|
||||
void Output(MediaData* aData) override;
|
||||
void Error() override;
|
||||
void InputExhausted() override;
|
||||
void DrainComplete() override;
|
||||
bool OnReaderTaskQueue() override;
|
||||
|
||||
RefPtr<FlushableTaskQueue> mTaskQueue;
|
||||
Benchmark* mMainThreadState;
|
||||
private:
|
||||
Atomic<Benchmark*> mMainThreadState;
|
||||
|
||||
RefPtr<FlushableTaskQueue> mDecoderTaskQueue;
|
||||
RefPtr<MediaDataDecoder> mDecoder;
|
||||
|
||||
RefPtr<TaskQueue> mTaskQueue;
|
||||
// Object only accessed on mTaskQueue
|
||||
RefPtr<MediaDataDemuxer> mDemuxer;
|
||||
RefPtr<MediaTrackDemuxer> mTrackDemuxer;
|
||||
nsTArray<RefPtr<MediaRawData>> mSamples;
|
||||
size_t mSampleIndex;
|
||||
TimeStamp mDecodeStartTime;
|
||||
uint32_t mFrameCount;
|
||||
const uint32_t mFramesToMeasure;
|
||||
const TimeDuration mTimeout;
|
||||
static const uint32_t sStartupFrames;
|
||||
bool mFinished;
|
||||
};
|
||||
|
||||
class BenchmarkPlayback : public QueueObject
|
||||
{
|
||||
public:
|
||||
explicit BenchmarkPlayback(Benchmark* aMainThreadState);
|
||||
void DemuxSamples();
|
||||
void Drain(RefPtr<MediaDataDecoder> aDecoder);
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
Benchmark* mMainThreadState;
|
||||
BenchmarkDecoder mDecoderState;
|
||||
};
|
||||
|
||||
class Benchmark : public QueueObject
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Benchmark)
|
||||
|
||||
static bool IsVP9DecodeFast();
|
||||
struct Parameters
|
||||
{
|
||||
Parameters()
|
||||
: mFramesToMeasure(-1)
|
||||
, mStartupFrame(1)
|
||||
, mTimeout(TimeDuration::Forever()) {}
|
||||
|
||||
void SaveResult(uint32_t aDecodeFps);
|
||||
void Drain(RefPtr<MediaDataDecoder> aDecoder);
|
||||
Parameters(int32_t aFramesToMeasure,
|
||||
uint32_t aStartupFrame,
|
||||
int32_t aStopAtFrame,
|
||||
const TimeDuration& aTimeout)
|
||||
: mFramesToMeasure(aFramesToMeasure)
|
||||
, mStartupFrame(aStartupFrame)
|
||||
, mStopAtFrame(Some(aStopAtFrame))
|
||||
, mTimeout(aTimeout) {}
|
||||
|
||||
const int32_t mFramesToMeasure;
|
||||
const uint32_t mStartupFrame;
|
||||
const Maybe<int32_t> mStopAtFrame;
|
||||
const TimeDuration mTimeout;
|
||||
};
|
||||
|
||||
typedef MozPromise<uint32_t, bool, /* IsExclusive = */ true> BenchmarkPromise;
|
||||
|
||||
Benchmark(MediaDataDemuxer* aDemuxer, const Parameters& aParameters = Parameters());
|
||||
RefPtr<BenchmarkPromise> Run();
|
||||
void ReturnResult(uint32_t aDecodeFps);
|
||||
void Dispose();
|
||||
bool IsOnPlaybackThread();
|
||||
|
||||
const Parameters mParameters;
|
||||
|
||||
private:
|
||||
Benchmark();
|
||||
virtual ~Benchmark() {}
|
||||
virtual ~Benchmark();
|
||||
RefPtr<Benchmark> mKeepAliveUntilComplete;
|
||||
BenchmarkPlayback mPlaybackState;
|
||||
MozPromiseHolder<BenchmarkPromise> mPromise;
|
||||
};
|
||||
|
||||
class VP9Benchmark
|
||||
{
|
||||
public:
|
||||
static bool IsVP9DecodeFast();
|
||||
static const char* sBenchmarkFpsPref;
|
||||
static bool sHasRunTest;
|
||||
};
|
||||
|
@ -8,6 +8,8 @@
|
||||
#define MOZILLA_QUEUE_OBJECT_H
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -80,7 +80,7 @@ IsWebMForced()
|
||||
bool mp4supported =
|
||||
DecoderTraits::IsMP4TypeAndEnabled(NS_LITERAL_CSTRING("video/mp4"));
|
||||
bool hwsupported = gfxPlatform::GetPlatform()->CanUseHardwareVideoDecoding();
|
||||
return !mp4supported || !hwsupported || Benchmark::IsVP9DecodeFast();
|
||||
return !mp4supported || !hwsupported || VP9Benchmark::IsVP9DecodeFast();
|
||||
}
|
||||
|
||||
static nsresult
|
||||
|
Loading…
x
Reference in New Issue
Block a user