| 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 |