mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1796069 - Simplify and make more flexible the PerformanceRecorder API. r=alwu
Differential Revision: https://phabricator.services.mozilla.com/D160751
This commit is contained in:
parent
373c7f77e9
commit
8143e2385f
@ -658,15 +658,14 @@ void ExternalEngineStateMachine::OnRequestAudio() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOGV("Start requesting audio");
|
LOGV("Start requesting audio");
|
||||||
PerformanceRecorder perfRecorder(PerformanceRecorder::Stage::RequestData);
|
PerformanceRecorder<PlaybackStage> perfRecorder(MediaStage::RequestData);
|
||||||
perfRecorder.Start();
|
|
||||||
RefPtr<ExternalEngineStateMachine> self = this;
|
RefPtr<ExternalEngineStateMachine> self = this;
|
||||||
mReader->RequestAudioData()
|
mReader->RequestAudioData()
|
||||||
->Then(
|
->Then(
|
||||||
OwnerThread(), __func__,
|
OwnerThread(), __func__,
|
||||||
[this, self, perfRecorder(std::move(perfRecorder))](
|
[this, self, perfRecorder(std::move(perfRecorder))](
|
||||||
const RefPtr<AudioData>& aAudio) mutable {
|
const RefPtr<AudioData>& aAudio) mutable {
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
mAudioDataRequest.Complete();
|
mAudioDataRequest.Complete();
|
||||||
LOGV("Completed requesting audio");
|
LOGV("Completed requesting audio");
|
||||||
AUTO_PROFILER_LABEL(
|
AUTO_PROFILER_LABEL(
|
||||||
@ -718,16 +717,15 @@ void ExternalEngineStateMachine::OnRequestVideo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOGV("Start requesting video");
|
LOGV("Start requesting video");
|
||||||
PerformanceRecorder perfRecorder(PerformanceRecorder::Stage::RequestData,
|
PerformanceRecorder<PlaybackStage> perfRecorder(MediaStage::RequestData,
|
||||||
Info().mVideo.mImage.height);
|
Info().mVideo.mImage.height);
|
||||||
perfRecorder.Start();
|
|
||||||
RefPtr<ExternalEngineStateMachine> self = this;
|
RefPtr<ExternalEngineStateMachine> self = this;
|
||||||
mReader->RequestVideoData(GetVideoThreshold(), false)
|
mReader->RequestVideoData(GetVideoThreshold(), false)
|
||||||
->Then(
|
->Then(
|
||||||
OwnerThread(), __func__,
|
OwnerThread(), __func__,
|
||||||
[this, self, perfRecorder(std::move(perfRecorder))](
|
[this, self, perfRecorder(std::move(perfRecorder))](
|
||||||
const RefPtr<VideoData>& aVideo) mutable {
|
const RefPtr<VideoData>& aVideo) mutable {
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
mVideoDataRequest.Complete();
|
mVideoDataRequest.Complete();
|
||||||
LOGV("Completed requesting video");
|
LOGV("Completed requesting video");
|
||||||
AUTO_PROFILER_LABEL(
|
AUTO_PROFILER_LABEL(
|
||||||
|
@ -326,9 +326,8 @@ already_AddRefed<VideoData> VideoData::CreateAndCopyData(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceRecorder perfRecorder(PerformanceRecorder::Stage::CopyDecodedVideo,
|
PerformanceRecorder<PlaybackStage> perfRecorder(MediaStage::CopyDecodedVideo,
|
||||||
aInfo.mImage.height);
|
aInfo.mImage.height);
|
||||||
perfRecorder.Start();
|
|
||||||
RefPtr<VideoData> v(new VideoData(aOffset, aTime, aDuration, aKeyframe,
|
RefPtr<VideoData> v(new VideoData(aOffset, aTime, aDuration, aKeyframe,
|
||||||
aTimecode, aInfo.mDisplay, 0));
|
aTimecode, aInfo.mDisplay, 0));
|
||||||
|
|
||||||
@ -349,7 +348,7 @@ already_AddRefed<VideoData> VideoData::CreateAndCopyData(
|
|||||||
: aAllocator,
|
: aAllocator,
|
||||||
aContainer, data)) {
|
aContainer, data)) {
|
||||||
v->mImage = d3d11Image;
|
v->mImage = d3d11Image;
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
return v.forget();
|
return v.forget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,7 +360,7 @@ already_AddRefed<VideoData> VideoData::CreateAndCopyData(
|
|||||||
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
|
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
|
||||||
if (ioImage->SetData(aContainer, data)) {
|
if (ioImage->SetData(aContainer, data)) {
|
||||||
v->mImage = ioImage;
|
v->mImage = ioImage;
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
return v.forget();
|
return v.forget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -383,7 +382,7 @@ already_AddRefed<VideoData> VideoData::CreateAndCopyData(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
return v.forget();
|
return v.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,9 +495,8 @@ already_AddRefed<MediaRawData> MediaRawData::Clone() const {
|
|||||||
if (mTrackInfo && mTrackInfo->GetAsVideoInfo()) {
|
if (mTrackInfo && mTrackInfo->GetAsVideoInfo()) {
|
||||||
sampleHeight = mTrackInfo->GetAsVideoInfo()->mImage.height;
|
sampleHeight = mTrackInfo->GetAsVideoInfo()->mImage.height;
|
||||||
}
|
}
|
||||||
PerformanceRecorder perfRecorder(PerformanceRecorder::Stage::CopyDemuxedData,
|
PerformanceRecorder<PlaybackStage> perfRecorder(MediaStage::CopyDemuxedData,
|
||||||
sampleHeight);
|
sampleHeight);
|
||||||
perfRecorder.Start();
|
|
||||||
RefPtr<MediaRawData> s = new MediaRawData;
|
RefPtr<MediaRawData> s = new MediaRawData;
|
||||||
s->mTimecode = mTimecode;
|
s->mTimecode = mTimecode;
|
||||||
s->mTime = mTime;
|
s->mTime = mTime;
|
||||||
@ -516,7 +514,7 @@ already_AddRefed<MediaRawData> MediaRawData::Clone() const {
|
|||||||
if (!s->mAlphaBuffer.Append(mAlphaBuffer.Data(), mAlphaBuffer.Length())) {
|
if (!s->mAlphaBuffer.Append(mAlphaBuffer.Data(), mAlphaBuffer.Length())) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
return s.forget();
|
return s.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3786,15 +3786,14 @@ void MediaDecoderStateMachine::RequestAudioData() {
|
|||||||
LOGV("Queueing audio task - queued=%zu, decoder-queued=%zu",
|
LOGV("Queueing audio task - queued=%zu, decoder-queued=%zu",
|
||||||
AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames());
|
AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames());
|
||||||
|
|
||||||
PerformanceRecorder perfRecorder(PerformanceRecorder::Stage::RequestData);
|
PerformanceRecorder<PlaybackStage> perfRecorder(MediaStage::RequestData);
|
||||||
perfRecorder.Start();
|
|
||||||
RefPtr<MediaDecoderStateMachine> self = this;
|
RefPtr<MediaDecoderStateMachine> self = this;
|
||||||
mReader->RequestAudioData()
|
mReader->RequestAudioData()
|
||||||
->Then(
|
->Then(
|
||||||
OwnerThread(), __func__,
|
OwnerThread(), __func__,
|
||||||
[this, self, perfRecorder(std::move(perfRecorder))](
|
[this, self, perfRecorder(std::move(perfRecorder))](
|
||||||
const RefPtr<AudioData>& aAudio) mutable {
|
const RefPtr<AudioData>& aAudio) mutable {
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
AUTO_PROFILER_LABEL(
|
AUTO_PROFILER_LABEL(
|
||||||
"MediaDecoderStateMachine::RequestAudioData:Resolved",
|
"MediaDecoderStateMachine::RequestAudioData:Resolved",
|
||||||
MEDIA_PLAYBACK);
|
MEDIA_PLAYBACK);
|
||||||
@ -3847,9 +3846,8 @@ void MediaDecoderStateMachine::RequestVideoData(
|
|||||||
VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(),
|
VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(),
|
||||||
aCurrentTime.ToMicroseconds(), mBypassingSkipToNextKeyFrameCheck);
|
aCurrentTime.ToMicroseconds(), mBypassingSkipToNextKeyFrameCheck);
|
||||||
|
|
||||||
PerformanceRecorder perfRecorder(PerformanceRecorder::Stage::RequestData,
|
PerformanceRecorder<PlaybackStage> perfRecorder(MediaStage::RequestData,
|
||||||
Info().mVideo.mImage.height);
|
Info().mVideo.mImage.height);
|
||||||
perfRecorder.Start();
|
|
||||||
RefPtr<MediaDecoderStateMachine> self = this;
|
RefPtr<MediaDecoderStateMachine> self = this;
|
||||||
mReader
|
mReader
|
||||||
->RequestVideoData(
|
->RequestVideoData(
|
||||||
@ -3859,7 +3857,7 @@ void MediaDecoderStateMachine::RequestVideoData(
|
|||||||
OwnerThread(), __func__,
|
OwnerThread(), __func__,
|
||||||
[this, self, perfRecorder(std::move(perfRecorder))](
|
[this, self, perfRecorder(std::move(perfRecorder))](
|
||||||
const RefPtr<VideoData>& aVideo) mutable {
|
const RefPtr<VideoData>& aVideo) mutable {
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
AUTO_PROFILER_LABEL(
|
AUTO_PROFILER_LABEL(
|
||||||
"MediaDecoderStateMachine::RequestVideoData:Resolved",
|
"MediaDecoderStateMachine::RequestVideoData:Resolved",
|
||||||
MEDIA_PLAYBACK);
|
MEDIA_PLAYBACK);
|
||||||
|
@ -1512,10 +1512,9 @@ void MediaFormatReader::DoDemuxVideo() {
|
|||||||
using SamplesPromise = MediaTrackDemuxer::SamplesPromise;
|
using SamplesPromise = MediaTrackDemuxer::SamplesPromise;
|
||||||
|
|
||||||
DDLOG(DDLogCategory::Log, "video_demuxing", DDNoValue{});
|
DDLOG(DDLogCategory::Log, "video_demuxing", DDNoValue{});
|
||||||
PerformanceRecorder perfRecorder(
|
PerformanceRecorder<PlaybackStage> perfRecorder(
|
||||||
PerformanceRecorder::Stage::RequestDemux,
|
MediaStage::RequestDemux,
|
||||||
mVideo.GetCurrentInfo()->GetAsVideoInfo()->mImage.height);
|
mVideo.GetCurrentInfo()->GetAsVideoInfo()->mImage.height);
|
||||||
perfRecorder.Start();
|
|
||||||
auto p = mVideo.mTrackDemuxer->GetSamples(1);
|
auto p = mVideo.mTrackDemuxer->GetSamples(1);
|
||||||
|
|
||||||
RefPtr<MediaFormatReader> self = this;
|
RefPtr<MediaFormatReader> self = this;
|
||||||
@ -1544,7 +1543,7 @@ void MediaFormatReader::DoDemuxVideo() {
|
|||||||
OwnerThread(), __func__,
|
OwnerThread(), __func__,
|
||||||
[self, perfRecorder(std::move(perfRecorder))](
|
[self, perfRecorder(std::move(perfRecorder))](
|
||||||
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) mutable {
|
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) mutable {
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
self->OnVideoDemuxCompleted(std::move(aSamples));
|
self->OnVideoDemuxCompleted(std::move(aSamples));
|
||||||
},
|
},
|
||||||
[self](const MediaResult& aError) { self->OnVideoDemuxFailed(aError); })
|
[self](const MediaResult& aError) { self->OnVideoDemuxFailed(aError); })
|
||||||
@ -1610,8 +1609,7 @@ void MediaFormatReader::DoDemuxAudio() {
|
|||||||
using SamplesPromise = MediaTrackDemuxer::SamplesPromise;
|
using SamplesPromise = MediaTrackDemuxer::SamplesPromise;
|
||||||
|
|
||||||
DDLOG(DDLogCategory::Log, "audio_demuxing", DDNoValue{});
|
DDLOG(DDLogCategory::Log, "audio_demuxing", DDNoValue{});
|
||||||
PerformanceRecorder perfRecorder(PerformanceRecorder::Stage::RequestDemux);
|
PerformanceRecorder<PlaybackStage> perfRecorder(MediaStage::RequestDemux);
|
||||||
perfRecorder.Start();
|
|
||||||
auto p = mAudio.mTrackDemuxer->GetSamples(1);
|
auto p = mAudio.mTrackDemuxer->GetSamples(1);
|
||||||
|
|
||||||
RefPtr<MediaFormatReader> self = this;
|
RefPtr<MediaFormatReader> self = this;
|
||||||
@ -1640,7 +1638,7 @@ void MediaFormatReader::DoDemuxAudio() {
|
|||||||
OwnerThread(), __func__,
|
OwnerThread(), __func__,
|
||||||
[self, perfRecorder(std::move(perfRecorder))](
|
[self, perfRecorder(std::move(perfRecorder))](
|
||||||
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) mutable {
|
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) mutable {
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
self->OnAudioDemuxCompleted(std::move(aSamples));
|
self->OnAudioDemuxCompleted(std::move(aSamples));
|
||||||
},
|
},
|
||||||
[self](const MediaResult& aError) { self->OnAudioDemuxFailed(aError); })
|
[self](const MediaResult& aError) { self->OnAudioDemuxFailed(aError); })
|
||||||
@ -1969,15 +1967,14 @@ void MediaFormatReader::DecodeDemuxedSamples(TrackType aTrack,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
PerformanceRecorder perfRecorder(PerformanceRecorder::Stage::RequestDecode,
|
PerformanceRecorder<PlaybackStage> perfRecorder(MediaStage::RequestDecode,
|
||||||
height, flag);
|
height, flag);
|
||||||
perfRecorder.Start();
|
|
||||||
decoder.mDecoder->Decode(aSample)
|
decoder.mDecoder->Decode(aSample)
|
||||||
->Then(
|
->Then(
|
||||||
mTaskQueue, __func__,
|
mTaskQueue, __func__,
|
||||||
[self, aTrack, &decoder, perfRecorder(std::move(perfRecorder))](
|
[self, aTrack, &decoder, perfRecorder(std::move(perfRecorder))](
|
||||||
MediaDataDecoder::DecodedData&& aResults) mutable {
|
MediaDataDecoder::DecodedData&& aResults) mutable {
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
decoder.mDecodeRequest.Complete();
|
decoder.mDecodeRequest.Complete();
|
||||||
self->NotifyNewOutput(aTrack, std::move(aResults));
|
self->NotifyNewOutput(aTrack, std::move(aResults));
|
||||||
},
|
},
|
||||||
|
@ -149,9 +149,8 @@ bool ArrayOfRemoteMediaRawData::Fill(
|
|||||||
entry->mEOS, height, entry->mDiscardPadding,
|
entry->mEOS, height, entry->mDiscardPadding,
|
||||||
entry->mOriginalPresentationWindow});
|
entry->mOriginalPresentationWindow});
|
||||||
}
|
}
|
||||||
PerformanceRecorder perfRecorder(PerformanceRecorder::Stage::CopyDemuxedData,
|
PerformanceRecorder<PlaybackStage> perfRecorder(MediaStage::CopyDemuxedData,
|
||||||
height);
|
height);
|
||||||
perfRecorder.Start();
|
|
||||||
mBuffers = RemoteArrayOfByteBuffer(dataBuffers, aAllocator);
|
mBuffers = RemoteArrayOfByteBuffer(dataBuffers, aAllocator);
|
||||||
if (!mBuffers.IsValid()) {
|
if (!mBuffers.IsValid()) {
|
||||||
return false;
|
return false;
|
||||||
@ -164,7 +163,7 @@ bool ArrayOfRemoteMediaRawData::Fill(
|
|||||||
if (!mExtraDatas.IsValid()) {
|
if (!mExtraDatas.IsValid()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,9 +178,8 @@ already_AddRefed<MediaRawData> ArrayOfRemoteMediaRawData::ElementAt(
|
|||||||
mExtraDatas.Count() == Count(),
|
mExtraDatas.Count() == Count(),
|
||||||
"Something ain't right here");
|
"Something ain't right here");
|
||||||
const auto& sample = mSamples[aIndex];
|
const auto& sample = mSamples[aIndex];
|
||||||
PerformanceRecorder perfRecorder(PerformanceRecorder::Stage::CopyDemuxedData,
|
PerformanceRecorder<PlaybackStage> perfRecorder(MediaStage::CopyDemuxedData,
|
||||||
sample.mHeight);
|
sample.mHeight);
|
||||||
perfRecorder.Start();
|
|
||||||
AlignedByteBuffer data = mBuffers.AlignedBufferAt<uint8_t>(aIndex);
|
AlignedByteBuffer data = mBuffers.AlignedBufferAt<uint8_t>(aIndex);
|
||||||
if (mBuffers.SizeAt(aIndex) && !data) {
|
if (mBuffers.SizeAt(aIndex) && !data) {
|
||||||
// OOM
|
// OOM
|
||||||
@ -206,7 +204,7 @@ already_AddRefed<MediaRawData> ArrayOfRemoteMediaRawData::ElementAt(
|
|||||||
rawData->mEOS = sample.mEOS;
|
rawData->mEOS = sample.mEOS;
|
||||||
rawData->mDiscardPadding = sample.mDiscardPadding;
|
rawData->mDiscardPadding = sample.mDiscardPadding;
|
||||||
rawData->mExtraData = mExtraDatas.MediaByteBufferAt(aIndex);
|
rawData->mExtraData = mExtraDatas.MediaByteBufferAt(aIndex);
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
return rawData.forget();
|
return rawData.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,9 +1098,8 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
|
|||||||
}
|
}
|
||||||
|
|
||||||
UINT height = std::min(inDesc.Height, outDesc.Height);
|
UINT height = std::min(inDesc.Height, outDesc.Height);
|
||||||
PerformanceRecorder perfRecorder(
|
PerformanceRecorder<PlaybackStage> perfRecorder(
|
||||||
PerformanceRecorder::Stage::CopyDecodedVideo, height);
|
MediaStage::CopyDecodedVideo, height);
|
||||||
perfRecorder.Start();
|
|
||||||
// The D3D11TextureClientAllocator may return a different texture format
|
// The D3D11TextureClientAllocator may return a different texture format
|
||||||
// than preferred. In which case the destination texture will be BGRA32.
|
// than preferred. In which case the destination texture will be BGRA32.
|
||||||
if (outDesc.Format == inDesc.Format) {
|
if (outDesc.Format == inDesc.Format) {
|
||||||
@ -1129,7 +1128,7 @@ D3D11DXVA2Manager::CopyToImage(IMFSample* aVideoSample,
|
|||||||
[&]() -> void { hr = mTransform->Output(&sample); });
|
[&]() -> void { hr = mTransform->Output(&sample); });
|
||||||
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
|
||||||
}
|
}
|
||||||
perfRecorder.End();
|
perfRecorder.Record();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mutex && mDevice != DeviceManagerDx::Get()->GetCompositorDevice() &&
|
if (!mutex && mDevice != DeviceManagerDx::Get()->GetCompositorDevice() &&
|
||||||
|
@ -7,77 +7,26 @@
|
|||||||
#include "PerformanceRecorder.h"
|
#include "PerformanceRecorder.h"
|
||||||
|
|
||||||
#include "mozilla/Logging.h"
|
#include "mozilla/Logging.h"
|
||||||
#include "mozilla/ProfilerMarkers.h"
|
|
||||||
#include "nsString.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
const char* StageToStr(PerformanceRecorder::Stage aStage) {
|
const char* StageToStr(MediaStage aStage) {
|
||||||
switch (aStage) {
|
switch (aStage) {
|
||||||
case PerformanceRecorder::Stage::RequestData:
|
case MediaStage::RequestData:
|
||||||
return "RequestData";
|
return "RequestData";
|
||||||
case PerformanceRecorder::Stage::RequestDemux:
|
case MediaStage::RequestDemux:
|
||||||
return "RequestDemux";
|
return "RequestDemux";
|
||||||
case PerformanceRecorder::Stage::CopyDemuxedData:
|
case MediaStage::CopyDemuxedData:
|
||||||
return "CopyDemuxedData";
|
return "CopyDemuxedData";
|
||||||
case PerformanceRecorder::Stage::RequestDecode:
|
case MediaStage::RequestDecode:
|
||||||
return "RequestDecode";
|
return "RequestDecode";
|
||||||
case PerformanceRecorder::Stage::CopyDecodedVideo:
|
case MediaStage::CopyDecodedVideo:
|
||||||
return "CopyDecodedVideo";
|
return "CopyDecodedVideo";
|
||||||
default:
|
default:
|
||||||
return "InvalidStage";
|
return "InvalidStage";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
|
||||||
const char* PerformanceRecorder::FindMediaResolution(int32_t aHeight) {
|
|
||||||
static const struct {
|
|
||||||
const int32_t mH;
|
|
||||||
const nsCString mRes;
|
|
||||||
} sResolutions[] = {{0, "A:0"_ns}, // other followings are for video
|
|
||||||
{240, "V:0<h<=240"_ns},
|
|
||||||
{480, "V:240<h<=480"_ns},
|
|
||||||
{576, "V:480<h<=576"_ns},
|
|
||||||
{720, "V:576<h<=720"_ns},
|
|
||||||
{1080, "V:720<h<=1080"_ns},
|
|
||||||
{1440, "V:1080<h<=1440"_ns},
|
|
||||||
{2160, "V:1440<h<=2160"_ns},
|
|
||||||
{INT_MAX, "V:h>2160"_ns}};
|
|
||||||
const char* resolution = sResolutions[0].mRes.get();
|
|
||||||
for (auto&& res : sResolutions) {
|
|
||||||
if (aHeight <= res.mH) {
|
|
||||||
resolution = res.mRes.get();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resolution;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */
|
|
||||||
bool PerformanceRecorder::IsMeasurementEnabled() {
|
|
||||||
return profiler_thread_is_being_profiled_for_markers() ||
|
|
||||||
PerformanceRecorder::sEnableMeasurementForTesting;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */
|
|
||||||
TimeStamp PerformanceRecorder::GetCurrentTimeForMeasurement() {
|
|
||||||
// The system call to get the clock is rather expensive on Windows. As we
|
|
||||||
// only report the measurement report via markers, if the marker isn't enabled
|
|
||||||
// then we won't do any measurement in order to save CPU time.
|
|
||||||
return IsMeasurementEnabled() ? TimeStamp::Now() : TimeStamp();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PerformanceRecorder::Start() {
|
|
||||||
MOZ_ASSERT(mStage != Stage::Invalid);
|
|
||||||
MOZ_ASSERT(!mStartTime);
|
|
||||||
mStartTime = Some(GetCurrentTimeForMeasurement());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PerformanceRecorder::Reset() {
|
|
||||||
mStartTime.reset();
|
|
||||||
mStage = Stage::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppendMediaInfoFlagToName(nsCString& aName, MediaInfoFlag aFlag) {
|
void AppendMediaInfoFlagToName(nsCString& aName, MediaInfoFlag aFlag) {
|
||||||
if (aFlag & MediaInfoFlag::KeyFrame) {
|
if (aFlag & MediaInfoFlag::KeyFrame) {
|
||||||
aName.Append("kf,");
|
aName.Append("kf,");
|
||||||
@ -100,26 +49,53 @@ void AppendMediaInfoFlagToName(nsCString& aName, MediaInfoFlag aFlag) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float PerformanceRecorder::End() {
|
/* static */
|
||||||
double elapsedTimeUs = 0.0;
|
const char* FindMediaResolution(int32_t aHeight) {
|
||||||
if (mStartTime && !mStartTime->IsNull()) {
|
static const struct {
|
||||||
MOZ_ASSERT(mStage != Stage::Invalid);
|
const int32_t mH;
|
||||||
if (IsMeasurementEnabled()) {
|
const nsCString mRes;
|
||||||
const auto now = TimeStamp::Now();
|
} sResolutions[] = {{0, "A:0"_ns}, // other followings are for video
|
||||||
elapsedTimeUs = (now - *mStartTime).ToMicroseconds();
|
{240, "V:0<h<=240"_ns},
|
||||||
MOZ_ASSERT(elapsedTimeUs >= 0, "Elapsed time can't be less than 0!");
|
{480, "V:240<h<=480"_ns},
|
||||||
nsAutoCString name(StageToStr(mStage));
|
{576, "V:480<h<=576"_ns},
|
||||||
name.Append(":");
|
{720, "V:576<h<=720"_ns},
|
||||||
name.Append(FindMediaResolution(mHeight));
|
{1080, "V:720<h<=1080"_ns},
|
||||||
name.Append(":");
|
{1440, "V:1080<h<=1440"_ns},
|
||||||
AppendMediaInfoFlagToName(name, mFlag);
|
{2160, "V:1440<h<=2160"_ns},
|
||||||
PROFILER_MARKER_UNTYPED(
|
{INT_MAX, "V:h>2160"_ns}};
|
||||||
name, MEDIA_PLAYBACK,
|
const char* resolution = sResolutions[0].mRes.get();
|
||||||
MarkerOptions(MarkerTiming::Interval(*mStartTime, now)));
|
for (auto&& res : sResolutions) {
|
||||||
|
if (aHeight <= res.mH) {
|
||||||
|
resolution = res.mRes.get();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Reset();
|
|
||||||
}
|
}
|
||||||
return elapsedTimeUs;
|
return resolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
bool PerformanceRecorderBase::IsMeasurementEnabled() {
|
||||||
|
return profiler_thread_is_being_profiled_for_markers() ||
|
||||||
|
PerformanceRecorderBase::sEnableMeasurementForTesting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
TimeStamp PerformanceRecorderBase::GetCurrentTimeForMeasurement() {
|
||||||
|
// The system call to get the clock is rather expensive on Windows. As we
|
||||||
|
// only report the measurement report via markers, if the marker isn't enabled
|
||||||
|
// then we won't do any measurement in order to save CPU time.
|
||||||
|
return IsMeasurementEnabled() ? TimeStamp::Now() : TimeStamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfilerString8View PlaybackStage::Name() const {
|
||||||
|
if (!mName) {
|
||||||
|
mName.emplace(StageToStr(mStage));
|
||||||
|
mName->Append(":");
|
||||||
|
mName->Append(FindMediaResolution(mHeight));
|
||||||
|
mName->Append(":");
|
||||||
|
AppendMediaInfoFlagToName(*mName, mFlag);
|
||||||
|
}
|
||||||
|
return *mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -7,11 +7,17 @@
|
|||||||
#ifndef mozilla_PerformanceRecorder_h
|
#ifndef mozilla_PerformanceRecorder_h
|
||||||
#define mozilla_PerformanceRecorder_h
|
#define mozilla_PerformanceRecorder_h
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/BaseProfilerMarkersPrerequisites.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
#include "mozilla/TypedEnumBits.h"
|
#include "mozilla/TypedEnumBits.h"
|
||||||
|
#include "nsPrintfCString.h"
|
||||||
#include "nsStringFwd.h"
|
#include "nsStringFwd.h"
|
||||||
|
#include "nsTPriorityQueue.h"
|
||||||
|
#include "mozilla/ProfilerMarkers.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
@ -29,106 +35,210 @@ enum class MediaInfoFlag : uint16_t {
|
|||||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(MediaInfoFlag)
|
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(MediaInfoFlag)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to record the passed time on the different stages in the
|
* This represents the different stages that a media data will go through
|
||||||
* media playback pipeline. It needs to call `Start()` and `End()` explicitly
|
* within the playback journey.
|
||||||
* in order to record the passed time between these two calls.
|
*
|
||||||
|
* |---| |---| |------|
|
||||||
|
* Copy Demuxed Copy Demuxed Copy Decoded
|
||||||
|
* Data Data Video
|
||||||
|
* |------------- | |-----------------------------------|
|
||||||
|
* Request Demux Request Decode
|
||||||
|
* |-----------------------------------------------------------|
|
||||||
|
* Request Data
|
||||||
|
*
|
||||||
|
* RequestData : Record the time where MediaDecoderStateMachine(MDSM) starts
|
||||||
|
* asking for a decoded data to MDSM receives a decoded data.
|
||||||
|
*
|
||||||
|
* RequestDemux : Record the time where MediaFormatReader(MFR) starts asking
|
||||||
|
* a demuxed sample to MFR received a demuxed sample. This stage is a sub-
|
||||||
|
* stage of RequestData.
|
||||||
|
*
|
||||||
|
* CopyDemuxedData : On some situations, we will need to copy the demuxed
|
||||||
|
* data, which is still not decoded yet so its size is still small. This
|
||||||
|
* records the time which we spend on copying data. This stage could happen
|
||||||
|
* multiple times, either being a sub-stage of RequestDemux (in MSE case),
|
||||||
|
* or being a sub-stage of RequestDecode (when sending data via IPC).
|
||||||
|
*
|
||||||
|
* RequestDecode : Record the time where MFR starts asking decoder to return
|
||||||
|
* a decoded data to MFR receives a decoded data. As the decoder might be
|
||||||
|
* remote, this stage might include the time spending on IPC trips. This
|
||||||
|
* stage is a sub-stage of RequestData.
|
||||||
|
*
|
||||||
|
* CopyDecodedVideo : If we can't reuse same decoder texture to the
|
||||||
|
* compositor, then we have to copy video data to to another sharable
|
||||||
|
* texture. This records the time which we spend on copying data. This stage
|
||||||
|
* is a sub- stage of RequestDecode.
|
||||||
*/
|
*/
|
||||||
class PerformanceRecorder {
|
enum class MediaStage : uint8_t {
|
||||||
|
Invalid,
|
||||||
|
RequestData,
|
||||||
|
RequestDemux,
|
||||||
|
CopyDemuxedData,
|
||||||
|
RequestDecode,
|
||||||
|
CopyDecodedVideo,
|
||||||
|
};
|
||||||
|
|
||||||
|
class PlaybackStage {
|
||||||
public:
|
public:
|
||||||
/**
|
explicit PlaybackStage(MediaStage aStage, int32_t aHeight = 0,
|
||||||
* This represents the different stages that a media data will go through
|
MediaInfoFlag aFlag = MediaInfoFlag::None)
|
||||||
* within the playback journey.
|
: mStage(aStage), mHeight(aHeight), mFlag(aFlag) {
|
||||||
*
|
MOZ_ASSERT(aStage != MediaStage::Invalid);
|
||||||
* |---| |---| |------|
|
|
||||||
* Copy Demuxed Copy Demuxed Copy Decoded
|
|
||||||
* Data Data Video
|
|
||||||
* |------------- | |-----------------------------------|
|
|
||||||
* Request Demux Request Decode
|
|
||||||
* |-----------------------------------------------------------|
|
|
||||||
* Request Data
|
|
||||||
*
|
|
||||||
* RequestData : Record the time where MediaDecoderStateMachine(MDSM) starts
|
|
||||||
* asking for a decoded data to MDSM receives a decoded data.
|
|
||||||
*
|
|
||||||
* RequestDemux : Record the time where MediaFormatReader(MFR) starts asking
|
|
||||||
* a demuxed sample to MFR received a demuxed sample. This stage is a sub-
|
|
||||||
* stage of RequestData.
|
|
||||||
*
|
|
||||||
* CopyDemuxedData : On some situations, we will need to copy the demuxed
|
|
||||||
* data, which is still not decoded yet so its size is still small. This
|
|
||||||
* records the time which we spend on copying data. This stage could happen
|
|
||||||
* multiple times, either being a sub-stage of RequestDemux (in MSE case), or
|
|
||||||
* being a sub-stage of RequestDecode (when sending data via IPC).
|
|
||||||
*
|
|
||||||
* RequestDecode : Record the time where MFR starts asking decoder to return
|
|
||||||
* a decoded data to MFR receives a decoded data. As the decoder might be
|
|
||||||
* remote, this stage might include the time spending on IPC trips. This stage
|
|
||||||
* is a sub-stage of RequestData.
|
|
||||||
*
|
|
||||||
* CopyDecodedVideo : If we can't reuse same decoder texture to the
|
|
||||||
* compositor, then we have to copy video data to to another sharable texture.
|
|
||||||
* This records the time which we spend on copying data. This stage is a sub-
|
|
||||||
* stage of RequestDecode.
|
|
||||||
*/
|
|
||||||
enum class Stage : uint8_t {
|
|
||||||
Invalid,
|
|
||||||
RequestData,
|
|
||||||
RequestDemux,
|
|
||||||
CopyDemuxedData,
|
|
||||||
RequestDecode,
|
|
||||||
CopyDecodedVideo,
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit PerformanceRecorder(Stage aStage, int32_t aHeight = 0,
|
|
||||||
MediaInfoFlag aFlag = MediaInfoFlag::None)
|
|
||||||
: mStage(aStage), mHeight(aHeight), mFlag(aFlag) {}
|
|
||||||
~PerformanceRecorder() = default;
|
|
||||||
|
|
||||||
PerformanceRecorder(PerformanceRecorder&& aRhs) noexcept {
|
|
||||||
mStage = aRhs.mStage;
|
|
||||||
mHeight = aRhs.mHeight;
|
|
||||||
mStartTime = std::move(aRhs.mStartTime);
|
|
||||||
mFlag = aRhs.mFlag;
|
|
||||||
aRhs.mStage = Stage::Invalid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceRecorder& operator=(PerformanceRecorder&& aRhs) noexcept {
|
ProfilerString8View Name() const;
|
||||||
MOZ_ASSERT(&aRhs != this, "self-moves are prohibited");
|
const MarkerCategory& Category() const {
|
||||||
mStage = aRhs.mStage;
|
return baseprofiler::category::MEDIA_PLAYBACK;
|
||||||
mHeight = aRhs.mHeight;
|
|
||||||
mStartTime = std::move(aRhs.mStartTime);
|
|
||||||
mFlag = aRhs.mFlag;
|
|
||||||
aRhs.mStage = Stage::Invalid;
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceRecorder(const PerformanceRecorder&) = delete;
|
MediaStage mStage;
|
||||||
PerformanceRecorder& operator=(const PerformanceRecorder&) = delete;
|
int32_t mHeight;
|
||||||
|
MediaInfoFlag mFlag;
|
||||||
|
|
||||||
void Start();
|
private:
|
||||||
|
mutable Maybe<nsCString> mName;
|
||||||
// Return the passed time if it has started and still valid. Otherwise,
|
};
|
||||||
// return 0.
|
|
||||||
float End();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void Reset();
|
|
||||||
|
|
||||||
|
class PerformanceRecorderBase {
|
||||||
|
public:
|
||||||
static bool IsMeasurementEnabled();
|
static bool IsMeasurementEnabled();
|
||||||
static TimeStamp GetCurrentTimeForMeasurement();
|
static TimeStamp GetCurrentTimeForMeasurement();
|
||||||
|
|
||||||
// Return the resolution range for the given height. Eg. V:1080<h<=1440.
|
// Return the resolution range for the given height. Eg. V:1080<h<=1440.
|
||||||
static const char* FindMediaResolution(int32_t aHeight);
|
static const char* FindMediaResolution(int32_t aHeight);
|
||||||
|
|
||||||
Stage mStage = Stage::Invalid;
|
protected:
|
||||||
int32_t mHeight;
|
|
||||||
MediaInfoFlag mFlag = MediaInfoFlag::None;
|
|
||||||
Maybe<TimeStamp> mStartTime;
|
|
||||||
|
|
||||||
// We would enable the measurement on testing.
|
// We would enable the measurement on testing.
|
||||||
static inline bool sEnableMeasurementForTesting = false;
|
static inline bool sEnableMeasurementForTesting = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename StageType>
|
||||||
|
class PerformanceRecorderImpl : public PerformanceRecorderBase {
|
||||||
|
public:
|
||||||
|
~PerformanceRecorderImpl() = default;
|
||||||
|
|
||||||
|
PerformanceRecorderImpl(PerformanceRecorderImpl&& aRhs) noexcept
|
||||||
|
: mStages(std::move(aRhs.mStages)) {}
|
||||||
|
PerformanceRecorderImpl& operator=(PerformanceRecorderImpl&&) = delete;
|
||||||
|
PerformanceRecorderImpl(const PerformanceRecorderImpl&) = delete;
|
||||||
|
PerformanceRecorderImpl& operator=(const PerformanceRecorderImpl&) = delete;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PerformanceRecorderImpl() = default;
|
||||||
|
|
||||||
|
// Stores the stage with the current time as its start time, associated with
|
||||||
|
// aId.
|
||||||
|
template <typename... Args>
|
||||||
|
void Start(int64_t aId, Args... aArgs) {
|
||||||
|
if (IsMeasurementEnabled()) {
|
||||||
|
mStages.Push(MakeTuple(aId, GetCurrentTimeForMeasurement(),
|
||||||
|
StageType(std::move(aArgs)...)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the passed time since creation of the aId stage in microseconds if
|
||||||
|
// it has not yet been recorded. Other stages with lower ids will be
|
||||||
|
// discarded. Otherwise, return 0.
|
||||||
|
template <typename F>
|
||||||
|
float Record(int64_t aId, F&& aStageMutator) {
|
||||||
|
while (!mStages.IsEmpty() && Get<0>(mStages.Top()) < aId) {
|
||||||
|
mStages.Pop();
|
||||||
|
}
|
||||||
|
if (mStages.IsEmpty()) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (Get<0>(mStages.Top()) != aId) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
Entry entry = mStages.Pop();
|
||||||
|
const auto& startTime = Get<1>(entry);
|
||||||
|
auto& stage = Get<2>(entry);
|
||||||
|
MOZ_ASSERT(Get<0>(entry) == aId);
|
||||||
|
double elapsedTimeUs = 0.0;
|
||||||
|
if (!startTime.IsNull() && IsMeasurementEnabled()) {
|
||||||
|
const auto now = TimeStamp::Now();
|
||||||
|
elapsedTimeUs = (now - startTime).ToMicroseconds();
|
||||||
|
MOZ_ASSERT(elapsedTimeUs >= 0, "Elapsed time can't be less than 0!");
|
||||||
|
aStageMutator(stage);
|
||||||
|
AUTO_PROFILER_STATS(PROFILER_MARKER_UNTYPED);
|
||||||
|
::profiler_add_marker(
|
||||||
|
stage.Name(), stage.Category(),
|
||||||
|
MarkerOptions(MarkerTiming::Interval(startTime, now)));
|
||||||
|
}
|
||||||
|
return static_cast<float>(elapsedTimeUs);
|
||||||
|
}
|
||||||
|
float Record(int64_t aId) {
|
||||||
|
return Record(aId, [](auto&) {});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using Entry = Tuple<int64_t, TimeStamp, StageType>;
|
||||||
|
|
||||||
|
struct IdComparator {
|
||||||
|
bool LessThan(const Entry& aTupleA, const Entry& aTupleB) {
|
||||||
|
return Get<0>(aTupleA) < Get<0>(aTupleB);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
nsTPriorityQueue<Entry, IdComparator> mStages;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to record the time spent on different stages in the media
|
||||||
|
* pipeline. `Record()` needs to be called explicitly to record a profiler
|
||||||
|
* marker registering the time passed since creation. A stage may be mutated in
|
||||||
|
* `Record()` in case data has become available since the recorder started.
|
||||||
|
*
|
||||||
|
* This variant is intended to be created on the stack when a stage starts, then
|
||||||
|
* recorded with `Record()` when the stage is finished.
|
||||||
|
*/
|
||||||
|
template <typename StageType>
|
||||||
|
class PerformanceRecorder : public PerformanceRecorderImpl<StageType> {
|
||||||
|
using Super = PerformanceRecorderImpl<StageType>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <typename... Args>
|
||||||
|
explicit PerformanceRecorder(Args... aArgs) {
|
||||||
|
Start(std::move(aArgs)...);
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename... Args>
|
||||||
|
void Start(Args... aArgs) {
|
||||||
|
Super::Start(0, std::move(aArgs)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <typename F>
|
||||||
|
float Record(F&& aStageMutator) {
|
||||||
|
return Super::Record(0, std::forward<F>(aStageMutator));
|
||||||
|
}
|
||||||
|
float Record() { return Super::Record(0); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to record the time spent on different stages in the media
|
||||||
|
* pipeline. `Start()` and `Record()` needs to be called explicitly to record a
|
||||||
|
* profiler marker registering the time passed since creation. A stage may be
|
||||||
|
* mutated in `Record()` in case data has become available since the recorder
|
||||||
|
* started.
|
||||||
|
*
|
||||||
|
* This variant is intended to be kept as a member in a class and supports async
|
||||||
|
* stages. The async stages may overlap each other. To distinguish different
|
||||||
|
* stages from each other, an int64_t is used as identifier. This is often a
|
||||||
|
* timestamp in microseconds, see TimeUnit::ToMicroseconds.
|
||||||
|
*/
|
||||||
|
template <typename StageType>
|
||||||
|
class PerformanceRecorderMulti : public PerformanceRecorderImpl<StageType> {
|
||||||
|
using Super = PerformanceRecorderImpl<StageType>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PerformanceRecorderMulti() = default;
|
||||||
|
|
||||||
|
using Super::Record;
|
||||||
|
using Super::Start;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // mozilla_PerformanceRecorder_h
|
#endif // mozilla_PerformanceRecorder_h
|
||||||
|
@ -8,15 +8,13 @@
|
|||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
|
||||||
using Stage = mozilla::PerformanceRecorder::Stage;
|
using namespace mozilla;
|
||||||
|
|
||||||
class PerformanceRecorderWrapper : public mozilla::PerformanceRecorder {
|
class PerformanceRecorderWrapper : public PerformanceRecorder<PlaybackStage> {
|
||||||
public:
|
public:
|
||||||
PerformanceRecorderWrapper(Stage aStage, int32_t aHeight)
|
PerformanceRecorderWrapper(MediaStage aStage, int32_t aHeight)
|
||||||
: PerformanceRecorder(aStage, aHeight) {}
|
: PerformanceRecorder(aStage, aHeight) {}
|
||||||
|
|
||||||
const char* Resolution() const { return FindMediaResolution(mHeight); }
|
|
||||||
|
|
||||||
static void EnableMeasurementOnNonMarkerSituation() {
|
static void EnableMeasurementOnNonMarkerSituation() {
|
||||||
sEnableMeasurementForTesting = true;
|
sEnableMeasurementForTesting = true;
|
||||||
}
|
}
|
||||||
@ -24,6 +22,8 @@ class PerformanceRecorderWrapper : public mozilla::PerformanceRecorder {
|
|||||||
|
|
||||||
TEST(PerformanceRecorder, TestResolution)
|
TEST(PerformanceRecorder, TestResolution)
|
||||||
{
|
{
|
||||||
|
PerformanceRecorderWrapper::EnableMeasurementOnNonMarkerSituation();
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const int32_t mH;
|
const int32_t mH;
|
||||||
const char* mRes;
|
const char* mRes;
|
||||||
@ -37,10 +37,12 @@ TEST(PerformanceRecorder, TestResolution)
|
|||||||
{2160, "V:1440<h<=2160"},
|
{2160, "V:1440<h<=2160"},
|
||||||
{4320, "V:h>2160"}};
|
{4320, "V:h>2160"}};
|
||||||
|
|
||||||
const Stage stage = Stage::RequestDecode;
|
const MediaStage stage = MediaStage::RequestDecode;
|
||||||
for (auto&& res : resolutions) {
|
for (auto&& res : resolutions) {
|
||||||
PerformanceRecorderWrapper w(stage, res.mH);
|
PerformanceRecorderWrapper w(stage, res.mH);
|
||||||
ASSERT_STREQ(w.Resolution(), res.mRes);
|
nsCString name;
|
||||||
|
w.Record([&](auto& aStage) { name = nsCString(aStage.Name()); });
|
||||||
|
ASSERT_NE(name.Find(res.mRes), kNotFound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,14 +50,61 @@ TEST(PerformanceRecorder, TestMoveOperation)
|
|||||||
{
|
{
|
||||||
PerformanceRecorderWrapper::EnableMeasurementOnNonMarkerSituation();
|
PerformanceRecorderWrapper::EnableMeasurementOnNonMarkerSituation();
|
||||||
|
|
||||||
const Stage stage = Stage::RequestDecode;
|
const MediaStage stage = MediaStage::RequestDecode;
|
||||||
const uint32_t resolution = 1080;
|
const uint32_t resolution = 1080;
|
||||||
PerformanceRecorderWrapper w1(stage, resolution);
|
PerformanceRecorderWrapper w1(stage, resolution);
|
||||||
w1.Start();
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
|
||||||
// w1 has been moved which won't continue measuring data.
|
// w1 has been moved which won't continue measuring data.
|
||||||
PerformanceRecorderWrapper w2(std::move(w1));
|
PerformanceRecorderWrapper w2(std::move(w1));
|
||||||
ASSERT_DOUBLE_EQ(w1.End(), 0.0);
|
ASSERT_DOUBLE_EQ(w1.Record(), 0.0);
|
||||||
ASSERT_TRUE(w2.End() > 0.0);
|
ASSERT_TRUE(w2.Record() > 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PerformanceRecorder, TestRecordInvalidation)
|
||||||
|
{
|
||||||
|
PerformanceRecorderWrapper::EnableMeasurementOnNonMarkerSituation();
|
||||||
|
|
||||||
|
const MediaStage stage = MediaStage::RequestDecode;
|
||||||
|
const uint32_t resolution = 1080;
|
||||||
|
PerformanceRecorderWrapper w(stage, resolution);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
|
||||||
|
ASSERT_TRUE(w.Record() > 0.0);
|
||||||
|
|
||||||
|
w.Record();
|
||||||
|
// w has been recorded and won't continue measuring data.
|
||||||
|
ASSERT_DOUBLE_EQ(w.Record(), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PerformanceRecorder, TestMultipleRecords)
|
||||||
|
{
|
||||||
|
PerformanceRecorderWrapper::EnableMeasurementOnNonMarkerSituation();
|
||||||
|
|
||||||
|
const MediaStage stage = MediaStage::RequestDecode;
|
||||||
|
PerformanceRecorderMulti<PlaybackStage> r;
|
||||||
|
|
||||||
|
r.Start(1, stage, 1);
|
||||||
|
r.Start(2, stage, 2);
|
||||||
|
r.Start(3, stage, 3);
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
|
||||||
|
// id 0 wasn't started
|
||||||
|
EXPECT_DOUBLE_EQ(r.Record(0), 0.0);
|
||||||
|
|
||||||
|
// id 1 gets recorded normally
|
||||||
|
EXPECT_TRUE(r.Record(1) > 0.0);
|
||||||
|
|
||||||
|
// id 1 was already recorded
|
||||||
|
EXPECT_DOUBLE_EQ(r.Record(1), 0.0);
|
||||||
|
|
||||||
|
// id 2 gets recorded normally
|
||||||
|
EXPECT_TRUE(r.Record(2) > 0.0);
|
||||||
|
|
||||||
|
// id 4 wasn't started
|
||||||
|
EXPECT_DOUBLE_EQ(r.Record(4), 0.0);
|
||||||
|
|
||||||
|
// All lower ids got discarded
|
||||||
|
EXPECT_DOUBLE_EQ(r.Record(3), 0.0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user