OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/stream_parser_factory.h" | 5 #include "media/filters/stream_parser_factory.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 #if BUILDFLAG(USE_PROPRIETARY_CODECS) | 28 #if BUILDFLAG(USE_PROPRIETARY_CODECS) |
29 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) | 29 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) |
30 #include "media/formats/mp2t/mp2t_stream_parser.h" | 30 #include "media/formats/mp2t/mp2t_stream_parser.h" |
31 #endif | 31 #endif |
32 #include "media/formats/mp4/es_descriptor.h" | 32 #include "media/formats/mp4/es_descriptor.h" |
33 #include "media/formats/mp4/mp4_stream_parser.h" | 33 #include "media/formats/mp4/mp4_stream_parser.h" |
34 #endif | 34 #endif |
35 | 35 |
36 namespace media { | 36 namespace media { |
37 | 37 |
38 typedef bool (*CodecIDValidatorFunction)( | 38 typedef bool (*CodecIDValidatorFunction)(const std::string& codecs_id, |
39 const std::string& codecs_id, | 39 MediaLog* media_log); |
40 const scoped_refptr<MediaLog>& media_log); | |
41 | 40 |
42 struct CodecInfo { | 41 struct CodecInfo { |
43 enum Type { | 42 enum Type { |
44 UNKNOWN, | 43 UNKNOWN, |
45 AUDIO, | 44 AUDIO, |
46 VIDEO | 45 VIDEO |
47 }; | 46 }; |
48 | 47 |
49 // Update tools/metrics/histograms/histograms.xml if new values are added. | 48 // Update tools/metrics/histograms/histograms.xml if new values are added. |
50 enum HistogramTag { | 49 enum HistogramTag { |
(...skipping 15 matching lines...) Expand all Loading... |
66 }; | 65 }; |
67 | 66 |
68 const char* pattern; | 67 const char* pattern; |
69 Type type; | 68 Type type; |
70 CodecIDValidatorFunction validator; | 69 CodecIDValidatorFunction validator; |
71 HistogramTag tag; | 70 HistogramTag tag; |
72 }; | 71 }; |
73 | 72 |
74 typedef StreamParser* (*ParserFactoryFunction)( | 73 typedef StreamParser* (*ParserFactoryFunction)( |
75 const std::vector<std::string>& codecs, | 74 const std::vector<std::string>& codecs, |
76 const scoped_refptr<MediaLog>& media_log); | 75 MediaLog* media_log); |
77 | 76 |
78 struct SupportedTypeInfo { | 77 struct SupportedTypeInfo { |
79 const char* type; | 78 const char* type; |
80 const ParserFactoryFunction factory_function; | 79 const ParserFactoryFunction factory_function; |
81 const CodecInfo** codecs; | 80 const CodecInfo** codecs; |
82 }; | 81 }; |
83 | 82 |
84 static const CodecInfo kVP8CodecInfo = { "vp8", CodecInfo::VIDEO, NULL, | 83 static const CodecInfo kVP8CodecInfo = { "vp8", CodecInfo::VIDEO, NULL, |
85 CodecInfo::HISTOGRAM_VP8 }; | 84 CodecInfo::HISTOGRAM_VP8 }; |
86 static const CodecInfo kLegacyVP9CodecInfo = {"vp9", CodecInfo::VIDEO, NULL, | 85 static const CodecInfo kLegacyVP9CodecInfo = {"vp9", CodecInfo::VIDEO, NULL, |
87 CodecInfo::HISTOGRAM_VP9}; | 86 CodecInfo::HISTOGRAM_VP9}; |
88 static const CodecInfo kVP9CodecInfo = {"vp09.*", CodecInfo::VIDEO, NULL, | 87 static const CodecInfo kVP9CodecInfo = {"vp09.*", CodecInfo::VIDEO, NULL, |
89 CodecInfo::HISTOGRAM_VP9}; | 88 CodecInfo::HISTOGRAM_VP9}; |
90 static const CodecInfo kVorbisCodecInfo = { "vorbis", CodecInfo::AUDIO, NULL, | 89 static const CodecInfo kVorbisCodecInfo = { "vorbis", CodecInfo::AUDIO, NULL, |
91 CodecInfo::HISTOGRAM_VORBIS }; | 90 CodecInfo::HISTOGRAM_VORBIS }; |
92 static const CodecInfo kOpusCodecInfo = { "opus", CodecInfo::AUDIO, NULL, | 91 static const CodecInfo kOpusCodecInfo = { "opus", CodecInfo::AUDIO, NULL, |
93 CodecInfo::HISTOGRAM_OPUS }; | 92 CodecInfo::HISTOGRAM_OPUS }; |
94 | 93 |
95 static const CodecInfo* kVideoWebMCodecs[] = { | 94 static const CodecInfo* kVideoWebMCodecs[] = { |
96 &kVP8CodecInfo, &kLegacyVP9CodecInfo, &kVP9CodecInfo, | 95 &kVP8CodecInfo, &kLegacyVP9CodecInfo, &kVP9CodecInfo, |
97 &kVorbisCodecInfo, &kOpusCodecInfo, NULL}; | 96 &kVorbisCodecInfo, &kOpusCodecInfo, NULL}; |
98 | 97 |
99 static const CodecInfo* kAudioWebMCodecs[] = { | 98 static const CodecInfo* kAudioWebMCodecs[] = { |
100 &kVorbisCodecInfo, | 99 &kVorbisCodecInfo, |
101 &kOpusCodecInfo, | 100 &kOpusCodecInfo, |
102 NULL | 101 NULL |
103 }; | 102 }; |
104 | 103 |
105 static StreamParser* BuildWebMParser(const std::vector<std::string>& codecs, | 104 static StreamParser* BuildWebMParser(const std::vector<std::string>& codecs, |
106 const scoped_refptr<MediaLog>& media_log) { | 105 MediaLog* media_log) { |
107 return new WebMStreamParser(); | 106 return new WebMStreamParser(); |
108 } | 107 } |
109 | 108 |
110 #if BUILDFLAG(USE_PROPRIETARY_CODECS) | 109 #if BUILDFLAG(USE_PROPRIETARY_CODECS) |
111 bool CheckIfMp4Vp9DemuxingEnabled(const std::string& codec_id, | 110 bool CheckIfMp4Vp9DemuxingEnabled(const std::string& codec_id, |
112 const scoped_refptr<MediaLog>& media_log) { | 111 MediaLog* media_log) { |
113 return base::CommandLine::ForCurrentProcess()->HasSwitch( | 112 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
114 switches::kEnableVp9InMp4); | 113 switches::kEnableVp9InMp4); |
115 } | 114 } |
116 | 115 |
117 // AAC Object Type IDs that Chrome supports. | 116 // AAC Object Type IDs that Chrome supports. |
118 static const int kAACLCObjectType = 2; | 117 static const int kAACLCObjectType = 2; |
119 static const int kAACSBRObjectType = 5; | 118 static const int kAACSBRObjectType = 5; |
120 static const int kAACPSObjectType = 29; | 119 static const int kAACPSObjectType = 29; |
121 | 120 |
122 static int GetMP4AudioObjectType(const std::string& codec_id, | 121 static int GetMP4AudioObjectType(const std::string& codec_id, |
123 const scoped_refptr<MediaLog>& media_log) { | 122 MediaLog* media_log) { |
124 // From RFC 6381 section 3.3 (ISO Base Media File Format Name Space): | 123 // From RFC 6381 section 3.3 (ISO Base Media File Format Name Space): |
125 // When the first element of a ['codecs' parameter value] is 'mp4a' ..., | 124 // When the first element of a ['codecs' parameter value] is 'mp4a' ..., |
126 // the second element is a hexadecimal representation of the MP4 Registration | 125 // the second element is a hexadecimal representation of the MP4 Registration |
127 // Authority ObjectTypeIndication (OTI). Note that MP4RA uses a leading "0x" | 126 // Authority ObjectTypeIndication (OTI). Note that MP4RA uses a leading "0x" |
128 // with these values, which is omitted here and hence implied. | 127 // with these values, which is omitted here and hence implied. |
129 std::vector<base::StringPiece> tokens = base::SplitStringPiece( | 128 std::vector<base::StringPiece> tokens = base::SplitStringPiece( |
130 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | 129 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
131 if (tokens.size() == 3 && tokens[0] == "mp4a" && tokens[1] == "40") { | 130 if (tokens.size() == 3 && tokens[0] == "mp4a" && tokens[1] == "40") { |
132 // From RFC 6381 section 3.3: | 131 // From RFC 6381 section 3.3: |
133 // One of the OTI values for 'mp4a' is 40 (identifying MPEG-4 audio). For | 132 // One of the OTI values for 'mp4a' is 40 (identifying MPEG-4 audio). For |
134 // this value, the third element identifies the audio ObjectTypeIndication | 133 // this value, the third element identifies the audio ObjectTypeIndication |
135 // (OTI) ... expressed as a decimal number. | 134 // (OTI) ... expressed as a decimal number. |
136 int audio_object_type; | 135 int audio_object_type; |
137 if (base::StringToInt(tokens[2], &audio_object_type)) | 136 if (base::StringToInt(tokens[2], &audio_object_type)) |
138 return audio_object_type; | 137 return audio_object_type; |
139 } | 138 } |
140 | 139 |
141 MEDIA_LOG(DEBUG, media_log) << "Malformed mimetype codec '" << codec_id | 140 MEDIA_LOG(DEBUG, media_log) << "Malformed mimetype codec '" << codec_id |
142 << "'"; | 141 << "'"; |
143 return -1; | 142 return -1; |
144 } | 143 } |
145 | 144 |
146 bool ValidateMP4ACodecID(const std::string& codec_id, | 145 bool ValidateMP4ACodecID(const std::string& codec_id, MediaLog* media_log) { |
147 const scoped_refptr<MediaLog>& media_log) { | |
148 int audio_object_type = GetMP4AudioObjectType(codec_id, media_log); | 146 int audio_object_type = GetMP4AudioObjectType(codec_id, media_log); |
149 if (audio_object_type == kAACLCObjectType || | 147 if (audio_object_type == kAACLCObjectType || |
150 audio_object_type == kAACSBRObjectType || | 148 audio_object_type == kAACSBRObjectType || |
151 audio_object_type == kAACPSObjectType) { | 149 audio_object_type == kAACPSObjectType) { |
152 return true; | 150 return true; |
153 } | 151 } |
154 | 152 |
155 MEDIA_LOG(DEBUG, media_log) << "Unsupported audio object type " | 153 MEDIA_LOG(DEBUG, media_log) << "Unsupported audio object type " |
156 << audio_object_type << " in codec '" << codec_id | 154 << audio_object_type << " in codec '" << codec_id |
157 << "'"; | 155 << "'"; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 &kAC3CodecInfo1, | 228 &kAC3CodecInfo1, |
231 &kAC3CodecInfo2, | 229 &kAC3CodecInfo2, |
232 &kAC3CodecInfo3, | 230 &kAC3CodecInfo3, |
233 &kEAC3CodecInfo1, | 231 &kEAC3CodecInfo1, |
234 &kEAC3CodecInfo2, | 232 &kEAC3CodecInfo2, |
235 &kEAC3CodecInfo3, | 233 &kEAC3CodecInfo3, |
236 #endif | 234 #endif |
237 NULL}; | 235 NULL}; |
238 | 236 |
239 static StreamParser* BuildMP4Parser(const std::vector<std::string>& codecs, | 237 static StreamParser* BuildMP4Parser(const std::vector<std::string>& codecs, |
240 const scoped_refptr<MediaLog>& media_log) { | 238 MediaLog* media_log) { |
241 std::set<int> audio_object_types; | 239 std::set<int> audio_object_types; |
242 | 240 |
243 bool has_sbr = false; | 241 bool has_sbr = false; |
244 for (size_t i = 0; i < codecs.size(); ++i) { | 242 for (size_t i = 0; i < codecs.size(); ++i) { |
245 std::string codec_id = codecs[i]; | 243 std::string codec_id = codecs[i]; |
246 if (base::MatchPattern(codec_id, kMPEG2AACLCCodecInfo.pattern)) { | 244 if (base::MatchPattern(codec_id, kMPEG2AACLCCodecInfo.pattern)) { |
247 audio_object_types.insert(mp4::kISO_13818_7_AAC_LC); | 245 audio_object_types.insert(mp4::kISO_13818_7_AAC_LC); |
248 } else if (base::MatchPattern(codec_id, kMPEG4AACCodecInfo.pattern)) { | 246 } else if (base::MatchPattern(codec_id, kMPEG4AACCodecInfo.pattern)) { |
249 int audio_object_type = GetMP4AudioObjectType(codec_id, media_log); | 247 int audio_object_type = GetMP4AudioObjectType(codec_id, media_log); |
250 DCHECK_GT(audio_object_type, 0); | 248 DCHECK_GT(audio_object_type, 0); |
(...skipping 23 matching lines...) Expand all Loading... |
274 | 272 |
275 static const CodecInfo kMP3CodecInfo = { NULL, CodecInfo::AUDIO, NULL, | 273 static const CodecInfo kMP3CodecInfo = { NULL, CodecInfo::AUDIO, NULL, |
276 CodecInfo::HISTOGRAM_MP3 }; | 274 CodecInfo::HISTOGRAM_MP3 }; |
277 | 275 |
278 static const CodecInfo* kAudioMP3Codecs[] = { | 276 static const CodecInfo* kAudioMP3Codecs[] = { |
279 &kMP3CodecInfo, | 277 &kMP3CodecInfo, |
280 NULL | 278 NULL |
281 }; | 279 }; |
282 | 280 |
283 static StreamParser* BuildMP3Parser(const std::vector<std::string>& codecs, | 281 static StreamParser* BuildMP3Parser(const std::vector<std::string>& codecs, |
284 const scoped_refptr<MediaLog>& media_log) { | 282 MediaLog* media_log) { |
285 return new MPEG1AudioStreamParser(); | 283 return new MPEG1AudioStreamParser(); |
286 } | 284 } |
287 | 285 |
288 static const CodecInfo kADTSCodecInfo = { NULL, CodecInfo::AUDIO, NULL, | 286 static const CodecInfo kADTSCodecInfo = { NULL, CodecInfo::AUDIO, NULL, |
289 CodecInfo::HISTOGRAM_MPEG4AAC }; | 287 CodecInfo::HISTOGRAM_MPEG4AAC }; |
290 static const CodecInfo* kAudioADTSCodecs[] = { | 288 static const CodecInfo* kAudioADTSCodecs[] = { |
291 &kADTSCodecInfo, | 289 &kADTSCodecInfo, |
292 NULL | 290 NULL |
293 }; | 291 }; |
294 | 292 |
295 static StreamParser* BuildADTSParser(const std::vector<std::string>& codecs, | 293 static StreamParser* BuildADTSParser(const std::vector<std::string>& codecs, |
296 const scoped_refptr<MediaLog>& media_log) { | 294 MediaLog* media_log) { |
297 return new ADTSStreamParser(); | 295 return new ADTSStreamParser(); |
298 } | 296 } |
299 | 297 |
300 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) | 298 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) |
301 // These codec ids correspond to object types registered with MP4RA and are the | 299 // These codec ids correspond to object types registered with MP4RA and are the |
302 // same as MP3 audio codec ids in media/base/mime_util_internal.cc. | 300 // same as MP3 audio codec ids in media/base/mime_util_internal.cc. |
303 // From http://www.mp4ra.org/object.html: | 301 // From http://www.mp4ra.org/object.html: |
304 // 69 Audio ISO/IEC 13818-3 | 302 // 69 Audio ISO/IEC 13818-3 |
305 // 6B Audio ISO/IEC 11172-3 | 303 // 6B Audio ISO/IEC 11172-3 |
306 static const CodecInfo kMPEG2TS_MP3CodecInfo1 = { | 304 static const CodecInfo kMPEG2TS_MP3CodecInfo1 = { |
307 "mp4a.69", CodecInfo::AUDIO, NULL, CodecInfo::HISTOGRAM_MP3}; | 305 "mp4a.69", CodecInfo::AUDIO, NULL, CodecInfo::HISTOGRAM_MP3}; |
308 static const CodecInfo kMPEG2TS_MP3CodecInfo2 = { | 306 static const CodecInfo kMPEG2TS_MP3CodecInfo2 = { |
309 "mp4a.6B", CodecInfo::AUDIO, NULL, CodecInfo::HISTOGRAM_MP3}; | 307 "mp4a.6B", CodecInfo::AUDIO, NULL, CodecInfo::HISTOGRAM_MP3}; |
310 | 308 |
311 static const CodecInfo* kVideoMP2TCodecs[] = {&kH264AVC1CodecInfo, | 309 static const CodecInfo* kVideoMP2TCodecs[] = {&kH264AVC1CodecInfo, |
312 &kH264AVC3CodecInfo, | 310 &kH264AVC3CodecInfo, |
313 &kMPEG2TS_MP3CodecInfo1, | 311 &kMPEG2TS_MP3CodecInfo1, |
314 &kMPEG2TS_MP3CodecInfo2, | 312 &kMPEG2TS_MP3CodecInfo2, |
315 &kMPEG4AACCodecInfo, | 313 &kMPEG4AACCodecInfo, |
316 &kMPEG2AACLCCodecInfo, | 314 &kMPEG2AACLCCodecInfo, |
317 NULL}; | 315 NULL}; |
318 | 316 |
319 static StreamParser* BuildMP2TParser(const std::vector<std::string>& codecs, | 317 static StreamParser* BuildMP2TParser(const std::vector<std::string>& codecs, |
320 const scoped_refptr<MediaLog>& media_log) { | 318 MediaLog* media_log) { |
321 bool has_sbr = false; | 319 bool has_sbr = false; |
322 for (size_t i = 0; i < codecs.size(); ++i) { | 320 for (size_t i = 0; i < codecs.size(); ++i) { |
323 std::string codec_id = codecs[i]; | 321 std::string codec_id = codecs[i]; |
324 if (base::MatchPattern(codec_id, kMPEG4AACCodecInfo.pattern)) { | 322 if (base::MatchPattern(codec_id, kMPEG4AACCodecInfo.pattern)) { |
325 int audio_object_type = GetMP4AudioObjectType(codec_id, media_log); | 323 int audio_object_type = GetMP4AudioObjectType(codec_id, media_log); |
326 if (audio_object_type == kAACSBRObjectType || | 324 if (audio_object_type == kAACSBRObjectType || |
327 audio_object_type == kAACPSObjectType) { | 325 audio_object_type == kAACPSObjectType) { |
328 has_sbr = true; | 326 has_sbr = true; |
329 } | 327 } |
330 } | 328 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 // not touched. | 395 // not touched. |
398 // |video_codecs| is updated with the appropriate HistogramTags for matching | 396 // |video_codecs| is updated with the appropriate HistogramTags for matching |
399 // video codecs specified in |codecs|. Value may be NULL, in which case it is | 397 // video codecs specified in |codecs|. Value may be NULL, in which case it is |
400 // not touched. | 398 // not touched. |
401 // | 399 // |
402 // Returns false otherwise. The values of |factory_function|, |audio_codecs|, | 400 // Returns false otherwise. The values of |factory_function|, |audio_codecs|, |
403 // and |video_codecs| are undefined. | 401 // and |video_codecs| are undefined. |
404 static bool CheckTypeAndCodecs( | 402 static bool CheckTypeAndCodecs( |
405 const std::string& type, | 403 const std::string& type, |
406 const std::vector<std::string>& codecs, | 404 const std::vector<std::string>& codecs, |
407 const scoped_refptr<MediaLog>& media_log, | 405 MediaLog* media_log, |
408 ParserFactoryFunction* factory_function, | 406 ParserFactoryFunction* factory_function, |
409 std::vector<CodecInfo::HistogramTag>* audio_codecs, | 407 std::vector<CodecInfo::HistogramTag>* audio_codecs, |
410 std::vector<CodecInfo::HistogramTag>* video_codecs) { | 408 std::vector<CodecInfo::HistogramTag>* video_codecs) { |
411 // Search for the SupportedTypeInfo for |type|. | 409 // Search for the SupportedTypeInfo for |type|. |
412 for (size_t i = 0; i < arraysize(kSupportedTypeInfo); ++i) { | 410 for (size_t i = 0; i < arraysize(kSupportedTypeInfo); ++i) { |
413 const SupportedTypeInfo& type_info = kSupportedTypeInfo[i]; | 411 const SupportedTypeInfo& type_info = kSupportedTypeInfo[i]; |
414 if (type == type_info.type) { | 412 if (type == type_info.type) { |
415 if (codecs.empty()) { | 413 if (codecs.empty()) { |
416 const CodecInfo* codec_info = type_info.codecs[0]; | 414 const CodecInfo* codec_info = type_info.codecs[0]; |
417 if (codec_info && !codec_info->pattern && | 415 if (codec_info && !codec_info->pattern && |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 // All codecs were supported by this |type|. | 455 // All codecs were supported by this |type|. |
458 return true; | 456 return true; |
459 } | 457 } |
460 } | 458 } |
461 | 459 |
462 // |type| didn't match any of the supported types. | 460 // |type| didn't match any of the supported types. |
463 return false; | 461 return false; |
464 } | 462 } |
465 | 463 |
466 bool StreamParserFactory::IsTypeSupported( | 464 bool StreamParserFactory::IsTypeSupported( |
467 const std::string& type, const std::vector<std::string>& codecs) { | 465 const std::string& type, |
468 return CheckTypeAndCodecs(type, codecs, new MediaLog(), NULL, NULL, NULL); | 466 const std::vector<std::string>& codecs) { |
| 467 // TODO(wolenetz): Questionable MediaLog usage, http://crbug.com/712310 |
| 468 MediaLog media_log; |
| 469 return CheckTypeAndCodecs(type, codecs, &media_log, NULL, NULL, NULL); |
469 } | 470 } |
470 | 471 |
471 std::unique_ptr<StreamParser> StreamParserFactory::Create( | 472 std::unique_ptr<StreamParser> StreamParserFactory::Create( |
472 const std::string& type, | 473 const std::string& type, |
473 const std::vector<std::string>& codecs, | 474 const std::vector<std::string>& codecs, |
474 const scoped_refptr<MediaLog>& media_log) { | 475 MediaLog* media_log) { |
475 std::unique_ptr<StreamParser> stream_parser; | 476 std::unique_ptr<StreamParser> stream_parser; |
476 ParserFactoryFunction factory_function; | 477 ParserFactoryFunction factory_function; |
477 std::vector<CodecInfo::HistogramTag> audio_codecs; | 478 std::vector<CodecInfo::HistogramTag> audio_codecs; |
478 std::vector<CodecInfo::HistogramTag> video_codecs; | 479 std::vector<CodecInfo::HistogramTag> video_codecs; |
479 | 480 |
480 if (CheckTypeAndCodecs(type, codecs, media_log, &factory_function, | 481 if (CheckTypeAndCodecs(type, codecs, media_log, &factory_function, |
481 &audio_codecs, &video_codecs)) { | 482 &audio_codecs, &video_codecs)) { |
482 // Log the number of codecs specified, as well as the details on each one. | 483 // Log the number of codecs specified, as well as the details on each one. |
483 UMA_HISTOGRAM_COUNTS_100("Media.MSE.NumberOfTracks", codecs.size()); | 484 UMA_HISTOGRAM_COUNTS_100("Media.MSE.NumberOfTracks", codecs.size()); |
484 for (size_t i = 0; i < audio_codecs.size(); ++i) { | 485 for (size_t i = 0; i < audio_codecs.size(); ++i) { |
485 UMA_HISTOGRAM_ENUMERATION("Media.MSE.AudioCodec", | 486 UMA_HISTOGRAM_ENUMERATION("Media.MSE.AudioCodec", |
486 audio_codecs[i], | 487 audio_codecs[i], |
487 CodecInfo::HISTOGRAM_MAX + 1); | 488 CodecInfo::HISTOGRAM_MAX + 1); |
488 } | 489 } |
489 for (size_t i = 0; i < video_codecs.size(); ++i) { | 490 for (size_t i = 0; i < video_codecs.size(); ++i) { |
490 UMA_HISTOGRAM_ENUMERATION("Media.MSE.VideoCodec", | 491 UMA_HISTOGRAM_ENUMERATION("Media.MSE.VideoCodec", |
491 video_codecs[i], | 492 video_codecs[i], |
492 CodecInfo::HISTOGRAM_MAX + 1); | 493 CodecInfo::HISTOGRAM_MAX + 1); |
493 } | 494 } |
494 | 495 |
495 stream_parser.reset(factory_function(codecs, media_log)); | 496 stream_parser.reset(factory_function(codecs, media_log)); |
496 } | 497 } |
497 | 498 |
498 return stream_parser; | 499 return stream_parser; |
499 } | 500 } |
500 | 501 |
501 } // namespace media | 502 } // namespace media |
OLD | NEW |