Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: media/filters/ffmpeg_demuxer.cc

Issue 2846693002: Add UMA metrics for VideoCodec.MP4 and VideoCodec.WebM (Closed)
Patch Set: Add DCHECK(open_called_) Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | media/filters/ffmpeg_glue.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/ffmpeg_demuxer.h" 5 #include "media/filters/ffmpeg_demuxer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 51
52 namespace { 52 namespace {
53 53
54 void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) { 54 void SetAVStreamDiscard(AVStream* stream, AVDiscard discard) {
55 DCHECK(stream); 55 DCHECK(stream);
56 stream->discard = discard; 56 stream->discard = discard;
57 } 57 }
58 58
59 } // namespace 59 } // namespace
60 60
61 static base::Time ExtractTimelineOffset(AVFormatContext* format_context) { 61 static base::Time ExtractTimelineOffset(
62 if (strstr(format_context->iformat->name, "webm") || 62 container_names::MediaContainerName container,
63 strstr(format_context->iformat->name, "matroska")) { 63 const AVFormatContext* format_context) {
64 if (container == container_names::CONTAINER_WEBM) {
64 const AVDictionaryEntry* entry = 65 const AVDictionaryEntry* entry =
65 av_dict_get(format_context->metadata, "creation_time", NULL, 0); 66 av_dict_get(format_context->metadata, "creation_time", NULL, 0);
66 67
67 base::Time timeline_offset; 68 base::Time timeline_offset;
68 69
69 // FFmpegDemuxerTests assume base::Time::FromUTCString() is used here. 70 // FFmpegDemuxerTests assume base::Time::FromUTCString() is used here.
70 if (entry != NULL && entry->value != NULL && 71 if (entry != NULL && entry->value != NULL &&
71 base::Time::FromUTCString(entry->value, &timeline_offset)) { 72 base::Time::FromUTCString(entry->value, &timeline_offset)) {
72 return timeline_offset; 73 return timeline_offset;
73 } 74 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 if (ToAudioSampleRate(audio_config.samples_per_second(), &asr)) { 154 if (ToAudioSampleRate(audio_config.samples_per_second(), &asr)) {
154 UMA_HISTOGRAM_ENUMERATION("Media.AudioSamplesPerSecond", asr, 155 UMA_HISTOGRAM_ENUMERATION("Media.AudioSamplesPerSecond", asr,
155 kAudioSampleRateMax + 1); 156 kAudioSampleRateMax + 1);
156 } else { 157 } else {
157 UMA_HISTOGRAM_COUNTS("Media.AudioSamplesPerSecondUnexpected", 158 UMA_HISTOGRAM_COUNTS("Media.AudioSamplesPerSecondUnexpected",
158 audio_config.samples_per_second()); 159 audio_config.samples_per_second());
159 } 160 }
160 } 161 }
161 162
162 // Record video decoder config UMA stats corresponding to a src= playback. 163 // Record video decoder config UMA stats corresponding to a src= playback.
163 static void RecordVideoCodecStats(const VideoDecoderConfig& video_config, 164 static void RecordVideoCodecStats(container_names::MediaContainerName container,
165 const VideoDecoderConfig& video_config,
164 AVColorRange color_range, 166 AVColorRange color_range,
165 MediaLog* media_log) { 167 MediaLog* media_log) {
166 media_log->RecordRapporWithSecurityOrigin("Media.OriginUrl.SRC.VideoCodec." + 168 media_log->RecordRapporWithSecurityOrigin("Media.OriginUrl.SRC.VideoCodec." +
167 GetCodecName(video_config.codec())); 169 GetCodecName(video_config.codec()));
168 170
169 UMA_HISTOGRAM_ENUMERATION("Media.VideoCodec", video_config.codec(), 171 UMA_HISTOGRAM_ENUMERATION("Media.VideoCodec", video_config.codec(),
170 kVideoCodecMax + 1); 172 kVideoCodecMax + 1);
173 if (container == container_names::CONTAINER_MOV) {
174 UMA_HISTOGRAM_ENUMERATION("Media.VideoCodec.MP4", video_config.codec(),
xhwang 2017/05/03 05:33:45 Shall we just name this Media.SRC.VideoCodec.MP4 t
wolenetz 2017/05/03 20:48:23 I don't recall the previous reason why we didn't d
175 kVideoCodecMax + 1);
176 } else if (container == container_names::CONTAINER_WEBM) {
177 UMA_HISTOGRAM_ENUMERATION("Media.VideoCodec.WebM", video_config.codec(),
178 kVideoCodecMax + 1);
179 }
171 180
172 // Drop UNKNOWN because U_H_E() uses one bucket for all values less than 1. 181 // Drop UNKNOWN because U_H_E() uses one bucket for all values less than 1.
173 if (video_config.profile() >= 0) { 182 if (video_config.profile() >= 0) {
174 UMA_HISTOGRAM_ENUMERATION("Media.VideoCodecProfile", video_config.profile(), 183 UMA_HISTOGRAM_ENUMERATION("Media.VideoCodecProfile", video_config.profile(),
175 VIDEO_CODEC_PROFILE_MAX + 1); 184 VIDEO_CODEC_PROFILE_MAX + 1);
176 } 185 }
177 UMA_HISTOGRAM_COUNTS_10000("Media.VideoVisibleWidth", 186 UMA_HISTOGRAM_COUNTS_10000("Media.VideoVisibleWidth",
178 video_config.visible_rect().width()); 187 video_config.visible_rect().width());
179 UmaHistogramAspectRatio("Media.VideoVisibleAspectRatio", 188 UmaHistogramAspectRatio("Media.VideoVisibleAspectRatio",
180 video_config.visible_rect()); 189 video_config.visible_rect());
(...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 1344
1336 // This AVStream does not successfully convert. 1345 // This AVStream does not successfully convert.
1337 continue; 1346 continue;
1338 } 1347 }
1339 1348
1340 StreamParser::TrackId track_id = stream->id; 1349 StreamParser::TrackId track_id = stream->id;
1341 std::string track_label = streams_[i]->GetMetadata("handler_name"); 1350 std::string track_label = streams_[i]->GetMetadata("handler_name");
1342 std::string track_language = streams_[i]->GetMetadata("language"); 1351 std::string track_language = streams_[i]->GetMetadata("language");
1343 1352
1344 // Some metadata is named differently in FFmpeg for webm files. 1353 // Some metadata is named differently in FFmpeg for webm files.
1345 if (strstr(format_context->iformat->name, "webm") || 1354 if (glue_->container() == container_names::CONTAINER_WEBM) {
1346 strstr(format_context->iformat->name, "matroska")) {
1347 // TODO(servolk): FFmpeg doesn't set stream->id correctly for webm files. 1355 // TODO(servolk): FFmpeg doesn't set stream->id correctly for webm files.
1348 // Need to fix that and use it as track id. crbug.com/323183 1356 // Need to fix that and use it as track id. crbug.com/323183
1349 track_id = 1357 track_id =
1350 static_cast<StreamParser::TrackId>(media_tracks->tracks().size() + 1); 1358 static_cast<StreamParser::TrackId>(media_tracks->tracks().size() + 1);
1351 track_label = streams_[i]->GetMetadata("title"); 1359 track_label = streams_[i]->GetMetadata("title");
1352 } 1360 }
1353 1361
1354 if (codec_type == AVMEDIA_TYPE_AUDIO) { 1362 if (codec_type == AVMEDIA_TYPE_AUDIO) {
1355 streams_[i]->SetEnabled(detected_audio_track_count == 1, 1363 streams_[i]->SetEnabled(detected_audio_track_count == 1,
1356 base::TimeDelta()); 1364 base::TimeDelta());
(...skipping 21 matching lines...) Expand all
1378 1386
1379 media_track = media_tracks->AddAudioTrack(audio_config, track_id, "main", 1387 media_track = media_tracks->AddAudioTrack(audio_config, track_id, "main",
1380 track_label, track_language); 1388 track_label, track_language);
1381 media_track->set_id(base::UintToString(track_id)); 1389 media_track->set_id(base::UintToString(track_id));
1382 DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) == 1390 DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) ==
1383 track_id_to_demux_stream_map_.end()); 1391 track_id_to_demux_stream_map_.end());
1384 track_id_to_demux_stream_map_[media_track->id()] = streams_[i].get(); 1392 track_id_to_demux_stream_map_[media_track->id()] = streams_[i].get();
1385 } else if (codec_type == AVMEDIA_TYPE_VIDEO) { 1393 } else if (codec_type == AVMEDIA_TYPE_VIDEO) {
1386 VideoDecoderConfig video_config = streams_[i]->video_decoder_config(); 1394 VideoDecoderConfig video_config = streams_[i]->video_decoder_config();
1387 1395
1388 RecordVideoCodecStats(video_config, stream->codecpar->color_range, 1396 RecordVideoCodecStats(glue_->container(), video_config,
1389 media_log_); 1397 stream->codecpar->color_range, media_log_);
1390 1398
1391 media_track = media_tracks->AddVideoTrack(video_config, track_id, "main", 1399 media_track = media_tracks->AddVideoTrack(video_config, track_id, "main",
1392 track_label, track_language); 1400 track_label, track_language);
1393 media_track->set_id(base::UintToString(track_id)); 1401 media_track->set_id(base::UintToString(track_id));
1394 DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) == 1402 DCHECK(track_id_to_demux_stream_map_.find(media_track->id()) ==
1395 track_id_to_demux_stream_map_.end()); 1403 track_id_to_demux_stream_map_.end());
1396 track_id_to_demux_stream_map_[media_track->id()] = streams_[i].get(); 1404 track_id_to_demux_stream_map_[media_track->id()] = streams_[i].get();
1397 } 1405 }
1398 1406
1399 max_duration = std::max(max_duration, streams_[i]->duration()); 1407 max_duration = std::max(max_duration, streams_[i]->duration());
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 // 1455 //
1448 // FFmpeg's use of negative timestamps for opus pre-skip is nonstandard, but 1456 // FFmpeg's use of negative timestamps for opus pre-skip is nonstandard, but
1449 // for more information on pre-skip see section 4.2 of the Ogg Opus spec: 1457 // for more information on pre-skip see section 4.2 of the Ogg Opus spec:
1450 // https://tools.ietf.org/html/draft-ietf-codec-oggopus-08#section-4.2 1458 // https://tools.ietf.org/html/draft-ietf-codec-oggopus-08#section-4.2
1451 for (const auto& stream : streams_) { 1459 for (const auto& stream : streams_) {
1452 if (!stream || stream->type() != DemuxerStream::AUDIO) 1460 if (!stream || stream->type() != DemuxerStream::AUDIO)
1453 continue; 1461 continue;
1454 const AVStream* audio_stream = stream->av_stream(); 1462 const AVStream* audio_stream = stream->av_stream();
1455 DCHECK(audio_stream); 1463 DCHECK(audio_stream);
1456 if (audio_stream->codecpar->codec_id == AV_CODEC_ID_OPUS || 1464 if (audio_stream->codecpar->codec_id == AV_CODEC_ID_OPUS ||
1457 (strcmp(format_context->iformat->name, "ogg") == 0 && 1465 (glue_->container() == container_names::CONTAINER_OGG &&
1458 audio_stream->codecpar->codec_id == AV_CODEC_ID_VORBIS)) { 1466 audio_stream->codecpar->codec_id == AV_CODEC_ID_VORBIS)) {
1459 for (size_t i = 0; i < streams_.size(); ++i) { 1467 for (size_t i = 0; i < streams_.size(); ++i) {
1460 if (!streams_[i]) 1468 if (!streams_[i])
1461 continue; 1469 continue;
1462 streams_[i]->enable_negative_timestamp_fixups(); 1470 streams_[i]->enable_negative_timestamp_fixups();
1463 1471
1464 // Fixup the seeking information to avoid selecting the audio stream 1472 // Fixup the seeking information to avoid selecting the audio stream
1465 // simply because it has a lower starting time. 1473 // simply because it has a lower starting time.
1466 if (streams_[i]->av_stream() == audio_stream && 1474 if (streams_[i]->av_stream() == audio_stream &&
1467 streams_[i]->start_time() < base::TimeDelta()) { 1475 streams_[i]->start_time() < base::TimeDelta()) {
1468 streams_[i]->set_start_time(base::TimeDelta()); 1476 streams_[i]->set_start_time(base::TimeDelta());
1469 } 1477 }
1470 } 1478 }
1471 } 1479 }
1472 } 1480 }
1473 1481
1474 // If no start time could be determined, default to zero. 1482 // If no start time could be determined, default to zero.
1475 if (start_time_ == kInfiniteDuration) { 1483 if (start_time_ == kInfiniteDuration) {
1476 start_time_ = base::TimeDelta(); 1484 start_time_ = base::TimeDelta();
1477 } 1485 }
1478 1486
1479 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS 1487 // MPEG-4 B-frames cause grief for a simple container like AVI. Enable PTS
1480 // generation so we always get timestamps, see http://crbug.com/169570 1488 // generation so we always get timestamps, see http://crbug.com/169570
1481 if (strcmp(format_context->iformat->name, "avi") == 0) 1489 if (glue_->container() == container_names::CONTAINER_AVI)
1482 format_context->flags |= AVFMT_FLAG_GENPTS; 1490 format_context->flags |= AVFMT_FLAG_GENPTS;
1483 1491
1484 // For testing purposes, don't overwrite the timeline offset if set already. 1492 // For testing purposes, don't overwrite the timeline offset if set already.
1485 if (timeline_offset_.is_null()) 1493 if (timeline_offset_.is_null()) {
1486 timeline_offset_ = ExtractTimelineOffset(format_context); 1494 timeline_offset_ =
1495 ExtractTimelineOffset(glue_->container(), format_context);
1496 }
1487 1497
1488 // Since we're shifting the externally visible start time to zero, we need to 1498 // Since we're shifting the externally visible start time to zero, we need to
1489 // adjust the timeline offset to compensate. 1499 // adjust the timeline offset to compensate.
1490 if (!timeline_offset_.is_null() && start_time_ < base::TimeDelta()) 1500 if (!timeline_offset_.is_null() && start_time_ < base::TimeDelta())
1491 timeline_offset_ += start_time_; 1501 timeline_offset_ += start_time_;
1492 1502
1493 if (max_duration == kInfiniteDuration && !timeline_offset_.is_null()) { 1503 if (max_duration == kInfiniteDuration && !timeline_offset_.is_null()) {
1494 SetLiveness(DemuxerStream::LIVENESS_LIVE); 1504 SetLiveness(DemuxerStream::LIVENESS_LIVE);
1495 } else if (max_duration != kInfiniteDuration) { 1505 } else if (max_duration != kInfiniteDuration) {
1496 SetLiveness(DemuxerStream::LIVENESS_RECORDED); 1506 SetLiveness(DemuxerStream::LIVENESS_RECORDED);
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 1891
1882 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) { 1892 void FFmpegDemuxer::SetLiveness(DemuxerStream::Liveness liveness) {
1883 DCHECK(task_runner_->BelongsToCurrentThread()); 1893 DCHECK(task_runner_->BelongsToCurrentThread());
1884 for (const auto& stream : streams_) { 1894 for (const auto& stream : streams_) {
1885 if (stream) 1895 if (stream)
1886 stream->SetLiveness(liveness); 1896 stream->SetLiveness(liveness);
1887 } 1897 }
1888 } 1898 }
1889 1899
1890 } // namespace media 1900 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | media/filters/ffmpeg_glue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698