Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Unified Diff: content/common/gpu/media/v4l2_slice_video_decode_accelerator.h

Issue 1822983002: Support external buffer import in VDA interface and add a V4L2SVDA impl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/common/gpu/media/v4l2_slice_video_decode_accelerator.h
diff --git a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h
index d4b0e2e7e027a66ebd2a0a1183240ff44dc6b4cd..f917e1a4e3bcc7a3cefb63412bb9fe8c7553d14f 100644
--- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h
+++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.h
@@ -11,6 +11,7 @@
#include <memory>
#include <queue>
+#include <utility>
#include <vector>
#include "base/macros.h"
@@ -49,6 +50,9 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
void Decode(const media::BitstreamBuffer& bitstream_buffer) override;
void AssignPictureBuffers(
const std::vector<media::PictureBuffer>& buffers) override;
+ void ImportBufferForPicture(int32_t picture_buffer_id,
+ const std::vector<gfx::GpuMemoryBufferHandle>&
+ gpu_memory_buffer_handles) override;
void ReusePictureBuffer(int32_t picture_buffer_id) override;
void Flush() override;
void Reset() override;
@@ -57,6 +61,7 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
const base::WeakPtr<Client>& decode_client,
const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner)
override;
+ media::VideoPixelFormat GetOutputFormat() const override;
static media::VideoDecodeAccelerator::SupportedProfiles
GetSupportedProfiles();
@@ -81,8 +86,10 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
bool at_device;
bool at_client;
int32_t picture_id;
+ GLuint texture_id;
EGLImageKHR egl_image;
EGLSyncKHR egl_sync;
+ std::vector<base::ScopedFD> dmabuf_fds;
bool cleared;
};
@@ -158,28 +165,31 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
// Dismiss all |picture_buffer_ids| via Client::DismissPictureBuffer()
// and signal |done| after finishing.
- void DismissPictures(std::vector<int32_t> picture_buffer_ids,
+ void DismissPictures(const std::vector<int32_t>& picture_buffer_ids,
base::WaitableEvent* done);
// Task to finish initialization on decoder_thread_.
void InitializeTask();
- // Surface set change (resolution change) flow.
- // If we have no surfaces allocated, just allocate them and return.
- // Otherwise mark us as pending for surface set change.
- void InitiateSurfaceSetChange();
- // If a surface set change is pending and we are ready, stop the device,
- // destroy outputs, releasing resources and dismissing pictures as required,
- // followed by allocating a new set for the new resolution/DPB size
- // as provided by decoder. Finally, try to resume decoding.
- void FinishSurfaceSetChangeIfNeeded();
-
void NotifyError(Error error);
void DestroyTask();
// Sets the state to kError and notifies client if needed.
void SetErrorState(Error error);
+ // Event handling. Events include flush, reset and resolution change and are
+ // processed while in kIdle state.
+
+ // Surface set change (resolution change) flow.
+ // If we have no surfaces allocated, start it immediately, otherwise mark
+ // ourselves as pending for surface set change.
+ void InitiateSurfaceSetChange();
+ // If a surface set change is pending and we are ready, stop the device,
+ // destroy outputs, releasing resources and dismissing pictures as required,
+ // followed by starting the flow to allocate a new set for the current
+ // resolution/DPB size, as provided by decoder.
+ bool FinishSurfaceSetChange();
+
// Flush flow when requested by client.
// When Flush() is called, it posts a FlushTask, which checks the input queue.
// If nothing is pending for decode on decoder_input_queue_, we call
@@ -190,22 +200,78 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
// Tell the decoder to flush all frames, reset it and mark us as scheduled
// for flush, so that we can finish it once all pending decodes are finished.
void InitiateFlush();
- // If all pending frames are decoded and we are waiting to flush, perform it.
- // This will send all pending pictures to client and notify the client that
- // flush is complete and puts us in a state ready to resume.
- void FinishFlushIfNeeded();
+ // To be called if decoder_flushing_ is true. If not all pending frames are
+ // decoded, return false, requesting the caller to try again later.
+ // Otherwise perform flush by sending all pending pictures to the client,
+ // notify it that flush is finished and return true, informing the caller
+ // that further progress can be made.
+ bool FinishFlush();
// Reset flow when requested by client.
- // Drop all inputs and reset the decoder and mark us as pending for reset.
+ // Drop all inputs, reset the decoder and mark us as pending for reset.
void ResetTask();
- // If all pending frames are decoded and we are waiting to reset, perform it.
- // This drops all pending outputs (client is not interested anymore),
- // notifies the client we are done and puts us in a state ready to resume.
- void FinishResetIfNeeded();
-
- // Process pending events if any.
+ // To be called if decoder_resetting_ is true. If not all pending frames are
+ // decoded, return false, requesting the caller to try again later.
+ // Otherwise perform reset by dropping all pending outputs (client is not
+ // interested anymore), notifying it that reset is finished, and return true,
+ // informing the caller that further progress can be made.
+ bool FinishReset();
+
+ // Called when a new event is pended. Transitions us into kIdle state (if not
+ // already in it), if possible. Also starts processing events.
+ void NewEventPending();
+
+ // Called after all events are processed successfully (i.e. all Finish*()
+ // methods return true) to return to decoding state.
+ bool FinishEventProcessing();
+
+ // Process pending events, if any.
void ProcessPendingEventsIfNeeded();
+
+ // Allocate V4L2 buffers and assign them to |buffers| provided by the client
+ // via AssignPictureBuffers() on decoder thread.
+ void AssignPictureBuffersTask(
+ const std::vector<media::PictureBuffer>& buffers);
+
+ // Use buffer backed by dmabuf file descriptors in |passed_dmabuf_fds| for the
+ // OutputRecord associated with |picture_buffer_id|, taking ownership of the
+ // file descriptors.
+ void ImportBufferForPictureTask(
+ int32_t picture_buffer_id,
+ // TODO(posciak): (crbug.com/561749) we should normally be able to pass
+ // the vector by itself via std::move, but it's not possible to do this
+ // if this method is used as a callback.
+ std::unique_ptr<std::vector<base::ScopedFD>> passed_dmabuf_fds);
+
+ // Create an EGLImage for the buffer associated with V4L2 |buffer_index| and
+ // for |picture_buffer_id|, backed by dmabuf file descriptors in
+ // |passed_dmabuf_fds|, taking ownership of them.
+ // The buffer should be bound to |texture_id| and is of |size| and format
+ // described by |fourcc|.
+ void CreateEGLImageFor(
+ size_t buffer_index,
+ int32_t picture_buffer_id,
+ // TODO(posciak): (crbug.com/561749) we should normally be able to pass
+ // the vector by itself via std::move, but it's not possible to do this
+ // if this method is used as a callback.
+ std::unique_ptr<std::vector<base::ScopedFD>> passed_dmabuf_fds,
+ GLuint texture_id,
+ const gfx::Size& size,
+ uint32_t fourcc);
+
+ // Take the EGLImage |egl_image|, created for |picture_buffer_id|, and use it
+ // for OutputRecord at |buffer_index|. The buffer is backed by
+ // |passed_dmabuf_fds|, and the OutputRecord takes ownership of them.
+ void AssignEGLImage(
+ size_t buffer_index,
+ int32_t picture_buffer_id,
+ EGLImageKHR egl_image,
+ // TODO(posciak): (crbug.com/561749) we should normally be able to pass
+ // the vector by itself via std::move, but it's not possible to do this
+ // if this method is used as a callback.
+ std::unique_ptr<std::vector<base::ScopedFD>> passed_dmabuf_fds);
+
// Performed on decoder_thread_ as a consequence of poll() on decoder_thread_
// returning an event.
void ServiceDeviceTask();
@@ -232,6 +298,9 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
// Transitional state when we are not decoding any more stream, but are
// performing flush, reset, resolution change or are destroying ourselves.
kIdle,
+ // Requested new PictureBuffers via ProvidePictureBuffers(), awaiting
+ // AssignPictureBuffers().
+ kAwaitingPictureBuffers,
// Error state, set when sending NotifyError to client.
kError,
};
@@ -347,6 +416,8 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
// Decoder state.
State state_;
+ Config::OutputMode output_mode_;
+
// If any of these are true, we are waiting for the device to finish decoding
// all previously-queued frames, so we can finish the flush/reset/surface
// change flows. These can stack.
@@ -380,10 +451,6 @@ class CONTENT_EXPORT V4L2SliceVideoDecodeAccelerator
// The number of pictures that are sent to PictureReady and will be cleared.
int picture_clearing_count_;
- // Used by the decoder thread to wait for AssignPictureBuffers to arrive
- // to avoid races with potential Reset requests.
- base::WaitableEvent pictures_assigned_;
-
// EGL state
EGLDisplay egl_display_;
« no previous file with comments | « content/common/gpu/media/v4l2_device.h ('k') | content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698