Commit e811a3e5 authored by Miguel Casas's avatar Miguel Casas Committed by Commit Bot

WebM: Parse VP9 Profile out of CodecPrivate

This CL teaches WebMVideoClient to parse the |codec_private|
field, if present, to figure out the VP9 Profile if any. This
is a necessary step to support VP9.2 10b on Vaapi.

TEST=crosvideo.appspot.com/?codec=vp9.2&loop=true and newly
added unittests.

Bug: 778093, 592074
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: Ic62519b32818fe409d15f54b6ddb9798deea88da
Reviewed-on: https://chromium-review.googlesource.com/786211
Commit-Queue: Miguel Casas <mcasas@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarSergey Volk <servolk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#519519}
parent bafc2ba3
......@@ -208,6 +208,7 @@ source_set("unit_tests") {
"webm/webm_parser_unittest.cc",
"webm/webm_stream_parser_unittest.cc",
"webm/webm_tracks_parser_unittest.cc",
"webm/webm_video_client_unittest.cc",
"webm/webm_webvtt_parser_unittest.cc",
]
......
......@@ -10,12 +10,30 @@
namespace media {
namespace {
// Tries to parse |data| to extract the VP9 Profile ID, or returns Profile 0.
media::VideoCodecProfile GetVP9CodecProfile(const std::vector<uint8_t>& data) {
// VP9 CodecPrivate (http://wiki.webmproject.org/vp9-codecprivate) might have
// Profile information in the first field, if present.
constexpr uint8_t kVP9ProfileFieldId = 0x01;
constexpr uint8_t kVP9ProfileFieldLength = 1;
if (data.size() < 3 || data[0] != kVP9ProfileFieldId ||
data[1] != kVP9ProfileFieldLength || data[2] > 3) {
return VP9PROFILE_PROFILE0;
}
return static_cast<VideoCodecProfile>(
static_cast<size_t>(VP9PROFILE_PROFILE0) + data[2]);
}
} // namespace
WebMVideoClient::WebMVideoClient(MediaLog* media_log) : media_log_(media_log) {
Reset();
}
WebMVideoClient::~WebMVideoClient() {
}
WebMVideoClient::~WebMVideoClient() {}
void WebMVideoClient::Reset() {
pixel_width_ = -1;
......@@ -45,9 +63,7 @@ bool WebMVideoClient::InitializeConfig(
profile = VP8PROFILE_ANY;
} else if (codec_id == "V_VP9") {
video_codec = kCodecVP9;
// TODO(servolk): Find a way to read actual VP9 profile from WebM.
// crbug.com/592074
profile = VP9PROFILE_PROFILE0;
profile = GetVP9CodecProfile(codec_private);
#if BUILDFLAG(ENABLE_AV1_DECODER)
} else if (codec_id == "V_AV1") {
// TODO(dalecurtis): AV1 profiles are not finalized, this needs updating
......
......@@ -11,6 +11,7 @@
#include <vector>
#include "base/macros.h"
#include "media/base/media_export.h"
#include "media/base/media_log.h"
#include "media/formats/webm/webm_colour_parser.h"
#include "media/formats/webm/webm_parser.h"
......@@ -20,7 +21,7 @@ class EncryptionScheme;
class VideoDecoderConfig;
// Helper class used to parse a Video element inside a TrackEntry element.
class WebMVideoClient : public WebMParserClient {
class MEDIA_EXPORT WebMVideoClient : public WebMParserClient {
public:
explicit WebMVideoClient(MediaLog* media_log);
~WebMVideoClient() override;
......@@ -41,6 +42,8 @@ class WebMVideoClient : public WebMParserClient {
VideoDecoderConfig* config);
private:
friend class WebMVideoClientTest;
// WebMParserClient implementation.
WebMParserClient* OnListStart(int id) override;
bool OnListEnd(int id) override;
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/formats/webm/webm_video_client.h"
#include "media/base/media_util.h"
#include "media/base/mock_media_log.h"
#include "media/base/video_decoder_config.h"
#include "media/formats/webm/webm_constants.h"
namespace media {
namespace {
const gfx::Size kCodedSize(321, 243);
}
static const struct CodecTestParams {
VideoCodecProfile profile;
const std::vector<uint8_t> codec_private;
} kCodecTestParams[] = {
{VP9PROFILE_PROFILE0, {}},
{VP9PROFILE_PROFILE2,
// Valid VP9 Profile 2 example, extracted out of a sample file at
// https://www.webmproject.org/vp9/levels/#test-bitstreams
{0x01, 0x01, 0x02, 0x02, 0x01, 0x0a, 0x3, 0x1, 0xa, 0x4, 0x1, 0x1}},
// Invalid VP9 CodecPrivate: too short.
{VP9PROFILE_PROFILE0, {0x01, 0x01}},
// Invalid VP9 CodecPrivate: wrong field id.
{VP9PROFILE_PROFILE0, {0x77, 0x01, 0x02}},
// Invalid VP9 CodecPrivate: wrong field length.
{VP9PROFILE_PROFILE0, {0x01, 0x75, 0x02}},
// Invalid VP9 CodecPrivate: wrong Profile (can't be > 3).
{VP9PROFILE_PROFILE0, {0x01, 0x01, 0x34}}};
class WebMVideoClientTest : public testing::TestWithParam<CodecTestParams> {
public:
WebMVideoClientTest() : webm_video_client_(&media_log_) {
// Simulate configuring width and height in the |webm_video_client_|.
webm_video_client_.OnUInt(kWebMIdPixelWidth, kCodedSize.width());
webm_video_client_.OnUInt(kWebMIdPixelHeight, kCodedSize.height());
}
testing::StrictMock<MockMediaLog> media_log_;
WebMVideoClient webm_video_client_;
DISALLOW_COPY_AND_ASSIGN(WebMVideoClientTest);
};
TEST_P(WebMVideoClientTest, InitializeConfigVP9Profiles) {
const std::string kCodecId = "V_VP9";
const VideoCodecProfile profile = GetParam().profile;
const std::vector<uint8_t> codec_private = GetParam().codec_private;
VideoDecoderConfig config;
EXPECT_TRUE(webm_video_client_.InitializeConfig(kCodecId, codec_private,
EncryptionScheme(), &config));
VideoDecoderConfig expected_config(kCodecVP9, profile, PIXEL_FORMAT_YV12,
COLOR_SPACE_HD_REC709, VIDEO_ROTATION_0,
kCodedSize, gfx::Rect(kCodedSize),
kCodedSize, codec_private, Unencrypted());
EXPECT_TRUE(config.Matches(expected_config))
<< "Config (" << config.AsHumanReadableString()
<< ") does not match expected ("
<< expected_config.AsHumanReadableString() << ")";
}
INSTANTIATE_TEST_CASE_P(/* No prefix. */,
WebMVideoClientTest,
::testing::ValuesIn(kCodecTestParams));
} // namespace media
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment