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

Side by Side Diff: media/base/mime_util_internal.cc

Issue 1624703002: Implement support for vp9 in ISO-BMFF (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 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/base/mime_util_internal.h" 5 #include "media/base/mime_util_internal.h"
6 6
7 #include "base/strings/string_number_conversions.h" 7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/string_split.h" 8 #include "base/strings/string_split.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
(...skipping 15 matching lines...) Expand all
26 }; 26 };
27 27
28 // List of codec IDs that provide enough information to determine the 28 // List of codec IDs that provide enough information to determine the
29 // codec and profile being requested. 29 // codec and profile being requested.
30 // 30 //
31 // The "mp4a" strings come from RFC 6381. 31 // The "mp4a" strings come from RFC 6381.
32 static const CodecIDMappings kUnambiguousCodecStringMap[] = { 32 static const CodecIDMappings kUnambiguousCodecStringMap[] = {
33 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous. 33 {"1", MimeUtil::PCM}, // We only allow this for WAV so it isn't ambiguous.
34 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId(). 34 // avc1/avc3.XXXXXX may be unambiguous; handled by ParseAVCCodecId().
35 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID(). 35 // hev1/hvc1.XXXXXX may be unambiguous; handled by ParseHEVCCodecID().
36 // vp9, vp9.0, vp09.xx.xx.xx.xx.xx.xx.xx may be unambiguous; handled by
ddorwin 2016/04/18 22:53:29 Is it possible for these to be ambiguous (at least
kqyang 2016/04/19 00:28:05 Per your suggestion below. Now it might be ambiguo
ddorwin 2016/04/19 17:10:00 ambiguous is not the same as "maybe". I'll make th
37 // ParseVp9CodecID().
36 {"mp3", MimeUtil::MP3}, 38 {"mp3", MimeUtil::MP3},
37 // Following is the list of RFC 6381 compliant audio codec strings: 39 // Following is the list of RFC 6381 compliant audio codec strings:
38 // mp4a.66 - MPEG-2 AAC MAIN 40 // mp4a.66 - MPEG-2 AAC MAIN
39 // mp4a.67 - MPEG-2 AAC LC 41 // mp4a.67 - MPEG-2 AAC LC
40 // mp4a.68 - MPEG-2 AAC SSR 42 // mp4a.68 - MPEG-2 AAC SSR
41 // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3) 43 // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3)
42 // mp4a.6B - MPEG-1 audio (MP3) 44 // mp4a.6B - MPEG-1 audio (MP3)
43 // mp4a.40.2 - MPEG-4 AAC LC 45 // mp4a.40.2 - MPEG-4 AAC LC
44 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility) 46 // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for compatibility)
45 // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR) 47 // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR)
(...skipping 21 matching lines...) Expand all
67 {"mp4a.a5", MimeUtil::AC3}, 69 {"mp4a.a5", MimeUtil::AC3},
68 {"mp4a.A5", MimeUtil::AC3}, 70 {"mp4a.A5", MimeUtil::AC3},
69 {"ec-3", MimeUtil::EAC3}, 71 {"ec-3", MimeUtil::EAC3},
70 {"mp4a.a6", MimeUtil::EAC3}, 72 {"mp4a.a6", MimeUtil::EAC3},
71 {"mp4a.A6", MimeUtil::EAC3}, 73 {"mp4a.A6", MimeUtil::EAC3},
72 #endif 74 #endif
73 {"vorbis", MimeUtil::VORBIS}, 75 {"vorbis", MimeUtil::VORBIS},
74 {"opus", MimeUtil::OPUS}, 76 {"opus", MimeUtil::OPUS},
75 {"vp8", MimeUtil::VP8}, 77 {"vp8", MimeUtil::VP8},
76 {"vp8.0", MimeUtil::VP8}, 78 {"vp8.0", MimeUtil::VP8},
77 {"vp9", MimeUtil::VP9},
78 {"vp9.0", MimeUtil::VP9},
79 {"theora", MimeUtil::THEORA}}; 79 {"theora", MimeUtil::THEORA}};
80 80
81 // List of codec IDs that are ambiguous and don't provide 81 // List of codec IDs that are ambiguous and don't provide
82 // enough information to determine the codec and profile. 82 // enough information to determine the codec and profile.
83 // The codec in these entries indicate the codec and profile 83 // The codec in these entries indicate the codec and profile
84 // we assume the user is trying to indicate. 84 // we assume the user is trying to indicate.
85 static const CodecIDMappings kAmbiguousCodecStringMap[] = { 85 static const CodecIDMappings kAmbiguousCodecStringMap[] = {
86 {"mp4a.40", MimeUtil::MPEG4_AAC}, 86 {"mp4a.40", MimeUtil::MPEG4_AAC},
87 {"avc1", MimeUtil::H264}, 87 {"avc1", MimeUtil::H264},
88 {"avc3", MimeUtil::H264}, 88 {"avc3", MimeUtil::H264},
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 *is_ambiguous = false; 178 *is_ambiguous = false;
179 } 179 }
180 180
181 return true; 181 return true;
182 } 182 }
183 183
184 return false; 184 return false;
185 } 185 }
186 #endif 186 #endif
187 187
188 // Handle parsing of vp9 codec IDs.
189 static bool ParseVp9CodecID(const std::string& mime_type_lower_case,
190 const std::string& codec_id,
191 MimeUtil::Codec* codec) {
192 if (mime_type_lower_case == "video/webm") {
193 if (codec_id == "vp9" || codec_id == "vp9.0") {
194 *codec = MimeUtil::VP9;
195 return true;
196 }
197 // TODO(kqyang): Should we support new codec string in WebM?
198 return false;
199 } else if (mime_type_lower_case == "audio/webm") {
200 return false;
201 }
202
203 #if BUILDFLAG(ENABLE_MP4_VP9_DEMUXING)
204 std::vector<std::string> fields = base::SplitString(
205 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
206 if (fields.size() < 1)
207 return false;
208
209 if (fields[0] == "vp09") {
210 *codec = MimeUtil::VP9;
211 } else {
212 return false;
213 }
214
215 if (fields.size() > 8)
216 return false;
217
218 std::vector<int> values;
219 for (size_t i = 1; i < fields.size(); ++i) {
220 // Missing value is not allowed.
221 if (fields[i] == "")
222 return false;
223 int value;
224 if (!base::StringToInt(fields[i], &value))
225 return false;
226 if (value < 0)
227 return false;
228 values.push_back(value);
229 }
230
231 // The spec specifies 8 fields (7 values excluding the first codec field).
232 // We do not allow missing fields.
233 if (values.size() < 7)
234 return false;
235
236 const int profile = values[0];
237 if (profile > 3)
238 return false;
239
240 const int bit_depth = values[2];
241 if (bit_depth != 8 && bit_depth != 10 && bit_depth != 12)
242 return false;
243
244 const int color_space = values[3];
245 if (color_space > 7)
246 return false;
247
248 const int chroma_subsampling = values[4];
249 if (chroma_subsampling > 3)
250 return false;
251
252 const int transfer_function = values[5];
253 if (transfer_function > 1)
254 return false;
255
256 const int video_full_range_flag = values[6];
257 if (video_full_range_flag > 1)
258 return false;
259
260 return true;
261 #else
262 return false;
263 #endif // #if BUILDFLAG(ENABLE_MP4_VP9_DEMUXING)
264 }
265
188 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) { 266 MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) {
189 #if defined(OS_ANDROID) 267 #if defined(OS_ANDROID)
190 platform_info_.is_unified_media_pipeline_enabled = 268 platform_info_.is_unified_media_pipeline_enabled =
191 IsUnifiedMediaPipelineEnabled(); 269 IsUnifiedMediaPipelineEnabled();
192 // When the unified media pipeline is enabled, we need support for both GPU 270 // When the unified media pipeline is enabled, we need support for both GPU
193 // video decoders and MediaCodec; indicated by HasPlatformDecoderSupport(). 271 // video decoders and MediaCodec; indicated by HasPlatformDecoderSupport().
194 // When the Android pipeline is used, we only need access to MediaCodec. 272 // When the Android pipeline is used, we only need access to MediaCodec.
195 platform_info_.has_platform_decoders = ArePlatformDecodersAvailable(); 273 platform_info_.has_platform_decoders = ArePlatformDecodersAvailable();
196 platform_info_.has_platform_vp8_decoder = 274 platform_info_.has_platform_vp8_decoder =
197 MediaCodecUtil::IsVp8DecoderAvailable(); 275 MediaCodecUtil::IsVp8DecoderAvailable();
(...skipping 12 matching lines...) Expand all
210 const std::vector<std::string>& codecs, 288 const std::vector<std::string>& codecs,
211 const std::string& mime_type_lower_case, 289 const std::string& mime_type_lower_case,
212 bool is_encrypted) const { 290 bool is_encrypted) const {
213 DCHECK(!supported_codecs.empty()); 291 DCHECK(!supported_codecs.empty());
214 DCHECK(!codecs.empty()); 292 DCHECK(!codecs.empty());
215 293
216 SupportsType result = IsSupported; 294 SupportsType result = IsSupported;
217 for (size_t i = 0; i < codecs.size(); ++i) { 295 for (size_t i = 0; i < codecs.size(); ++i) {
218 bool is_ambiguous = true; 296 bool is_ambiguous = true;
219 Codec codec = INVALID_CODEC; 297 Codec codec = INVALID_CODEC;
220 if (!StringToCodec(codecs[i], &codec, &is_ambiguous, is_encrypted)) 298 if (!StringToCodec(mime_type_lower_case, codecs[i], &codec, &is_ambiguous,
299 is_encrypted)) {
221 return IsNotSupported; 300 return IsNotSupported;
301 }
222 302
223 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) || 303 if (!IsCodecSupported(codec, mime_type_lower_case, is_encrypted) ||
224 supported_codecs.find(codec) == supported_codecs.end()) { 304 supported_codecs.find(codec) == supported_codecs.end()) {
225 return IsNotSupported; 305 return IsNotSupported;
226 } 306 }
227 307
228 if (is_ambiguous) 308 if (is_ambiguous)
229 result = MayBeSupported; 309 result = MayBeSupported;
230 } 310 }
231 311
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) 374 #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
295 mp4_audio_codecs.insert(AC3); 375 mp4_audio_codecs.insert(AC3);
296 mp4_audio_codecs.insert(EAC3); 376 mp4_audio_codecs.insert(EAC3);
297 #endif // BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) 377 #endif // BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING)
298 378
299 CodecSet mp4_video_codecs; 379 CodecSet mp4_video_codecs;
300 mp4_video_codecs.insert(H264); 380 mp4_video_codecs.insert(H264);
301 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 381 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
302 mp4_video_codecs.insert(HEVC_MAIN); 382 mp4_video_codecs.insert(HEVC_MAIN);
303 #endif // BUILDFLAG(ENABLE_HEVC_DEMUXING) 383 #endif // BUILDFLAG(ENABLE_HEVC_DEMUXING)
384 #if BUILDFLAG(ENABLE_MP4_VP9_DEMUXING)
385 // Only VP9 with valid codec string vp09.xx.xx.xx.xx.xx.xx.xx is supported.
386 // See ParseVp9CodecID for details.
387 mp4_video_codecs.insert(VP9);
388 #endif // BUILDFLAG(ENABLE_MP4_VP9_DEMUXING)
304 CodecSet mp4_codecs(mp4_audio_codecs); 389 CodecSet mp4_codecs(mp4_audio_codecs);
305 mp4_codecs.insert(mp4_video_codecs.begin(), mp4_video_codecs.end()); 390 mp4_codecs.insert(mp4_video_codecs.begin(), mp4_video_codecs.end());
306 #endif // defined(USE_PROPRIETARY_CODECS) 391 #endif // defined(USE_PROPRIETARY_CODECS)
307 392
308 AddContainerWithCodecs("audio/wav", wav_codecs, false); 393 AddContainerWithCodecs("audio/wav", wav_codecs, false);
309 AddContainerWithCodecs("audio/x-wav", wav_codecs, false); 394 AddContainerWithCodecs("audio/x-wav", wav_codecs, false);
310 AddContainerWithCodecs("audio/webm", webm_audio_codecs, false); 395 AddContainerWithCodecs("audio/webm", webm_audio_codecs, false);
311 DCHECK(!webm_video_codecs.empty()); 396 DCHECK(!webm_video_codecs.empty());
312 AddContainerWithCodecs("video/webm", webm_codecs, false); 397 AddContainerWithCodecs("video/webm", webm_codecs, false);
313 AddContainerWithCodecs("audio/ogg", ogg_audio_codecs, false); 398 AddContainerWithCodecs("audio/ogg", ogg_audio_codecs, false);
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 631
547 // MediaPlayer can always play VP8. Note: This is incorrect for MSE, but 632 // MediaPlayer can always play VP8. Note: This is incorrect for MSE, but
548 // MSE does not use this code. http://crbug.com/587303. 633 // MSE does not use this code. http://crbug.com/587303.
549 return true; 634 return true;
550 635
551 case VP9: { 636 case VP9: {
552 // If clear, the unified pipeline can always decode VP9 in software. 637 // If clear, the unified pipeline can always decode VP9 in software.
553 if (!is_encrypted && platform_info.is_unified_media_pipeline_enabled) 638 if (!is_encrypted && platform_info.is_unified_media_pipeline_enabled)
554 return true; 639 return true;
555 640
556 // Otherwise, platform support is required. 641 if (!platform_info.has_platform_vp9_decoder)
557 return platform_info.has_platform_vp9_decoder; 642 return false;
643
644 // Encrypted content is demuxed so the container is irrelevant.
645 if (is_encrypted)
646 return true;
647
648 // MediaPlayer only supports VP9 in WebM.
649 return mime_type_lower_case == "video/webm";
558 } 650 }
559 } 651 }
560 652
561 return false; 653 return false;
562 } 654 }
563 655
564 bool MimeUtil::StringToCodec(const std::string& codec_id, 656 bool MimeUtil::StringToCodec(const std::string& mime_type_lower_case,
657 const std::string& codec_id,
565 Codec* codec, 658 Codec* codec,
566 bool* is_ambiguous, 659 bool* is_ambiguous,
567 bool is_encrypted) const { 660 bool is_encrypted) const {
568 StringToCodecMappings::const_iterator itr = 661 StringToCodecMappings::const_iterator itr =
569 string_to_codec_map_.find(codec_id); 662 string_to_codec_map_.find(codec_id);
570 if (itr != string_to_codec_map_.end()) { 663 if (itr != string_to_codec_map_.end()) {
571 *codec = itr->second.codec; 664 *codec = itr->second.codec;
572 *is_ambiguous = itr->second.is_ambiguous; 665 *is_ambiguous = itr->second.is_ambiguous;
573 return true; 666 return true;
574 } 667 }
(...skipping 30 matching lines...) Expand all
605 case H264PROFILE_MAIN: 698 case H264PROFILE_MAIN:
606 case H264PROFILE_HIGH: 699 case H264PROFILE_HIGH:
607 *is_ambiguous = !IsValidH264Level(level_idc); 700 *is_ambiguous = !IsValidH264Level(level_idc);
608 break; 701 break;
609 default: 702 default:
610 *is_ambiguous = true; 703 *is_ambiguous = true;
611 } 704 }
612 return true; 705 return true;
613 } 706 }
614 707
708 if (ParseVp9CodecID(mime_type_lower_case, codec_id, codec)) {
709 *is_ambiguous = false;
ddorwin 2016/04/18 22:53:29 Please see the conversations at https://codereview
kqyang 2016/04/19 00:28:05 Done. vp9 and vp9.0 are assumed to be profile 0.
710 return true;
711 }
712
615 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id; 713 DVLOG(4) << __FUNCTION__ << ": Unrecognized codec id " << codec_id;
616 return false; 714 return false;
617 } 715 }
618 716
619 bool MimeUtil::IsCodecSupported(Codec codec, 717 bool MimeUtil::IsCodecSupported(Codec codec,
620 const std::string& mime_type_lower_case, 718 const std::string& mime_type_lower_case,
621 bool is_encrypted) const { 719 bool is_encrypted) const {
622 DCHECK_NE(codec, INVALID_CODEC); 720 DCHECK_NE(codec, INVALID_CODEC);
623 721
624 #if defined(OS_ANDROID) 722 #if defined(OS_ANDROID)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 const std::string& mime_type_lower_case, 774 const std::string& mime_type_lower_case,
677 bool is_encrypted) const { 775 bool is_encrypted) const {
678 Codec default_codec = Codec::INVALID_CODEC; 776 Codec default_codec = Codec::INVALID_CODEC;
679 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec)) 777 if (!GetDefaultCodecLowerCase(mime_type_lower_case, &default_codec))
680 return false; 778 return false;
681 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted); 779 return IsCodecSupported(default_codec, mime_type_lower_case, is_encrypted);
682 } 780 }
683 781
684 } // namespace internal 782 } // namespace internal
685 } // namespace media 783 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698