0

media/gpu/v4l2: process change resolution event correctly

Make sure that there is no pending change resolution
after the last buffer is received.

BUG=b:161904111
TEST=seek test starting to pass on trogdor

Change-Id: I7e01216d3f24f19d097d72c99a4f2ed8598c5f91
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2382950
Reviewed-by: Alexandre Courbot <acourbot@chromium.org>
Commit-Queue: Fritz Koenig <frkoenig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805758}
This commit is contained in:
Fritz Koenig
2020-09-10 15:29:51 +00:00
committed by Commit Bot
parent d0f5de465c
commit e6283bcc0c
3 changed files with 26 additions and 15 deletions

@ -569,6 +569,8 @@ void V4L2VideoDecoder::ServiceDeviceTask(bool event) {
<< ", Number of queued output buffers: "
<< output_queue_->QueuedBuffersCount();
backend_->OnServiceDeviceTask(event);
// Dequeue V4L2 output buffer first to reduce output latency.
bool success;
while (output_queue_->QueuedBuffersCount() > 0) {
@ -597,8 +599,6 @@ void V4L2VideoDecoder::ServiceDeviceTask(bool event) {
if (!dequeued_buffer)
break;
}
backend_->OnServiceDeviceTask(event);
}
void V4L2VideoDecoder::OutputFrame(scoped_refptr<VideoFrame> frame,

@ -230,18 +230,21 @@ void V4L2StatefulVideoDecoderBackend::ScheduleDecodeWork() {
weak_this_));
}
void V4L2StatefulVideoDecoderBackend::ProcessEventQueue() {
while (base::Optional<struct v4l2_event> ev = device_->DequeueEvent()) {
if (ev->type == V4L2_EVENT_SOURCE_CHANGE &&
(ev->u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION)) {
ChangeResolution();
}
}
}
void V4L2StatefulVideoDecoderBackend::OnServiceDeviceTask(bool event) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOGF(3);
if (event) {
while (base::Optional<struct v4l2_event> ev = device_->DequeueEvent()) {
if (ev->type == V4L2_EVENT_SOURCE_CHANGE &&
(ev->u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION)) {
ChangeResolution();
}
}
}
if (event)
ProcessEventQueue();
// We can enqueue dequeued output buffers immediately.
EnqueueOutputBuffers();
@ -384,11 +387,16 @@ void V4L2StatefulVideoDecoderBackend::OnOutputBufferDequeued(
// The order here is important! A flush event may come after a resolution
// change event (but not the opposite), so we must make sure both events
// are processed in the correct order.
if (buffer->IsLast() && resolution_change_cb_) {
std::move(resolution_change_cb_).Run();
} else if (buffer->IsLast() && flush_cb_) {
// We were waiting for a flush to complete, and received the last buffer.
CompleteFlush();
if (buffer->IsLast()){
if (!resolution_change_cb_ && !flush_cb_)
ProcessEventQueue();
if (resolution_change_cb_) {
std::move(resolution_change_cb_).Run();
} else if (flush_cb_) {
// We were waiting for a flush to complete, and received the last buffer.
CompleteFlush();
}
}
EnqueueOutputBuffers();

@ -112,6 +112,9 @@ class V4L2StatefulVideoDecoderBackend : public V4L2VideoDecoderBackend {
void ScheduleDecodeWork();
// Process all the event in the event queue
void ProcessEventQueue();
// Video profile we are decoding.
VideoCodecProfile profile_;