зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1873394 - part2 : add telemetry probe to record error and crash. r=jolin,chutten
Differential Revision: https://phabricator.services.mozilla.com/D198110
This commit is contained in:
Родитель
1e0c17c84c
Коммит
55fe15a99b
|
@ -15,7 +15,9 @@
|
|||
#include "mozilla/ProfilerLabels.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -248,6 +250,7 @@ void ExternalEngineStateMachine::OnEngineInitFailure() {
|
|||
state->mEngineInitRequest.Complete();
|
||||
state->mInitPromise = nullptr;
|
||||
// TODO : Should fallback to the normal playback with media engine.
|
||||
ReportTelemetry(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||
DecodeError(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
|
||||
}
|
||||
|
||||
|
@ -276,14 +279,16 @@ void ExternalEngineStateMachine::OnMetadataRead(MetadataHolder&& aMetadata) {
|
|||
|
||||
if (!IsFormatSupportedByExternalEngine(*mInfo)) {
|
||||
// The external engine doesn't support the type, try to notify the decoder
|
||||
// to use our own state machine again.
|
||||
// to use our own state machine again. Not a real "error", because it would
|
||||
// fallback to another state machine.
|
||||
DecodeError(
|
||||
MediaResult(NS_ERROR_DOM_MEDIA_EXTERNAL_ENGINE_NOT_SUPPORTED_ERR));
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WMF_MEDIA_ENGINE
|
||||
// Only support encrypted playback.
|
||||
// Only support encrypted playback. Not a real "error", because it would
|
||||
// fallback to another state machine.
|
||||
if (!mInfo->IsEncrypted() &&
|
||||
StaticPrefs::media_wmf_media_engine_enabled() == 2) {
|
||||
LOG("External engine only supports encrypted playback by the pref");
|
||||
|
@ -331,6 +336,7 @@ void ExternalEngineStateMachine::OnMetadataNotRead(const MediaResult& aError) {
|
|||
MOZ_ASSERT(mState.IsReadingMetadata());
|
||||
LOGE("Decode metadata failed, shutting down decoder");
|
||||
mState.AsReadingMetadata()->mMetadataRequest.Complete();
|
||||
ReportTelemetry(aError);
|
||||
DecodeError(aError);
|
||||
}
|
||||
|
||||
|
@ -466,6 +472,7 @@ void ExternalEngineStateMachine::OnSeekRejected(
|
|||
MOZ_ASSERT(NS_FAILED(aReject.mError),
|
||||
"Cancels should also disconnect mSeekRequest");
|
||||
state->RejectIfExists(__func__);
|
||||
ReportTelemetry(aReject.mError);
|
||||
DecodeError(aReject.mError);
|
||||
}
|
||||
|
||||
|
@ -838,6 +845,7 @@ void ExternalEngineStateMachine::OnRequestAudio() {
|
|||
// so here just silently ignore this.
|
||||
break;
|
||||
default:
|
||||
ReportTelemetry(aError);
|
||||
DecodeError(aError);
|
||||
}
|
||||
})
|
||||
|
@ -914,6 +922,7 @@ void ExternalEngineStateMachine::OnRequestVideo() {
|
|||
// so here just silently ignore this.
|
||||
break;
|
||||
default:
|
||||
ReportTelemetry(aError);
|
||||
DecodeError(aError);
|
||||
}
|
||||
})
|
||||
|
@ -1100,11 +1109,14 @@ void ExternalEngineStateMachine::NotifyErrorInternal(
|
|||
if (aError == NS_ERROR_DOM_MEDIA_NOT_SUPPORTED_ERR) {
|
||||
// The external engine doesn't support the type, try to notify the decoder
|
||||
// to use our own state machine again.
|
||||
ReportTelemetry(NS_ERROR_DOM_MEDIA_EXTERNAL_ENGINE_NOT_SUPPORTED_ERR);
|
||||
DecodeError(
|
||||
MediaResult(NS_ERROR_DOM_MEDIA_EXTERNAL_ENGINE_NOT_SUPPORTED_ERR));
|
||||
} else if (aError == NS_ERROR_DOM_MEDIA_REMOTE_DECODER_CRASHED_MF_CDM_ERR) {
|
||||
ReportTelemetry(NS_ERROR_DOM_MEDIA_REMOTE_DECODER_CRASHED_MF_CDM_ERR);
|
||||
RecoverFromCDMProcessCrashIfNeeded();
|
||||
} else {
|
||||
ReportTelemetry(aError);
|
||||
DecodeError(aError);
|
||||
}
|
||||
}
|
||||
|
@ -1190,7 +1202,8 @@ RefPtr<SetCDMPromise> ExternalEngineStateMachine::SetCDMProxy(
|
|||
}
|
||||
|
||||
// TODO : set CDM proxy again if we recreate the media engine after crash.
|
||||
LOG("SetCDMProxy=%p", aProxy);
|
||||
mKeySystem = NS_ConvertUTF16toUTF8(aProxy->KeySystem());
|
||||
LOG("SetCDMProxy=%p (key-system=%s)", aProxy, mKeySystem.get());
|
||||
MOZ_DIAGNOSTIC_ASSERT(mEngine);
|
||||
if (!mEngine->SetCDMProxy(aProxy)) {
|
||||
LOG("Failed to set CDM proxy on the engine");
|
||||
|
@ -1216,6 +1229,45 @@ bool ExternalEngineStateMachine::IsCDMProxySupported(CDMProxy* aProxy) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void ExternalEngineStateMachine::ReportTelemetry(const MediaResult& aError) {
|
||||
glean::mfcdm::ErrorExtra extraData;
|
||||
extraData.errorName = Some(aError.ErrorName());
|
||||
nsAutoCString resolution;
|
||||
if (mInfo) {
|
||||
if (mInfo->HasAudio()) {
|
||||
extraData.audioCodec = Some(mInfo->mAudio.mMimeType);
|
||||
}
|
||||
if (mInfo->HasVideo()) {
|
||||
extraData.videoCodec = Some(mInfo->mVideo.mMimeType);
|
||||
DetermineResolutionForTelemetry(*mInfo, resolution);
|
||||
extraData.resolution = Some(resolution);
|
||||
}
|
||||
}
|
||||
if (!mKeySystem.IsEmpty()) {
|
||||
extraData.keySystem = Some(mKeySystem);
|
||||
}
|
||||
glean::mfcdm::error.Record(Some(extraData));
|
||||
if (MOZ_LOG_TEST(gMediaDecoderLog, LogLevel::Debug)) {
|
||||
nsPrintfCString logMessage{"MFCDM Error event, error=%s",
|
||||
aError.ErrorName().get()};
|
||||
if (mInfo) {
|
||||
if (mInfo->HasAudio()) {
|
||||
logMessage.Append(
|
||||
nsPrintfCString{", audio=%s", mInfo->mAudio.mMimeType.get()});
|
||||
}
|
||||
if (mInfo->HasVideo()) {
|
||||
logMessage.Append(nsPrintfCString{", video=%s, resolution=%s",
|
||||
mInfo->mVideo.mMimeType.get(),
|
||||
resolution.get()});
|
||||
}
|
||||
}
|
||||
if (!mKeySystem.IsEmpty()) {
|
||||
logMessage.Append(nsPrintfCString{", keySystem=%s", mKeySystem.get()});
|
||||
}
|
||||
LOG("%s", logMessage.get());
|
||||
}
|
||||
}
|
||||
|
||||
#undef FMT
|
||||
#undef LOG
|
||||
#undef LOGV
|
||||
|
|
|
@ -291,6 +291,8 @@ class ExternalEngineStateMachine final
|
|||
|
||||
void RecoverFromCDMProcessCrashIfNeeded();
|
||||
|
||||
void ReportTelemetry(const MediaResult& aError);
|
||||
|
||||
UniquePtr<ExternalPlaybackEngine> mEngine;
|
||||
|
||||
bool mHasEnoughAudio = false;
|
||||
|
@ -304,6 +306,9 @@ class ExternalEngineStateMachine final
|
|||
|
||||
// It would be zero for audio-only playback.
|
||||
gfx::IntSize mVideoDisplay;
|
||||
|
||||
// It would be set if playback is encrypted.
|
||||
nsCString mKeySystem;
|
||||
};
|
||||
|
||||
class ExternalPlaybackEngine {
|
||||
|
|
|
@ -1225,4 +1225,28 @@ bool IsWaveMimetype(const nsACString& aMimeType) {
|
|||
aMimeType.EqualsLiteral("audio/wave; codecs=65534");
|
||||
}
|
||||
|
||||
void DetermineResolutionForTelemetry(const MediaInfo& aInfo,
|
||||
nsCString& aResolutionOut) {
|
||||
if (aInfo.HasAudio()) {
|
||||
aResolutionOut.AppendASCII("AV,");
|
||||
} else {
|
||||
aResolutionOut.AppendASCII("V,");
|
||||
}
|
||||
static const struct {
|
||||
int32_t mH;
|
||||
const char* mRes;
|
||||
} sResolutions[] = {{240, "0<h<=240"}, {480, "240<h<=480"},
|
||||
{576, "480<h<=576"}, {720, "576<h<=720"},
|
||||
{1080, "720<h<=1080"}, {2160, "1080<h<=2160"}};
|
||||
const char* resolution = "h>2160";
|
||||
int32_t height = aInfo.mVideo.mDisplay.height;
|
||||
for (const auto& res : sResolutions) {
|
||||
if (height <= res.mH) {
|
||||
resolution = res.mRes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
aResolutionOut.AppendASCII(resolution);
|
||||
}
|
||||
|
||||
} // end namespace mozilla
|
||||
|
|
|
@ -578,6 +578,9 @@ inline gfx::YUVColorSpace DefaultColorSpace(const gfx::IntSize& aSize) {
|
|||
|
||||
bool IsWaveMimetype(const nsACString& aMimeType);
|
||||
|
||||
void DetermineResolutionForTelemetry(const MediaInfo& aInfo,
|
||||
nsCString& aResolutionOut);
|
||||
|
||||
} // end namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,3 +48,41 @@ mfcdm:
|
|||
type: quantity
|
||||
expires: 130
|
||||
telemetry_mirror: Mfcdm_EmePlayback_Gecko
|
||||
error:
|
||||
type: event
|
||||
description:
|
||||
Record the error or crash happened while using the media engine playback.
|
||||
The value of this event is the name of error. This probe covers both EME
|
||||
and non-EME playback.
|
||||
metadata:
|
||||
tags:
|
||||
- 'Core :: Audio/Video: Playback'
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1873394
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1873394#c7
|
||||
data_sensitivity:
|
||||
- technical
|
||||
notification_emails:
|
||||
- media-alerts@mozilla.com
|
||||
extra_keys:
|
||||
error_name:
|
||||
description: The name of the error
|
||||
type: string
|
||||
current_state:
|
||||
description: The state of the external state machine was being used when the error or crash happened
|
||||
type: string
|
||||
audio_codec:
|
||||
description: The audio codec was being used when the error or crash happened
|
||||
type: string
|
||||
video_codec:
|
||||
description: The video codec was being used when the error or crash happened
|
||||
type: string
|
||||
resolution:
|
||||
description: The video resolution was being used when the error or crash happened
|
||||
type: string
|
||||
key_system:
|
||||
description: The key system was being used when the error or crash happened
|
||||
type: string
|
||||
expires: 130
|
||||
telemetry_mirror: Mfcdm_Error_Gecko
|
||||
|
|
|
@ -436,22 +436,8 @@ void TelemetryProbesReporter::ReportResultForVideo() {
|
|||
|
||||
// Keyed by audio+video or video alone, and by a resolution range.
|
||||
const MediaInfo& info = mOwner->GetMediaInfo();
|
||||
nsCString key(info.HasAudio() ? "AV," : "V,");
|
||||
static const struct {
|
||||
int32_t mH;
|
||||
const char* mRes;
|
||||
} sResolutions[] = {{240, "0<h<=240"}, {480, "240<h<=480"},
|
||||
{576, "480<h<=576"}, {720, "576<h<=720"},
|
||||
{1080, "720<h<=1080"}, {2160, "1080<h<=2160"}};
|
||||
const char* resolution = "h>2160";
|
||||
int32_t height = info.mVideo.mDisplay.height;
|
||||
for (const auto& res : sResolutions) {
|
||||
if (height <= res.mH) {
|
||||
resolution = res.mRes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
key.AppendASCII(resolution);
|
||||
nsCString key;
|
||||
DetermineResolutionForTelemetry(info, key);
|
||||
|
||||
auto visiblePlayTimeS = totalVideoPlayTimeS - invisiblePlayTimeS;
|
||||
LOG("VIDEO_VISIBLE_PLAY_TIME = %f, keys: '%s' and 'All'", visiblePlayTimeS,
|
||||
|
|
|
@ -3506,6 +3506,26 @@ mfcdm:
|
|||
played_time: The amount of time the EME content has been played (in seconds)
|
||||
rendered_frames: The amount of video frames has been rendered
|
||||
dropped_frames: The amount of video frames don't get rendered but dropped
|
||||
error:
|
||||
objects: ["gecko"]
|
||||
bug_numbers: [1873394]
|
||||
description:
|
||||
Record the error or crash happened while using the media engine playback.
|
||||
The value of this event is the name of error.
|
||||
products:
|
||||
- firefox
|
||||
record_in_processes: ["all"]
|
||||
release_channel_collection: opt-out
|
||||
expiry_version: "130"
|
||||
notification_emails:
|
||||
- media-alerts@mozilla.com
|
||||
extra_keys:
|
||||
error_name: The name of the error
|
||||
current_state: The state of the external state machine was being used when the error or crash happened
|
||||
video_codec: The video codec was being used when the error or crash happened
|
||||
audio_codec: The audio codec was being used when the error or crash happened
|
||||
resolution: The video resolution was being used when the error or crash happened
|
||||
key_system: The key system was being used when the error or crash happened
|
||||
|
||||
installation:
|
||||
first_seen:
|
||||
|
|
Загрузка…
Ссылка в новой задаче