Commit bd2cb9f5 authored by Frank Liberato's avatar Frank Liberato Committed by Chromium LUCI CQ

Handle duplicate vp9 pictures in D3D11VideoDecoder.

Allow duplicate pictures by returning the same ref-counted picture
buffer to the VP9Decoder, with an updated timestamp.

This also replaces the boolean "in client use" with a counter, since
the same PictureBuffer can be out at the client as more than one
VideoFrame now.  We can only re-use it for decoding once all of the
client uses are returned to the decoder.

Bug: 1164463
Change-Id: I93fa076ae4fdd955687122df6c4cb12485cd6a7e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2623030
Commit-Queue: Frank Liberato <liberato@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842317}
parent aaf8a467
...@@ -548,6 +548,7 @@ source_set("unit_tests") { ...@@ -548,6 +548,7 @@ source_set("unit_tests") {
sources += [ sources += [
"windows/d3d11_copying_texture_wrapper_unittest.cc", "windows/d3d11_copying_texture_wrapper_unittest.cc",
"windows/d3d11_decoder_configurator_unittest.cc", "windows/d3d11_decoder_configurator_unittest.cc",
"windows/d3d11_picture_buffer_unittest.cc",
"windows/d3d11_texture_selector_unittest.cc", "windows/d3d11_texture_selector_unittest.cc",
"windows/d3d11_texture_wrapper_unittest.cc", "windows/d3d11_texture_wrapper_unittest.cc",
"windows/d3d11_video_decoder_unittest.cc", "windows/d3d11_video_decoder_unittest.cc",
......
...@@ -80,12 +80,19 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer ...@@ -80,12 +80,19 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer
size_t picture_index() const { return picture_index_; } size_t picture_index() const { return picture_index_; }
// Is this PictureBuffer backing a VideoFrame right now? // Is this PictureBuffer backing a VideoFrame right now?
bool in_client_use() const { return in_client_use_; } bool in_client_use() const { return in_client_use_ > 0; }
// Is this PictureBuffer holding an image that's in use by the decoder? // Is this PictureBuffer holding an image that's in use by the decoder?
bool in_picture_use() const { return in_picture_use_; } bool in_picture_use() const { return in_picture_use_; }
void set_in_client_use(bool use) { in_client_use_ = use; } void add_client_use() {
in_client_use_++;
DCHECK_GT(in_client_use_, 0);
}
void remove_client_use() {
DCHECK_GT(in_client_use_, 0);
in_client_use_--;
}
void set_in_picture_use(bool use) { in_picture_use_ = use; } void set_in_picture_use(bool use) { in_picture_use_ = use; }
const ComD3D11VideoDecoderOutputView& output_view() const { const ComD3D11VideoDecoderOutputView& output_view() const {
...@@ -108,7 +115,7 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer ...@@ -108,7 +115,7 @@ class MEDIA_GPU_EXPORT D3D11PictureBuffer
std::unique_ptr<Texture2DWrapper> texture_wrapper_; std::unique_ptr<Texture2DWrapper> texture_wrapper_;
gfx::Size size_; gfx::Size size_;
bool in_picture_use_ = false; bool in_picture_use_ = false;
bool in_client_use_ = false; int in_client_use_ = 0;
size_t picture_index_; size_t picture_index_;
ComD3D11VideoDecoderOutputView output_view_; ComD3D11VideoDecoderOutputView output_view_;
......
// Copyright 2021 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 <utility>
#include "base/callback_helpers.h"
#include "base/test/task_environment.h"
#include "media/gpu/windows/d3d11_picture_buffer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
class D3D11PictureBufferTest : public ::testing::Test {
public:
D3D11PictureBufferTest() {
picture_buffer_ = base::MakeRefCounted<D3D11PictureBuffer>(
task_environment_.GetMainThreadTaskRunner(), nullptr, 0, nullptr,
gfx::Size(), 0);
}
base::test::TaskEnvironment task_environment_;
scoped_refptr<D3D11PictureBuffer> picture_buffer_;
};
// The processor proxy wraps the VideoDevice/VideoContext and stores some of the
// d3d11 types. Make sure that the arguments we give these methods are passed
// through correctly.
TEST_F(D3D11PictureBufferTest, InClientUse) {
EXPECT_FALSE(picture_buffer_->in_client_use());
// Add two client refs.
picture_buffer_->add_client_use();
EXPECT_TRUE(picture_buffer_->in_client_use());
picture_buffer_->add_client_use();
EXPECT_TRUE(picture_buffer_->in_client_use());
// Remove them. Should still be in use by the client until the second one has
// been removed.
picture_buffer_->remove_client_use();
EXPECT_TRUE(picture_buffer_->in_client_use());
picture_buffer_->remove_client_use();
EXPECT_FALSE(picture_buffer_->in_client_use());
}
} // namespace media
\ No newline at end of file
...@@ -470,7 +470,7 @@ void D3D11VideoDecoder::ReceivePictureBufferFromClient( ...@@ -470,7 +470,7 @@ void D3D11VideoDecoder::ReceivePictureBufferFromClient(
// We may decode into this buffer again. // We may decode into this buffer again.
// Note that |buffer| might no longer be in |picture_buffers_| if we've // Note that |buffer| might no longer be in |picture_buffers_| if we've
// replaced them. That's okay. // replaced them. That's okay.
buffer->set_in_client_use(false); buffer->remove_client_use();
// Also re-start decoding in case it was waiting for more pictures. // Also re-start decoding in case it was waiting for more pictures.
DoDecode(); DoDecode();
...@@ -818,7 +818,7 @@ bool D3D11VideoDecoder::OutputResult(const CodecPicture* picture, ...@@ -818,7 +818,7 @@ bool D3D11VideoDecoder::OutputResult(const CodecPicture* picture,
DCHECK(texture_selector_); DCHECK(texture_selector_);
TRACE_EVENT0("gpu", "D3D11VideoDecoder::OutputResult"); TRACE_EVENT0("gpu", "D3D11VideoDecoder::OutputResult");
picture_buffer->set_in_client_use(true); picture_buffer->add_client_use();
// Note: The pixel format doesn't matter. // Note: The pixel format doesn't matter.
gfx::Rect visible_rect = picture->visible_rect(); gfx::Rect visible_rect = picture->visible_rect();
......
...@@ -63,7 +63,7 @@ scoped_refptr<VP9Picture> D3D11VP9Accelerator::CreateVP9Picture() { ...@@ -63,7 +63,7 @@ scoped_refptr<VP9Picture> D3D11VP9Accelerator::CreateVP9Picture() {
D3D11PictureBuffer* picture_buffer = client_->GetPicture(); D3D11PictureBuffer* picture_buffer = client_->GetPicture();
if (!picture_buffer) if (!picture_buffer)
return nullptr; return nullptr;
return base::MakeRefCounted<D3D11VP9Picture>(picture_buffer); return base::MakeRefCounted<D3D11VP9Picture>(picture_buffer, client_);
} }
bool D3D11VP9Accelerator::BeginFrame(const D3D11VP9Picture& pic) { bool D3D11VP9Accelerator::BeginFrame(const D3D11VP9Picture& pic) {
......
...@@ -6,8 +6,10 @@ ...@@ -6,8 +6,10 @@
namespace media { namespace media {
D3D11VP9Picture::D3D11VP9Picture(D3D11PictureBuffer* picture_buffer) D3D11VP9Picture::D3D11VP9Picture(D3D11PictureBuffer* picture_buffer,
D3D11VideoDecoderClient* client)
: picture_buffer_(picture_buffer), : picture_buffer_(picture_buffer),
client_(client),
picture_index_(picture_buffer_->picture_index()) { picture_index_(picture_buffer_->picture_index()) {
picture_buffer_->set_in_picture_use(true); picture_buffer_->set_in_picture_use(true);
} }
...@@ -16,4 +18,11 @@ D3D11VP9Picture::~D3D11VP9Picture() { ...@@ -16,4 +18,11 @@ D3D11VP9Picture::~D3D11VP9Picture() {
picture_buffer_->set_in_picture_use(false); picture_buffer_->set_in_picture_use(false);
} }
scoped_refptr<VP9Picture> D3D11VP9Picture::CreateDuplicate() {
// We've already sent off the base frame for rendering, so we can just stamp
// |picture_buffer_| with the updated timestamp.
client_->UpdateTimestamp(picture_buffer_);
return this;
}
} // namespace media } // namespace media
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "media/gpu/vp9_picture.h" #include "media/gpu/vp9_picture.h"
#include "media/gpu/windows/d3d11_picture_buffer.h" #include "media/gpu/windows/d3d11_picture_buffer.h"
#include "media/gpu/windows/d3d11_video_decoder_client.h"
namespace media { namespace media {
...@@ -15,7 +16,8 @@ class D3D11PictureBuffer; ...@@ -15,7 +16,8 @@ class D3D11PictureBuffer;
class D3D11VP9Picture : public VP9Picture { class D3D11VP9Picture : public VP9Picture {
public: public:
explicit D3D11VP9Picture(D3D11PictureBuffer* picture_buffer); explicit D3D11VP9Picture(D3D11PictureBuffer* picture_buffer,
D3D11VideoDecoderClient* client);
D3D11PictureBuffer* picture_buffer() const { return picture_buffer_; } D3D11PictureBuffer* picture_buffer() const { return picture_buffer_; }
...@@ -24,8 +26,11 @@ class D3D11VP9Picture : public VP9Picture { ...@@ -24,8 +26,11 @@ class D3D11VP9Picture : public VP9Picture {
protected: protected:
~D3D11VP9Picture() override; ~D3D11VP9Picture() override;
scoped_refptr<VP9Picture> CreateDuplicate() override;
private: private:
D3D11PictureBuffer* picture_buffer_; D3D11PictureBuffer* picture_buffer_;
D3D11VideoDecoderClient* client_;
size_t picture_index_; size_t picture_index_;
}; };
......
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