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 |