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" |
| 9 #include "base/strings/string_util.h" |
8 | 10 |
9 namespace media { | 11 namespace media { |
10 | 12 |
11 // The names come from src/third_party/ffmpeg/libavcodec/codec_desc.c | 13 // The names come from src/third_party/ffmpeg/libavcodec/codec_desc.c |
12 std::string GetCodecName(VideoCodec codec) { | 14 std::string GetCodecName(VideoCodec codec) { |
13 switch (codec) { | 15 switch (codec) { |
14 case kUnknownVideoCodec: | 16 case kUnknownVideoCodec: |
15 return "unknown"; | 17 return "unknown"; |
16 case kCodecH264: | 18 case kCodecH264: |
17 return "h264"; | 19 return "h264"; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 return "h264 multiview high"; | 64 return "h264 multiview high"; |
63 case VP8PROFILE_ANY: | 65 case VP8PROFILE_ANY: |
64 return "vp8"; | 66 return "vp8"; |
65 case VP9PROFILE_ANY: | 67 case VP9PROFILE_ANY: |
66 return "vp9"; | 68 return "vp9"; |
67 } | 69 } |
68 NOTREACHED(); | 70 NOTREACHED(); |
69 return ""; | 71 return ""; |
70 } | 72 } |
71 | 73 |
| 74 bool ParseAVCCodecId(const std::string& codec_id, |
| 75 VideoCodecProfile* profile, |
| 76 uint8_t* level_idc) { |
| 77 // Make sure we have avc1.xxxxxx or avc3.xxxxxx , where xxxxxx are hex digits |
| 78 if (!base::StartsWith(codec_id, "avc1.", base::CompareCase::SENSITIVE) && |
| 79 !base::StartsWith(codec_id, "avc3.", base::CompareCase::SENSITIVE)) { |
| 80 return false; |
| 81 } |
| 82 uint32_t elem = 0; |
| 83 if (codec_id.size() != 11 || |
| 84 !base::HexStringToUInt(base::StringPiece(codec_id).substr(5), &elem)) { |
| 85 DVLOG(4) << __FUNCTION__ << ": invalid avc codec id (" << codec_id << ")"; |
| 86 return false; |
| 87 } |
| 88 |
| 89 uint8_t level_byte = elem & 0xFF; |
| 90 uint8_t constraints_byte = (elem >> 8) & 0xFF; |
| 91 uint8_t profile_idc = (elem >> 16) & 0xFF; |
| 92 |
| 93 // Check that the lower two bits of |constraints_byte| are zero (those are |
| 94 // reserved and must be zero according to ISO IEC 14496-10). |
| 95 if (constraints_byte & 3) { |
| 96 DVLOG(4) << __FUNCTION__ << ": non-zero reserved bits in codec id " |
| 97 << codec_id; |
| 98 return false; |
| 99 } |
| 100 |
| 101 VideoCodecProfile out_profile = VIDEO_CODEC_PROFILE_UNKNOWN; |
| 102 // profile_idc values for each profile are taken from ISO IEC 14496-10 and |
| 103 // https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Profiles |
| 104 switch (profile_idc) { |
| 105 case 66: |
| 106 out_profile = H264PROFILE_BASELINE; |
| 107 break; |
| 108 case 77: |
| 109 out_profile = H264PROFILE_MAIN; |
| 110 break; |
| 111 case 83: |
| 112 out_profile = H264PROFILE_SCALABLEBASELINE; |
| 113 break; |
| 114 case 86: |
| 115 out_profile = H264PROFILE_SCALABLEHIGH; |
| 116 break; |
| 117 case 88: |
| 118 out_profile = H264PROFILE_EXTENDED; |
| 119 break; |
| 120 case 100: |
| 121 out_profile = H264PROFILE_HIGH; |
| 122 break; |
| 123 case 110: |
| 124 out_profile = H264PROFILE_HIGH10PROFILE; |
| 125 break; |
| 126 case 118: |
| 127 out_profile = H264PROFILE_MULTIVIEWHIGH; |
| 128 break; |
| 129 case 122: |
| 130 out_profile = H264PROFILE_HIGH422PROFILE; |
| 131 break; |
| 132 case 128: |
| 133 out_profile = H264PROFILE_STEREOHIGH; |
| 134 break; |
| 135 case 244: |
| 136 out_profile = H264PROFILE_HIGH444PREDICTIVEPROFILE; |
| 137 break; |
| 138 default: |
| 139 DVLOG(1) << "Warning: unrecognized AVC/H.264 profile " << profile_idc; |
| 140 return false; |
| 141 } |
| 142 |
| 143 // TODO(servolk): Take into account also constraint set flags 3 through 5. |
| 144 uint8_t constraint_set0_flag = (constraints_byte >> 7) & 1; |
| 145 uint8_t constraint_set1_flag = (constraints_byte >> 6) & 1; |
| 146 uint8_t constraint_set2_flag = (constraints_byte >> 5) & 1; |
| 147 if (constraint_set2_flag && out_profile > H264PROFILE_EXTENDED) { |
| 148 out_profile = H264PROFILE_EXTENDED; |
| 149 } |
| 150 if (constraint_set1_flag && out_profile > H264PROFILE_MAIN) { |
| 151 out_profile = H264PROFILE_MAIN; |
| 152 } |
| 153 if (constraint_set0_flag && out_profile > H264PROFILE_BASELINE) { |
| 154 out_profile = H264PROFILE_BASELINE; |
| 155 } |
| 156 |
| 157 if (level_idc) |
| 158 *level_idc = level_byte; |
| 159 |
| 160 if (profile) |
| 161 *profile = out_profile; |
| 162 |
| 163 return true; |
| 164 } |
| 165 |
72 } // namespace media | 166 } // namespace media |
OLD | NEW |