Commit d383c8e1 authored by Zhaoliang Ma's avatar Zhaoliang Ma Committed by Commit Bot

MojoVEA: Implement mojo video encoder IsFlushSupported/FLush

In webcodecs, VideoEncodeAcceleratorAdapter needs to call Flush method,
since the mojoVEA doesn't support IsFlushSupported, so the
VideoEncodeAcceleratorAdapter cannot really call the backendVEA Flush
even the backendVEA support Flush. This CL fix this issue.

Bug: 1128768, 1110279
Change-Id: I4853c2bd0e494cafdd806d183ab3d659ca542d7a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2389840Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarEugene Zemtsov <eugene@chromium.org>
Reviewed-by: default avatarDan Sanders <sandersd@chromium.org>
Commit-Queue: Zhaoliang Ma <zhaoliang.ma@intel.com>
Cr-Commit-Position: refs/heads/master@{#827668}
parent 2e7da93c
......@@ -4,6 +4,8 @@
#include "media/mojo/clients/mojo_video_encode_accelerator.h"
#include <utility>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
......@@ -250,6 +252,24 @@ void MojoVideoEncodeAccelerator::RequestEncodingParametersChange(
vea_->RequestEncodingParametersChange(bitrate, framerate);
}
bool MojoVideoEncodeAccelerator::IsFlushSupported() {
DVLOG(2) << __func__;
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(vea_.is_bound());
bool flush_support = false;
vea_->IsFlushSupported(&flush_support);
return flush_support;
}
void MojoVideoEncodeAccelerator::Flush(FlushCallback flush_callback) {
DVLOG(2) << __func__;
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(vea_.is_bound());
vea_->Flush(std::move(flush_callback));
}
void MojoVideoEncodeAccelerator::Destroy() {
DVLOG(1) << __func__;
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
......
......@@ -43,6 +43,8 @@ class MojoVideoEncodeAccelerator : public VideoEncodeAccelerator {
uint32_t framerate_num) override;
void RequestEncodingParametersChange(const VideoBitrateAllocation& bitrate,
uint32_t framerate) override;
bool IsFlushSupported() override;
void Flush(FlushCallback flush_callback) override;
void Destroy() override;
private:
......
......@@ -91,6 +91,20 @@ class MockMojoVideoEncodeAccelerator : public mojom::VideoEncodeAccelerator {
MOCK_METHOD2(RequestEncodingParametersChange,
void(const media::VideoBitrateAllocation&, uint32_t));
void IsFlushSupported(IsFlushSupportedCallback callback) override {
DoIsFlushSupported();
std::move(callback).Run(true);
}
MOCK_METHOD0(DoIsFlushSupported, void());
void Flush(FlushCallback callback) override {
FlushCallback mock_callback;
DoFlush(std::move(mock_callback));
// Actually, this callback should run on DoFlush, but in test, manally run
// it on Flush.
std::move(callback).Run(true);
}
MOCK_METHOD1(DoFlush, void(FlushCallback));
void set_initialization_success(bool success) {
initialization_success_ = success;
}
......@@ -307,4 +321,22 @@ TEST_F(MojoVideoEncodeAcceleratorTest, InitializeFailure) {
base::RunLoop().RunUntilIdle();
}
// This test verifies the IsFlushSupported() and Flush() communication.
TEST_F(MojoVideoEncodeAcceleratorTest, IsFlushSupportedAndFlush) {
std::unique_ptr<MockVideoEncodeAcceleratorClient> mock_vea_client =
std::make_unique<MockVideoEncodeAcceleratorClient>();
Initialize(mock_vea_client.get());
EXPECT_CALL(*mock_mojo_vea(), DoIsFlushSupported());
bool ret = mojo_vea()->IsFlushSupported();
base::RunLoop().RunUntilIdle();
if (ret) {
EXPECT_CALL(*mock_mojo_vea(), DoFlush(_));
auto flush_callback =
base::BindOnce([](bool status) { EXPECT_EQ(status, true); });
mojo_vea()->Flush(std::move(flush_callback));
base::RunLoop().RunUntilIdle();
}
}
} // namespace media
......@@ -126,6 +126,11 @@ interface VideoEncodeAccelerator {
RequestEncodingParametersChange(
VideoBitrateAllocation bitrate_allocation,
uint32 framerate);
[Sync]
IsFlushSupported() => (bool result);
Flush() => (bool result);
};
struct Vp8Metadata {
......
......@@ -103,8 +103,11 @@ void MojoVideoEncodeAcceleratorService::Encode(
EncodeCallback callback) {
DVLOG(2) << __func__ << " tstamp=" << frame->timestamp();
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!encoder_)
if (!encoder_) {
DLOG(ERROR) << __func__ << " Failed to encode, the encoder is invalid";
std::move(callback).Run();
return;
}
if (frame->coded_size() != input_coded_size_ &&
frame->storage_type() != media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) {
......@@ -170,6 +173,35 @@ void MojoVideoEncodeAcceleratorService::RequestEncodingParametersChange(
encoder_->RequestEncodingParametersChange(bitrate_allocation, framerate);
}
void MojoVideoEncodeAcceleratorService::IsFlushSupported(
IsFlushSupportedCallback callback) {
DVLOG(2) << __func__;
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!encoder_) {
DLOG(ERROR) << __func__
<< " Failed to detect flush support, the encoder is invalid";
std::move(callback).Run(false);
return;
}
bool flush_support = encoder_->IsFlushSupported();
std::move(callback).Run(flush_support);
}
void MojoVideoEncodeAcceleratorService::Flush(FlushCallback callback) {
DVLOG(2) << __func__;
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!encoder_) {
DLOG(ERROR) << __func__ << " Failed to flush, the encoder is invalid";
std::move(callback).Run(false);
return;
}
encoder_->Flush(std::move(callback));
}
void MojoVideoEncodeAcceleratorService::RequireBitstreamBuffers(
unsigned int input_count,
const gfx::Size& input_coded_size,
......
......@@ -67,6 +67,8 @@ class MEDIA_MOJO_EXPORT MojoVideoEncodeAcceleratorService
void RequestEncodingParametersChange(
const media::VideoBitrateAllocation& bitrate_allocation,
uint32_t framerate) override;
void IsFlushSupported(IsFlushSupportedCallback callback) override;
void Flush(FlushCallback callback) override;
private:
friend class MojoVideoEncodeAcceleratorIntegrationTest;
......
......@@ -330,4 +330,24 @@ TEST_F(MojoVideoEncodeAcceleratorServiceTest, CallsBeforeInitializeAreIgnored) {
}
}
// This test verifies that IsFlushSupported/Flush on FakeVEA.
TEST_F(MojoVideoEncodeAcceleratorServiceTest, IsFlushSupportedAndFlush) {
CreateMojoVideoEncodeAccelerator();
BindAndInitialize();
ASSERT_TRUE(fake_vea());
// media::VideoEncodeAccelerator::IsFlushSupported and Flush are return
// false as default, so here expect false for both IsFlushSupported and
// Flush.
auto flush_support =
base::BindOnce([](bool status) { EXPECT_EQ(status, false); });
mojo_vea_service()->IsFlushSupported(std::move(flush_support));
base::RunLoop().RunUntilIdle();
auto flush_callback =
base::BindOnce([](bool status) { EXPECT_EQ(status, false); });
mojo_vea_service()->IsFlushSupported(std::move(flush_callback));
}
} // namespace media
......@@ -313,7 +313,7 @@ void VideoEncodeAcceleratorAdapter::FlushOnAcceleratorThread(StatusCB done_cb) {
// If flush is not supported FlushCompleted() will be called by
// BitstreamBufferReady() when |pending_encodes_| is empty.
if (accelerator_->IsFlushSupported()) {
if (flush_support_) {
accelerator_->Flush(
base::BindOnce(&VideoEncodeAcceleratorAdapter::FlushCompleted,
base::Unretained(this)));
......@@ -342,6 +342,7 @@ void VideoEncodeAcceleratorAdapter::RequireBitstreamBuffers(
accelerator_->UseOutputBitstreamBuffer(
BitstreamBuffer(buffer_id, region->Duplicate(), region->GetSize()));
InitCompleted(Status());
flush_support_ = accelerator_->IsFlushSupported();
}
void VideoEncodeAcceleratorAdapter::BitstreamBufferReady(
......@@ -419,7 +420,7 @@ void VideoEncodeAcceleratorAdapter::BitstreamBufferReady(
}
}
output_cb_.Run(std::move(result), std::move(desc));
if (pending_encodes_.empty() && !accelerator_->IsFlushSupported()) {
if (pending_encodes_.empty() && !flush_support_) {
// Manually call FlushCompleted(), since |accelerator_| won't do it for us.
FlushCompleted(true);
}
......
......@@ -116,6 +116,7 @@ class MEDIA_EXPORT VideoEncodeAcceleratorAdapter
scoped_refptr<base::SequencedTaskRunner> callback_task_runner_;
State state_ = State::kNotInitialized;
bool flush_support_ = false;
Options options_;
OutputCB output_cb_;
......
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