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

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

Issue 2723833002: WebM support for new multipart VP9 string. (Closed)
Patch Set: Rebase Created 3 years, 9 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
« no previous file with comments | « media/base/video_codecs.h ('k') | media/base/video_codecs_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 return "dolby vision profile 4"; 87 return "dolby vision profile 4";
88 case DOLBYVISION_PROFILE5: 88 case DOLBYVISION_PROFILE5:
89 return "dolby vision profile 5"; 89 return "dolby vision profile 5";
90 case DOLBYVISION_PROFILE7: 90 case DOLBYVISION_PROFILE7:
91 return "dolby vision profile 7"; 91 return "dolby vision profile 7";
92 } 92 }
93 NOTREACHED(); 93 NOTREACHED();
94 return ""; 94 return "";
95 } 95 }
96 96
97 // Described in ISO 23001-8:2016 Table 3.
98 bool ParseVp9Eotf(const int value, gfx::ColorSpace::TransferID* eotf) {
99 switch (value) {
100 case 1:
101 *eotf = gfx::ColorSpace::TransferID::BT709;
102 break;
103 case 2:
104 // "2" is interpreted as "Unspecified"
105 *eotf = gfx::ColorSpace::TransferID::INVALID;
106 break;
107 case 4:
108 *eotf = gfx::ColorSpace::TransferID::GAMMA22;
109 break;
110 case 5:
111 *eotf = gfx::ColorSpace::TransferID::GAMMA28;
112 break;
113 case 6:
114 *eotf = gfx::ColorSpace::TransferID::SMPTE170M;
115 break;
116 case 7:
117 *eotf = gfx::ColorSpace::TransferID::SMPTE240M;
118 break;
119 case 8:
120 *eotf = gfx::ColorSpace::TransferID::LINEAR;
121 break;
122 case 9:
123 *eotf = gfx::ColorSpace::TransferID::LOG;
124 break;
125 case 10:
126 *eotf = gfx::ColorSpace::TransferID::LOG_SQRT;
127 break;
128 case 11:
129 *eotf = gfx::ColorSpace::TransferID::IEC61966_2_4;
130 break;
131 case 12:
132 *eotf = gfx::ColorSpace::TransferID::BT1361_ECG;
133 break;
134 case 13:
135 *eotf = gfx::ColorSpace::TransferID::IEC61966_2_1;
136 break;
137 case 14:
138 *eotf = gfx::ColorSpace::TransferID::BT2020_10;
139 break;
140 case 15:
141 *eotf = gfx::ColorSpace::TransferID::BT2020_12;
142 break;
143 case 16:
144 *eotf = gfx::ColorSpace::TransferID::SMPTEST2084;
145 break;
146 case 17:
147 *eotf = gfx::ColorSpace::TransferID::SMPTEST428_1;
148 break;
149 default:
150 // Includes reserved values of 0, 3, 18 - 255.
151 *eotf = gfx::ColorSpace::TransferID::INVALID;
152 return false;
153 }
154
155 return true;
156 }
157
97 bool ParseNewStyleVp9CodecID(const std::string& codec_id, 158 bool ParseNewStyleVp9CodecID(const std::string& codec_id,
98 VideoCodecProfile* profile, 159 VideoCodecProfile* profile,
99 uint8_t* level_idc) { 160 uint8_t* level_idc,
161 gfx::ColorSpace::TransferID* eotf) {
162 // Initialize optional fields to their defaults.
163 *eotf = gfx::ColorSpace::TransferID::BT709;
164
100 std::vector<std::string> fields = base::SplitString( 165 std::vector<std::string> fields = base::SplitString(
101 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); 166 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
102 167
103 // TODO(kqyang): The spec specifies 8 fields. We do not allow missing or extra 168 // First four fields are mandatory. No more than 9 fields are expected.
104 // fields. See crbug.com/667834. 169 if (fields.size() < 4 || fields.size() > 9) {
105 if (fields.size() != 8) 170 DVLOG(3) << __func__ << " Invalid number of fields (" << fields.size()
171 << ")";
106 return false; 172 return false;
173 }
107 174
108 if (fields[0] != "vp09") 175 if (fields[0] != "vp09") {
176 DVLOG(3) << __func__ << " Invalid 4CC (" << fields[0] << ")";
109 return false; 177 return false;
178 }
110 179
111 std::vector<int> values; 180 std::vector<int> values;
112 for (size_t i = 1; i < fields.size(); ++i) { 181 for (size_t i = 1; i < fields.size(); ++i) {
113 // Missing value is not allowed. 182 // Missing value is not allowed.
114 if (fields[i] == "") 183 if (fields[i] == "") {
184 DVLOG(3) << __func__ << " Invalid missing field (position:" << i << ")";
115 return false; 185 return false;
186 }
116 int value; 187 int value;
117 if (!base::StringToInt(fields[i], &value)) 188 if (!base::StringToInt(fields[i], &value) || value < 0) {
189 DVLOG(3) << __func__ << " Invalid field value (" << value << ")";
118 return false; 190 return false;
119 if (value < 0) 191 }
120 return false;
121 values.push_back(value); 192 values.push_back(value);
122 } 193 }
123 194
124 const int profile_idc = values[0]; 195 const int profile_idc = values[0];
125 switch (profile_idc) { 196 switch (profile_idc) {
126 case 0: 197 case 0:
127 *profile = VP9PROFILE_PROFILE0; 198 *profile = VP9PROFILE_PROFILE0;
128 break; 199 break;
129 case 1: 200 case 1:
130 *profile = VP9PROFILE_PROFILE1; 201 *profile = VP9PROFILE_PROFILE1;
131 break; 202 break;
132 case 2: 203 case 2:
133 *profile = VP9PROFILE_PROFILE2; 204 *profile = VP9PROFILE_PROFILE2;
134 break; 205 break;
135 case 3: 206 case 3:
136 *profile = VP9PROFILE_PROFILE3; 207 *profile = VP9PROFILE_PROFILE3;
137 break; 208 break;
138 default: 209 default:
210 DVLOG(3) << __func__ << " Invalid profile (" << profile_idc << ")";
139 return false; 211 return false;
140 } 212 }
141 213
142 *level_idc = values[1]; 214 *level_idc = values[1];
143 // TODO(kqyang): Check if |level_idc| is valid. See crbug.com/667834. 215 switch (*level_idc) {
216 case 1:
217 case 11:
218 case 2:
219 case 21:
220 case 3:
221 case 31:
222 case 4:
223 case 41:
224 case 5:
225 case 51:
226 case 52:
227 case 6:
228 case 61:
229 case 62:
230 break;
231 default:
232 DVLOG(3) << __func__ << " Invalid level (" << *level_idc << ")";
233 return false;
234 }
144 235
145 const int bit_depth = values[2]; 236 const int bit_depth = values[2];
146 if (bit_depth != 8 && bit_depth != 10 && bit_depth != 12) 237 if (bit_depth != 8 && bit_depth != 10 && bit_depth != 12) {
238 DVLOG(3) << __func__ << " Invalid bit-depth (" << bit_depth << ")";
147 return false; 239 return false;
240 }
148 241
149 const int color_space = values[3]; 242 if (values.size() < 4)
150 if (color_space > 7) 243 return true;
244 const int color_primaries = values[3];
245 // TODO(chcunningham): parse and bubble up color primaries, described in ISO
246 // 23001-8:2016 Table 2.
247 // Values 0, 3, and 23 - 255 are reserved.
248 if (color_primaries == 0 || color_primaries == 3 || color_primaries > 22) {
249 DVLOG(3) << __func__ << " Invalid color primaries (" << color_primaries
250 << ")";
151 return false; 251 return false;
252 }
152 253
153 const int chroma_subsampling = values[4]; 254 if (values.size() < 5)
154 if (chroma_subsampling > 3) 255 return true;
256 if (!ParseVp9Eotf(values[4], eotf)) {
257 DVLOG(3) << __func__ << " Invalid transfer function (" << values[4] << ")";
155 return false; 258 return false;
259 }
156 260
157 const int transfer_function = values[5]; 261 // TODO(chcunningham): Parse and bubble up the following fields. For now just
158 if (transfer_function > 1) 262 // doing basic validation.
263
264 if (values.size() < 6)
265 return true;
266 const int matrix_coefficients = values[5];
267 if (matrix_coefficients > 11) {
268 DVLOG(3) << __func__ << " Invalid matrix coefficients ("
269 << matrix_coefficients << ")";
159 return false; 270 return false;
271 }
160 272
273 if (values.size() < 7)
274 return true;
161 const int video_full_range_flag = values[6]; 275 const int video_full_range_flag = values[6];
162 if (video_full_range_flag > 1) 276 if (video_full_range_flag > 1) {
277 DVLOG(3) << __func__ << " Invalid full range flag ("
278 << video_full_range_flag << ")";
163 return false; 279 return false;
280 }
281
282 if (values.size() < 8)
283 return true;
284 const int chroma_subsampling = values[7];
285 if (chroma_subsampling > 3 ||
286 (chroma_subsampling != 3 && matrix_coefficients == 0)) {
287 DVLOG(3) << __func__ << " Invalid chroma subsampling ("
288 << chroma_subsampling << ")";
289 return false;
290 }
164 291
165 return true; 292 return true;
166 } 293 }
167 294
168 bool ParseLegacyVp9CodecID(const std::string& codec_id, 295 bool ParseLegacyVp9CodecID(const std::string& codec_id,
169 VideoCodecProfile* profile, 296 VideoCodecProfile* profile,
170 uint8_t* level_idc) { 297 uint8_t* level_idc) {
171 if (codec_id == "vp9" || codec_id == "vp9.0") { 298 if (codec_id == "vp9" || codec_id == "vp9.0") {
172 // Profile is not included in the codec string. Assuming profile 0 to be 299 // Profile is not included in the codec string. Assuming profile 0 to be
173 // backward compatible. 300 // backward compatible.
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 652
526 return true; 653 return true;
527 } 654 }
528 #endif 655 #endif
529 656
530 VideoCodec StringToVideoCodec(const std::string& codec_id) { 657 VideoCodec StringToVideoCodec(const std::string& codec_id) {
531 std::vector<std::string> elem = base::SplitString( 658 std::vector<std::string> elem = base::SplitString(
532 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 659 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
533 if (elem.empty()) 660 if (elem.empty())
534 return kUnknownVideoCodec; 661 return kUnknownVideoCodec;
662
535 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; 663 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
536 uint8_t level = 0; 664 uint8_t level = 0;
665 gfx::ColorSpace::TransferID eotf = gfx::ColorSpace::TransferID::INVALID;
666
537 if (codec_id == "vp8" || codec_id == "vp8.0") 667 if (codec_id == "vp8" || codec_id == "vp8.0")
538 return kCodecVP8; 668 return kCodecVP8;
539 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level) || 669 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level, &eotf) ||
540 ParseLegacyVp9CodecID(codec_id, &profile, &level)) { 670 ParseLegacyVp9CodecID(codec_id, &profile, &level)) {
541 return kCodecVP9; 671 return kCodecVP9;
542 } 672 }
543 if (codec_id == "theora") 673 if (codec_id == "theora")
544 return kCodecTheora; 674 return kCodecTheora;
545 if (ParseAVCCodecId(codec_id, &profile, &level)) 675 if (ParseAVCCodecId(codec_id, &profile, &level))
546 return kCodecH264; 676 return kCodecH264;
547 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) 677 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
548 if (ParseAVCCodecId(TranslateLegacyAvc1CodecIds(codec_id), &profile, &level)) 678 if (ParseAVCCodecId(TranslateLegacyAvc1CodecIds(codec_id), &profile, &level))
549 return kCodecH264; 679 return kCodecH264;
550 #endif 680 #endif
551 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 681 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
552 if (ParseHEVCCodecId(codec_id, &profile, &level)) 682 if (ParseHEVCCodecId(codec_id, &profile, &level))
553 return kCodecHEVC; 683 return kCodecHEVC;
554 #endif 684 #endif
555 #if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) 685 #if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
556 if (ParseDolbyVisionCodecId(codec_id, &profile, &level)) 686 if (ParseDolbyVisionCodecId(codec_id, &profile, &level))
557 return kCodecDolbyVision; 687 return kCodecDolbyVision;
558 #endif 688 #endif
559 return kUnknownVideoCodec; 689 return kUnknownVideoCodec;
560 } 690 }
561 691
562 } // namespace media 692 } // namespace media
OLDNEW
« no previous file with comments | « media/base/video_codecs.h ('k') | media/base/video_codecs_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698