Commit e6283bcc authored by Fritz Koenig's avatar Fritz Koenig Committed by Commit Bot

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/+/2382950Reviewed-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Commit-Queue: Fritz Koenig <frkoenig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805758}
parent d0f5de46
...@@ -569,6 +569,8 @@ void V4L2VideoDecoder::ServiceDeviceTask(bool event) { ...@@ -569,6 +569,8 @@ void V4L2VideoDecoder::ServiceDeviceTask(bool event) {
<< ", Number of queued output buffers: " << ", Number of queued output buffers: "
<< output_queue_->QueuedBuffersCount(); << output_queue_->QueuedBuffersCount();
backend_->OnServiceDeviceTask(event);
// Dequeue V4L2 output buffer first to reduce output latency. // Dequeue V4L2 output buffer first to reduce output latency.
bool success; bool success;
while (output_queue_->QueuedBuffersCount() > 0) { while (output_queue_->QueuedBuffersCount() > 0) {
...@@ -597,8 +599,6 @@ void V4L2VideoDecoder::ServiceDeviceTask(bool event) { ...@@ -597,8 +599,6 @@ void V4L2VideoDecoder::ServiceDeviceTask(bool event) {
if (!dequeued_buffer) if (!dequeued_buffer)
break; break;
} }
backend_->OnServiceDeviceTask(event);
} }
void V4L2VideoDecoder::OutputFrame(scoped_refptr<VideoFrame> frame, void V4L2VideoDecoder::OutputFrame(scoped_refptr<VideoFrame> frame,
......
...@@ -230,18 +230,21 @@ void V4L2StatefulVideoDecoderBackend::ScheduleDecodeWork() { ...@@ -230,18 +230,21 @@ void V4L2StatefulVideoDecoderBackend::ScheduleDecodeWork() {
weak_this_)); 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) { void V4L2StatefulVideoDecoderBackend::OnServiceDeviceTask(bool event) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOGF(3); DVLOGF(3);
if (event) { if (event)
while (base::Optional<struct v4l2_event> ev = device_->DequeueEvent()) { ProcessEventQueue();
if (ev->type == V4L2_EVENT_SOURCE_CHANGE &&
(ev->u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION)) {
ChangeResolution();
}
}
}
// We can enqueue dequeued output buffers immediately. // We can enqueue dequeued output buffers immediately.
EnqueueOutputBuffers(); EnqueueOutputBuffers();
...@@ -384,11 +387,16 @@ void V4L2StatefulVideoDecoderBackend::OnOutputBufferDequeued( ...@@ -384,11 +387,16 @@ void V4L2StatefulVideoDecoderBackend::OnOutputBufferDequeued(
// The order here is important! A flush event may come after a resolution // 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 // change event (but not the opposite), so we must make sure both events
// are processed in the correct order. // are processed in the correct order.
if (buffer->IsLast() && resolution_change_cb_) { if (buffer->IsLast()){
std::move(resolution_change_cb_).Run(); if (!resolution_change_cb_ && !flush_cb_)
} else if (buffer->IsLast() && flush_cb_) { ProcessEventQueue();
// We were waiting for a flush to complete, and received the last buffer.
CompleteFlush(); 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(); EnqueueOutputBuffers();
......
...@@ -112,6 +112,9 @@ class V4L2StatefulVideoDecoderBackend : public V4L2VideoDecoderBackend { ...@@ -112,6 +112,9 @@ class V4L2StatefulVideoDecoderBackend : public V4L2VideoDecoderBackend {
void ScheduleDecodeWork(); void ScheduleDecodeWork();
// Process all the event in the event queue
void ProcessEventQueue();
// Video profile we are decoding. // Video profile we are decoding.
VideoCodecProfile profile_; VideoCodecProfile profile_;
......
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