0

StableVideoDecoderService: Implement Initialize().

This CL implements the StableVideoDecoderService::Initialize() method
which simply forwards that call to the underlying mojom::VideoDecoder.

The unit tests are expanded to cover the new code.

Bug: b:195769334
Test: ./media_unittests --gtest_filter="StableVideoDecoderServiceTest.*" in amd64-generic VM.
Change-Id: Ib488328f5041dd79e0a9ffcaab8fa8b024110962
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3673497
Reviewed-by: Pilar Molina Lopez <pmolinalopez@chromium.org>
Commit-Queue: Andres Calderon Jaramillo <andrescj@chromium.org>
Reviewed-by: Dan Sanders <sandersd@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1012669}
This commit is contained in:
Andres Calderon Jaramillo
2022-06-09 20:13:10 +00:00
committed by Chromium LUCI CQ
parent d5aa6fd6d9
commit f68af62946
2 changed files with 123 additions and 4 deletions

@ -52,7 +52,7 @@ void StableVideoDecoderService::Construct(
DCHECK(!stable_media_log_remote_.is_bound());
stable_media_log_remote_.Bind(std::move(stable_media_log_remote));
DCHECK(!video_frame_handle_releaser_remote_);
DCHECK(!video_frame_handle_releaser_remote_.is_bound());
DCHECK(!stable_video_frame_handle_releaser_receiver_.is_bound());
stable_video_frame_handle_releaser_receiver_.Bind(
std::move(stable_video_frame_handle_releaser_receiver));
@ -71,7 +71,28 @@ void StableVideoDecoderService::Initialize(
mojo::PendingRemote<stable::mojom::StableCdmContext> cdm_context,
InitializeCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
NOTIMPLEMENTED();
if (!video_decoder_client_receiver_.is_bound()) {
std::move(callback).Run(DecoderStatus::Codes::kFailedToCreateDecoder,
/*needs_bitstream_conversion=*/false,
/*max_decode_requests=*/1,
VideoDecoderType::kUnknown);
return;
}
// The |config| should have been validated at deserialization time.
DCHECK(config.IsValidConfig());
// TODO(b/195769334): implement out-of-process video decoding of hardware
// protected content.
if (config.is_encrypted()) {
std::move(callback).Run(DecoderStatus::Codes::kUnsupportedConfig,
/*needs_bitstream_conversion=*/false,
/*max_decode_requests=*/1,
VideoDecoderType::kUnknown);
return;
}
dst_video_decoder_remote_->Initialize(
config, low_delay, /*cdm_id=*/absl::nullopt, std::move(callback));
}
void StableVideoDecoderService::Decode(

@ -26,6 +26,20 @@ namespace media {
namespace {
VideoDecoderConfig CreateValidVideoDecoderConfig() {
const VideoDecoderConfig config(
VideoCodec::kH264, VideoCodecProfile::H264PROFILE_BASELINE,
VideoDecoderConfig::AlphaMode::kHasAlpha, VideoColorSpace::REC709(),
VideoTransformation(VIDEO_ROTATION_90, /*mirrored=*/true),
/*coded_size=*/gfx::Size(640, 368),
/*visible_rect=*/gfx::Rect(1, 1, 630, 360),
/*natural_size=*/gfx::Size(1260, 720),
/*extra_data=*/std::vector<uint8_t>{1, 2, 3},
EncryptionScheme::kUnencrypted);
DCHECK(config.IsValidConfig());
return config;
}
class MockVideoFrameHandleReleaser : public mojom::VideoFrameHandleReleaser {
public:
explicit MockVideoFrameHandleReleaser(
@ -336,8 +350,8 @@ TEST_F(StableVideoDecoderServiceTest, FactoryCanCreateStableVideoDecoders) {
}
}
// Tests that a call to stable::mojom::VideoDecoder::Construct() call gets
// routed correctly to the underlying mojom::VideoDecoder.
// Tests that a call to stable::mojom::VideoDecoder::Construct() gets routed
// correctly to the underlying mojom::VideoDecoder.
TEST_F(StableVideoDecoderServiceTest, StableVideoDecoderCanBeConstructed) {
auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
auto* mock_video_decoder_raw = mock_video_decoder.get();
@ -368,6 +382,90 @@ TEST_F(StableVideoDecoderServiceTest,
/*expect_construct_call=*/false));
}
// Tests that a call to stable::mojom::VideoDecoder::Initialize() gets routed
// correctly to the underlying mojom::VideoDecoder. Also tests that when the
// underlying mojom::VideoDecoder calls the initialization callback, the call
// gets routed to the client.
TEST_F(StableVideoDecoderServiceTest, StableVideoDecoderCanBeInitialized) {
auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
auto* mock_video_decoder_raw = mock_video_decoder.get();
auto stable_video_decoder_remote =
CreateStableVideoDecoder(std::move(mock_video_decoder));
ASSERT_TRUE(stable_video_decoder_remote.is_bound());
ASSERT_TRUE(stable_video_decoder_remote.is_connected());
auto auxiliary_endpoints = ConstructStableVideoDecoder(
stable_video_decoder_remote, *mock_video_decoder_raw,
/*expect_construct_call=*/true);
ASSERT_TRUE(auxiliary_endpoints);
const VideoDecoderConfig config_to_send = CreateValidVideoDecoderConfig();
VideoDecoderConfig received_config;
constexpr bool kLowDelay = true;
constexpr absl::optional<base::UnguessableToken> kCdmId = absl::nullopt;
StrictMock<base::MockOnceCallback<void(
const media::DecoderStatus& status, bool needs_bitstream_conversion,
int32_t max_decode_requests, VideoDecoderType decoder_type)>>
initialize_cb_to_send;
mojom::VideoDecoder::InitializeCallback received_initialize_cb;
const DecoderStatus kDecoderStatus = DecoderStatus::Codes::kAborted;
constexpr bool kNeedsBitstreamConversion = true;
constexpr int32_t kMaxDecodeRequests = 123;
constexpr VideoDecoderType kDecoderType = VideoDecoderType::kVda;
EXPECT_CALL(*mock_video_decoder_raw,
Initialize(/*config=*/_, kLowDelay, kCdmId,
/*callback=*/_))
.WillOnce([&](const VideoDecoderConfig& config, bool low_delay,
const absl::optional<base::UnguessableToken>& cdm_id,
mojom::VideoDecoder::InitializeCallback callback) {
received_config = config;
received_initialize_cb = std::move(callback);
});
EXPECT_CALL(initialize_cb_to_send,
Run(kDecoderStatus, kNeedsBitstreamConversion, kMaxDecodeRequests,
kDecoderType));
stable_video_decoder_remote->Initialize(
config_to_send, kLowDelay,
mojo::PendingRemote<stable::mojom::StableCdmContext>(),
initialize_cb_to_send.Get());
stable_video_decoder_remote.FlushForTesting();
ASSERT_TRUE(Mock::VerifyAndClearExpectations(mock_video_decoder_raw));
std::move(received_initialize_cb)
.Run(kDecoderStatus, kNeedsBitstreamConversion, kMaxDecodeRequests,
kDecoderType);
task_environment_.RunUntilIdle();
}
// Tests that the StableVideoDecoderService rejects a call to
// stable::mojom::VideoDecoder::Initialize() before
// stable::mojom::VideoDecoder::Construct() gets called.
TEST_F(StableVideoDecoderServiceTest,
StableVideoDecoderCannotBeInitializedBeforeConstruction) {
auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();
auto stable_video_decoder_remote =
CreateStableVideoDecoder(std::move(mock_video_decoder));
ASSERT_TRUE(stable_video_decoder_remote.is_bound());
ASSERT_TRUE(stable_video_decoder_remote.is_connected());
const VideoDecoderConfig config_to_send = CreateValidVideoDecoderConfig();
constexpr bool kLowDelay = true;
StrictMock<base::MockOnceCallback<void(
const media::DecoderStatus& status, bool needs_bitstream_conversion,
int32_t max_decode_requests, VideoDecoderType decoder_type)>>
initialize_cb_to_send;
EXPECT_CALL(initialize_cb_to_send,
Run(DecoderStatus(DecoderStatus::Codes::kFailed),
/*needs_bitstream_conversion=*/false,
/*max_decode_requests=*/1, VideoDecoderType::kUnknown));
stable_video_decoder_remote->Initialize(
config_to_send, kLowDelay,
mojo::PendingRemote<stable::mojom::StableCdmContext>(),
initialize_cb_to_send.Get());
stable_video_decoder_remote.FlushForTesting();
}
TEST_F(StableVideoDecoderServiceTest,
StableVideoDecoderClientReceivesOnVideoFrameDecodedEvent) {
auto mock_video_decoder = std::make_unique<StrictMock<MockVideoDecoder>>();