diff options
author | Lucas Stach <l.stach@pengutronix.de> | 2018-11-05 10:25:02 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-11-23 05:27:05 -0500 |
commit | c3d996fb03c6539771ad778cd66ff5595bfc263a (patch) | |
tree | 3d15ea8e7b53f5ab7b7b658a569711e4c2c5bc81 | |
parent | 51407c2da0b7baac581d0d9fbfc297d10b7d0424 (diff) | |
download | linux-c3d996fb03c6539771ad778cd66ff5595bfc263a.tar.bz2 |
media: coda: limit queueing into internal bitstream buffer
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>
Signed-off-by: Hans Verkuil <hansverk@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r-- | drivers/media/platform/coda/coda-bit.c | 28 |
1 files changed, 28 insertions, 0 deletions
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) |