[PATCH 18/30] [media] coda: let userspace force IDR frames by enabling the keyframe flag in the source buffer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This disables forcing IDR frames at GOP size intervals on CODA7541 and CODA960,
which is only needed to work around a firmware bug on CodaDx6.
Instead, the V4L2_BUF_FLAG_KEYFRAME v4l2 buffer flag is cleared before marking
the source buffer done for dequeueing. Userspace can set it before queueing a
frame to force an IDR frame, to implement VFU (Video Fast Update).

Signed-off-by: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx>
---
 drivers/media/platform/coda.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
index 11e059d..cf75112 100644
--- a/drivers/media/platform/coda.c
+++ b/drivers/media/platform/coda.c
@@ -1264,22 +1264,22 @@ static void coda_prepare_encode(struct coda_ctx *ctx)
 	 * frame as IDR. This is a problem for some decoders that can't
 	 * recover when a frame is lost.
 	 */
-	if (src_buf->v4l2_buf.sequence % ctx->params.gop_size) {
-		src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
-		src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
-	} else {
+	if ((src_buf->v4l2_buf.sequence % ctx->params.gop_size) == 0)
 		src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
+	if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
 		src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
-	}
+	else
+		src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
 
 	if (dev->devtype->product == CODA_960)
 		coda_set_gdi_regs(ctx);
 
 	/*
-	 * Copy headers at the beginning of the first frame for H.264 only.
-	 * In MPEG4 they are already copied by the coda.
+	 * Copy headers in front of the first frame and forced I frames for
+	 * H.264 only. In MPEG4 they are already copied by the CODA.
 	 */
-	if (src_buf->v4l2_buf.sequence == 0) {
+	if (src_buf->v4l2_buf.sequence == 0 ||
+	    src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) {
 		pic_stream_buffer_addr =
 			vb2_dma_contig_plane_dma_addr(dst_buf, 0) +
 			ctx->vpu_header_size[0] +
@@ -3245,6 +3245,8 @@ static void coda_finish_encode(struct coda_ctx *ctx)
 		src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
 	dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
 
+	/* Clear keyframe flag so userspace can misuse it to force an IDR frame */
+	src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
 	v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
 
 	dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-- 
2.0.0.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux