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

Unified Diff: media/gpu/v4l2_video_decode_accelerator.cc

Issue 2408703002: V4L2VideoDecodeAccelerator: implement flush by VIDIOC_DECODER_CMD. (Closed)
Patch Set: rebase Created 4 years, 2 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
« no previous file with comments | « media/gpu/v4l2_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/gpu/v4l2_video_decode_accelerator.cc
diff --git a/media/gpu/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2_video_decode_accelerator.cc
index b4ac8a19f993babcca1d4833d9a59ce3e83dc9e4..d48cc76c59dce0897d792594269a2bfbcbb7c040 100644
--- a/media/gpu/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2_video_decode_accelerator.cc
@@ -164,6 +164,8 @@ V4L2VideoDecodeAccelerator::V4L2VideoDecodeAccelerator(
decoder_decode_buffer_tasks_scheduled_(0),
decoder_frames_at_client_(0),
decoder_flushing_(false),
+ decoder_cmd_supported_(false),
+ flush_waiting_last_output_buffer_(false),
reset_pending_(false),
decoder_partial_frame_pending_(false),
input_streamon_(false),
@@ -287,6 +289,8 @@ bool V4L2VideoDecodeAccelerator::Initialize(const Config& config,
return false;
}
+ decoder_cmd_supported_ = DecoderCmdSupported();
+
decoder_state_ = kInitialized;
output_mode_ = config.output_mode;
@@ -1393,6 +1397,17 @@ bool V4L2VideoDecodeAccelerator::DequeueOutputBuffer() {
SendPictureReady();
output_record.cleared = true;
}
+ if ((dqbuf.flags & V4L2_BUF_FLAG_LAST)) {
+ DVLOGF(3) << "Got last output buffer. Waiting last buffer="
+ << flush_waiting_last_output_buffer_;
+ if (flush_waiting_last_output_buffer_) {
+ struct v4l2_decoder_cmd cmd;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.cmd = V4L2_DEC_CMD_START;
+ IOCTL_OR_ERROR_RETURN(VIDIOC_DECODER_CMD, &cmd);
kcwu 2016/10/11 08:46:05 IOCTL_OR_ERROR_RETURN_FALSE. wondering why compile
wuchengli 2016/10/11 10:30:57 Fixed.
+ flush_waiting_last_output_buffer_ = false;
+ }
+ }
}
return true;
}
@@ -1544,12 +1559,21 @@ void V4L2VideoDecodeAccelerator::FlushTask() {
// We don't support stacked flushing.
DCHECK(!decoder_flushing_);
-
- // Queue up an empty buffer -- this triggers the flush.
- decoder_input_queue_.push(
- linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
- decode_client_, decode_task_runner_, nullptr, kFlushBufferId)));
+ DCHECK(!flush_waiting_last_output_buffer_);
+ if (decoder_cmd_supported_) {
+ struct v4l2_decoder_cmd cmd;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.cmd = V4L2_DEC_CMD_STOP;
+ IOCTL_OR_ERROR_RETURN(VIDIOC_DECODER_CMD, &cmd);
+ flush_waiting_last_output_buffer_ = true;
+ } else {
+ // Queue up an empty buffer -- this triggers the flush.
+ decoder_input_queue_.push(
+ linked_ptr<BitstreamBufferRef>(new BitstreamBufferRef(
+ decode_client_, decode_task_runner_, nullptr, kFlushBufferId)));
+ }
decoder_flushing_ = true;
+
SendPictureReady(); // Send all pending PictureReady.
ScheduleDecodeBufferTaskIfNeeded();
@@ -1557,8 +1581,10 @@ void V4L2VideoDecodeAccelerator::FlushTask() {
void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
- if (!decoder_flushing_)
+ if (!decoder_flushing_) {
+ DVLOGF(3) << "Not flushing";
return;
+ }
// Pipeline is empty when:
// * Decoder input queue is empty of non-delayed buffers.
@@ -1568,15 +1594,25 @@ void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
// * All image processor buffers are returned.
if (!decoder_input_queue_.empty()) {
if (decoder_input_queue_.front()->input_id !=
- decoder_delay_bitstream_buffer_id_)
+ decoder_delay_bitstream_buffer_id_) {
+ DVLOGF(3) << "Some decoder inputs are not queued.";
return;
+ }
}
- if (decoder_current_input_buffer_ != -1)
+ if (decoder_current_input_buffer_ != -1) {
+ DVLOGF(3) << "Current input buffer != -1";
return;
- if ((input_ready_queue_.size() + input_buffer_queued_count_) != 0)
+ }
+ if ((input_ready_queue_.size() + input_buffer_queued_count_) != 0) {
+ DVLOGF(3) << "some input buffers are not dequeued.";
return;
+ }
if (image_processor_bitstream_buffer_ids_.size() != 0)
return;
+ if (flush_waiting_last_output_buffer_) {
+ DVLOGF(3) << "Waiting last output buffer";
+ return;
+ }
// TODO(posciak): crbug.com/270039. Exynos requires a streamoff-streamon
// sequence after flush to continue, even if we are not resetting. This would
@@ -1603,6 +1639,25 @@ void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
ScheduleDecodeBufferTaskIfNeeded();
}
+bool V4L2VideoDecodeAccelerator::DecoderCmdSupported() {
kcwu 2016/10/11 08:46:05 How about named it as IsDecoderCmdSupported() ?
wuchengli 2016/10/11 10:30:57 Done.
+ struct v4l2_decoder_cmd cmd;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.cmd = V4L2_DEC_CMD_START;
+ if (device_->Ioctl(VIDIOC_TRY_DECODER_CMD, &cmd) != 0) {
+ DVLOGF(3) "V4L2_DEC_CMD_START is not supported.";
+ return false;
+ }
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.cmd = V4L2_DEC_CMD_STOP;
+ if (device_->Ioctl(VIDIOC_TRY_DECODER_CMD, &cmd) != 0) {
+ DVLOGF(3) "V4L2_DEC_CMD_STOP is not supported.";
+ return false;
+ }
+
+ return true;
+}
+
void V4L2VideoDecodeAccelerator::ResetTask() {
DVLOGF(3);
DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
@@ -1722,6 +1777,7 @@ void V4L2VideoDecodeAccelerator::DestroyTask() {
while (!decoder_input_queue_.empty())
decoder_input_queue_.pop();
decoder_flushing_ = false;
+ flush_waiting_last_output_buffer_ = false;
kcwu 2016/10/11 08:46:05 I'm wondering, if it is valid to call Reset() when
wuchengli 2016/10/11 10:30:57 I cleared flush_waiting_last_output_buffer_ in Sto
if (image_processor_)
image_processor_.release()->Destroy();
« no previous file with comments | « media/gpu/v4l2_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698