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 "media/base/video_codecs.h" | 5 #include "media/base/video_codecs.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/strings/string_split.h" | 9 #include "base/strings/string_split.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
79 return "vp9 profile2"; | 79 return "vp9 profile2"; |
80 case VP9PROFILE_PROFILE3: | 80 case VP9PROFILE_PROFILE3: |
81 return "vp9 profile3"; | 81 return "vp9 profile3"; |
82 } | 82 } |
83 NOTREACHED(); | 83 NOTREACHED(); |
84 return ""; | 84 return ""; |
85 } | 85 } |
86 | 86 |
87 bool ParseNewStyleVp9CodecID(const std::string& codec_id, | 87 bool ParseNewStyleVp9CodecID(const std::string& codec_id, |
88 VideoCodecProfile* profile, | 88 VideoCodecProfile* profile, |
89 uint8_t* level_idc) { | 89 uint8_t* level_idc, |
90 gfx::ColorSpace::TransferID* eotf) { | |
91 LOG(ERROR) << __func__ << " 0"; | |
servolk
2017/03/02 18:56:36
Nit: don't forget to remove this debug logging.
chcunningham
2017/03/02 23:13:08
Acknowledged.
| |
92 | |
93 // Initialize optional fields to their defaults. | |
94 *eotf = gfx::ColorSpace::TransferID::BT709; | |
95 | |
90 std::vector<std::string> fields = base::SplitString( | 96 std::vector<std::string> fields = base::SplitString( |
91 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | 97 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); |
92 | 98 |
93 // TODO(kqyang): The spec specifies 8 fields. We do not allow missing or extra | 99 // First four fields are mandatory. No more than 9 fields are expected. |
94 // fields. See crbug.com/667834. | 100 if (fields.size() < 4 || fields.size() > 9) |
95 if (fields.size() != 8) | |
96 return false; | 101 return false; |
97 | 102 |
98 if (fields[0] != "vp09") | 103 if (fields[0] != "vp09") |
99 return false; | 104 return false; |
100 | 105 |
106 LOG(ERROR) << __func__ << " 1"; | |
107 | |
101 std::vector<int> values; | 108 std::vector<int> values; |
102 for (size_t i = 1; i < fields.size(); ++i) { | 109 for (size_t i = 1; i < fields.size(); ++i) { |
103 // Missing value is not allowed. | 110 // Missing value is not allowed. ------------------------------------------ is still this right? |
104 if (fields[i] == "") | 111 if (fields[i] == "") |
105 return false; | 112 return false; |
106 int value; | 113 int value; |
107 if (!base::StringToInt(fields[i], &value)) | 114 if (!base::StringToInt(fields[i], &value)) |
108 return false; | 115 return false; |
109 if (value < 0) | 116 if (value < 0) |
110 return false; | 117 return false; |
111 values.push_back(value); | 118 values.push_back(value); |
112 } | 119 } |
113 | 120 |
121 LOG(ERROR) << __func__ << " 2"; | |
114 const int profile_idc = values[0]; | 122 const int profile_idc = values[0]; |
115 switch (profile_idc) { | 123 switch (profile_idc) { |
116 case 0: | 124 case 0: |
117 *profile = VP9PROFILE_PROFILE0; | 125 *profile = VP9PROFILE_PROFILE0; |
118 break; | 126 break; |
119 case 1: | 127 case 1: |
120 *profile = VP9PROFILE_PROFILE1; | 128 *profile = VP9PROFILE_PROFILE1; |
121 break; | 129 break; |
122 case 2: | 130 case 2: |
123 *profile = VP9PROFILE_PROFILE2; | 131 *profile = VP9PROFILE_PROFILE2; |
124 break; | 132 break; |
125 case 3: | 133 case 3: |
126 *profile = VP9PROFILE_PROFILE3; | 134 *profile = VP9PROFILE_PROFILE3; |
127 break; | 135 break; |
128 default: | 136 default: |
129 return false; | 137 return false; |
130 } | 138 } |
131 | 139 |
140 LOG(ERROR) << __func__ << " 3"; | |
132 *level_idc = values[1]; | 141 *level_idc = values[1]; |
133 // TODO(kqyang): Check if |level_idc| is valid. See crbug.com/667834. | 142 // TODO(kqyang): Check if |level_idc| is valid. See crbug.com/667834. |
134 | 143 |
135 const int bit_depth = values[2]; | 144 const int bit_depth = values[2]; |
136 if (bit_depth != 8 && bit_depth != 10 && bit_depth != 12) | 145 if (bit_depth != 8 && bit_depth != 10 && bit_depth != 12) |
137 return false; | 146 return false; |
138 | 147 |
148 if (values.size() < 4) | |
149 return true; | |
150 LOG(ERROR) << __func__ << " 4"; | |
139 const int color_space = values[3]; | 151 const int color_space = values[3]; |
140 if (color_space > 7) | 152 if (color_space > 9) |
141 return false; | 153 return false; |
142 | 154 |
143 const int chroma_subsampling = values[4]; | 155 LOG(ERROR) << __func__ << " 5"; |
144 if (chroma_subsampling > 3) | 156 if (values.size() < 5) |
157 return true; | |
158 const int transfer_function = values[4]; | |
159 switch (transfer_function) { | |
160 case 0: | |
servolk
2017/03/02 18:56:36
Are those values taken from https://docs.google.co
chcunningham
2017/03/02 23:13:08
Right, these values are taken from a draft which i
| |
161 // "0" bucket denotes one of: | |
162 // Rec. ITU-R BT.709-6 | |
163 // Rec. ITU-R BT.601-7 525 or 625 | |
164 // Rec. ITU-R BT.2020. | |
165 // These are all non-HDR, so just grab 709 since they're all treated | |
166 // the same from a capabilities standpoint. | |
167 *eotf = gfx::ColorSpace::TransferID::BT709; | |
168 break; | |
169 case 1: | |
170 *eotf = gfx::ColorSpace::TransferID::SMPTEST2084; | |
171 break; | |
172 case 2: | |
173 *eotf = gfx::ColorSpace::TransferID::ARIB_STD_B67; // AKA "HLG" | |
174 break; | |
175 default: | |
176 *eotf = gfx::ColorSpace::TransferID::INVALID; | |
177 DVLOG(4) << __func__ << ": invalid transfer function id (" | |
178 << transfer_function << ")"; | |
179 return false; | |
180 } | |
181 | |
182 LOG(ERROR) << __func__ << " 6"; | |
183 if (values.size() < 6) | |
184 return true; | |
185 const int matrix_coefficients = values[5]; | |
186 if (matrix_coefficients < 0) | |
145 return false; | 187 return false; |
146 | 188 |
147 const int transfer_function = values[5]; | 189 LOG(ERROR) << __func__ << " 7"; |
148 if (transfer_function > 1) | 190 if (values.size() < 7) |
191 return true; | |
192 const int video_full_range_flag = values[6]; | |
193 if (video_full_range_flag < 0 || video_full_range_flag > 1) | |
149 return false; | 194 return false; |
150 | 195 |
151 const int video_full_range_flag = values[6]; | 196 LOG(ERROR) << __func__ << " 8"; |
152 if (video_full_range_flag > 1) | 197 if (values.size() < 8) |
198 return true; | |
199 const int chroma_subsampling = values[7]; | |
200 if (chroma_subsampling < 0 || chroma_subsampling > 3) | |
153 return false; | 201 return false; |
154 | 202 |
203 LOG(ERROR) << __func__ << " 9"; | |
155 return true; | 204 return true; |
156 } | 205 } |
157 | 206 |
158 bool ParseLegacyVp9CodecID(const std::string& codec_id, | 207 bool ParseLegacyVp9CodecID(const std::string& codec_id, |
159 VideoCodecProfile* profile, | 208 VideoCodecProfile* profile, |
160 uint8_t* level_idc) { | 209 uint8_t* level_idc) { |
161 if (codec_id == "vp9" || codec_id == "vp9.0") { | 210 if (codec_id == "vp9" || codec_id == "vp9.0") { |
162 // Profile is not included in the codec string. Assuming profile 0 to be | 211 // Profile is not included in the codec string. Assuming profile 0 to be |
163 // backward compatible. | 212 // backward compatible. |
164 *profile = VP9PROFILE_PROFILE0; | 213 *profile = VP9PROFILE_PROFILE0; |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 | 466 |
418 return true; | 467 return true; |
419 } | 468 } |
420 #endif | 469 #endif |
421 | 470 |
422 VideoCodec StringToVideoCodec(const std::string& codec_id) { | 471 VideoCodec StringToVideoCodec(const std::string& codec_id) { |
423 std::vector<std::string> elem = base::SplitString( | 472 std::vector<std::string> elem = base::SplitString( |
424 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 473 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
425 if (elem.empty()) | 474 if (elem.empty()) |
426 return kUnknownVideoCodec; | 475 return kUnknownVideoCodec; |
476 | |
427 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; | 477 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; |
428 uint8_t level = 0; | 478 uint8_t level = 0; |
479 gfx::ColorSpace::TransferID eotf = gfx::ColorSpace::TransferID::INVALID; | |
480 | |
429 if (codec_id == "vp8" || codec_id == "vp8.0") | 481 if (codec_id == "vp8" || codec_id == "vp8.0") |
430 return kCodecVP8; | 482 return kCodecVP8; |
431 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level) || | 483 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level, &eotf) || |
432 ParseLegacyVp9CodecID(codec_id, &profile, &level)) { | 484 ParseLegacyVp9CodecID(codec_id, &profile, &level)) { |
433 return kCodecVP9; | 485 return kCodecVP9; |
434 } | 486 } |
435 if (codec_id == "theora") | 487 if (codec_id == "theora") |
436 return kCodecTheora; | 488 return kCodecTheora; |
437 if (ParseAVCCodecId(codec_id, &profile, &level)) | 489 if (ParseAVCCodecId(codec_id, &profile, &level)) |
438 return kCodecH264; | 490 return kCodecH264; |
439 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) | 491 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) |
440 if (ParseAVCCodecId(TranslateLegacyAvc1CodecIds(codec_id), &profile, &level)) | 492 if (ParseAVCCodecId(TranslateLegacyAvc1CodecIds(codec_id), &profile, &level)) |
441 return kCodecH264; | 493 return kCodecH264; |
442 #endif | 494 #endif |
443 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 495 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
444 if (ParseHEVCCodecId(codec_id, &profile, &level)) | 496 if (ParseHEVCCodecId(codec_id, &profile, &level)) |
445 return kCodecHEVC; | 497 return kCodecHEVC; |
446 #endif | 498 #endif |
447 return kUnknownVideoCodec; | 499 return kUnknownVideoCodec; |
448 } | 500 } |
449 | 501 |
450 } // namespace media | 502 } // namespace media |
OLD | NEW |