diff mbox series

[04/15] media: coda: limit queueing into internal bitstream buffer

Message ID 20181105152513.26345-4-p.zabel@pengutronix.de (mailing list archive)
State New, archived
Headers show
Series [01/15] media: coda: fix memory corruption in case more than 32 instances are opened | expand

Commit Message

Philipp Zabel Nov. 5, 2018, 3:25 p.m. UTC
From: Lucas Stach <l.stach@pengutronix.de>

The ringbuffer used to hold the bitstream is very conservatively sized,
as keyframes can get very large and still need to fit into this buffer.
This means that the buffer is way oversized for the average stream to
the extend that it will hold a few hundred frames when the video data
is compressing well.

The current strategy of queueing as much bitstream data as possible
leads to large delays when draining the decoder. In order to keep the
drain latency to a reasonable bound, try to only queue a full reorder
window of buffers. We can't always hit this low target for very well
compressible video data, as we might end up with less than the minimum
amount of data that needs to be available to the bitstream prefetcher,
so we must take this into account and allow more buffers to be queued
in this case.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 drivers/media/platform/coda/coda-bit.c | 28 ++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

Comments

Philipp Zabel Nov. 14, 2018, 2:59 p.m. UTC | #1
Hi,

I forgot to add the proper SoB tag:

On Mon, 2018-11-05 at 16:25 +0100, Philipp Zabel wrote:
> From: Lucas Stach <l.stach@pengutronix.de>
> 
> The ringbuffer used to hold the bitstream is very conservatively sized,
> as keyframes can get very large and still need to fit into this buffer.
> This means that the buffer is way oversized for the average stream to
> the extend that it will hold a few hundred frames when the video data
> is compressing well.
> 
> The current strategy of queueing as much bitstream data as possible
> leads to large delays when draining the decoder. In order to keep the
> drain latency to a reasonable bound, try to only queue a full reorder
> window of buffers. We can't always hit this low target for very well
> compressible video data, as we might end up with less than the minimum
> amount of data that needs to be available to the bitstream prefetcher,
> so we must take this into account and allow more buffers to be queued
> in this case.
> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>

regards
Philipp
diff mbox series

Patch

diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index e5ce0bec8ec3..ee9d2a402ccd 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -269,6 +269,23 @@  void coda_fill_bitstream(struct coda_ctx *ctx, struct list_head *buffer_list)
 		    ctx->num_metas > 1)
 			break;
 
+		if (ctx->num_internal_frames &&
+		    ctx->num_metas >= ctx->num_internal_frames) {
+			meta = list_first_entry(&ctx->buffer_meta_list,
+						struct coda_buffer_meta, list);
+
+			/*
+			 * If we managed to fill in at least a full reorder
+			 * window of buffers (num_internal_frames is a
+			 * conservative estimate for this) and the bitstream
+			 * prefetcher has at least 2 256 bytes periods beyond
+			 * the first buffer to fetch, we can safely stop queuing
+			 * in order to limit the decoder drain latency.
+			 */
+			if (coda_bitstream_can_fetch_past(ctx, meta->end))
+				break;
+		}
+
 		src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 
 		/* Drop frames that do not start/end with a SOI/EOI markers */
@@ -2252,6 +2269,17 @@  static void coda_finish_decode(struct coda_ctx *ctx)
 
 	/* The rotator will copy the current display frame next time */
 	ctx->display_idx = display_idx;
+
+	/*
+	 * The current decode run might have brought the bitstream fill level
+	 * below the size where we can start the next decode run. As userspace
+	 * might have filled the output queue completely and might thus be
+	 * blocked, we can't rely on the next qbuf to trigger the bitstream
+	 * refill. Check if we have data to refill the bitstream now.
+	 */
+	mutex_lock(&ctx->bitstream_mutex);
+	coda_fill_bitstream(ctx, NULL);
+	mutex_unlock(&ctx->bitstream_mutex);
 }
 
 static void coda_decode_timeout(struct coda_ctx *ctx)