Commit 1fa22f68 authored by Miguel Casas's avatar Miguel Casas Committed by Commit Bot

V4L2SliceVDA: use DecodeSurfaceHandler interface

This CL moves V4L2SliceVDA to use DecodeSurfaceHandler interface.

This needs moving the inner V4L2DecodeSurface out of V4L2VDA, which
causes a ripple of mechanic substitutions in the .cc file. Note that
the inner classes still have the * to V4L2VDA because other methods
are needed in addition to the interface.

Partial diagram before: https://goo.gl/LBxH3h, after: https://goo.gl/E6sDrc.

Bug: 875005
Test: v_d_a_unittests and simplechrome on kevin
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: Ibed94b8763e02ffbfef3b5137684306761e5d748
Reviewed-on: https://chromium-review.googlesource.com/1178667Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Commit-Queue: Miguel Casas <mcasas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587869}
parent e7316a58
...@@ -70,8 +70,7 @@ const uint32_t V4L2SliceVideoDecodeAccelerator::supported_input_fourccs_[] = { ...@@ -70,8 +70,7 @@ const uint32_t V4L2SliceVideoDecodeAccelerator::supported_input_fourccs_[] = {
V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME, V4L2_PIX_FMT_VP9_FRAME, V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME, V4L2_PIX_FMT_VP9_FRAME,
}; };
class V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface class V4L2DecodeSurface : public base::RefCounted<V4L2DecodeSurface> {
: public base::RefCounted<V4L2DecodeSurface> {
public: public:
using ReleaseCB = base::Callback<void(int)>; using ReleaseCB = base::Callback<void(int)>;
...@@ -126,28 +125,27 @@ class V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface ...@@ -126,28 +125,27 @@ class V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface
DISALLOW_COPY_AND_ASSIGN(V4L2DecodeSurface); DISALLOW_COPY_AND_ASSIGN(V4L2DecodeSurface);
}; };
V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::V4L2DecodeSurface( V4L2DecodeSurface::V4L2DecodeSurface(int input_record,
int input_record, int output_record,
int output_record, const ReleaseCB& release_cb)
const ReleaseCB& release_cb)
: input_record_(input_record), : input_record_(input_record),
output_record_(output_record), output_record_(output_record),
config_store_(input_record + 1), config_store_(input_record + 1),
decoded_(false), decoded_(false),
release_cb_(release_cb) {} release_cb_(release_cb) {}
V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::~V4L2DecodeSurface() { V4L2DecodeSurface::~V4L2DecodeSurface() {
DVLOGF(5) << "Releasing output record id=" << output_record_; DVLOGF(5) << "Releasing output record id=" << output_record_;
release_cb_.Run(output_record_); release_cb_.Run(output_record_);
} }
void V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::SetReferenceSurfaces( void V4L2DecodeSurface::SetReferenceSurfaces(
const std::vector<scoped_refptr<V4L2DecodeSurface>>& ref_surfaces) { const std::vector<scoped_refptr<V4L2DecodeSurface>>& ref_surfaces) {
DCHECK(reference_surfaces_.empty()); DCHECK(reference_surfaces_.empty());
reference_surfaces_ = ref_surfaces; reference_surfaces_ = ref_surfaces;
} }
void V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::SetDecoded() { void V4L2DecodeSurface::SetDecoded() {
DCHECK(!decoded_); DCHECK(!decoded_);
decoded_ = true; decoded_ = true;
...@@ -160,8 +158,7 @@ void V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::SetDecoded() { ...@@ -160,8 +158,7 @@ void V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::SetDecoded() {
base::ResetAndReturn(&done_cb_).Run(); base::ResetAndReturn(&done_cb_).Run();
} }
std::string V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface::ToString() std::string V4L2DecodeSurface::ToString() const {
const {
std::string out; std::string out;
base::StringAppendF(&out, "Buffer %d -> %d. ", input_record_, output_record_); base::StringAppendF(&out, "Buffer %d -> %d. ", input_record_, output_record_);
base::StringAppendF(&out, "Reference surfaces:"); base::StringAppendF(&out, "Reference surfaces:");
...@@ -378,84 +375,63 @@ class V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator ...@@ -378,84 +375,63 @@ class V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator
// This allows us to keep decoders oblivious of our implementation details. // This allows us to keep decoders oblivious of our implementation details.
class V4L2H264Picture : public H264Picture { class V4L2H264Picture : public H264Picture {
public: public:
explicit V4L2H264Picture( explicit V4L2H264Picture(const scoped_refptr<V4L2DecodeSurface>& dec_surface);
const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>&
dec_surface);
V4L2H264Picture* AsV4L2H264Picture() override { return this; } V4L2H264Picture* AsV4L2H264Picture() override { return this; }
scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> scoped_refptr<V4L2DecodeSurface> dec_surface() { return dec_surface_; }
dec_surface() {
return dec_surface_;
}
private: private:
~V4L2H264Picture() override; ~V4L2H264Picture() override;
scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> scoped_refptr<V4L2DecodeSurface> dec_surface_;
dec_surface_;
DISALLOW_COPY_AND_ASSIGN(V4L2H264Picture); DISALLOW_COPY_AND_ASSIGN(V4L2H264Picture);
}; };
V4L2H264Picture::V4L2H264Picture( V4L2H264Picture::V4L2H264Picture(
const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>& const scoped_refptr<V4L2DecodeSurface>& dec_surface)
dec_surface)
: dec_surface_(dec_surface) {} : dec_surface_(dec_surface) {}
V4L2H264Picture::~V4L2H264Picture() {} V4L2H264Picture::~V4L2H264Picture() {}
class V4L2VP8Picture : public VP8Picture { class V4L2VP8Picture : public VP8Picture {
public: public:
explicit V4L2VP8Picture( explicit V4L2VP8Picture(const scoped_refptr<V4L2DecodeSurface>& dec_surface);
const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>&
dec_surface);
V4L2VP8Picture* AsV4L2VP8Picture() override { return this; } V4L2VP8Picture* AsV4L2VP8Picture() override { return this; }
scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> scoped_refptr<V4L2DecodeSurface> dec_surface() { return dec_surface_; }
dec_surface() {
return dec_surface_;
}
private: private:
~V4L2VP8Picture() override; ~V4L2VP8Picture() override;
scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> scoped_refptr<V4L2DecodeSurface> dec_surface_;
dec_surface_;
DISALLOW_COPY_AND_ASSIGN(V4L2VP8Picture); DISALLOW_COPY_AND_ASSIGN(V4L2VP8Picture);
}; };
V4L2VP8Picture::V4L2VP8Picture( V4L2VP8Picture::V4L2VP8Picture(
const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>& const scoped_refptr<V4L2DecodeSurface>& dec_surface)
dec_surface)
: dec_surface_(dec_surface) {} : dec_surface_(dec_surface) {}
V4L2VP8Picture::~V4L2VP8Picture() {} V4L2VP8Picture::~V4L2VP8Picture() {}
class V4L2VP9Picture : public VP9Picture { class V4L2VP9Picture : public VP9Picture {
public: public:
explicit V4L2VP9Picture( explicit V4L2VP9Picture(const scoped_refptr<V4L2DecodeSurface>& dec_surface);
const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>&
dec_surface);
V4L2VP9Picture* AsV4L2VP9Picture() override { return this; } V4L2VP9Picture* AsV4L2VP9Picture() override { return this; }
scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> scoped_refptr<V4L2DecodeSurface> dec_surface() { return dec_surface_; }
dec_surface() {
return dec_surface_;
}
private: private:
~V4L2VP9Picture() override; ~V4L2VP9Picture() override;
scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> scoped_refptr<V4L2DecodeSurface> dec_surface_;
dec_surface_;
DISALLOW_COPY_AND_ASSIGN(V4L2VP9Picture); DISALLOW_COPY_AND_ASSIGN(V4L2VP9Picture);
}; };
V4L2VP9Picture::V4L2VP9Picture( V4L2VP9Picture::V4L2VP9Picture(
const scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface>& const scoped_refptr<V4L2DecodeSurface>& dec_surface)
dec_surface)
: dec_surface_(dec_surface) {} : dec_surface_(dec_surface) {}
V4L2VP9Picture::~V4L2VP9Picture() {} V4L2VP9Picture::~V4L2VP9Picture() {}
...@@ -2591,10 +2567,10 @@ V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::SubmitDecode( ...@@ -2591,10 +2567,10 @@ V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::SubmitDecode(
bool V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::OutputPicture( bool V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::OutputPicture(
const scoped_refptr<H264Picture>& pic) { const scoped_refptr<H264Picture>& pic) {
scoped_refptr<V4L2DecodeSurface> dec_surface = // TODO(crbug.com/647725): Insert correct color space.
H264PictureToV4L2DecodeSurface(pic); v4l2_dec_->SurfaceReady(H264PictureToV4L2DecodeSurface(pic),
dec_surface->set_visible_rect(pic->visible_rect()); pic->bitstream_id(), pic->visible_rect(),
v4l2_dec_->SurfaceReady(pic->bitstream_id(), dec_surface); VideoColorSpace());
return true; return true;
} }
...@@ -2604,9 +2580,9 @@ void V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::Reset() { ...@@ -2604,9 +2580,9 @@ void V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator::Reset() {
memset(&v4l2_slice_params_, 0, sizeof(v4l2_slice_params_)); memset(&v4l2_slice_params_, 0, sizeof(v4l2_slice_params_));
} }
scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> scoped_refptr<V4L2DecodeSurface> V4L2SliceVideoDecodeAccelerator::
V4L2SliceVideoDecodeAccelerator::V4L2H264Accelerator:: V4L2H264Accelerator::H264PictureToV4L2DecodeSurface(
H264PictureToV4L2DecodeSurface(const scoped_refptr<H264Picture>& pic) { const scoped_refptr<H264Picture>& pic) {
V4L2H264Picture* v4l2_pic = pic->AsV4L2H264Picture(); V4L2H264Picture* v4l2_pic = pic->AsV4L2H264Picture();
CHECK(v4l2_pic); CHECK(v4l2_pic);
return v4l2_pic->dec_surface(); return v4l2_pic->dec_surface();
...@@ -2827,16 +2803,16 @@ bool V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator::SubmitDecode( ...@@ -2827,16 +2803,16 @@ bool V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator::SubmitDecode(
bool V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator::OutputPicture( bool V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator::OutputPicture(
const scoped_refptr<VP8Picture>& pic) { const scoped_refptr<VP8Picture>& pic) {
scoped_refptr<V4L2DecodeSurface> dec_surface = // TODO(crbug.com/647725): Insert correct color space.
VP8PictureToV4L2DecodeSurface(pic); v4l2_dec_->SurfaceReady(VP8PictureToV4L2DecodeSurface(pic),
dec_surface->set_visible_rect(pic->visible_rect()); pic->bitstream_id(), pic->visible_rect(),
v4l2_dec_->SurfaceReady(pic->bitstream_id(), dec_surface); VideoColorSpace());
return true; return true;
} }
scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> scoped_refptr<V4L2DecodeSurface> V4L2SliceVideoDecodeAccelerator::
V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator:: V4L2VP8Accelerator::VP8PictureToV4L2DecodeSurface(
VP8PictureToV4L2DecodeSurface(const scoped_refptr<VP8Picture>& pic) { const scoped_refptr<VP8Picture>& pic) {
V4L2VP8Picture* v4l2_pic = pic->AsV4L2VP8Picture(); V4L2VP8Picture* v4l2_pic = pic->AsV4L2VP8Picture();
CHECK(v4l2_pic); CHECK(v4l2_pic);
return v4l2_pic->dec_surface(); return v4l2_pic->dec_surface();
...@@ -3131,10 +3107,10 @@ bool V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::SubmitDecode( ...@@ -3131,10 +3107,10 @@ bool V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::SubmitDecode(
bool V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::OutputPicture( bool V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::OutputPicture(
const scoped_refptr<VP9Picture>& pic) { const scoped_refptr<VP9Picture>& pic) {
scoped_refptr<V4L2DecodeSurface> dec_surface = // TODO(crbug.com/647725): Insert correct color space.
VP9PictureToV4L2DecodeSurface(pic); v4l2_dec_->SurfaceReady(VP9PictureToV4L2DecodeSurface(pic),
dec_surface->set_visible_rect(pic->visible_rect()); pic->bitstream_id(), pic->visible_rect(),
v4l2_dec_->SurfaceReady(pic->bitstream_id(), dec_surface); VideoColorSpace());
return true; return true;
} }
...@@ -3201,20 +3177,23 @@ bool V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::GetFrameContext( ...@@ -3201,20 +3177,23 @@ bool V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator::GetFrameContext(
return true; return true;
} }
scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> scoped_refptr<V4L2DecodeSurface> V4L2SliceVideoDecodeAccelerator::
V4L2SliceVideoDecodeAccelerator::V4L2VP9Accelerator:: V4L2VP9Accelerator::VP9PictureToV4L2DecodeSurface(
VP9PictureToV4L2DecodeSurface(const scoped_refptr<VP9Picture>& pic) { const scoped_refptr<VP9Picture>& pic) {
V4L2VP9Picture* v4l2_pic = pic->AsV4L2VP9Picture(); V4L2VP9Picture* v4l2_pic = pic->AsV4L2VP9Picture();
CHECK(v4l2_pic); CHECK(v4l2_pic);
return v4l2_pic->dec_surface(); return v4l2_pic->dec_surface();
} }
void V4L2SliceVideoDecodeAccelerator::SurfaceReady( void V4L2SliceVideoDecodeAccelerator::SurfaceReady(
const scoped_refptr<V4L2DecodeSurface>& dec_surface,
int32_t bitstream_id, int32_t bitstream_id,
const scoped_refptr<V4L2DecodeSurface>& dec_surface) { const gfx::Rect& visible_rect,
const VideoColorSpace& /* color_space */) {
DVLOGF(4); DVLOGF(4);
DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
dec_surface->set_visible_rect(visible_rect);
decoder_display_queue_.push(std::make_pair(bitstream_id, dec_surface)); decoder_display_queue_.push(std::make_pair(bitstream_id, dec_surface));
TryOutputSurfaces(); TryOutputSurfaces();
} }
...@@ -3265,7 +3244,7 @@ void V4L2SliceVideoDecodeAccelerator::OutputSurface( ...@@ -3265,7 +3244,7 @@ void V4L2SliceVideoDecodeAccelerator::OutputSurface(
output_record.cleared = true; output_record.cleared = true;
} }
scoped_refptr<V4L2SliceVideoDecodeAccelerator::V4L2DecodeSurface> scoped_refptr<V4L2DecodeSurface>
V4L2SliceVideoDecodeAccelerator::CreateSurface() { V4L2SliceVideoDecodeAccelerator::CreateSurface() {
DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
DCHECK_EQ(state_, kDecoding); DCHECK_EQ(state_, kDecoding);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "media/gpu/decode_surface_handler.h"
#include "media/gpu/gpu_video_decode_accelerator_helpers.h" #include "media/gpu/gpu_video_decode_accelerator_helpers.h"
#include "media/gpu/h264_decoder.h" #include "media/gpu/h264_decoder.h"
#include "media/gpu/media_gpu_export.h" #include "media/gpu/media_gpu_export.h"
...@@ -30,15 +31,16 @@ ...@@ -30,15 +31,16 @@
namespace media { namespace media {
class V4L2DecodeSurface;
// An implementation of VideoDecodeAccelerator that utilizes the V4L2 slice // An implementation of VideoDecodeAccelerator that utilizes the V4L2 slice
// level codec API for decoding. The slice level API provides only a low-level // level codec API for decoding. The slice level API provides only a low-level
// decoding functionality and requires userspace to provide support for parsing // decoding functionality and requires userspace to provide support for parsing
// the input stream and managing decoder state across frames. // the input stream and managing decoder state across frames.
class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator
: public VideoDecodeAccelerator { : public VideoDecodeAccelerator,
public DecodeSurfaceHandler<V4L2DecodeSurface> {
public: public:
class V4L2DecodeSurface;
V4L2SliceVideoDecodeAccelerator( V4L2SliceVideoDecodeAccelerator(
const scoped_refptr<V4L2Device>& device, const scoped_refptr<V4L2Device>& device,
EGLDisplay egl_display, EGLDisplay egl_display,
...@@ -129,6 +131,15 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator ...@@ -129,6 +131,15 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator
// //
// Below methods are used by accelerator implementations. // Below methods are used by accelerator implementations.
// //
// DecodeSurfaceHandler implementation.
scoped_refptr<V4L2DecodeSurface> CreateSurface() override;
// SurfaceReady() uses |decoder_display_queue_| to guarantee that decoding
// of |dec_surface| happens in order.
void SurfaceReady(const scoped_refptr<V4L2DecodeSurface>& dec_surface,
int32_t bitstream_id,
const gfx::Rect& visible_rect,
const VideoColorSpace& /* color_space */) override;
// Append slice data in |data| of size |size| to pending hardware // Append slice data in |data| of size |size| to pending hardware
// input buffer with |index|. This buffer will be submitted for decode // input buffer with |index|. This buffer will be submitted for decode
// on the next DecodeSurface(). Return true on success. // on the next DecodeSurface(). Return true on success.
...@@ -144,15 +155,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator ...@@ -144,15 +155,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator
// Return true if the driver exposes V4L2 control |ctrl_id|, false otherwise. // Return true if the driver exposes V4L2 control |ctrl_id|, false otherwise.
bool IsCtrlExposed(uint32_t ctrl_id); bool IsCtrlExposed(uint32_t ctrl_id);
// |dec_surface| is ready to be outputted once decode is finished.
// This can be called before decode is actually done in hardware, and this
// method is responsible for maintaining the ordering, i.e. the surfaces will
// be outputted in the same order as SurfaceReady calls. To do so, the
// surfaces are put on decoder_display_queue_ and sent to output in that
// order once all preceding surfaces are sent.
void SurfaceReady(int32_t bitstream_id,
const scoped_refptr<V4L2DecodeSurface>& dec_surface);
// //
// Internal methods of this class. // Internal methods of this class.
// //
...@@ -350,9 +352,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator ...@@ -350,9 +352,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecodeAccelerator
// front of the queue that are already decoded to the client, in order. // front of the queue that are already decoded to the client, in order.
void TryOutputSurfaces(); void TryOutputSurfaces();
// Creates a new decode surface or returns nullptr if one is not available.
scoped_refptr<V4L2DecodeSurface> CreateSurface();
// Send decoded pictures to PictureReady. // Send decoded pictures to PictureReady.
void SendPictureReady(); void SendPictureReady();
......
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