diff options
Diffstat (limited to 'drivers/media/platform/mtk-vcodec')
7 files changed, 73 insertions, 65 deletions
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index d022c65bb34c..851903867bc9 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -129,11 +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); - - dstbuf->ready_to_display = true; + ctx->picinfo.fb_sz[1]); mtk_v4l2_debug(2, "[%d]status=%x queue id=%d to done_list %d", @@ -278,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; @@ -299,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; @@ -352,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); @@ -388,7 +411,7 @@ static void mtk_vdec_worker(struct work_struct *work) } buf.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0); buf.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); - buf.size = (size_t)src_buf->planes[0].bytesused; + buf.size = (size_t)src_buf->vb2_buf.planes[0].bytesused; if (!buf.va) { v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); mtk_v4l2_err("[%d] id=%d src_addr is NULL!!", @@ -976,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 @@ -1103,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, @@ -1122,11 +1145,9 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2); buf->queued_in_vb2 = true; buf->queued_in_v4l2 = true; - buf->ready_to_display = false; } else { buf->queued_in_vb2 = false; buf->queued_in_v4l2 = true; - buf->ready_to_display = false; } mutex_unlock(&ctx->lock); return; @@ -1155,10 +1176,10 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) src_mem.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0); src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); - src_mem.size = (size_t)src_buf->planes[0].bytesused; + src_mem.size = (size_t)src_buf->vb2_buf.planes[0].bytesused; mtk_v4l2_debug(2, "[%d] buf id=%d va=%p dma=%pad size=%zx", - ctx->id, src_buf->index, + ctx->id, src_buf->vb2_buf.index, src_mem.va, &src_mem.dma_addr, src_mem.size); @@ -1182,7 +1203,7 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) } mtk_v4l2_debug(ret ? 0 : 1, "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d", - ctx->id, src_buf->index, + ctx->id, src_buf->vb2_buf.index, src_mem.size, ret, res_chg); return; } @@ -1194,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) @@ -1253,7 +1271,6 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb) if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { buf->used = false; - buf->ready_to_display = false; buf->queued_in_v4l2 = false; } else { buf->lastframe = false; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h index dc4fc1df63c5..e4984edec4f8 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h @@ -45,7 +45,6 @@ struct vdec_fb { * @list: link list * @used: Capture buffer contain decoded frame data and keep in * codec data structure - * @ready_to_display: Capture buffer not display yet * @queued_in_vb2: Capture buffer is queue in vb2 * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2 * queue yet @@ -60,7 +59,6 @@ struct mtk_video_dec_buf { struct list_head list; bool used; - bool ready_to_display; bool queued_in_vb2; bool queued_in_v4l2; bool lastframe; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index e7e2a108def9..662a84b822af 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -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; }; /** diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c index c6b48b5925fb..50351adafc47 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c @@ -894,7 +894,7 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q) if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) { - dst_buf->planes[0].bytesused = 0; + dst_buf->vb2_buf.planes[0].bytesused = 0; v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); } } else { @@ -947,7 +947,7 @@ static int mtk_venc_encode_header(void *priv) bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0); bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); - bs_buf.size = (size_t)dst_buf->planes[0].length; + bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length; mtk_v4l2_debug(1, "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu", @@ -976,7 +976,7 @@ static int mtk_venc_encode_header(void *priv) } ctx->state = MTK_STATE_HEADER; - dst_buf->planes[0].bytesused = enc_result.bs_size; + dst_buf->vb2_buf.planes[0].bytesused = enc_result.bs_size; v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); return 0; @@ -1107,12 +1107,12 @@ static void mtk_venc_worker(struct work_struct *work) if (ret) { v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); - dst_buf->planes[0].bytesused = 0; + dst_buf->vb2_buf.planes[0].bytesused = 0; v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); mtk_v4l2_err("venc_if_encode failed=%d", ret); } else { v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); - dst_buf->planes[0].bytesused = enc_result.bs_size; + dst_buf->vb2_buf.planes[0].bytesused = enc_result.bs_size; v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); mtk_v4l2_debug(2, "venc_if_encode bs size=%d", enc_result.bs_size); diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c index 02c960c63ac0..cdbcd6909728 100644 --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c @@ -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) diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c index bac3723038de..ba79136421ef 100644 --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c @@ -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) diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c index bc8349bc2e80..939ea14bf6c5 100644 --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c @@ -481,15 +481,15 @@ static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst) */ if ((frm_to_show->fb != NULL) && (inst->cur_fb->base_y.size >= - frm_to_show->fb->base_y.size)) { + frm_to_show->fb->base_y.size) && + (inst->cur_fb->base_c.size >= + frm_to_show->fb->base_c.size)) { memcpy((void *)inst->cur_fb->base_y.va, (void *)frm_to_show->fb->base_y.va, - vsi->buf_w * - vsi->buf_h); + frm_to_show->fb->base_y.size); memcpy((void *)inst->cur_fb->base_c.va, (void *)frm_to_show->fb->base_c.va, - vsi->buf_w * - vsi->buf_h / 2); + frm_to_show->fb->base_c.size); } else { /* After resolution change case, current CAPTURE buffer * may have less buffer size than frm_to_show buffer @@ -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) @@ -895,7 +894,7 @@ static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, if (vsi->resolution_changed) { if (!vp9_alloc_work_buf(inst)) { - ret = -EINVAL; + ret = -EIO; goto DECODE_ERROR; } } @@ -924,14 +923,12 @@ static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, if (vsi->show_existing_frame && (vsi->frm_to_show_idx < VP9_MAX_FRM_BUF_NUM)) { - mtk_vcodec_err(inst, + mtk_vcodec_debug(inst, "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", vsi->new_fb_idx, vsi->frm_to_show_idx); vp9_ref_cnt_fb(inst, &vsi->new_fb_idx, vsi->frm_to_show_idx); - ret = -EINVAL; - goto DECODE_ERROR; } /* VPU assign the buffer pointer in its address space, |