Commit 8bfa58f5 authored by Chih-Yu Huang's avatar Chih-Yu Huang Committed by Commit Bot

v4l2_vda: Skip flush if before any buffer is decoded.

When VDA enqueue flush input buffer to the Tegra driver before
enqueuing any normal input buffer, Tegra driver will stuck.

Now for the devices which do not support V4L2 decoder command, if we
call Flush() before decoding any buffer, we skip sending an empty
buffer to the driver and notify flush is done.

BUG=chromium:845627
TEST=pass video_decode_accelerator_unittest on nyan-big and peach-pit


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: I34a5ec76d95fac8f5bedd3ead08202b1a4e41dcd
Reviewed-on: https://chromium-review.googlesource.com/1127559
Commit-Queue: Chih-Yu Huang <akahuang@chromium.org>
Reviewed-by: default avatarPawel Osciak <posciak@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580811}
parent bbfe6717
...@@ -1268,7 +1268,9 @@ void V4L2VideoDecodeAccelerator::Enqueue() { ...@@ -1268,7 +1268,9 @@ void V4L2VideoDecodeAccelerator::Enqueue() {
while (!input_ready_queue_.empty()) { while (!input_ready_queue_.empty()) {
const int buffer = input_ready_queue_.front(); const int buffer = input_ready_queue_.front();
InputRecord& input_record = input_buffer_map_[buffer]; InputRecord& input_record = input_buffer_map_[buffer];
if (input_record.input_id == kFlushBufferId && decoder_cmd_supported_) {
bool flush_handled = false;
if (input_record.input_id == kFlushBufferId) {
// Send the flush command after all input buffers are dequeued. This makes // Send the flush command after all input buffers are dequeued. This makes
// sure all previous resolution changes have been handled because the // sure all previous resolution changes have been handled because the
// driver must hold the input buffer that triggers resolution change. The // driver must hold the input buffer that triggers resolution change. The
...@@ -1279,27 +1281,37 @@ void V4L2VideoDecodeAccelerator::Enqueue() { ...@@ -1279,27 +1281,37 @@ void V4L2VideoDecodeAccelerator::Enqueue() {
// yet. Also, V4L2VDA calls STREAMOFF and STREAMON after resolution // yet. Also, V4L2VDA calls STREAMOFF and STREAMON after resolution
// change. They implicitly send a V4L2_DEC_CMD_STOP and V4L2_DEC_CMD_START // change. They implicitly send a V4L2_DEC_CMD_STOP and V4L2_DEC_CMD_START
// to the decoder. // to the decoder.
if (input_buffer_queued_count_ == 0) { if (input_buffer_queued_count_ > 0)
input_ready_queue_.pop();
free_input_buffers_.push_back(buffer);
input_record.input_id = -1;
if (coded_size_.IsEmpty() || !input_streamon_) {
// (1) If coded_size_.IsEmpty(), no output buffer could have been
// allocated and there is nothing to flush. We can NotifyFlushDone()
// immediately, without requesting flush to the driver via
// SendDecoderCmdStop().
// (2) If input stream is off, we will never get the output buffer
// with V4L2_BUF_FLAG_LAST. We should NotifyFlushDone().
NotifyFlushDoneIfNeeded();
} else if (!SendDecoderCmdStop()) {
return;
}
} else {
break; break;
if (coded_size_.IsEmpty() || !input_streamon_) {
// In these situations, we should call NotifyFlushDone() immediately:
// (1) If coded_size_.IsEmpty(), no output buffer could have been
// allocated and there is nothing to flush.
// (2) If input stream is off, we will never get the output buffer
// with V4L2_BUF_FLAG_LAST.
VLOGF(2) << "Nothing to flush. Notify flush done directly.";
NofityFlushDone();
flush_handled = true;
} else if (decoder_cmd_supported_) {
if (!SendDecoderCmdStop())
return;
flush_handled = true;
} }
} else if (!EnqueueInputRecord()) }
return; if (flush_handled) {
// Recycle the buffer directly if we already handled the flush request.
input_ready_queue_.pop();
free_input_buffers_.push_back(buffer);
input_record.input_id = -1;
} else {
// Enqueue an input buffer, or an empty flush buffer if decoder cmd
// is not supported and there may be buffers to be flushed.
if (!EnqueueInputRecord())
return;
}
} }
if (old_inputs_queued == 0 && input_buffer_queued_count_ != 0) { if (old_inputs_queued == 0 && input_buffer_queued_count_ != 0) {
// We just started up a previously empty queue. // We just started up a previously empty queue.
// Queue state changed; signal interrupt. // Queue state changed; signal interrupt.
...@@ -1693,14 +1705,17 @@ void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() { ...@@ -1693,14 +1705,17 @@ void V4L2VideoDecodeAccelerator::NotifyFlushDoneIfNeeded() {
if (!StartDevicePoll()) if (!StartDevicePoll())
return; return;
NofityFlushDone();
// While we were flushing, we early-outed DecodeBufferTask()s.
ScheduleDecodeBufferTaskIfNeeded();
}
void V4L2VideoDecodeAccelerator::NofityFlushDone() {
decoder_delay_bitstream_buffer_id_ = -1; decoder_delay_bitstream_buffer_id_ = -1;
decoder_flushing_ = false; decoder_flushing_ = false;
VLOGF(2) << "returning flush"; VLOGF(2) << "returning flush";
child_task_runner_->PostTask(FROM_HERE, child_task_runner_->PostTask(FROM_HERE,
base::Bind(&Client::NotifyFlushDone, client_)); base::Bind(&Client::NotifyFlushDone, client_));
// While we were flushing, we early-outed DecodeBufferTask()s.
ScheduleDecodeBufferTaskIfNeeded();
} }
bool V4L2VideoDecodeAccelerator::IsDecoderCmdSupported() { bool V4L2VideoDecodeAccelerator::IsDecoderCmdSupported() {
......
...@@ -300,6 +300,8 @@ class MEDIA_GPU_EXPORT V4L2VideoDecodeAccelerator ...@@ -300,6 +300,8 @@ class MEDIA_GPU_EXPORT V4L2VideoDecodeAccelerator
// called any time a relevant queue could potentially be emptied: see // called any time a relevant queue could potentially be emptied: see
// function definition. // function definition.
void NotifyFlushDoneIfNeeded(); void NotifyFlushDoneIfNeeded();
// Notify the client of a flush completion.
void NofityFlushDone();
// Returns true if VIDIOC_DECODER_CMD is supported. // Returns true if VIDIOC_DECODER_CMD is supported.
bool IsDecoderCmdSupported(); bool IsDecoderCmdSupported();
// Send V4L2_DEC_CMD_START to the driver. Return true if success. // Send V4L2_DEC_CMD_START to the driver. Return true if success.
......
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