Commit d09ed310 authored by Philipp Zabel's avatar Philipp Zabel Committed by Mauro Carvalho Chehab
Browse files

media: coda: mark last pending buffer or last meta on decoder stop command



If there is still a buffer pending, mark it as the last buffer. It will
create a meta that is flagged as last when the buffer is copied into the
bitstream ring buffer. If there are no more buffers pending, find the
last bitstream meta and mark it as last. If there is no bitstream meta
either, wake up the capture queue as there will be no more decoded
frames.

Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 9ee50a94
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -402,6 +402,9 @@ void coda_fill_bitstream(struct coda_ctx *ctx, struct list_head *buffer_list)
				meta->timestamp = src_buf->vb2_buf.timestamp;
				meta->start = start;
				meta->end = ctx->bitstream_fifo.kfifo.in;
				meta->last = src_buf->flags & V4L2_BUF_FLAG_LAST;
				if (meta->last)
					coda_dbg(1, ctx, "marking last meta");
				spin_lock(&ctx->buffer_meta_lock);
				list_add_tail(&meta->list,
					      &ctx->buffer_meta_list);
@@ -2334,6 +2337,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
			memset(&decoded_frame->meta, 0,
			       sizeof(struct coda_buffer_meta));
			decoded_frame->meta.sequence = val;
			decoded_frame->meta.last = false;
			ctx->sequence_offset++;
		}

+37 −7
Original line number Diff line number Diff line
@@ -1077,6 +1077,8 @@ static int coda_decoder_cmd(struct file *file, void *fh,
	struct coda_dev *dev = ctx->dev;
	struct vb2_v4l2_buffer *buf;
	struct vb2_queue *dst_vq;
	bool stream_end;
	bool wakeup;
	int ret;

	ret = coda_try_decoder_cmd(file, fh, dc);
@@ -1097,22 +1099,50 @@ static int coda_decoder_cmd(struct file *file, void *fh,
		mutex_unlock(&ctx->bitstream_mutex);
		break;
	case V4L2_DEC_CMD_STOP:
		stream_end = false;
		wakeup = false;

		buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx);
		if (buf)
		if (buf) {
			coda_dbg(1, ctx, "marking last pending buffer\n");

			/* Mark last buffer */
			buf->flags |= V4L2_BUF_FLAG_LAST;

			if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) == 0) {
				coda_dbg(1, ctx, "all remaining buffers queued\n");
				stream_end = true;
			}
		} else {
			coda_dbg(1, ctx, "marking last meta\n");

			/* Mark last meta */
			spin_lock(&ctx->buffer_meta_lock);
			if (!list_empty(&ctx->buffer_meta_list)) {
				struct coda_buffer_meta *meta;

				meta = list_last_entry(&ctx->buffer_meta_list,
						       struct coda_buffer_meta,
						       list);
				meta->last = true;
				stream_end = true;
			} else {
				wakeup = true;
			}
			spin_unlock(&ctx->buffer_meta_lock);
		}

		if (stream_end) {
			coda_dbg(1, ctx, "all remaining buffers queued\n");

			/* Set the stream-end flag on this context */
			coda_bit_stream_end_flag(ctx);
			ctx->hold = false;
			v4l2_m2m_try_schedule(ctx->fh.m2m_ctx);
		}

			flush_work(&ctx->pic_run_work);

		if (wakeup) {
			/* If there is no buffer in flight, wake up */
			if (!ctx->streamon_out ||
			    ctx->qsequence == ctx->osequence)
			coda_wake_up_capture_queue(ctx);
		}

+1 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ struct coda_buffer_meta {
	u64			timestamp;
	unsigned int		start;
	unsigned int		end;
	bool			last;
};

/* Per-queue, driver-specific private data */