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 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 |