Index: media/base/video_codecs.cc |
diff --git a/media/base/video_codecs.cc b/media/base/video_codecs.cc |
index 7b3f77f04ecc451e2b831f010c47ea7a6ab26030..9e60cb66e900f4bfe92b4bc82c51b479f70962a8 100644 |
--- a/media/base/video_codecs.cc |
+++ b/media/base/video_codecs.cc |
@@ -5,6 +5,8 @@ |
#include "media/base/video_codecs.h" |
#include "base/logging.h" |
+#include "base/strings/string_number_conversions.h" |
+#include "base/strings/string_util.h" |
namespace media { |
@@ -69,4 +71,96 @@ std::string GetProfileName(VideoCodecProfile profile) { |
return ""; |
} |
+bool ParseAVCCodecId(const std::string& codec_id, |
+ VideoCodecProfile* profile, |
+ uint8_t* level_idc) { |
+ // Make sure we have avc1.xxxxxx or avc3.xxxxxx , where xxxxxx are hex digits |
+ if (!base::StartsWith(codec_id, "avc1.", base::CompareCase::SENSITIVE) && |
+ !base::StartsWith(codec_id, "avc3.", base::CompareCase::SENSITIVE)) { |
+ return false; |
+ } |
+ uint32_t elem = 0; |
+ if (codec_id.size() != 11 || |
+ !base::HexStringToUInt(base::StringPiece(codec_id).substr(5), &elem)) { |
+ DVLOG(4) << __FUNCTION__ << ": invalid avc codec id (" << codec_id << ")"; |
+ return false; |
+ } |
+ |
+ uint8_t level_byte = elem & 0xFF; |
+ uint8_t constraints_byte = (elem >> 8) & 0xFF; |
+ uint8_t profile_idc = (elem >> 16) & 0xFF; |
+ |
+ // Check that the lower two bits of |constraints_byte| are zero (those are |
+ // reserved and must be zero according to ISO IEC 14496-10). |
+ if (constraints_byte & 3) { |
+ DVLOG(4) << __FUNCTION__ << ": non-zero reserved bits in codec id " |
+ << codec_id; |
+ return false; |
+ } |
+ |
+ VideoCodecProfile out_profile = VIDEO_CODEC_PROFILE_UNKNOWN; |
+ // profile_idc values for each profile are taken from ISO IEC 14496-10 and |
+ // https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Profiles |
+ switch (profile_idc) { |
+ case 66: |
+ out_profile = H264PROFILE_BASELINE; |
+ break; |
+ case 77: |
+ out_profile = H264PROFILE_MAIN; |
+ break; |
+ case 83: |
+ out_profile = H264PROFILE_SCALABLEBASELINE; |
+ break; |
+ case 86: |
+ out_profile = H264PROFILE_SCALABLEHIGH; |
+ break; |
+ case 88: |
+ out_profile = H264PROFILE_EXTENDED; |
+ break; |
+ case 100: |
+ out_profile = H264PROFILE_HIGH; |
+ break; |
+ case 110: |
+ out_profile = H264PROFILE_HIGH10PROFILE; |
+ break; |
+ case 118: |
+ out_profile = H264PROFILE_MULTIVIEWHIGH; |
+ break; |
+ case 122: |
+ out_profile = H264PROFILE_HIGH422PROFILE; |
+ break; |
+ case 128: |
+ out_profile = H264PROFILE_STEREOHIGH; |
+ break; |
+ case 244: |
+ out_profile = H264PROFILE_HIGH444PREDICTIVEPROFILE; |
+ break; |
+ default: |
+ DVLOG(1) << "Warning: unrecognized AVC/H.264 profile " << profile_idc; |
+ return false; |
+ } |
+ |
+ // TODO(servolk): Take into account also constraint set flags 3 through 5. |
+ uint8_t constraint_set0_flag = (constraints_byte >> 7) & 1; |
+ uint8_t constraint_set1_flag = (constraints_byte >> 6) & 1; |
+ uint8_t constraint_set2_flag = (constraints_byte >> 5) & 1; |
+ if (constraint_set2_flag && out_profile > H264PROFILE_EXTENDED) { |
+ out_profile = H264PROFILE_EXTENDED; |
+ } |
+ if (constraint_set1_flag && out_profile > H264PROFILE_MAIN) { |
+ out_profile = H264PROFILE_MAIN; |
+ } |
+ if (constraint_set0_flag && out_profile > H264PROFILE_BASELINE) { |
+ out_profile = H264PROFILE_BASELINE; |
+ } |
+ |
+ if (level_idc) |
+ *level_idc = level_byte; |
+ |
+ if (profile) |
+ *profile = out_profile; |
+ |
+ return true; |
+} |
+ |
} // namespace media |