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_util.h" | 10 #include "base/strings/string_util.h" |
| 10 | 11 |
| 11 namespace media { | 12 namespace media { |
| 12 | 13 |
| 13 // The names come from src/third_party/ffmpeg/libavcodec/codec_desc.c | 14 // The names come from src/third_party/ffmpeg/libavcodec/codec_desc.c |
| 14 std::string GetCodecName(VideoCodec codec) { | 15 std::string GetCodecName(VideoCodec codec) { |
| 15 switch (codec) { | 16 switch (codec) { |
| 16 case kUnknownVideoCodec: | 17 case kUnknownVideoCodec: |
| 17 return "unknown"; | 18 return "unknown"; |
| 18 case kCodecH264: | 19 case kCodecH264: |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 55 case H264PROFILE_HIGH444PREDICTIVEPROFILE: | 56 case H264PROFILE_HIGH444PREDICTIVEPROFILE: |
| 56 return "h264 high 4:4:4 predictive"; | 57 return "h264 high 4:4:4 predictive"; |
| 57 case H264PROFILE_SCALABLEBASELINE: | 58 case H264PROFILE_SCALABLEBASELINE: |
| 58 return "h264 scalable baseline"; | 59 return "h264 scalable baseline"; |
| 59 case H264PROFILE_SCALABLEHIGH: | 60 case H264PROFILE_SCALABLEHIGH: |
| 60 return "h264 scalable high"; | 61 return "h264 scalable high"; |
| 61 case H264PROFILE_STEREOHIGH: | 62 case H264PROFILE_STEREOHIGH: |
| 62 return "h264 stereo high"; | 63 return "h264 stereo high"; |
| 63 case H264PROFILE_MULTIVIEWHIGH: | 64 case H264PROFILE_MULTIVIEWHIGH: |
| 64 return "h264 multiview high"; | 65 return "h264 multiview high"; |
| 66 case HEVCPROFILE_MAIN: | |
| 67 return "hevc main"; | |
| 68 case HEVCPROFILE_MAIN10: | |
| 69 return "hevc main 10"; | |
| 70 case HEVCPROFILE_MAIN_STILL_PICTURE: | |
| 71 return "hevc main still-picture"; | |
| 65 case VP8PROFILE_ANY: | 72 case VP8PROFILE_ANY: |
| 66 return "vp8"; | 73 return "vp8"; |
| 67 case VP9PROFILE_PROFILE0: | 74 case VP9PROFILE_PROFILE0: |
| 68 return "vp9 profile0"; | 75 return "vp9 profile0"; |
| 69 case VP9PROFILE_PROFILE1: | 76 case VP9PROFILE_PROFILE1: |
| 70 return "vp9 profile1"; | 77 return "vp9 profile1"; |
| 71 case VP9PROFILE_PROFILE2: | 78 case VP9PROFILE_PROFILE2: |
| 72 return "vp9 profile2"; | 79 return "vp9 profile2"; |
| 73 case VP9PROFILE_PROFILE3: | 80 case VP9PROFILE_PROFILE3: |
| 74 return "vp9 profile3"; | 81 return "vp9 profile3"; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 | 169 |
| 163 if (level_idc) | 170 if (level_idc) |
| 164 *level_idc = level_byte; | 171 *level_idc = level_byte; |
| 165 | 172 |
| 166 if (profile) | 173 if (profile) |
| 167 *profile = out_profile; | 174 *profile = out_profile; |
| 168 | 175 |
| 169 return true; | 176 return true; |
| 170 } | 177 } |
| 171 | 178 |
| 179 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | |
| 180 // The specification for HEVC codec id strings can be found in ISO IEC 14496-15 | |
| 181 // dated 2012 or newer in the Annex E.3 | |
| 182 bool ParseHEVCCodecId(const std::string& codec_id, | |
| 183 VideoCodecProfile* profile, | |
| 184 uint8_t* level_idc) { | |
| 185 if (!base::StartsWith(codec_id, "hev1.", base::CompareCase::SENSITIVE) && | |
| 186 !base::StartsWith(codec_id, "hvc1.", base::CompareCase::SENSITIVE)) { | |
| 187 return false; | |
| 188 } | |
| 189 | |
| 190 // HEVC codec id consists of: | |
| 191 const int kMaxHevcCodecIdLength = | |
| 192 5 + // 'hev1.' or 'hvc1.' prefix (5 chars) | |
| 193 4 + // profile, e.g. '.A12' (max 4 chars) | |
| 194 9 + // profile_compatibility, dot + 32-bit hex number (max 9 chars) | |
| 195 5 + // tier and level, e.g. '.H120' (max 5 chars) | |
| 196 18; // up to 6 constraint bytes, bytes are dot-separated and hex-encoded. | |
| 197 | |
| 198 if (codec_id.size() > kMaxHevcCodecIdLength) { | |
| 199 DVLOG(4) << __FUNCTION__ << ": Codec id is too long (" << codec_id << ")"; | |
| 200 return false; | |
| 201 } | |
| 202 | |
| 203 std::vector<std::string> elem = base::SplitString( | |
| 204 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 205 DCHECK(elem[0] == "hev1" || elem[0] == "hvc1"); | |
| 206 | |
| 207 if (elem.size() < 4) { | |
| 208 DVLOG(4) << __FUNCTION__ << ": invalid HEVC codec id " << codec_id; | |
| 209 return false; | |
| 210 } | |
| 211 | |
| 212 uint8_t general_profile_space = 0; | |
| 213 if (elem[1].size() > 0 && | |
| 214 (elem[1][0] == 'A' || elem[1][0] == 'B' || elem[1][0] == 'C')) { | |
| 215 general_profile_space = 1 + (elem[1][0] - 'A'); | |
| 216 elem[1].erase(0, 1); | |
| 217 } | |
| 218 DCHECK(general_profile_space >= 0 && general_profile_space <= 3); | |
|
ddorwin
2016/04/20 23:32:41
Should we be doing anything with general_profile_s
servolk
2016/04/20 23:57:48
No, general_profile_space is expected to be 0 for
ddorwin
2016/04/21 00:00:31
Then why do we allow 1, 2, and 3?
To the original
servolk
2016/04/21 00:13:27
Well, let me clarify. What I quoted above is from
| |
| 219 | |
| 220 unsigned general_profile_idc = 0; | |
| 221 if (!base::StringToUint(elem[1], &general_profile_idc) || | |
| 222 general_profile_idc > 0x1f) { | |
| 223 DVLOG(4) << __FUNCTION__ << ": invalid general_profile_idc=" << elem[1]; | |
| 224 return false; | |
| 225 } | |
| 226 | |
| 227 uint32_t general_profile_compatibility_flags = 0; | |
| 228 if (!base::HexStringToUInt(elem[2], &general_profile_compatibility_flags)) { | |
| 229 DVLOG(4) << __FUNCTION__ | |
| 230 << ": invalid general_profile_compatibility_flags=" << elem[2]; | |
| 231 return false; | |
| 232 } | |
| 233 | |
| 234 if (profile) { | |
| 235 // TODO(servolk): Handle format range extension profiles as explained in | |
| 236 // HEVC standard (ISO/IEC ISO/IEC 23008-2) section A.3.5 | |
| 237 if (general_profile_idc == 3 || (general_profile_compatibility_flags & 4)) { | |
| 238 *profile = HEVCPROFILE_MAIN_STILL_PICTURE; | |
| 239 } | |
| 240 if (general_profile_idc == 2 || (general_profile_compatibility_flags & 2)) { | |
| 241 *profile = HEVCPROFILE_MAIN10; | |
| 242 } | |
| 243 if (general_profile_idc == 1 || (general_profile_compatibility_flags & 1)) { | |
| 244 *profile = HEVCPROFILE_MAIN; | |
| 245 } | |
| 246 } | |
| 247 | |
| 248 uint8_t general_tier_flag; | |
| 249 if (elem[3].size() > 0 && (elem[3][0] == 'L' || elem[3][0] == 'H')) { | |
| 250 general_tier_flag = (elem[3][0] == 'L') ? 0 : 1; | |
| 251 elem[3].erase(0, 1); | |
| 252 } else { | |
| 253 DVLOG(4) << __FUNCTION__ << ": invalid general_tier_flag=" << elem[3]; | |
| 254 return false; | |
| 255 } | |
| 256 DCHECK(general_tier_flag == 0 || general_tier_flag == 1); | |
| 257 | |
| 258 unsigned general_level_idc = 0; | |
| 259 if (!base::StringToUint(elem[3], &general_level_idc) || | |
| 260 general_level_idc > 0xff) { | |
| 261 DVLOG(4) << __FUNCTION__ << ": invalid general_level_idc=" << elem[3]; | |
| 262 return false; | |
| 263 } | |
| 264 | |
| 265 if (level_idc) | |
| 266 *level_idc = static_cast<uint8_t>(general_level_idc); | |
| 267 | |
| 268 uint8_t constraint_flags[6]; | |
| 269 memset(constraint_flags, 0, sizeof(constraint_flags)); | |
| 270 | |
| 271 if (elem.size() > 10) { | |
| 272 DVLOG(4) << __FUNCTION__ << ": unexpected number of trailing bytes in HEVC " | |
| 273 << "codec id " << codec_id; | |
| 274 return false; | |
| 275 } | |
| 276 for (size_t i = 4; i < elem.size(); ++i) { | |
| 277 unsigned constr_byte = 0; | |
| 278 if (!base::HexStringToUInt(elem[i], &constr_byte) || constr_byte > 0xFF) { | |
| 279 DVLOG(4) << __FUNCTION__ << ": invalid constraint byte=" << elem[i]; | |
| 280 return false; | |
| 281 } | |
| 282 constraint_flags[i] = constr_byte; | |
| 283 } | |
| 284 | |
| 285 return true; | |
| 286 } | |
| 287 #endif | |
| 288 | |
| 172 } // namespace media | 289 } // namespace media |
| OLD | NEW |