|
|
@@ -226,6 +226,7 @@ void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming)
|
|
|
{
|
|
|
struct vb2_buffer *src_buf;
|
|
|
struct coda_buffer_meta *meta;
|
|
|
+ unsigned long flags;
|
|
|
u32 start;
|
|
|
|
|
|
if (ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG)
|
|
|
@@ -274,8 +275,13 @@ void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming)
|
|
|
meta->start = start;
|
|
|
meta->end = ctx->bitstream_fifo.kfifo.in &
|
|
|
ctx->bitstream_fifo.kfifo.mask;
|
|
|
+ spin_lock_irqsave(&ctx->buffer_meta_lock,
|
|
|
+ flags);
|
|
|
list_add_tail(&meta->list,
|
|
|
&ctx->buffer_meta_list);
|
|
|
+ ctx->num_metas++;
|
|
|
+ spin_unlock_irqrestore(&ctx->buffer_meta_lock,
|
|
|
+ flags);
|
|
|
|
|
|
trace_coda_bit_queue(ctx, src_buf, meta);
|
|
|
}
|
|
|
@@ -1665,6 +1671,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
|
|
|
struct coda_dev *dev = ctx->dev;
|
|
|
struct coda_q_data *q_data_dst;
|
|
|
struct coda_buffer_meta *meta;
|
|
|
+ unsigned long flags;
|
|
|
u32 reg_addr, reg_stride;
|
|
|
|
|
|
dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
|
|
|
@@ -1743,6 +1750,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
|
|
|
coda_write(dev, ctx->iram_info.axi_sram_use,
|
|
|
CODA7_REG_BIT_AXI_SRAM_USE);
|
|
|
|
|
|
+ spin_lock_irqsave(&ctx->buffer_meta_lock, flags);
|
|
|
meta = list_first_entry_or_null(&ctx->buffer_meta_list,
|
|
|
struct coda_buffer_meta, list);
|
|
|
|
|
|
@@ -1762,6 +1770,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
|
|
|
kfifo_in(&ctx->bitstream_fifo, buf, pad);
|
|
|
}
|
|
|
}
|
|
|
+ spin_unlock_irqrestore(&ctx->buffer_meta_lock, flags);
|
|
|
|
|
|
coda_kfifo_sync_to_device_full(ctx);
|
|
|
|
|
|
@@ -1783,6 +1792,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
|
|
|
struct vb2_buffer *dst_buf;
|
|
|
struct coda_buffer_meta *meta;
|
|
|
unsigned long payload;
|
|
|
+ unsigned long flags;
|
|
|
int width, height;
|
|
|
int decoded_idx;
|
|
|
int display_idx;
|
|
|
@@ -1908,11 +1918,13 @@ static void coda_finish_decode(struct coda_ctx *ctx)
|
|
|
} else {
|
|
|
val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1;
|
|
|
val -= ctx->sequence_offset;
|
|
|
- mutex_lock(&ctx->bitstream_mutex);
|
|
|
+ spin_lock_irqsave(&ctx->buffer_meta_lock, flags);
|
|
|
if (!list_empty(&ctx->buffer_meta_list)) {
|
|
|
meta = list_first_entry(&ctx->buffer_meta_list,
|
|
|
struct coda_buffer_meta, list);
|
|
|
list_del(&meta->list);
|
|
|
+ ctx->num_metas--;
|
|
|
+ spin_unlock_irqrestore(&ctx->buffer_meta_lock, flags);
|
|
|
/*
|
|
|
* Clamp counters to 16 bits for comparison, as the HW
|
|
|
* counter rolls over at this point for h.264. This
|
|
|
@@ -1929,13 +1941,13 @@ static void coda_finish_decode(struct coda_ctx *ctx)
|
|
|
ctx->frame_metas[decoded_idx] = *meta;
|
|
|
kfree(meta);
|
|
|
} else {
|
|
|
+ spin_unlock_irqrestore(&ctx->buffer_meta_lock, flags);
|
|
|
v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n");
|
|
|
memset(&ctx->frame_metas[decoded_idx], 0,
|
|
|
sizeof(struct coda_buffer_meta));
|
|
|
ctx->frame_metas[decoded_idx].sequence = val;
|
|
|
ctx->sequence_offset++;
|
|
|
}
|
|
|
- mutex_unlock(&ctx->bitstream_mutex);
|
|
|
|
|
|
trace_coda_dec_pic_done(ctx, &ctx->frame_metas[decoded_idx]);
|
|
|
|