mirror of https://gitee.com/openkylin/linux.git
media: coda: always hold back decoder jobs until we have enough bitstream payload
The bitstream prefetch unit reads data in 256 byte blocks with some kind of queueing. For the decoder to see data up to a desired position in the next run, the bitstream has to be filled for 2 256 byte blocks past that position aligned up to the next 256 byte boundary. This should make sure we never run into a buffer underrun condition if userspace does not supply new input buffers fast enough. 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>
This commit is contained in:
parent
6c0f5d236f
commit
51407c2da0
|
@ -1273,6 +1273,7 @@ static int coda_job_ready(void *m2m_priv)
|
||||||
bool stream_end = ctx->bit_stream_param &
|
bool stream_end = ctx->bit_stream_param &
|
||||||
CODA_BIT_STREAM_END_FLAG;
|
CODA_BIT_STREAM_END_FLAG;
|
||||||
int num_metas = ctx->num_metas;
|
int num_metas = ctx->num_metas;
|
||||||
|
struct coda_buffer_meta *meta;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
count = hweight32(ctx->frm_dis_flg);
|
count = hweight32(ctx->frm_dis_flg);
|
||||||
|
@ -1293,16 +1294,18 @@ static int coda_job_ready(void *m2m_priv)
|
||||||
|
|
||||||
if (!stream_end && (num_metas + src_bufs) < 2) {
|
if (!stream_end && (num_metas + src_bufs) < 2) {
|
||||||
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
|
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
|
||||||
"%d: not ready: need 2 buffers available (%d, %d)\n",
|
"%d: not ready: need 2 buffers available (queue:%d + bitstream:%d)\n",
|
||||||
ctx->idx, num_metas, src_bufs);
|
ctx->idx, num_metas, src_bufs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!src_bufs && !stream_end &&
|
meta = list_first_entry(&ctx->buffer_meta_list,
|
||||||
(coda_get_bitstream_payload(ctx) < 512)) {
|
struct coda_buffer_meta, list);
|
||||||
|
if (!coda_bitstream_can_fetch_past(ctx, meta->end) &&
|
||||||
|
!stream_end) {
|
||||||
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
|
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
|
||||||
"%d: not ready: not enough bitstream data (%d).\n",
|
"not ready: not enough bitstream data to read past %u (%u)\n",
|
||||||
ctx->idx, coda_get_bitstream_payload(ctx));
|
meta->end, ctx->bitstream_fifo.kfifo.in);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,6 +296,18 @@ static inline unsigned int coda_get_bitstream_payload(struct coda_ctx *ctx)
|
||||||
return kfifo_len(&ctx->bitstream_fifo);
|
return kfifo_len(&ctx->bitstream_fifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The bitstream prefetcher needs to read at least 2 256 byte periods past
|
||||||
|
* the desired bitstream position for all data to reach the decoder.
|
||||||
|
*/
|
||||||
|
static inline bool coda_bitstream_can_fetch_past(struct coda_ctx *ctx,
|
||||||
|
unsigned int pos)
|
||||||
|
{
|
||||||
|
return (int)(ctx->bitstream_fifo.kfifo.in - ALIGN(pos, 256)) > 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool coda_bitstream_can_fetch_past(struct coda_ctx *ctx, unsigned int pos);
|
||||||
|
|
||||||
void coda_bit_stream_end_flag(struct coda_ctx *ctx);
|
void coda_bit_stream_end_flag(struct coda_ctx *ctx);
|
||||||
|
|
||||||
void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
|
void coda_m2m_buf_done(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf,
|
||||||
|
|
Loading…
Reference in New Issue