| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <string> | 5 #include "chromecast/media/base/media_codec_support.h" |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/callback.h" | |
| 9 #include "base/strings/string_number_conversions.h" | |
| 10 #include "base/strings/string_util.h" | |
| 11 | |
| 12 // TODO(servolk): Temp definitions to fix Chromecast build until media mime | |
| 13 // type refactoring checks are properly upstreamed. | |
| 14 namespace net { | |
| 15 | |
| 16 typedef base::Callback<bool(const std::string&)> IsCodecSupportedCB; | |
| 17 | |
| 18 static bool IsValidH264BaselineProfile(const std::string& profile_str) { | |
| 19 uint32 constraint_set_bits; | |
| 20 if (profile_str.size() != 4 || | |
| 21 profile_str[0] != '4' || | |
| 22 profile_str[1] != '2' || | |
| 23 profile_str[3] != '0' || | |
| 24 !base::HexStringToUInt(base::StringPiece(profile_str.c_str() + 2, 1), | |
| 25 &constraint_set_bits)) { | |
| 26 return false; | |
| 27 } | |
| 28 | |
| 29 return constraint_set_bits >= 8; | |
| 30 } | |
| 31 | |
| 32 static bool IsValidH264Level(const std::string& level_str) { | |
| 33 uint32 level; | |
| 34 if (level_str.size() != 2 || !base::HexStringToUInt(level_str, &level)) | |
| 35 return false; | |
| 36 | |
| 37 // Valid levels taken from Table A-1 in ISO-14496-10. | |
| 38 // Essentially |level_str| is toHex(10 * level). | |
| 39 return ((level >= 10 && level <= 13) || | |
| 40 (level >= 20 && level <= 22) || | |
| 41 (level >= 30 && level <= 32) || | |
| 42 (level >= 40 && level <= 42) || | |
| 43 (level >= 50 && level <= 51)); | |
| 44 } | |
| 45 | |
| 46 static bool ParseH264CodecID(const std::string& codec_id, | |
| 47 bool* is_ambiguous) { | |
| 48 // Make sure we have avc1.xxxxxx or avc3.xxxxxx | |
| 49 if (codec_id.size() != 11 || | |
| 50 (!StartsWithASCII(codec_id, "avc1.", true) && | |
| 51 !StartsWithASCII(codec_id, "avc3.", true))) { | |
| 52 return false; | |
| 53 } | |
| 54 | |
| 55 std::string profile = StringToUpperASCII(codec_id.substr(5, 4)); | |
| 56 if (IsValidH264BaselineProfile(profile) || | |
| 57 profile == "4D40" || profile == "6400") { | |
| 58 *is_ambiguous = !IsValidH264Level(StringToUpperASCII(codec_id.substr(9))); | |
| 59 } else { | |
| 60 *is_ambiguous = true; | |
| 61 } | |
| 62 | |
| 63 return true; | |
| 64 } | |
| 65 | |
| 66 bool DefaultIsCodecSupported(const std::string& codec) { | |
| 67 if (codec == "1" /*PCM*/ || codec == "vorbis" || codec == "opus" || | |
| 68 codec == "theora" || codec == "vp8" || codec == "vp8.0" || | |
| 69 codec == "vp9" || codec == "vp9.0") | |
| 70 return true; | |
| 71 | |
| 72 if (codec == "mp3" || codec == "mp4a.66" || codec == "mp4a.67" || | |
| 73 codec == "mp4a.68" || codec == "mp4a.69" || codec == "mp4a.6B" || | |
| 74 codec == "mp4a.40.2" || codec == "mp4a.40.02" || codec == "mp4a.40.29" || | |
| 75 codec == "mp4a.40.5" || codec == "mp4a.40.05" || codec == "mp4a.40") | |
| 76 return true; | |
| 77 | |
| 78 #if defined(ENABLE_MPEG2TS_STREAM_PARSER) | |
| 79 // iOS 3.0 to 3.1.2 used non-standard codec ids for H.264 Baseline and Main | |
| 80 // profiles in HTTP Live Streaming (HLS). Apple recommends using these | |
| 81 // non-standard strings for compatibility with older iOS devices, and so many | |
| 82 // HLS apps still use these. See | |
| 83 // https://developer.apple.com/library/ios/documentation/NetworkingInternet/Co
nceptual/StreamingMediaGuide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.h
tml | |
| 84 // mp4a.40.34 is also Apple-specific name for MP3 in mpeg2ts container for HLS | |
| 85 if (codec == "avc1.66.30" || codec == "avc1.77.30" || codec == "mp4a.40.34") | |
| 86 return true; | |
| 87 #endif | |
| 88 | |
| 89 | |
| 90 bool is_ambiguous = true; | |
| 91 if (codec == "avc1" || codec == "avc3" || | |
| 92 ParseH264CodecID(codec, &is_ambiguous)) { | |
| 93 return true; | |
| 94 } | |
| 95 | |
| 96 // Unknown codec id | |
| 97 return false; | |
| 98 } | |
| 99 | |
| 100 } | |
| 101 | 6 |
| 102 namespace chromecast { | 7 namespace chromecast { |
| 103 namespace media { | 8 namespace media { |
| 104 | 9 |
| 105 // This is a default implementation of GetIsCodecSupportedOnChromecastCB that is | 10 // This is a default implementation of GetIsCodecSupportedOnChromecastCB that is |
| 106 // going to be used for brandings other than 'Chrome'. Most platforms will want | 11 // going to be used for brandings other than 'Chrome'. Most platforms will want |
| 107 // to use their own custom implementations of the IsCodecSupportedCB callback. | 12 // to use their own custom implementations of the IsCodecSupportedCB callback. |
| 108 net::IsCodecSupportedCB GetIsCodecSupportedOnChromecastCB() { | 13 net::IsCodecSupportedCB GetIsCodecSupportedOnChromecastCB() { |
| 109 return base::Bind(&net::DefaultIsCodecSupported); | 14 return base::Bind(&net::DefaultIsCodecSupported); |
| 110 } | 15 } |
| 111 | 16 |
| 112 } // namespace media | 17 } // namespace media |
| 113 } // namespace chromecast | 18 } // namespace chromecast |
| 114 | 19 |
| OLD | NEW |