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

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

Issue 2640113004: Introduce Dolby Vision video codec and Demuxer support (Closed)
Patch Set: fix CQ failure Created 3 years, 10 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
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"
11 11
12 namespace media { 12 namespace media {
13 13
14 // 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
15 std::string GetCodecName(VideoCodec codec) { 15 std::string GetCodecName(VideoCodec codec) {
16 switch (codec) { 16 switch (codec) {
17 case kUnknownVideoCodec: 17 case kUnknownVideoCodec:
18 return "unknown"; 18 return "unknown";
19 case kCodecH264: 19 case kCodecH264:
20 return "h264"; 20 return "h264";
21 case kCodecHEVC: 21 case kCodecHEVC:
22 return "hevc"; 22 return "hevc";
23 case kCodecDolbyVision:
24 return "dolbyvision";
23 case kCodecVC1: 25 case kCodecVC1:
24 return "vc1"; 26 return "vc1";
25 case kCodecMPEG2: 27 case kCodecMPEG2:
26 return "mpeg2video"; 28 return "mpeg2video";
27 case kCodecMPEG4: 29 case kCodecMPEG4:
28 return "mpeg4"; 30 return "mpeg4";
29 case kCodecTheora: 31 case kCodecTheora:
30 return "theora"; 32 return "theora";
31 case kCodecVP8: 33 case kCodecVP8:
32 return "vp8"; 34 return "vp8";
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 DVLOG(4) << __func__ << ": invalid constraint byte=" << elem[i]; 422 DVLOG(4) << __func__ << ": invalid constraint byte=" << elem[i];
413 return false; 423 return false;
414 } 424 }
415 constraint_flags[i - 4] = constr_byte; 425 constraint_flags[i - 4] = constr_byte;
416 } 426 }
417 427
418 return true; 428 return true;
419 } 429 }
420 #endif 430 #endif
421 431
432 #if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
433 // The specification for Dolby Vision codec id strings can be found in Dolby
434 // Vision streams within the MPEG-DASH format.
435 bool ParseDolbyVisionCodecId(const std::string& codec_id,
436 VideoCodecProfile* profile,
437 uint8_t* level_idc) {
438 if (!base::StartsWith(codec_id, "dvh1.", base::CompareCase::SENSITIVE) &&
439 !base::StartsWith(codec_id, "dvhe.", base::CompareCase::SENSITIVE) &&
440 !base::StartsWith(codec_id, "dva1.", base::CompareCase::SENSITIVE) &&
441 !base::StartsWith(codec_id, "dvav.", base::CompareCase::SENSITIVE)) {
442 return false;
443 }
444
445 const int kMaxDvCodecIdLength = 5 // FOURCC string
446 + 1 // delimiting period
447 + 2 // profile id as 2 digit string
448 + 1 // delimiting period
449 + 2; // level id as 2 digit string.
450
451 if (codec_id.size() > kMaxDvCodecIdLength) {
452 DVLOG(4) << __func__ << ": Codec id is too long (" << codec_id << ")";
453 return false;
454 }
455
456 std::vector<std::string> elem = base::SplitString(
457 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
458 DCHECK(elem[0] == "dvh1" || elem[0] == "dvhe" || elem[0] == "dva1" ||
459 elem[0] == "dvav");
460
461 if (elem.size() != 3) {
462 DVLOG(4) << __func__ << ": invalid dolby vision codec id " << codec_id;
463 return false;
464 }
465
466 unsigned profile_id = 0;
467 if (!base::StringToUint(elem[1], &profile_id) || profile_id > 7) {
468 DVLOG(4) << __func__ << ": invalid profile_id=" << elem[1];
469 return false;
470 }
471
472 // Only profiles 0, 4, 5 and 7 are valid. Profile 0 is encoded based on AVC
473 // while profile 4, 5 and 7 are based on HEVC.
474 switch (profile_id) {
475 case 0:
476 *profile = DOLBYVISION_PROFILE0;
477 break;
478 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
479 case 4:
480 *profile = DOLBYVISION_PROFILE4;
481 break;
482 case 5:
483 *profile = DOLBYVISION_PROFILE5;
484 break;
485 case 7:
486 *profile = DOLBYVISION_PROFILE7;
487 break;
488 #endif
489 default:
490 DVLOG(4) << __func__
491 << ": depecrated and not supported profile_id=" << profile_id;
492 return false;
493 }
494
495 unsigned level_id = 0;
496 if (!base::StringToUint(elem[2], &level_id) || level_id > 9 || level_id < 1) {
497 DVLOG(4) << __func__ << ": invalid level_id=" << elem[2];
498 return false;
499 }
500
501 *level_idc = level_id;
502
503 return true;
504 }
505 #endif
506
422 VideoCodec StringToVideoCodec(const std::string& codec_id) { 507 VideoCodec StringToVideoCodec(const std::string& codec_id) {
423 std::vector<std::string> elem = base::SplitString( 508 std::vector<std::string> elem = base::SplitString(
424 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 509 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
425 if (elem.empty()) 510 if (elem.empty())
426 return kUnknownVideoCodec; 511 return kUnknownVideoCodec;
427 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; 512 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
428 uint8_t level = 0; 513 uint8_t level = 0;
429 if (codec_id == "vp8" || codec_id == "vp8.0") 514 if (codec_id == "vp8" || codec_id == "vp8.0")
430 return kCodecVP8; 515 return kCodecVP8;
431 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level) || 516 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level) ||
432 ParseLegacyVp9CodecID(codec_id, &profile, &level)) { 517 ParseLegacyVp9CodecID(codec_id, &profile, &level)) {
433 return kCodecVP9; 518 return kCodecVP9;
434 } 519 }
435 if (codec_id == "theora") 520 if (codec_id == "theora")
436 return kCodecTheora; 521 return kCodecTheora;
437 if (ParseAVCCodecId(codec_id, &profile, &level)) 522 if (ParseAVCCodecId(codec_id, &profile, &level))
438 return kCodecH264; 523 return kCodecH264;
439 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) 524 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
440 if (ParseAVCCodecId(TranslateLegacyAvc1CodecIds(codec_id), &profile, &level)) 525 if (ParseAVCCodecId(TranslateLegacyAvc1CodecIds(codec_id), &profile, &level))
441 return kCodecH264; 526 return kCodecH264;
442 #endif 527 #endif
443 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 528 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
444 if (ParseHEVCCodecId(codec_id, &profile, &level)) 529 if (ParseHEVCCodecId(codec_id, &profile, &level))
445 return kCodecHEVC; 530 return kCodecHEVC;
446 #endif 531 #endif
532 #if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
533 if (ParseDolbyVisionCodecId(codec_id, &profile, &level))
534 return kCodecDolbyVision;
535 #endif
447 return kUnknownVideoCodec; 536 return kUnknownVideoCodec;
448 } 537 }
449 538
450 } // namespace media 539 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698