Commit 02b14ba0 authored by kqyang's avatar kqyang Committed by Commit bot

Add UMA metrics for Media.{SRC,MSE}.VideoCodec.{MP4,WebM}

BUG=715161
TEST=Manually tested with SRC/MSE playback (then checked about:://histograms)

Review-Url: https://codereview.chromium.org/2846693002
Cr-Commit-Position: refs/heads/master@{#469469}
parent d817ddec
...@@ -58,9 +58,10 @@ void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) { ...@@ -58,9 +58,10 @@ void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) {
} // namespace } // namespace
static base::Time ExtractTimelineOffset(AVFormatContext* format_context) { static base::Time ExtractTimelineOffset(
if (strstr(format_context->iformat->name, "webm") || container_names::MediaContainerName container,
strstr(format_context->iformat->name, "matroska")) { const AVFormatContext* format_context) {
if (container == container_names::CONTAINER_WEBM) {
const AVDictionaryEntry* entry = const AVDictionaryEntry* entry =
av_dict_get(format_context->metadata, "creation_time", NULL, 0); av_dict_get(format_context->metadata, "creation_time", NULL, 0);
...@@ -160,14 +161,24 @@ static void RecordAudioCodecStats(const AudioDecoderConfig& audio_config) { ...@@ -160,14 +161,24 @@ static void RecordAudioCodecStats(const AudioDecoderConfig& audio_config) {
} }
// Record video decoder config UMA stats corresponding to a src= playback. // Record video decoder config UMA stats corresponding to a src= playback.
static void RecordVideoCodecStats(const VideoDecoderConfig& video_config, static void RecordVideoCodecStats(container_names::MediaContainerName container,
const VideoDecoderConfig& video_config,
AVColorRange color_range, AVColorRange color_range,
MediaLog* media_log) { MediaLog* media_log) {
media_log->RecordRapporWithSecurityOrigin("Media.OriginUrl.SRC.VideoCodec." + media_log->RecordRapporWithSecurityOrigin("Media.OriginUrl.SRC.VideoCodec." +
GetCodecName(video_config.codec())); GetCodecName(video_config.codec()));
// TODO(xhwang): Fix these misleading metric names. They should be something
// like "Media.SRC.Xxxx". See http://crbug.com/716183.
UMA_HISTOGRAM_ENUMERATION("Media.VideoCodec", video_config.codec(), UMA_HISTOGRAM_ENUMERATION("Media.VideoCodec", video_config.codec(),
kVideoCodecMax + 1); kVideoCodecMax + 1);
if (container == container_names::CONTAINER_MOV) {
UMA_HISTOGRAM_ENUMERATION("Media.SRC.VideoCodec.MP4", video_config.codec(),
kVideoCodecMax + 1);
} else if (container == container_names::CONTAINER_WEBM) {
UMA_HISTOGRAM_ENUMERATION("Media.SRC.VideoCodec.WebM", video_config.codec(),
kVideoCodecMax + 1);
}
// Drop UNKNOWN because U_H_E() uses one bucket for all values less than 1. // Drop UNKNOWN because U_H_E() uses one bucket for all values less than 1.
if (video_config.profile() >= 0) { if (video_config.profile() >= 0) {
...@@ -1342,8 +1353,7 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, ...@@ -1342,8 +1353,7 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
std::string track_language = streams_[i]->GetMetadata("language"); std::string track_language = streams_[i]->GetMetadata("language");
// Some metadata is named differently in FFmpeg for webm files. // Some metadata is named differently in FFmpeg for webm files.
if (strstr(format_context->iformat->name, "webm") || if (glue_->container() == container_names::CONTAINER_WEBM) {
strstr(format_context->iformat->name, "matroska")) {
// TODO(servolk): FFmpeg doesn't set stream->id correctly for webm files. // TODO(servolk): FFmpeg doesn't set stream->id correctly for webm files.
// Need to fix that and use it as track id. crbug.com/323183 // Need to fix that and use it as track id. crbug.com/323183
track_id = track_id =
...@@ -1385,8 +1395,8 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, ...@@ -1385,8 +1395,8 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
} else if (codec_type == AVMEDIA_TYPE_VIDEO) { } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
VideoDecoderConfig video_config = streams_[i]->video_decoder_config(); VideoDecoderConfig video_config = streams_[i]->video_decoder_config();
RecordVideoCodecStats(video_config, stream->codecpar->color_range, RecordVideoCodecStats(glue_->container(), video_config,
media_log_); stream->codecpar->color_range, media_log_);
media_track = media_tracks->AddVideoTrack(video_config, track_id, "main", media_track = media_tracks->AddVideoTrack(video_config, track_id, "main",
track_label, track_language); track_label, track_language);
...@@ -1454,7 +1464,7 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, ...@@ -1454,7 +1464,7 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
const AVStream* audio_stream = stream->av_stream(); const AVStream* audio_stream = stream->av_stream();
DCHECK(audio_stream); DCHECK(audio_stream);
if (audio_stream->codecpar->codec_id == AV_CODEC_ID_OPUS || if (audio_stream->codecpar->codec_id == AV_CODEC_ID_OPUS ||
(strcmp(format_context->iformat->name, "ogg") == 0 && (glue_->container() == container_names::CONTAINER_OGG &&
audio_stream->codecpar->codec_id == AV_CODEC_ID_VORBIS)) { audio_stream->codecpar->codec_id == AV_CODEC_ID_VORBIS)) {
for (size_t i = 0; i < streams_.size(); ++i) { for (size_t i = 0; i < streams_.size(); ++i) {
if (!streams_[i]) if (!streams_[i])
...@@ -1478,12 +1488,14 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb, ...@@ -1478,12 +1488,14 @@ void FFmpegDemuxer::OnFindStreamInfoDone(const PipelineStatusCB& status_cb,
// MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
// generation so we always get timestamps, see http://crbug.com/169570 // generation so we always get timestamps, see http://crbug.com/169570
if (strcmp(format_context->iformat->name, "avi") == 0) if (glue_->container() == container_names::CONTAINER_AVI)
format_context->flags |= AVFMT_FLAG_GENPTS; format_context->flags |= AVFMT_FLAG_GENPTS;
// For testing purposes, don't overwrite the timeline offset if set already. // For testing purposes, don't overwrite the timeline offset if set already.
if (timeline_offset_.is_null()) if (timeline_offset_.is_null()) {
timeline_offset_ = ExtractTimelineOffset(format_context); timeline_offset_ =
ExtractTimelineOffset(glue_->container(), format_context);
}
// Since we're shifting the externally visible start time to zero, we need to // Since we're shifting the externally visible start time to zero, we need to
// adjust the timeline offset to compensate. // adjust the timeline offset to compensate.
......
...@@ -100,8 +100,7 @@ void FFmpegGlue::InitializeFFmpeg() { ...@@ -100,8 +100,7 @@ void FFmpegGlue::InitializeFFmpeg() {
CHECK(initialized); CHECK(initialized);
} }
FFmpegGlue::FFmpegGlue(FFmpegURLProtocol* protocol) FFmpegGlue::FFmpegGlue(FFmpegURLProtocol* protocol) {
: open_called_(false) {
InitializeFFmpeg(); InitializeFFmpeg();
// Initialize an AVIOContext using our custom read and seek operations. Don't // Initialize an AVIOContext using our custom read and seek operations. Don't
...@@ -157,41 +156,38 @@ bool FFmpegGlue::OpenContext() { ...@@ -157,41 +156,38 @@ bool FFmpegGlue::OpenContext() {
if (num_read < container_names::kMinimumContainerSize) if (num_read < container_names::kMinimumContainerSize)
return false; return false;
UMA_HISTOGRAM_SPARSE_SLOWLY( container_ = container_names::DetermineContainer(buffer.data(), num_read);
"Media.DetectedContainer", UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedContainer", container_);
container_names::DetermineContainer(buffer.data(), num_read));
return false; return false;
} else if (ret < 0) { } else if (ret < 0) {
return false; return false;
} }
// Rely on ffmpeg's parsing if we're able to succesfully open the file. // Rely on ffmpeg's parsing if we're able to succesfully open the file.
container_names::MediaContainerName container =
container_names::CONTAINER_UNKNOWN;
if (strcmp(format_context_->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0) if (strcmp(format_context_->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0)
container = container_names::CONTAINER_MOV; container_ = container_names::CONTAINER_MOV;
else if (strcmp(format_context_->iformat->name, "flac") == 0) else if (strcmp(format_context_->iformat->name, "flac") == 0)
container = container_names::CONTAINER_FLAC; container_ = container_names::CONTAINER_FLAC;
else if (strcmp(format_context_->iformat->name, "matroska,webm") == 0) else if (strcmp(format_context_->iformat->name, "matroska,webm") == 0)
container = container_names::CONTAINER_WEBM; container_ = container_names::CONTAINER_WEBM;
else if (strcmp(format_context_->iformat->name, "ogg") == 0) else if (strcmp(format_context_->iformat->name, "ogg") == 0)
container = container_names::CONTAINER_OGG; container_ = container_names::CONTAINER_OGG;
else if (strcmp(format_context_->iformat->name, "wav") == 0) else if (strcmp(format_context_->iformat->name, "wav") == 0)
container = container_names::CONTAINER_WAV; container_ = container_names::CONTAINER_WAV;
else if (strcmp(format_context_->iformat->name, "aac") == 0) else if (strcmp(format_context_->iformat->name, "aac") == 0)
container = container_names::CONTAINER_AAC; container_ = container_names::CONTAINER_AAC;
else if (strcmp(format_context_->iformat->name, "mp3") == 0) else if (strcmp(format_context_->iformat->name, "mp3") == 0)
container = container_names::CONTAINER_MP3; container_ = container_names::CONTAINER_MP3;
else if (strcmp(format_context_->iformat->name, "amr") == 0) else if (strcmp(format_context_->iformat->name, "amr") == 0)
container = container_names::CONTAINER_AMR; container_ = container_names::CONTAINER_AMR;
else if (strcmp(format_context_->iformat->name, "avi") == 0) else if (strcmp(format_context_->iformat->name, "avi") == 0)
container = container_names::CONTAINER_AVI; container_ = container_names::CONTAINER_AVI;
// TODO(jrummell): Remove GSM detection. http://crbug.com/711774 // TODO(jrummell): Remove GSM detection. http://crbug.com/711774
else if (strcmp(format_context_->iformat->name, "gsm") == 0) else if (strcmp(format_context_->iformat->name, "gsm") == 0)
container = container_names::CONTAINER_GSM; container_ = container_names::CONTAINER_GSM;
DCHECK_NE(container, container_names::CONTAINER_UNKNOWN); DCHECK_NE(container_, container_names::CONTAINER_UNKNOWN);
UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedContainer", container); UMA_HISTOGRAM_SPARSE_SLOWLY("Media.DetectedContainer", container_);
return true; return true;
} }
......
...@@ -29,7 +29,9 @@ ...@@ -29,7 +29,9 @@
#include <memory> #include <memory>
#include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "media/base/container_names.h"
#include "media/base/media_export.h" #include "media/base/media_export.h"
#include "media/ffmpeg/ffmpeg_deleters.h" #include "media/ffmpeg/ffmpeg_deleters.h"
...@@ -71,11 +73,19 @@ class MEDIA_EXPORT FFmpegGlue { ...@@ -71,11 +73,19 @@ class MEDIA_EXPORT FFmpegGlue {
// through the FFmpegURLProtocol provided during construction. // through the FFmpegURLProtocol provided during construction.
bool OpenContext(); bool OpenContext();
AVFormatContext* format_context() { return format_context_; } AVFormatContext* format_context() { return format_context_; }
// Returns the container name.
// Note that it is only available after calling OpenContext.
container_names::MediaContainerName container() const {
DCHECK(open_called_);
return container_;
}
private: private:
bool open_called_; bool open_called_ = false;
AVFormatContext* format_context_; AVFormatContext* format_context_ = nullptr;
std::unique_ptr<AVIOContext, ScopedPtrAVFree> avio_context_; std::unique_ptr<AVIOContext, ScopedPtrAVFree> avio_context_;
container_names::MediaContainerName container_ =
container_names::CONTAINER_UNKNOWN;
DISALLOW_COPY_AND_ASSIGN(FFmpegGlue); DISALLOW_COPY_AND_ASSIGN(FFmpegGlue);
}; };
......
...@@ -491,6 +491,13 @@ std::unique_ptr<StreamParser> StreamParserFactory::Create( ...@@ -491,6 +491,13 @@ std::unique_ptr<StreamParser> StreamParserFactory::Create(
UMA_HISTOGRAM_ENUMERATION("Media.MSE.VideoCodec", UMA_HISTOGRAM_ENUMERATION("Media.MSE.VideoCodec",
video_codecs[i], video_codecs[i],
CodecInfo::HISTOGRAM_MAX + 1); CodecInfo::HISTOGRAM_MAX + 1);
if (type == "video/mp4") {
UMA_HISTOGRAM_ENUMERATION("Media.MSE.VideoCodec.MP4", video_codecs[i],
CodecInfo::HISTOGRAM_MAX + 1);
} else if (type == "video/webm") {
UMA_HISTOGRAM_ENUMERATION("Media.MSE.VideoCodec.WebM", video_codecs[i],
CodecInfo::HISTOGRAM_MAX + 1);
}
} }
stream_parser.reset(factory_function(codecs, media_log)); stream_parser.reset(factory_function(codecs, media_log));
......
...@@ -27941,6 +27941,22 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. ...@@ -27941,6 +27941,22 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</summary> </summary>
</histogram> </histogram>
<histogram name="Media.MSE.VideoCodec.MP4" enum="MSECodec">
<owner>media-dev@chromium.org</owner>
<summary>
Video codec used in Media Source Extensions playback if the media container
is MP4. Set when AddId() is called during playback.
</summary>
</histogram>
<histogram name="Media.MSE.VideoCodec.WebM" enum="MSECodec">
<owner>media-dev@chromium.org</owner>
<summary>
Video codec used in Media Source Extensions playback if the media container
is WebM. Set when AddId() is called during playback.
</summary>
</histogram>
<histogram name="Media.Netflix.AudioBitrate" units="kbps"> <histogram name="Media.Netflix.AudioBitrate" units="kbps">
<obsolete> <obsolete>
Deprecated 04/2016 as doesn't have data nor owner. Deprecated 04/2016 as doesn't have data nor owner.
...@@ -28307,6 +28323,22 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. ...@@ -28307,6 +28323,22 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</summary> </summary>
</histogram> </histogram>
<histogram name="Media.SRC.VideoCodec.MP4" enum="VideoCodec">
<owner>media-dev@chromium.org</owner>
<summary>
Video codec used in plain src= (not MSE) HTML5 media if the media container
is MP4.
</summary>
</histogram>
<histogram name="Media.SRC.VideoCodec.WebM" enum="VideoCodec">
<owner>media-dev@chromium.org</owner>
<summary>
Video codec used in plain src= (not MSE) HTML5 media if the media container
is WebM.
</summary>
</histogram>
<histogram base="true" name="Media.Timeline.DragGestureDuration" units="ms"> <histogram base="true" name="Media.Timeline.DragGestureDuration" units="ms">
<!-- Name completed by histogram_suffixes name="MediaTimelineWidths" --> <!-- Name completed by histogram_suffixes name="MediaTimelineWidths" -->
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment