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 14 matching lines...) Expand all Loading... | |
| 25 case kCodecMPEG2: | 25 case kCodecMPEG2: |
| 26 return "mpeg2video"; | 26 return "mpeg2video"; |
| 27 case kCodecMPEG4: | 27 case kCodecMPEG4: |
| 28 return "mpeg4"; | 28 return "mpeg4"; |
| 29 case kCodecTheora: | 29 case kCodecTheora: |
| 30 return "theora"; | 30 return "theora"; |
| 31 case kCodecVP8: | 31 case kCodecVP8: |
| 32 return "vp8"; | 32 return "vp8"; |
| 33 case kCodecVP9: | 33 case kCodecVP9: |
| 34 return "vp9"; | 34 return "vp9"; |
| 35 case kCodecDolbyVision: | |
|
wolenetz
2017/01/25 23:42:41
nit: these cases are already not in sequence with
erickung1
2017/02/03 18:18:31
Done.
| |
| 36 return "dolbyvision"; | |
| 35 } | 37 } |
| 36 NOTREACHED(); | 38 NOTREACHED(); |
| 37 return ""; | 39 return ""; |
| 38 } | 40 } |
| 39 | 41 |
| 40 std::string GetProfileName(VideoCodecProfile profile) { | 42 std::string GetProfileName(VideoCodecProfile profile) { |
| 41 switch (profile) { | 43 switch (profile) { |
| 42 case VIDEO_CODEC_PROFILE_UNKNOWN: | 44 case VIDEO_CODEC_PROFILE_UNKNOWN: |
| 43 return "unknown"; | 45 return "unknown"; |
| 44 case H264PROFILE_BASELINE: | 46 case H264PROFILE_BASELINE: |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 72 case VP8PROFILE_ANY: | 74 case VP8PROFILE_ANY: |
| 73 return "vp8"; | 75 return "vp8"; |
| 74 case VP9PROFILE_PROFILE0: | 76 case VP9PROFILE_PROFILE0: |
| 75 return "vp9 profile0"; | 77 return "vp9 profile0"; |
| 76 case VP9PROFILE_PROFILE1: | 78 case VP9PROFILE_PROFILE1: |
| 77 return "vp9 profile1"; | 79 return "vp9 profile1"; |
| 78 case VP9PROFILE_PROFILE2: | 80 case VP9PROFILE_PROFILE2: |
| 79 return "vp9 profile2"; | 81 return "vp9 profile2"; |
| 80 case VP9PROFILE_PROFILE3: | 82 case VP9PROFILE_PROFILE3: |
| 81 return "vp9 profile3"; | 83 return "vp9 profile3"; |
| 84 case DOLBYVISION_PROFILE0: | |
| 85 return "dolby vision profile 0"; | |
| 86 case DOLBYVISION_PROFILE4: | |
| 87 return "dolby vision profile 4"; | |
| 88 case DOLBYVISION_PROFILE5: | |
| 89 return "dolby vision profile 5"; | |
| 90 case DOLBYVISION_PROFILE7: | |
| 91 return "dolby vision profile 7"; | |
| 82 } | 92 } |
| 83 NOTREACHED(); | 93 NOTREACHED(); |
| 84 return ""; | 94 return ""; |
| 85 } | 95 } |
| 86 | 96 |
| 87 bool ParseNewStyleVp9CodecID(const std::string& codec_id, | 97 bool ParseNewStyleVp9CodecID(const std::string& codec_id, |
| 88 VideoCodecProfile* profile, | 98 VideoCodecProfile* profile, |
| 89 uint8_t* level_idc) { | 99 uint8_t* level_idc) { |
| 90 std::vector<std::string> fields = base::SplitString( | 100 std::vector<std::string> fields = base::SplitString( |
| 91 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | 101 codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 DVLOG(4) << __func__ << ": invalid constraint byte=" << elem[i]; | 373 DVLOG(4) << __func__ << ": invalid constraint byte=" << elem[i]; |
| 364 return false; | 374 return false; |
| 365 } | 375 } |
| 366 constraint_flags[i - 4] = constr_byte; | 376 constraint_flags[i - 4] = constr_byte; |
| 367 } | 377 } |
| 368 | 378 |
| 369 return true; | 379 return true; |
| 370 } | 380 } |
| 371 #endif | 381 #endif |
| 372 | 382 |
| 383 #if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) | |
| 384 // The specification for Dolby Vision codec id strings can be found in Dolby | |
| 385 // Vision streams within the MPEG-DASH format. | |
| 386 bool ParseDolbyVisionCodecId(const std::string& codec_id, | |
| 387 VideoCodecProfile* profile, | |
| 388 uint8_t* level_idc) { | |
| 389 if (!base::StartsWith(codec_id, "dvh1.", base::CompareCase::SENSITIVE) && | |
| 390 !base::StartsWith(codec_id, "dvhe.", base::CompareCase::SENSITIVE) && | |
| 391 !base::StartsWith(codec_id, "dva1.", base::CompareCase::SENSITIVE) && | |
| 392 !base::StartsWith(codec_id, "dvav.", base::CompareCase::SENSITIVE)) { | |
| 393 return false; | |
| 394 } | |
| 395 | |
| 396 const int kMaxDvCodecIdLength = 5 // FOURCC string | |
| 397 + 1 // delimiting period | |
| 398 + 2 // profile id as 2 digit string | |
| 399 + 1 // delimiting period | |
| 400 + 2; // level id as 2 digit string. | |
| 401 | |
| 402 if (codec_id.size() > kMaxDvCodecIdLength) { | |
| 403 DVLOG(4) << __func__ << ": Codec id is too long (" << codec_id << ")"; | |
| 404 return false; | |
| 405 } | |
| 406 | |
| 407 std::vector<std::string> elem = base::SplitString( | |
| 408 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 409 DCHECK(elem[0] == "dvh1" || elem[0] == "dvhe" || elem[0] == "dva1" || | |
| 410 elem[0] == "dvav"); | |
| 411 | |
| 412 if (elem.size() != 3) { | |
| 413 DVLOG(4) << __func__ << ": invalid dolby vision codec id " << codec_id; | |
| 414 return false; | |
| 415 } | |
| 416 | |
| 417 unsigned profile_id = 0; | |
| 418 if (!base::StringToUint(elem[1], &profile_id) || profile_id > 7) { | |
| 419 DVLOG(4) << __func__ << ": invalid profile_id=" << elem[1]; | |
| 420 return false; | |
| 421 } | |
| 422 | |
| 423 // Only profile 0, 4 ,5 and 7 are valid. | |
|
wolenetz
2017/01/25 23:42:41
nit: s/profile/profiles/ and s/4 ,/4, /
erickung1
2017/02/03 18:18:31
Done.
| |
| 424 switch (profile_id) { | |
| 425 case 0: | |
| 426 *profile = DOLBYVISION_PROFILE0; | |
| 427 break; | |
| 428 case 4: | |
| 429 *profile = DOLBYVISION_PROFILE4; | |
| 430 break; | |
| 431 case 5: | |
| 432 *profile = DOLBYVISION_PROFILE5; | |
| 433 break; | |
| 434 case 7: | |
| 435 *profile = DOLBYVISION_PROFILE7; | |
| 436 break; | |
| 437 default: | |
| 438 DVLOG(4) << __func__ << ": depecrated profile_id=" << profile_id; | |
|
wolenetz
2017/01/25 23:42:41
nit: s/deprecated/deprecated and not supported/ ?
erickung1
2017/02/03 18:18:31
Done.
| |
| 439 return false; | |
| 440 } | |
| 441 | |
| 442 unsigned level_id = 0; | |
| 443 if (!base::StringToUint(elem[2], &level_id) || level_id > 9 || level_id < 1) { | |
| 444 DVLOG(4) << __func__ << ": invalid level_id=" << elem[2]; | |
| 445 return false; | |
| 446 } | |
| 447 | |
| 448 *level_idc = level_id; | |
| 449 | |
| 450 return true; | |
| 451 } | |
| 452 #endif | |
| 453 | |
| 373 VideoCodec StringToVideoCodec(const std::string& codec_id) { | 454 VideoCodec StringToVideoCodec(const std::string& codec_id) { |
| 374 std::vector<std::string> elem = base::SplitString( | 455 std::vector<std::string> elem = base::SplitString( |
| 375 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 456 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 376 if (elem.empty()) | 457 if (elem.empty()) |
| 377 return kUnknownVideoCodec; | 458 return kUnknownVideoCodec; |
| 378 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; | 459 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; |
| 379 uint8_t level = 0; | 460 uint8_t level = 0; |
| 380 if (codec_id == "vp8" || codec_id == "vp8.0") | 461 if (codec_id == "vp8" || codec_id == "vp8.0") |
| 381 return kCodecVP8; | 462 return kCodecVP8; |
| 382 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level) || | 463 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level) || |
| 383 ParseLegacyVp9CodecID(codec_id, &profile, &level)) { | 464 ParseLegacyVp9CodecID(codec_id, &profile, &level)) { |
| 384 return kCodecVP9; | 465 return kCodecVP9; |
| 385 } | 466 } |
| 386 if (codec_id == "theora") | 467 if (codec_id == "theora") |
| 387 return kCodecTheora; | 468 return kCodecTheora; |
| 388 if (ParseAVCCodecId(codec_id, &profile, &level)) | 469 if (ParseAVCCodecId(codec_id, &profile, &level)) |
| 389 return kCodecH264; | 470 return kCodecH264; |
| 390 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 471 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
| 391 if (ParseHEVCCodecId(codec_id, &profile, &level)) | 472 if (ParseHEVCCodecId(codec_id, &profile, &level)) |
| 392 return kCodecHEVC; | 473 return kCodecHEVC; |
| 393 #endif | 474 #endif |
| 475 #if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) | |
| 476 if (ParseDolbyVisionCodecId(codec_id, &profile, &level)) | |
| 477 return kCodecDolbyVision; | |
| 478 #endif | |
| 394 return kUnknownVideoCodec; | 479 return kUnknownVideoCodec; |
| 395 } | 480 } |
| 396 | 481 |
| 397 } // namespace media | 482 } // namespace media |
| OLD | NEW |