aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/coda
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2014-10-02 13:08:32 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-10-28 13:37:32 -0400
commit7cbb105feff82722206613f3e4cee3e98df827d9 (patch)
treef5d8a09735dd1afe3642a7afbdc96f2ae3300557 /drivers/media/platform/coda
parentcb1d3a336371e35c3920cc50a701c5403c255644 (diff)
[media] coda: store bitstream buffer position with buffer metadata
Storing the buffer position in the bitstream with the buffer metadata allows to later use that information to drop metadata for skipped buffers and to determine whether bitstream padding has to be applied. This patch also renames struct coda_timestamp to struct coda_buffer_meta to make clear that it contains more than only the buffer timestamp. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Kamil Debski <k.debski@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/platform/coda')
-rw-r--r--drivers/media/platform/coda/coda-bit.c53
-rw-r--r--drivers/media/platform/coda/coda-common.c14
-rw-r--r--drivers/media/platform/coda/coda.h8
3 files changed, 43 insertions, 32 deletions
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index 931248dc60f9..d1ecda54666e 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -217,11 +217,16 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
217void coda_fill_bitstream(struct coda_ctx *ctx) 217void coda_fill_bitstream(struct coda_ctx *ctx)
218{ 218{
219 struct vb2_buffer *src_buf; 219 struct vb2_buffer *src_buf;
220 struct coda_timestamp *ts; 220 struct coda_buffer_meta *meta;
221 u32 start;
221 222
222 while (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) > 0) { 223 while (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) > 0) {
223 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 224 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
224 225
226 /* Buffer start position */
227 start = ctx->bitstream_fifo.kfifo.in &
228 ctx->bitstream_fifo.kfifo.mask;
229
225 if (coda_bitstream_try_queue(ctx, src_buf)) { 230 if (coda_bitstream_try_queue(ctx, src_buf)) {
226 /* 231 /*
227 * Source buffer is queued in the bitstream ringbuffer; 232 * Source buffer is queued in the bitstream ringbuffer;
@@ -229,12 +234,16 @@ void coda_fill_bitstream(struct coda_ctx *ctx)
229 */ 234 */
230 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 235 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
231 236
232 ts = kmalloc(sizeof(*ts), GFP_KERNEL); 237 meta = kmalloc(sizeof(*meta), GFP_KERNEL);
233 if (ts) { 238 if (meta) {
234 ts->sequence = src_buf->v4l2_buf.sequence; 239 meta->sequence = src_buf->v4l2_buf.sequence;
235 ts->timecode = src_buf->v4l2_buf.timecode; 240 meta->timecode = src_buf->v4l2_buf.timecode;
236 ts->timestamp = src_buf->v4l2_buf.timestamp; 241 meta->timestamp = src_buf->v4l2_buf.timestamp;
237 list_add_tail(&ts->list, &ctx->timestamp_list); 242 meta->start = start;
243 meta->end = ctx->bitstream_fifo.kfifo.in &
244 ctx->bitstream_fifo.kfifo.mask;
245 list_add_tail(&meta->list,
246 &ctx->buffer_meta_list);
238 } 247 }
239 248
240 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); 249 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
@@ -1629,7 +1638,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
1629 struct coda_q_data *q_data_src; 1638 struct coda_q_data *q_data_src;
1630 struct coda_q_data *q_data_dst; 1639 struct coda_q_data *q_data_dst;
1631 struct vb2_buffer *dst_buf; 1640 struct vb2_buffer *dst_buf;
1632 struct coda_timestamp *ts; 1641 struct coda_buffer_meta *meta;
1633 unsigned long payload; 1642 unsigned long payload;
1634 int width, height; 1643 int width, height;
1635 int decoded_idx; 1644 int decoded_idx;
@@ -1757,23 +1766,23 @@ static void coda_finish_decode(struct coda_ctx *ctx)
1757 val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1; 1766 val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1;
1758 val -= ctx->sequence_offset; 1767 val -= ctx->sequence_offset;
1759 mutex_lock(&ctx->bitstream_mutex); 1768 mutex_lock(&ctx->bitstream_mutex);
1760 if (!list_empty(&ctx->timestamp_list)) { 1769 if (!list_empty(&ctx->buffer_meta_list)) {
1761 ts = list_first_entry(&ctx->timestamp_list, 1770 meta = list_first_entry(&ctx->buffer_meta_list,
1762 struct coda_timestamp, list); 1771 struct coda_buffer_meta, list);
1763 list_del(&ts->list); 1772 list_del(&meta->list);
1764 if (val != (ts->sequence & 0xffff)) { 1773 if (val != (meta->sequence & 0xffff)) {
1765 v4l2_err(&dev->v4l2_dev, 1774 v4l2_err(&dev->v4l2_dev,
1766 "sequence number mismatch (%d(%d) != %d)\n", 1775 "sequence number mismatch (%d(%d) != %d)\n",
1767 val, ctx->sequence_offset, 1776 val, ctx->sequence_offset,
1768 ts->sequence); 1777 meta->sequence);
1769 } 1778 }
1770 ctx->frame_timestamps[decoded_idx] = *ts; 1779 ctx->frame_metas[decoded_idx] = *meta;
1771 kfree(ts); 1780 kfree(meta);
1772 } else { 1781 } else {
1773 v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n"); 1782 v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n");
1774 memset(&ctx->frame_timestamps[decoded_idx], 0, 1783 memset(&ctx->frame_metas[decoded_idx], 0,
1775 sizeof(struct coda_timestamp)); 1784 sizeof(struct coda_buffer_meta));
1776 ctx->frame_timestamps[decoded_idx].sequence = val; 1785 ctx->frame_metas[decoded_idx].sequence = val;
1777 } 1786 }
1778 mutex_unlock(&ctx->bitstream_mutex); 1787 mutex_unlock(&ctx->bitstream_mutex);
1779 1788
@@ -1812,9 +1821,9 @@ static void coda_finish_decode(struct coda_ctx *ctx)
1812 V4L2_BUF_FLAG_PFRAME | 1821 V4L2_BUF_FLAG_PFRAME |
1813 V4L2_BUF_FLAG_BFRAME); 1822 V4L2_BUF_FLAG_BFRAME);
1814 dst_buf->v4l2_buf.flags |= ctx->frame_types[ctx->display_idx]; 1823 dst_buf->v4l2_buf.flags |= ctx->frame_types[ctx->display_idx];
1815 ts = &ctx->frame_timestamps[ctx->display_idx]; 1824 meta = &ctx->frame_metas[ctx->display_idx];
1816 dst_buf->v4l2_buf.timecode = ts->timecode; 1825 dst_buf->v4l2_buf.timecode = meta->timecode;
1817 dst_buf->v4l2_buf.timestamp = ts->timestamp; 1826 dst_buf->v4l2_buf.timestamp = meta->timestamp;
1818 1827
1819 switch (q_data_dst->fourcc) { 1828 switch (q_data_dst->fourcc) {
1820 case V4L2_PIX_FMT_YUV420: 1829 case V4L2_PIX_FMT_YUV420:
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index 76b80d27a135..6eaf88e88862 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -1279,14 +1279,14 @@ static void coda_stop_streaming(struct vb2_queue *q)
1279 } 1279 }
1280 1280
1281 if (!ctx->streamon_out && !ctx->streamon_cap) { 1281 if (!ctx->streamon_out && !ctx->streamon_cap) {
1282 struct coda_timestamp *ts; 1282 struct coda_buffer_meta *meta;
1283 1283
1284 mutex_lock(&ctx->bitstream_mutex); 1284 mutex_lock(&ctx->bitstream_mutex);
1285 while (!list_empty(&ctx->timestamp_list)) { 1285 while (!list_empty(&ctx->buffer_meta_list)) {
1286 ts = list_first_entry(&ctx->timestamp_list, 1286 meta = list_first_entry(&ctx->buffer_meta_list,
1287 struct coda_timestamp, list); 1287 struct coda_buffer_meta, list);
1288 list_del(&ts->list); 1288 list_del(&meta->list);
1289 kfree(ts); 1289 kfree(meta);
1290 } 1290 }
1291 mutex_unlock(&ctx->bitstream_mutex); 1291 mutex_unlock(&ctx->bitstream_mutex);
1292 kfifo_init(&ctx->bitstream_fifo, 1292 kfifo_init(&ctx->bitstream_fifo,
@@ -1642,7 +1642,7 @@ static int coda_open(struct file *file)
1642 ctx->bitstream.vaddr, ctx->bitstream.size); 1642 ctx->bitstream.vaddr, ctx->bitstream.size);
1643 mutex_init(&ctx->bitstream_mutex); 1643 mutex_init(&ctx->bitstream_mutex);
1644 mutex_init(&ctx->buffer_mutex); 1644 mutex_init(&ctx->buffer_mutex);
1645 INIT_LIST_HEAD(&ctx->timestamp_list); 1645 INIT_LIST_HEAD(&ctx->buffer_meta_list);
1646 1646
1647 coda_lock(ctx); 1647 coda_lock(ctx);
1648 list_add(&ctx->list, &dev->instances); 1648 list_add(&ctx->list, &dev->instances);
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h
index c14dee82891f..8dd81a75c2fb 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -130,11 +130,13 @@ struct coda_params {
130 u32 slice_max_mb; 130 u32 slice_max_mb;
131}; 131};
132 132
133struct coda_timestamp { 133struct coda_buffer_meta {
134 struct list_head list; 134 struct list_head list;
135 u32 sequence; 135 u32 sequence;
136 struct v4l2_timecode timecode; 136 struct v4l2_timecode timecode;
137 struct timeval timestamp; 137 struct timeval timestamp;
138 u32 start;
139 u32 end;
138}; 140};
139 141
140/* Per-queue, driver-specific private data */ 142/* Per-queue, driver-specific private data */
@@ -220,9 +222,9 @@ struct coda_ctx {
220 struct coda_aux_buf slicebuf; 222 struct coda_aux_buf slicebuf;
221 struct coda_aux_buf internal_frames[CODA_MAX_FRAMEBUFFERS]; 223 struct coda_aux_buf internal_frames[CODA_MAX_FRAMEBUFFERS];
222 u32 frame_types[CODA_MAX_FRAMEBUFFERS]; 224 u32 frame_types[CODA_MAX_FRAMEBUFFERS];
223 struct coda_timestamp frame_timestamps[CODA_MAX_FRAMEBUFFERS]; 225 struct coda_buffer_meta frame_metas[CODA_MAX_FRAMEBUFFERS];
224 u32 frame_errors[CODA_MAX_FRAMEBUFFERS]; 226 u32 frame_errors[CODA_MAX_FRAMEBUFFERS];
225 struct list_head timestamp_list; 227 struct list_head buffer_meta_list;
226 struct coda_aux_buf workbuf; 228 struct coda_aux_buf workbuf;
227 int num_internal_frames; 229 int num_internal_frames;
228 int idx; 230 int idx;