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

Unified Diff: media/base/video_codecs.cc

Issue 2723833002: WebM support for new multipart VP9 string. (Closed)
Patch Set: Rebase 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/video_codecs.cc
diff --git a/media/base/video_codecs.cc b/media/base/video_codecs.cc
index e68e4337693b6fc816bb298430198ada750d0d6c..f726b034ed27a8fc5f114d4ec4b7c86a82bb631e 100644
--- a/media/base/video_codecs.cc
+++ b/media/base/video_codecs.cc
@@ -94,30 +94,101 @@ std::string GetProfileName(VideoCodecProfile profile) {
return "";
}
+// Described in ISO 23001-8:2016 Table 3.
+bool ParseVp9Eotf(const int value, gfx::ColorSpace::TransferID* eotf) {
+ switch (value) {
+ case 1:
+ *eotf = gfx::ColorSpace::TransferID::BT709;
+ break;
+ case 2:
+ // "2" is interpreted as "Unspecified"
+ *eotf = gfx::ColorSpace::TransferID::INVALID;
+ break;
+ case 4:
+ *eotf = gfx::ColorSpace::TransferID::GAMMA22;
+ break;
+ case 5:
+ *eotf = gfx::ColorSpace::TransferID::GAMMA28;
+ break;
+ case 6:
+ *eotf = gfx::ColorSpace::TransferID::SMPTE170M;
+ break;
+ case 7:
+ *eotf = gfx::ColorSpace::TransferID::SMPTE240M;
+ break;
+ case 8:
+ *eotf = gfx::ColorSpace::TransferID::LINEAR;
+ break;
+ case 9:
+ *eotf = gfx::ColorSpace::TransferID::LOG;
+ break;
+ case 10:
+ *eotf = gfx::ColorSpace::TransferID::LOG_SQRT;
+ break;
+ case 11:
+ *eotf = gfx::ColorSpace::TransferID::IEC61966_2_4;
+ break;
+ case 12:
+ *eotf = gfx::ColorSpace::TransferID::BT1361_ECG;
+ break;
+ case 13:
+ *eotf = gfx::ColorSpace::TransferID::IEC61966_2_1;
+ break;
+ case 14:
+ *eotf = gfx::ColorSpace::TransferID::BT2020_10;
+ break;
+ case 15:
+ *eotf = gfx::ColorSpace::TransferID::BT2020_12;
+ break;
+ case 16:
+ *eotf = gfx::ColorSpace::TransferID::SMPTEST2084;
+ break;
+ case 17:
+ *eotf = gfx::ColorSpace::TransferID::SMPTEST428_1;
+ break;
+ default:
+ // Includes reserved values of 0, 3, 18 - 255.
+ *eotf = gfx::ColorSpace::TransferID::INVALID;
+ return false;
+ }
+
+ return true;
+}
+
bool ParseNewStyleVp9CodecID(const std::string& codec_id,
VideoCodecProfile* profile,
- uint8_t* level_idc) {
+ uint8_t* level_idc,
+ gfx::ColorSpace::TransferID* eotf) {
+ // Initialize optional fields to their defaults.
+ *eotf = gfx::ColorSpace::TransferID::BT709;
+
std::vector<std::string> fields = base::SplitString(
codec_id, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
- // TODO(kqyang): The spec specifies 8 fields. We do not allow missing or extra
- // fields. See crbug.com/667834.
- if (fields.size() != 8)
+ // First four fields are mandatory. No more than 9 fields are expected.
+ if (fields.size() < 4 || fields.size() > 9) {
+ DVLOG(3) << __func__ << " Invalid number of fields (" << fields.size()
+ << ")";
return false;
+ }
- if (fields[0] != "vp09")
+ if (fields[0] != "vp09") {
+ DVLOG(3) << __func__ << " Invalid 4CC (" << fields[0] << ")";
return false;
+ }
std::vector<int> values;
for (size_t i = 1; i < fields.size(); ++i) {
// Missing value is not allowed.
- if (fields[i] == "")
+ if (fields[i] == "") {
+ DVLOG(3) << __func__ << " Invalid missing field (position:" << i << ")";
return false;
+ }
int value;
- if (!base::StringToInt(fields[i], &value))
- return false;
- if (value < 0)
+ if (!base::StringToInt(fields[i], &value) || value < 0) {
+ DVLOG(3) << __func__ << " Invalid field value (" << value << ")";
return false;
+ }
values.push_back(value);
}
@@ -136,31 +207,87 @@ bool ParseNewStyleVp9CodecID(const std::string& codec_id,
*profile = VP9PROFILE_PROFILE3;
break;
default:
+ DVLOG(3) << __func__ << " Invalid profile (" << profile_idc << ")";
return false;
}
*level_idc = values[1];
- // TODO(kqyang): Check if |level_idc| is valid. See crbug.com/667834.
+ switch (*level_idc) {
+ case 1:
+ case 11:
+ case 2:
+ case 21:
+ case 3:
+ case 31:
+ case 4:
+ case 41:
+ case 5:
+ case 51:
+ case 52:
+ case 6:
+ case 61:
+ case 62:
+ break;
+ default:
+ DVLOG(3) << __func__ << " Invalid level (" << *level_idc << ")";
+ return false;
+ }
const int bit_depth = values[2];
- if (bit_depth != 8 && bit_depth != 10 && bit_depth != 12)
+ if (bit_depth != 8 && bit_depth != 10 && bit_depth != 12) {
+ DVLOG(3) << __func__ << " Invalid bit-depth (" << bit_depth << ")";
return false;
+ }
- const int color_space = values[3];
- if (color_space > 7)
+ if (values.size() < 4)
+ return true;
+ const int color_primaries = values[3];
+ // TODO(chcunningham): parse and bubble up color primaries, described in ISO
+ // 23001-8:2016 Table 2.
+ // Values 0, 3, and 23 - 255 are reserved.
+ if (color_primaries == 0 || color_primaries == 3 || color_primaries > 22) {
+ DVLOG(3) << __func__ << " Invalid color primaries (" << color_primaries
+ << ")";
return false;
+ }
- const int chroma_subsampling = values[4];
- if (chroma_subsampling > 3)
+ if (values.size() < 5)
+ return true;
+ if (!ParseVp9Eotf(values[4], eotf)) {
+ DVLOG(3) << __func__ << " Invalid transfer function (" << values[4] << ")";
return false;
+ }
- const int transfer_function = values[5];
- if (transfer_function > 1)
+ // TODO(chcunningham): Parse and bubble up the following fields. For now just
+ // doing basic validation.
+
+ if (values.size() < 6)
+ return true;
+ const int matrix_coefficients = values[5];
+ if (matrix_coefficients > 11) {
+ DVLOG(3) << __func__ << " Invalid matrix coefficients ("
+ << matrix_coefficients << ")";
return false;
+ }
+ if (values.size() < 7)
+ return true;
const int video_full_range_flag = values[6];
- if (video_full_range_flag > 1)
+ if (video_full_range_flag > 1) {
+ DVLOG(3) << __func__ << " Invalid full range flag ("
+ << video_full_range_flag << ")";
return false;
+ }
+
+ if (values.size() < 8)
+ return true;
+ const int chroma_subsampling = values[7];
+ if (chroma_subsampling > 3 ||
+ (chroma_subsampling != 3 && matrix_coefficients == 0)) {
+ DVLOG(3) << __func__ << " Invalid chroma subsampling ("
+ << chroma_subsampling << ")";
+ return false;
+ }
return true;
}
@@ -532,11 +659,14 @@ VideoCodec StringToVideoCodec(const std::string& codec_id) {
codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
if (elem.empty())
return kUnknownVideoCodec;
+
VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
uint8_t level = 0;
+ gfx::ColorSpace::TransferID eotf = gfx::ColorSpace::TransferID::INVALID;
+
if (codec_id == "vp8" || codec_id == "vp8.0")
return kCodecVP8;
- if (ParseNewStyleVp9CodecID(codec_id, &profile, &level) ||
+ if (ParseNewStyleVp9CodecID(codec_id, &profile, &level, &eotf) ||
ParseLegacyVp9CodecID(codec_id, &profile, &level)) {
return kCodecVP9;
}
« 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