Browse Source

[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>
Philipp Zabel 11 năm trước cách đây
mục cha
commit
7cbb105fef

+ 31 - 22
drivers/media/platform/coda/coda-bit.c

@@ -217,11 +217,16 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
 void coda_fill_bitstream(struct coda_ctx *ctx)
 void coda_fill_bitstream(struct coda_ctx *ctx)
 {
 {
 	struct vb2_buffer *src_buf;
 	struct vb2_buffer *src_buf;
-	struct coda_timestamp *ts;
+	struct coda_buffer_meta *meta;
+	u32 start;
 
 
 	while (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) > 0) {
 	while (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) > 0) {
 		src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 		src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 
 
+		/* Buffer start position */
+		start = ctx->bitstream_fifo.kfifo.in &
+			ctx->bitstream_fifo.kfifo.mask;
+
 		if (coda_bitstream_try_queue(ctx, src_buf)) {
 		if (coda_bitstream_try_queue(ctx, src_buf)) {
 			/*
 			/*
 			 * Source buffer is queued in the bitstream ringbuffer;
 			 * Source buffer is queued in the bitstream ringbuffer;
@@ -229,12 +234,16 @@ void coda_fill_bitstream(struct coda_ctx *ctx)
 			 */
 			 */
 			src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 			src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 
 
-			ts = kmalloc(sizeof(*ts), GFP_KERNEL);
-			if (ts) {
-				ts->sequence = src_buf->v4l2_buf.sequence;
-				ts->timecode = src_buf->v4l2_buf.timecode;
-				ts->timestamp = src_buf->v4l2_buf.timestamp;
-				list_add_tail(&ts->list, &ctx->timestamp_list);
+			meta = kmalloc(sizeof(*meta), GFP_KERNEL);
+			if (meta) {
+				meta->sequence = src_buf->v4l2_buf.sequence;
+				meta->timecode = src_buf->v4l2_buf.timecode;
+				meta->timestamp = src_buf->v4l2_buf.timestamp;
+				meta->start = start;
+				meta->end = ctx->bitstream_fifo.kfifo.in &
+					    ctx->bitstream_fifo.kfifo.mask;
+				list_add_tail(&meta->list,
+					      &ctx->buffer_meta_list);
 			}
 			}
 
 
 			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
 			v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
@@ -1629,7 +1638,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
 	struct coda_q_data *q_data_src;
 	struct coda_q_data *q_data_src;
 	struct coda_q_data *q_data_dst;
 	struct coda_q_data *q_data_dst;
 	struct vb2_buffer *dst_buf;
 	struct vb2_buffer *dst_buf;
-	struct coda_timestamp *ts;
+	struct coda_buffer_meta *meta;
 	unsigned long payload;
 	unsigned long payload;
 	int width, height;
 	int width, height;
 	int decoded_idx;
 	int decoded_idx;
@@ -1757,23 +1766,23 @@ static void coda_finish_decode(struct coda_ctx *ctx)
 		val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1;
 		val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1;
 		val -= ctx->sequence_offset;
 		val -= ctx->sequence_offset;
 		mutex_lock(&ctx->bitstream_mutex);
 		mutex_lock(&ctx->bitstream_mutex);
-		if (!list_empty(&ctx->timestamp_list)) {
-			ts = list_first_entry(&ctx->timestamp_list,
-					      struct coda_timestamp, list);
-			list_del(&ts->list);
-			if (val != (ts->sequence & 0xffff)) {
+		if (!list_empty(&ctx->buffer_meta_list)) {
+			meta = list_first_entry(&ctx->buffer_meta_list,
+					      struct coda_buffer_meta, list);
+			list_del(&meta->list);
+			if (val != (meta->sequence & 0xffff)) {
 				v4l2_err(&dev->v4l2_dev,
 				v4l2_err(&dev->v4l2_dev,
 					 "sequence number mismatch (%d(%d) != %d)\n",
 					 "sequence number mismatch (%d(%d) != %d)\n",
 					 val, ctx->sequence_offset,
 					 val, ctx->sequence_offset,
-					 ts->sequence);
+					 meta->sequence);
 			}
 			}
-			ctx->frame_timestamps[decoded_idx] = *ts;
-			kfree(ts);
+			ctx->frame_metas[decoded_idx] = *meta;
+			kfree(meta);
 		} else {
 		} else {
 			v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n");
 			v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n");
-			memset(&ctx->frame_timestamps[decoded_idx], 0,
-			       sizeof(struct coda_timestamp));
-			ctx->frame_timestamps[decoded_idx].sequence = val;
+			memset(&ctx->frame_metas[decoded_idx], 0,
+			       sizeof(struct coda_buffer_meta));
+			ctx->frame_metas[decoded_idx].sequence = val;
 		}
 		}
 		mutex_unlock(&ctx->bitstream_mutex);
 		mutex_unlock(&ctx->bitstream_mutex);
 
 
@@ -1812,9 +1821,9 @@ static void coda_finish_decode(struct coda_ctx *ctx)
 					     V4L2_BUF_FLAG_PFRAME |
 					     V4L2_BUF_FLAG_PFRAME |
 					     V4L2_BUF_FLAG_BFRAME);
 					     V4L2_BUF_FLAG_BFRAME);
 		dst_buf->v4l2_buf.flags |= ctx->frame_types[ctx->display_idx];
 		dst_buf->v4l2_buf.flags |= ctx->frame_types[ctx->display_idx];
-		ts = &ctx->frame_timestamps[ctx->display_idx];
-		dst_buf->v4l2_buf.timecode = ts->timecode;
-		dst_buf->v4l2_buf.timestamp = ts->timestamp;
+		meta = &ctx->frame_metas[ctx->display_idx];
+		dst_buf->v4l2_buf.timecode = meta->timecode;
+		dst_buf->v4l2_buf.timestamp = meta->timestamp;
 
 
 		switch (q_data_dst->fourcc) {
 		switch (q_data_dst->fourcc) {
 		case V4L2_PIX_FMT_YUV420:
 		case V4L2_PIX_FMT_YUV420:

+ 7 - 7
drivers/media/platform/coda/coda-common.c

@@ -1279,14 +1279,14 @@ static void coda_stop_streaming(struct vb2_queue *q)
 	}
 	}
 
 
 	if (!ctx->streamon_out && !ctx->streamon_cap) {
 	if (!ctx->streamon_out && !ctx->streamon_cap) {
-		struct coda_timestamp *ts;
+		struct coda_buffer_meta *meta;
 
 
 		mutex_lock(&ctx->bitstream_mutex);
 		mutex_lock(&ctx->bitstream_mutex);
-		while (!list_empty(&ctx->timestamp_list)) {
-			ts = list_first_entry(&ctx->timestamp_list,
-					      struct coda_timestamp, list);
-			list_del(&ts->list);
-			kfree(ts);
+		while (!list_empty(&ctx->buffer_meta_list)) {
+			meta = list_first_entry(&ctx->buffer_meta_list,
+						struct coda_buffer_meta, list);
+			list_del(&meta->list);
+			kfree(meta);
 		}
 		}
 		mutex_unlock(&ctx->bitstream_mutex);
 		mutex_unlock(&ctx->bitstream_mutex);
 		kfifo_init(&ctx->bitstream_fifo,
 		kfifo_init(&ctx->bitstream_fifo,
@@ -1642,7 +1642,7 @@ static int coda_open(struct file *file)
 		ctx->bitstream.vaddr, ctx->bitstream.size);
 		ctx->bitstream.vaddr, ctx->bitstream.size);
 	mutex_init(&ctx->bitstream_mutex);
 	mutex_init(&ctx->bitstream_mutex);
 	mutex_init(&ctx->buffer_mutex);
 	mutex_init(&ctx->buffer_mutex);
-	INIT_LIST_HEAD(&ctx->timestamp_list);
+	INIT_LIST_HEAD(&ctx->buffer_meta_list);
 
 
 	coda_lock(ctx);
 	coda_lock(ctx);
 	list_add(&ctx->list, &dev->instances);
 	list_add(&ctx->list, &dev->instances);

+ 5 - 3
drivers/media/platform/coda/coda.h

@@ -130,11 +130,13 @@ struct coda_params {
 	u32			slice_max_mb;
 	u32			slice_max_mb;
 };
 };
 
 
-struct coda_timestamp {
+struct coda_buffer_meta {
 	struct list_head	list;
 	struct list_head	list;
 	u32			sequence;
 	u32			sequence;
 	struct v4l2_timecode	timecode;
 	struct v4l2_timecode	timecode;
 	struct timeval		timestamp;
 	struct timeval		timestamp;
+	u32			start;
+	u32			end;
 };
 };
 
 
 /* Per-queue, driver-specific private data */
 /* Per-queue, driver-specific private data */
@@ -220,9 +222,9 @@ struct coda_ctx {
 	struct coda_aux_buf		slicebuf;
 	struct coda_aux_buf		slicebuf;
 	struct coda_aux_buf		internal_frames[CODA_MAX_FRAMEBUFFERS];
 	struct coda_aux_buf		internal_frames[CODA_MAX_FRAMEBUFFERS];
 	u32				frame_types[CODA_MAX_FRAMEBUFFERS];
 	u32				frame_types[CODA_MAX_FRAMEBUFFERS];
-	struct coda_timestamp		frame_timestamps[CODA_MAX_FRAMEBUFFERS];
+	struct coda_buffer_meta		frame_metas[CODA_MAX_FRAMEBUFFERS];
 	u32				frame_errors[CODA_MAX_FRAMEBUFFERS];
 	u32				frame_errors[CODA_MAX_FRAMEBUFFERS];
-	struct list_head		timestamp_list;
+	struct list_head		buffer_meta_list;
 	struct coda_aux_buf		workbuf;
 	struct coda_aux_buf		workbuf;
 	int				num_internal_frames;
 	int				num_internal_frames;
 	int				idx;
 	int				idx;