diff mbox

media: coda: fix comparision of decoded frames' indexes

Message ID 20171117143010.501-1-martink@posteo.de (mailing list archive)
State New, archived
Headers show

Commit Message

Martin Kepplinger-Novakovic Nov. 17, 2017, 2:30 p.m. UTC
At this point the driver looks the currently decoded frame's index
and compares is to VPU-specific state values. Directly before this
if and else statements the indexes are read (index for decoded and
for displayed frame).

Now what is saved in ctx->display_idx is an older value at this point!
During these index checks, the current values apply, so fix this by
taking display_idx instead of ctx->display_idx.

ctx->display_idx is updated later in the same function.

Signed-off-by: Martin Kepplinger <martink@posteo.de>
---

Please review this thoroughly, but in case I am wrong here, this is
at least very strange to read and *should* be accompanied with a
comment about what's going on with that index value!

I don't think it matter that much here because at least playing h264
worked before and works with this change, but I've tested it anyways.

thanks

                               martin


 drivers/media/platform/coda/coda-bit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Philipp Zabel Nov. 22, 2017, 1:43 p.m. UTC | #1
Hi Martin,

On Fri, 2017-11-17 at 15:30 +0100, Martin Kepplinger wrote:
> At this point the driver looks the currently decoded frame's index
> and compares is to VPU-specific state values. Directly before this
> if and else statements the indexes are read (index for decoded and
> for displayed frame).
> 
> Now what is saved in ctx->display_idx is an older value at this point!

Yes. The rotator that copies out the decoded frame runs in parallel with
the decoding of the next frame. So the decoder signals with display_idx
which decoded frame should be presented next, but it is only copied out
into the vb2 buffer during the following run. The same happens with the
VDOA, but manually, in prepare_decode.

That means that at this point display_idx is the index of the previously
decoded internal frame that should be presented next, and ctx-
>display_idx is the index of the internal frame that was just copied
into the externally visible vb2 buffer.

The logic reads someting like this:

	if (no frame was decoded) {
		if (a frame will be copied out next time) {
			adapt sequence number offset;
		} else if (no frame was copied out this time) {
			hold until further input;
		}
	}

Basically, it will just wait one more run until it stops the stream,
assuming that there is really nothing useful in the bitstream
ringbuffer.

> During these index checks, the current values apply, so fix this by
> taking display_idx instead of ctx->display_idx.

display_idx is already checked later in the same function.
According to the i.MX6 VPU API document, it can be -2 (never seen) or -3
during sequence start (if there is frame reordering, depending on
whether decoder skip is enabled), and I think I've seen -3 as prescan
failure on i.MX5. -1 means EOS according to that document, that's why we
always hold in that case.

> ctx->display_idx is updated later in the same function.
> 
> Signed-off-by: Martin Kepplinger <martink@posteo.de>
> ---
> 
> Please review this thoroughly, but in case I am wrong here, this is
> at least very strange to read and *should* be accompanied with a
> comment about what's going on with that index value!

Maybe it would be less confusing to move this into the display_idx checks below, given that we already hold unconditionally
on display_idx == -1.

> I don't think it matter that much here because at least playing h264
> worked before and works with this change, but I've tested it anyways.

I think this shouldn't happen at all if you feed it a well formed h.264
stream. But if you have a skip because of broken data while there is
still no display frame at the beginning of the stream or after an IDR,
this might be hit.

regards
Philipp
Martin Kepplinger-Novakovic Nov. 24, 2017, 7:47 a.m. UTC | #2
Am 22.11.2017 14:43 schrieb Philipp Zabel:
> Hi Martin,
> 
> On Fri, 2017-11-17 at 15:30 +0100, Martin Kepplinger wrote:
>> At this point the driver looks the currently decoded frame's index
>> and compares is to VPU-specific state values. Directly before this
>> if and else statements the indexes are read (index for decoded and
>> for displayed frame).
>> 
>> Now what is saved in ctx->display_idx is an older value at this point!
> 
> Yes. The rotator that copies out the decoded frame runs in parallel 
> with
> the decoding of the next frame. So the decoder signals with display_idx
> which decoded frame should be presented next, but it is only copied out
> into the vb2 buffer during the following run. The same happens with the
> VDOA, but manually, in prepare_decode.
> 
> That means that at this point display_idx is the index of the 
> previously
> decoded internal frame that should be presented next, and ctx-
>> display_idx is the index of the internal frame that was just copied
> into the externally visible vb2 buffer.
> 
> The logic reads someting like this:
> 
> 	if (no frame was decoded) {
> 		if (a frame will be copied out next time) {
> 			adapt sequence number offset;
> 		} else if (no frame was copied out this time) {
> 			hold until further input;
> 		}
> 	}
> 
> Basically, it will just wait one more run until it stops the stream,
> assuming that there is really nothing useful in the bitstream
> ringbuffer.
> 
>> During these index checks, the current values apply, so fix this by
>> taking display_idx instead of ctx->display_idx.
> 
> display_idx is already checked later in the same function.
> According to the i.MX6 VPU API document, it can be -2 (never seen) or 
> -3
> during sequence start (if there is frame reordering, depending on
> whether decoder skip is enabled), and I think I've seen -3 as prescan
> failure on i.MX5. -1 means EOS according to that document, that's why 
> we
> always hold in that case.
> 
>> ctx->display_idx is updated later in the same function.
>> 
>> Signed-off-by: Martin Kepplinger <martink@posteo.de>
>> ---
>> 
>> Please review this thoroughly, but in case I am wrong here, this is
>> at least very strange to read and *should* be accompanied with a
>> comment about what's going on with that index value!
> 
> Maybe it would be less confusing to move this into the display_idx
> checks below, given that we already hold unconditionally
> on display_idx == -1.
> 
>> I don't think it matter that much here because at least playing h264
>> worked before and works with this change, but I've tested it anyways.
> 
> I think this shouldn't happen at all if you feed it a well formed h.264
> stream. But if you have a skip because of broken data while there is
> still no display frame at the beginning of the stream or after an IDR,
> this might be hit.

Right. Let's leave it this way. In case of real changes, one can think 
about
cleanup.

Thanks for clarification and helping to understand this thing! I 
appreciate it.

                                  martin
diff mbox

Patch

diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index bfc4ecf6f068..fe38527a90e2 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -2089,7 +2089,7 @@  static void coda_finish_decode(struct coda_ctx *ctx)
 		/* no frame was decoded, but we might have a display frame */
 		if (display_idx >= 0 && display_idx < ctx->num_internal_frames)
 			ctx->sequence_offset++;
-		else if (ctx->display_idx < 0)
+		else if (display_idx < 0)
 			ctx->hold = true;
 	} else if (decoded_idx == -2) {
 		/* no frame was decoded, we still return remaining buffers */