Chromium Code Reviews| 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 return "vp9 profile1"; | 77 return "vp9 profile1"; |
| 78 case VP9PROFILE_PROFILE2: | 78 case VP9PROFILE_PROFILE2: |
| 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, | |
| 88 VideoCodecProfile* profile, | |
| 89 uint8_t* level_idc) { | |
| 90 std::vector<std::string> fields = base::SplitString( | |
| 91 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 92 | |
| 93 // TODO(kqyang): The spec specifies 8 fields. We do not allow missing or extra | |
| 94 // fields. See crbug.com/667834. | |
| 95 if (fields.size() != 8) | |
| 96 return false; | |
| 97 | |
| 98 if (fields[0] != "vp09") | |
| 99 return false; | |
| 100 | |
| 101 std::vector<int> values; | |
| 102 for (size_t i = 1; i < fields.size(); ++i) { | |
| 103 // Missing value is not allowed. | |
| 104 if (fields[i] == "") | |
| 105 return false; | |
| 106 int value; | |
| 107 if (!base::StringToInt(fields[i], &value)) | |
| 108 return false; | |
| 109 if (value < 0) | |
| 110 return false; | |
| 111 values.push_back(value); | |
| 112 } | |
| 113 | |
| 114 const int profile_idc = values[0]; | |
| 115 switch (profile_idc) { | |
| 116 case 0: | |
| 117 *profile = VP9PROFILE_PROFILE0; | |
| 118 break; | |
| 119 case 1: | |
| 120 *profile = VP9PROFILE_PROFILE1; | |
| 121 break; | |
| 122 case 2: | |
| 123 *profile = VP9PROFILE_PROFILE2; | |
| 124 break; | |
| 125 case 3: | |
| 126 *profile = VP9PROFILE_PROFILE3; | |
| 127 break; | |
| 128 default: | |
| 129 return false; | |
| 130 } | |
| 131 | |
|
ddorwin
2016/11/29 23:48:51
Do we have a separate bug to actually check the va
kqyang
2016/11/30 02:31:17
No. We haven't decided whether we want to validate
ddorwin
2016/12/02 18:55:54
We can avoid commenting here, but there should be
kqyang
2016/12/02 21:15:07
We can use crbug.com/667834 to track the decision
| |
| 132 *level_idc = values[1]; | |
|
ddorwin
2016/11/29 23:48:51
An easy check is that this can't be less than 10,
kqyang
2016/11/30 02:31:17
This mapping (actual level = level / 10) does not
ddorwin
2016/12/02 18:55:54
This appears to be the one value where we don't ch
kqyang
2016/12/02 21:15:07
Done.
| |
| 133 | |
| 134 const int bit_depth = values[2]; | |
| 135 if (bit_depth != 8 && bit_depth != 10 && bit_depth != 12) | |
| 136 return false; | |
| 137 | |
| 138 const int color_space = values[3]; | |
| 139 if (color_space > 7) | |
| 140 return false; | |
| 141 | |
| 142 const int chroma_subsampling = values[4]; | |
| 143 if (chroma_subsampling > 3) | |
| 144 return false; | |
| 145 | |
| 146 const int transfer_function = values[5]; | |
| 147 if (transfer_function > 1) | |
| 148 return false; | |
| 149 | |
| 150 const int video_full_range_flag = values[6]; | |
| 151 if (video_full_range_flag > 1) | |
| 152 return false; | |
| 153 | |
| 154 return true; | |
| 155 } | |
| 156 | |
| 157 bool ParseLegacyVp9CodecID(const std::string& codec_id, | |
| 158 VideoCodecProfile* profile, | |
| 159 uint8_t* level_idc) { | |
| 160 if (codec_id == "vp9" || codec_id == "vp9.0") { | |
| 161 // Profile is not included in the codec string. Assuming profile 0 to be | |
| 162 // backward compatible. | |
| 163 *profile = VP9PROFILE_PROFILE0; | |
| 164 // Use 0 to indicate unknown level. | |
| 165 *level_idc = 0; | |
| 166 return true; | |
| 167 } | |
| 168 return false; | |
| 169 } | |
| 170 | |
| 87 bool ParseAVCCodecId(const std::string& codec_id, | 171 bool ParseAVCCodecId(const std::string& codec_id, |
| 88 VideoCodecProfile* profile, | 172 VideoCodecProfile* profile, |
| 89 uint8_t* level_idc) { | 173 uint8_t* level_idc) { |
| 90 // Make sure we have avc1.xxxxxx or avc3.xxxxxx , where xxxxxx are hex digits | 174 // Make sure we have avc1.xxxxxx or avc3.xxxxxx , where xxxxxx are hex digits |
| 91 if (!base::StartsWith(codec_id, "avc1.", base::CompareCase::SENSITIVE) && | 175 if (!base::StartsWith(codec_id, "avc1.", base::CompareCase::SENSITIVE) && |
| 92 !base::StartsWith(codec_id, "avc3.", base::CompareCase::SENSITIVE)) { | 176 !base::StartsWith(codec_id, "avc3.", base::CompareCase::SENSITIVE)) { |
| 93 return false; | 177 return false; |
| 94 } | 178 } |
| 95 uint32_t elem = 0; | 179 uint32_t elem = 0; |
| 96 if (codec_id.size() != 11 || | 180 if (codec_id.size() != 11 || |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 285 } | 369 } |
| 286 #endif | 370 #endif |
| 287 | 371 |
| 288 VideoCodec StringToVideoCodec(const std::string& codec_id) { | 372 VideoCodec StringToVideoCodec(const std::string& codec_id) { |
| 289 std::vector<std::string> elem = base::SplitString( | 373 std::vector<std::string> elem = base::SplitString( |
| 290 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 374 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 291 if (elem.empty()) | 375 if (elem.empty()) |
| 292 return kUnknownVideoCodec; | 376 return kUnknownVideoCodec; |
| 293 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; | 377 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; |
| 294 uint8_t level = 0; | 378 uint8_t level = 0; |
| 379 if (codec_id == "vp8" || codec_id == "vp8.0") | |
| 380 return kCodecVP8; | |
| 381 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level) || | |
| 382 ParseLegacyVp9CodecID(codec_id, &profile, &level)) { | |
| 383 return kCodecVP9; | |
| 384 } | |
| 385 if (codec_id == "theora") | |
| 386 return kCodecTheora; | |
| 295 if (ParseAVCCodecId(codec_id, &profile, &level)) | 387 if (ParseAVCCodecId(codec_id, &profile, &level)) |
| 296 return kCodecH264; | 388 return kCodecH264; |
| 297 if (codec_id == "vp8" || codec_id == "vp8.0") | |
| 298 return kCodecVP8; | |
| 299 if (codec_id == "vp9" || codec_id == "vp9.0") | |
| 300 return kCodecVP9; | |
| 301 if (codec_id == "theora") | |
| 302 return kCodecTheora; | |
| 303 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 389 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 304 if (ParseHEVCCodecId(codec_id, &profile, &level)) | 390 if (ParseHEVCCodecId(codec_id, &profile, &level)) |
| 305 return kCodecHEVC; | 391 return kCodecHEVC; |
| 306 #endif | 392 #endif |
| 307 return kUnknownVideoCodec; | 393 return kUnknownVideoCodec; |
| 308 } | 394 } |
| 309 | 395 |
| 310 } // namespace media | 396 } // namespace media |
| OLD | NEW |