[media] coda: implement forced key frames
authorPhilipp Zabel <p.zabel@pengutronix.de>
Tue, 6 Jun 2017 15:59:01 +0000 (12:59 -0300)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Wed, 7 Jun 2017 15:29:34 +0000 (12:29 -0300)
Implement the V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME control to force IDR
frames. This is useful to implement VFU (Video Fast Update) on RTP
transmissions.
We already force an IDR frame at the beginning of each GOP to work
around a firmware bug on i.MX27, use the same mechanism to service IDR
requests from userspace.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/platform/coda/coda-bit.c
drivers/media/platform/coda/coda-common.c
drivers/media/platform/coda/coda.h

index 403214e00e95447deb6c042b8efe1c2b918967fd..22e4630f36711a272b8d22f1fc425f9cb6189ae3 100644 (file)
@@ -1247,12 +1247,18 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
        dst_buf->sequence = ctx->osequence;
        ctx->osequence++;
 
+       force_ipicture = ctx->params.force_ipicture;
+       if (force_ipicture)
+               ctx->params.force_ipicture = false;
+       else if ((src_buf->sequence % ctx->params.gop_size) == 0)
+               force_ipicture = 1;
+
        /*
         * Workaround coda firmware BUG that only marks the first
         * frame as IDR. This is a problem for some decoders that can't
         * recover when a frame is lost.
         */
-       if (src_buf->sequence % ctx->params.gop_size) {
+       if (!force_ipicture) {
                src_buf->flags |= V4L2_BUF_FLAG_PFRAME;
                src_buf->flags &= ~V4L2_BUF_FLAG_KEYFRAME;
        } else {
@@ -1291,8 +1297,7 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
                pic_stream_buffer_size = q_data_dst->sizeimage;
        }
 
-       if (src_buf->flags & V4L2_BUF_FLAG_KEYFRAME) {
-               force_ipicture = 1;
+       if (force_ipicture) {
                switch (dst_fourcc) {
                case V4L2_PIX_FMT_H264:
                        quant_param = ctx->params.h264_intra_qp;
@@ -1309,7 +1314,6 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
                        break;
                }
        } else {
-               force_ipicture = 0;
                switch (dst_fourcc) {
                case V4L2_PIX_FMT_H264:
                        quant_param = ctx->params.h264_inter_qp;
index 4724dfef064317d5d62848d1b8ecb26495e6bfe4..78bd9a4ace0e4d643f753ac1f0f3b0f82ace106d 100644 (file)
@@ -1700,6 +1700,9 @@ static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
        case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
                ctx->params.intra_refresh = ctrl->val;
                break;
+       case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
+               ctx->params.force_ipicture = true;
+               break;
        case V4L2_CID_JPEG_COMPRESSION_QUALITY:
                coda_set_jpeg_compression_quality(ctx, ctrl->val);
                break;
index 308116d855e6fca6682453fa52156e90e533808c..76d059431ca13a3d0999205d7f2e535f426e84eb 100644 (file)
@@ -135,6 +135,7 @@ struct coda_params {
        u32                     vbv_size;
        u32                     slice_max_bits;
        u32                     slice_max_mb;
+       bool                    force_ipicture;
 };
 
 struct coda_buffer_meta {