media: mtk-vcodec: enlarge struct vdec_pic_info fields
authorYunfei Dong <yunfei.dong@mediatek.com>
Fri, 29 Mar 2019 08:37:14 +0000 (04:37 -0400)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Mon, 22 Apr 2019 15:02:39 +0000 (11:02 -0400)
Enlarge the plane number to support more complex case
and add the support for fmt change case.

Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c

index 710dcebb42b3f11ab484ddc4d44e6667194c763b..851903867bc9a170a5e971716b075610e971494a 100644 (file)
@@ -129,9 +129,9 @@ static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx)
        mutex_lock(&ctx->lock);
        if (dstbuf->used) {
                vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0,
-                                       ctx->picinfo.y_bs_sz);
+                                       ctx->picinfo.fb_sz[0]);
                vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1,
-                                       ctx->picinfo.c_bs_sz);
+                                       ctx->picinfo.fb_sz[1]);
 
                mtk_v4l2_debug(2,
                                "[%d]status=%x queue id=%d to done_list %d",
@@ -276,6 +276,27 @@ static void mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx)
        clean_free_buffer(ctx);
 }
 
+static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx,
+                               unsigned int pixelformat)
+{
+       struct mtk_video_fmt *fmt;
+       struct mtk_q_data *dst_q_data;
+       unsigned int k;
+
+       dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
+       for (k = 0; k < NUM_FORMATS; k++) {
+               fmt = &mtk_video_formats[k];
+               if (fmt->fourcc == pixelformat) {
+                       mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)",
+                               dst_q_data->fmt.fourcc, pixelformat);
+                       dst_q_data->fmt = fmt;
+                       return;
+               }
+       }
+
+       mtk_v4l2_err("Cannot get fourcc(%d), using init value", pixelformat);
+}
+
 static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx)
 {
        unsigned int dpbsize = 0;
@@ -297,6 +318,10 @@ static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx)
                return -EINVAL;
        }
 
+       if (ctx->last_decoded_picinfo.cap_fourcc != ctx->picinfo.cap_fourcc &&
+               ctx->picinfo.cap_fourcc != 0)
+               mtk_vdec_update_fmt(ctx, ctx->picinfo.cap_fourcc);
+
        if ((ctx->last_decoded_picinfo.pic_w == ctx->picinfo.pic_w) ||
            (ctx->last_decoded_picinfo.pic_h == ctx->picinfo.pic_h))
                return 0;
@@ -350,11 +375,11 @@ static void mtk_vdec_worker(struct work_struct *work)
        pfb = &dst_buf_info->frame_buffer;
        pfb->base_y.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
        pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
-       pfb->base_y.size = ctx->picinfo.y_bs_sz + ctx->picinfo.y_len_sz;
+       pfb->base_y.size = ctx->picinfo.fb_sz[0];
 
        pfb->base_c.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 1);
        pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 1);
-       pfb->base_c.size = ctx->picinfo.c_bs_sz + ctx->picinfo.c_len_sz;
+       pfb->base_c.size = ctx->picinfo.fb_sz[1];
        pfb->status = 0;
        mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id);
 
@@ -974,14 +999,13 @@ static int vidioc_vdec_g_fmt(struct file *file, void *priv,
                 * So we just return picinfo yet, and update picinfo in
                 * stop_streaming hook function
                 */
-               q_data->sizeimage[0] = ctx->picinfo.y_bs_sz +
-                                       ctx->picinfo.y_len_sz;
-               q_data->sizeimage[1] = ctx->picinfo.c_bs_sz +
-                                       ctx->picinfo.c_len_sz;
+               q_data->sizeimage[0] = ctx->picinfo.fb_sz[0];
+               q_data->sizeimage[1] = ctx->picinfo.fb_sz[1];
                q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w;
                q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w;
                q_data->coded_width = ctx->picinfo.buf_w;
                q_data->coded_height = ctx->picinfo.buf_h;
+               ctx->last_decoded_picinfo.cap_fourcc = q_data->fmt->fourcc;
 
                /*
                 * Width and height are set to the dimensions
@@ -1101,10 +1125,11 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
        struct mtk_vcodec_mem src_mem;
        bool res_chg = false;
        int ret = 0;
-       unsigned int dpbsize = 1;
+       unsigned int dpbsize = 1, i = 0;
        struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
        struct vb2_v4l2_buffer *vb2_v4l2 = NULL;
        struct mtk_video_dec_buf *buf = NULL;
+       struct mtk_q_data *dst_q_data;
 
        mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p",
                        ctx->id, vb->vb2_queue->type,
@@ -1190,21 +1215,18 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
        }
 
        ctx->last_decoded_picinfo = ctx->picinfo;
-       ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
-                                               ctx->picinfo.y_bs_sz +
-                                               ctx->picinfo.y_len_sz;
-       ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
-                                               ctx->picinfo.buf_w;
-       ctx->q_data[MTK_Q_DATA_DST].sizeimage[1] =
-                                               ctx->picinfo.c_bs_sz +
-                                               ctx->picinfo.c_len_sz;
-       ctx->q_data[MTK_Q_DATA_DST].bytesperline[1] = ctx->picinfo.buf_w;
+       dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
+       for (i = 0; i < dst_q_data->fmt->num_planes; i++) {
+               dst_q_data->sizeimage[i] = ctx->picinfo.fb_sz[i];
+               dst_q_data->bytesperline[i] = ctx->picinfo.buf_w;
+       }
+
        mtk_v4l2_debug(2, "[%d] vdec_if_init() OK wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x",
                        ctx->id,
                        ctx->picinfo.buf_w, ctx->picinfo.buf_h,
                        ctx->picinfo.pic_w, ctx->picinfo.pic_h,
-                       ctx->q_data[MTK_Q_DATA_DST].sizeimage[0],
-                       ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]);
+                       dst_q_data->sizeimage[0],
+                       dst_q_data->sizeimage[1]);
 
        ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
        if (dpbsize == 0)
index e7e2a108def96adf50bcb8e4f7f6ccd0b7a41fd4..662a84b822af6468009074f62bb4d679564ed7ac 100644 (file)
@@ -211,24 +211,20 @@ struct mtk_vcodec_pm {
  * @pic_h: picture height
  * @buf_w: picture buffer width (64 aligned up from pic_w)
  * @buf_h: picture buffer heiht (64 aligned up from pic_h)
- * @y_bs_sz: Y bitstream size
- * @c_bs_sz: CbCr bitstream size
- * @y_len_sz: additional size required to store decompress information for y
- *             plane
- * @c_len_sz: additional size required to store decompress information for cbcr
- *             plane
+ * @fb_sz: bitstream size of each plane
  * E.g. suppose picture size is 176x144,
  *      buffer size will be aligned to 176x160.
+ * @cap_fourcc: fourcc number(may changed when resolution change)
+ * @reserved: align struct to 64-bit in order to adjust 32-bit and 64-bit os.
  */
 struct vdec_pic_info {
        unsigned int pic_w;
        unsigned int pic_h;
        unsigned int buf_w;
        unsigned int buf_h;
-       unsigned int y_bs_sz;
-       unsigned int c_bs_sz;
-       unsigned int y_len_sz;
-       unsigned int c_len_sz;
+       unsigned int fb_sz[VIDEO_MAX_PLANES];
+       unsigned int cap_fourcc;
+       unsigned int reserved;
 };
 
 /**
index 02c960c63ac0854b137ee05fb7e05bc4d415a2cc..cdbcd69097280306c4bd6ff1f18a32b4fa0610e4 100644 (file)
@@ -253,8 +253,8 @@ static void get_pic_info(struct vdec_h264_inst *inst,
        *pic = inst->vsi->pic;
        mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
                         pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h);
-       mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz,
-                        pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz);
+       mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
+                        pic->fb_sz[0], pic->fb_sz[1]);
 }
 
 static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr)
index bac3723038de8154628d70d41da868063668e7e2..ba79136421ef1308feee897686edc8914738d46f 100644 (file)
@@ -294,8 +294,8 @@ static void get_pic_info(struct vdec_vp8_inst *inst, struct vdec_pic_info *pic)
 
        mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
                         pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h);
-       mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz,
-                        pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz);
+       mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
+                        pic->fb_sz[0], pic->fb_sz[1]);
 }
 
 static void vp8_dec_finish(struct vdec_vp8_inst *inst)
index bc8349bc2e80c5c4fc72a6253246fa0e1c4b9b10..6fe83207bbc42c20a6d6d744903212506b2a3ea3 100644 (file)
@@ -702,10 +702,8 @@ static void init_all_fb_lists(struct vdec_vp9_inst *inst)
 
 static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic)
 {
-       pic->y_bs_sz = inst->vsi->buf_sz_y_bs;
-       pic->c_bs_sz = inst->vsi->buf_sz_c_bs;
-       pic->y_len_sz = inst->vsi->buf_len_sz_y;
-       pic->c_len_sz = inst->vsi->buf_len_sz_c;
+       pic->fb_sz[0] = inst->vsi->buf_sz_y_bs + inst->vsi->buf_len_sz_y;
+       pic->fb_sz[1] = inst->vsi->buf_sz_c_bs + inst->vsi->buf_len_sz_c;
 
        pic->pic_w = inst->vsi->pic_w;
        pic->pic_h = inst->vsi->pic_h;
@@ -714,8 +712,9 @@ static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic)
 
        mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
                 pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h);
-       mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz,
-                pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz);
+       mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
+               pic->fb_sz[0],
+               pic->fb_sz[1]);
 }
 
 static void get_disp_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)