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

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

Issue 2640113004: Introduce Dolby Vision video codec and Demuxer support (Closed)
Patch Set: fix build break on Android Created 3 years, 9 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
« no previous file with comments | « media/base/video_codecs.h ('k') | media/base/video_codecs_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 bool IsDolbyVisionAVCCodecId(const std::string& codec_id) {
434 return base::StartsWith(codec_id, "dva1.", base::CompareCase::SENSITIVE) ||
435 base::StartsWith(codec_id, "dvav.", base::CompareCase::SENSITIVE);
436 }
437
438 bool IsDolbyVisionHEVCCodecId(const std::string& codec_id) {
439 return base::StartsWith(codec_id, "dvh1.", base::CompareCase::SENSITIVE) ||
440 base::StartsWith(codec_id, "dvhe.", base::CompareCase::SENSITIVE);
441 }
442
443 // The specification for Dolby Vision codec id strings can be found in Dolby
444 // Vision streams within the MPEG-DASH format.
445 bool ParseDolbyVisionCodecId(const std::string& codec_id,
446 VideoCodecProfile* profile,
447 uint8_t* level_idc) {
448 if (!IsDolbyVisionAVCCodecId(codec_id) &&
449 !IsDolbyVisionHEVCCodecId(codec_id)) {
450 return false;
451 }
452
453 const int kMaxDvCodecIdLength = 5 // FOURCC string
454 + 1 // delimiting period
455 + 2 // profile id as 2 digit string
456 + 1 // delimiting period
457 + 2; // level id as 2 digit string.
458
459 if (codec_id.size() > kMaxDvCodecIdLength) {
460 DVLOG(4) << __func__ << ": Codec id is too long (" << codec_id << ")";
461 return false;
462 }
463
464 std::vector<std::string> elem = base::SplitString(
465 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
466 DCHECK(elem[0] == "dvh1" || elem[0] == "dvhe" || elem[0] == "dva1" ||
467 elem[0] == "dvav");
468
469 if (elem.size() != 3) {
470 DVLOG(4) << __func__ << ": invalid dolby vision codec id " << codec_id;
471 return false;
472 }
473
474 // Profile string should be two digits.
475 unsigned profile_id = 0;
476 if (elem[1].size() != 2 || !base::StringToUint(elem[1], &profile_id) ||
477 profile_id > 7) {
478 DVLOG(4) << __func__ << ": invalid format or profile_id=" << elem[1];
479 return false;
480 }
481
482 // Only profiles 0, 4, 5 and 7 are valid. Profile 0 is encoded based on AVC
483 // while profile 4, 5 and 7 are based on HEVC.
484 switch (profile_id) {
485 case 0:
486 if (!IsDolbyVisionAVCCodecId(codec_id)) {
487 DVLOG(4) << __func__
488 << ": codec id is mismatched with profile_id=" << profile_id;
489 return false;
490 }
491 *profile = DOLBYVISION_PROFILE0;
492 break;
493 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
494 case 4:
495 case 5:
496 case 7:
497 if (!IsDolbyVisionHEVCCodecId(codec_id)) {
498 DVLOG(4) << __func__
499 << ": codec id is mismatched with profile_id=" << profile_id;
500 return false;
501 }
502 if (profile_id == 4)
503 *profile = DOLBYVISION_PROFILE4;
504 else if (profile_id == 5)
505 *profile = DOLBYVISION_PROFILE5;
506 else if (profile_id == 7)
507 *profile = DOLBYVISION_PROFILE7;
508 break;
509 #endif
510 default:
511 DVLOG(4) << __func__
512 << ": depecrated and not supported profile_id=" << profile_id;
513 return false;
514 }
515
516 // Level string should be two digits.
517 unsigned level_id = 0;
518 if (elem[2].size() != 2 || !base::StringToUint(elem[2], &level_id) ||
519 level_id > 9 || level_id < 1) {
520 DVLOG(4) << __func__ << ": invalid format level_id=" << elem[2];
521 return false;
522 }
523
524 *level_idc = level_id;
525
526 return true;
527 }
528 #endif
529
422 VideoCodec StringToVideoCodec(const std::string& codec_id) { 530 VideoCodec StringToVideoCodec(const std::string& codec_id) {
423 std::vector<std::string> elem = base::SplitString( 531 std::vector<std::string> elem = base::SplitString(
424 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 532 codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
425 if (elem.empty()) 533 if (elem.empty())
426 return kUnknownVideoCodec; 534 return kUnknownVideoCodec;
427 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; 535 VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
428 uint8_t level = 0; 536 uint8_t level = 0;
429 if (codec_id == "vp8" || codec_id == "vp8.0") 537 if (codec_id == "vp8" || codec_id == "vp8.0")
430 return kCodecVP8; 538 return kCodecVP8;
431 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level) || 539 if (ParseNewStyleVp9CodecID(codec_id, &profile, &level) ||
432 ParseLegacyVp9CodecID(codec_id, &profile, &level)) { 540 ParseLegacyVp9CodecID(codec_id, &profile, &level)) {
433 return kCodecVP9; 541 return kCodecVP9;
434 } 542 }
435 if (codec_id == "theora") 543 if (codec_id == "theora")
436 return kCodecTheora; 544 return kCodecTheora;
437 if (ParseAVCCodecId(codec_id, &profile, &level)) 545 if (ParseAVCCodecId(codec_id, &profile, &level))
438 return kCodecH264; 546 return kCodecH264;
439 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) 547 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
440 if (ParseAVCCodecId(TranslateLegacyAvc1CodecIds(codec_id), &profile, &level)) 548 if (ParseAVCCodecId(TranslateLegacyAvc1CodecIds(codec_id), &profile, &level))
441 return kCodecH264; 549 return kCodecH264;
442 #endif 550 #endif
443 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 551 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
444 if (ParseHEVCCodecId(codec_id, &profile, &level)) 552 if (ParseHEVCCodecId(codec_id, &profile, &level))
445 return kCodecHEVC; 553 return kCodecHEVC;
446 #endif 554 #endif
555 #if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
556 if (ParseDolbyVisionCodecId(codec_id, &profile, &level))
557 return kCodecDolbyVision;
558 #endif
447 return kUnknownVideoCodec; 559 return kUnknownVideoCodec;
448 } 560 }
449 561
450 } // namespace media 562 } // namespace media
OLDNEW
« no previous file with comments | « media/base/video_codecs.h ('k') | media/base/video_codecs_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698