diff options
Diffstat (limited to 'drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c')
| -rw-r--r-- | drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c | 204 |
1 files changed, 129 insertions, 75 deletions
diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c index f62703cebb77..3f8701e5614f 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c @@ -30,7 +30,7 @@ #define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12M #define DEF_DST_FMT_ENC V4L2_PIX_FMT_H264 -static struct s5p_mfc_fmt formats[] = { +static const struct s5p_mfc_fmt formats[] = { { .fourcc = V4L2_PIX_FMT_NV12MT_16X16, .codec_mode = S5P_MFC_CODEC_NONE, @@ -60,6 +60,20 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V6PLUS_BITS, }, { + .fourcc = V4L2_PIX_FMT_YUV420M, + .codec_mode = S5P_MFC_CODEC_NONE, + .type = MFC_FMT_RAW, + .num_planes = 3, + .versions = MFC_V12_BIT, + }, + { + .fourcc = V4L2_PIX_FMT_YVU420M, + .codec_mode = S5P_MFC_CODEC_NONE, + .type = MFC_FMT_RAW, + .num_planes = 3, + .versions = MFC_V12_BIT, + }, + { .fourcc = V4L2_PIX_FMT_H264, .codec_mode = S5P_MFC_CODEC_H264_ENC, .type = MFC_FMT_ENC, @@ -92,12 +106,12 @@ static struct s5p_mfc_fmt formats[] = { .codec_mode = S5P_FIMV_CODEC_HEVC_ENC, .type = MFC_FMT_ENC, .num_planes = 1, - .versions = MFC_V10_BIT, + .versions = MFC_V10PLUS_BITS, }, }; #define NUM_FORMATS ARRAY_SIZE(formats) -static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t) +static const struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t) { unsigned int i; @@ -1150,7 +1164,6 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_enc_params *p = &ctx->enc_params; struct s5p_mfc_buf *dst_mb; - unsigned int enc_pb_count; if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) { if (!list_empty(&ctx->dst_queue)) { @@ -1172,14 +1185,12 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) set_work_bit_irqsave(ctx); s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); } else { - enc_pb_count = s5p_mfc_hw_call(dev->mfc_ops, - get_enc_dpb_count, dev); - if (ctx->pb_count < enc_pb_count) - ctx->pb_count = enc_pb_count; + ctx->pb_count = s5p_mfc_hw_call(dev->mfc_ops, get_enc_dpb_count, dev); if (FW_HAS_E_MIN_SCRATCH_BUF(dev)) { ctx->scratch_buf_size = s5p_mfc_hw_call(dev->mfc_ops, get_e_min_scratch_buf_size, dev); - ctx->bank1.size += ctx->scratch_buf_size; + if (!IS_MFCV12(dev)) + ctx->bank1.size += ctx->scratch_buf_size; } ctx->state = MFCINST_HEAD_PRODUCED; } @@ -1192,14 +1203,20 @@ static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx) struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_buf *dst_mb; struct s5p_mfc_buf *src_mb; - unsigned long src_y_addr, src_c_addr, dst_addr; + unsigned long src_y_addr, src_c_addr, src_c_1_addr, dst_addr; unsigned int dst_size; src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0); src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1); + if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YVU420M) + src_c_1_addr = + vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 2); + else + src_c_1_addr = 0; s5p_mfc_hw_call(dev->mfc_ops, set_enc_frame_buffer, ctx, - src_y_addr, src_c_addr); + src_y_addr, src_c_addr, src_c_1_addr); dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0); @@ -1214,8 +1231,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_buf *mb_entry; - unsigned long enc_y_addr = 0, enc_c_addr = 0; - unsigned long mb_y_addr, mb_c_addr; + unsigned long enc_y_addr = 0, enc_c_addr = 0, enc_c_1_addr = 0; + unsigned long mb_y_addr, mb_c_addr, mb_c_1_addr; int slice_type; unsigned int strm_size; bool src_ready; @@ -1228,18 +1245,26 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT)); if (slice_type >= 0) { s5p_mfc_hw_call(dev->mfc_ops, get_enc_frame_buffer, ctx, - &enc_y_addr, &enc_c_addr); + &enc_y_addr, &enc_c_addr, &enc_c_1_addr); list_for_each_entry(mb_entry, &ctx->src_queue, list) { mb_y_addr = vb2_dma_contig_plane_dma_addr( &mb_entry->b->vb2_buf, 0); mb_c_addr = vb2_dma_contig_plane_dma_addr( &mb_entry->b->vb2_buf, 1); - if ((enc_y_addr == mb_y_addr) && - (enc_c_addr == mb_c_addr)) { + if (ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YUV420M || + ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YVU420M) + mb_c_1_addr = vb2_dma_contig_plane_dma_addr + (&mb_entry->b->vb2_buf, 2); + else + mb_c_1_addr = 0; + if (enc_y_addr == mb_y_addr && enc_c_addr == mb_c_addr && enc_c_1_addr + == mb_c_1_addr) { list_del(&mb_entry->list); ctx->src_queue_cnt--; vb2_buffer_done(&mb_entry->b->vb2_buf, - VB2_BUF_STATE_DONE); + VB2_BUF_STATE_DONE); break; } } @@ -1248,20 +1273,27 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) &mb_entry->b->vb2_buf, 0); mb_c_addr = vb2_dma_contig_plane_dma_addr( &mb_entry->b->vb2_buf, 1); - if ((enc_y_addr == mb_y_addr) && - (enc_c_addr == mb_c_addr)) { + if (ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YUV420M || + ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) + mb_c_1_addr = vb2_dma_contig_plane_dma_addr(& + mb_entry->b->vb2_buf, 2); + else + mb_c_1_addr = 0; + if (enc_y_addr == mb_y_addr && enc_c_addr == mb_c_addr && enc_c_1_addr + == mb_c_1_addr) { list_del(&mb_entry->list); ctx->ref_queue_cnt--; vb2_buffer_done(&mb_entry->b->vb2_buf, - VB2_BUF_STATE_DONE); + VB2_BUF_STATE_DONE); break; } } } if (ctx->src_queue_cnt > 0 && (ctx->state == MFCINST_RUNNING || - ctx->state == MFCINST_FINISHING)) { + ctx->state == MFCINST_FINISHING)) { mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, - list); + list); if (mb_entry->flags & MFC_BUF_FLAG_USED) { list_del(&mb_entry->list); ctx->src_queue_cnt--; @@ -1297,7 +1329,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) if (ctx->state == MFCINST_FINISHING && ctx->ref_queue_cnt == 0) src_ready = false; if (!src_ready || ctx->dst_queue_cnt == 0) - clear_work_bit(ctx); + clear_work_bit_irqsave(ctx); return 0; } @@ -1343,7 +1375,7 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, return -EINVAL; } -static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv, +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { return vidioc_enum_fmt(file, f, false); @@ -1357,8 +1389,8 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; + struct s5p_mfc_ctx *ctx = file_to_ctx(file); mfc_debug(2, "f->type = %d ctx->state = %d\n", f->type, ctx->state); if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -1380,10 +1412,15 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc; pix_fmt_mp->num_planes = ctx->src_fmt->num_planes; - pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width; + pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0]; pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size; - pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width; + pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1]; pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size; + if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YVU420M) { + pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2]; + pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1; + } } else { mfc_err("invalid buf type\n"); return -EINVAL; @@ -1394,7 +1431,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) { struct s5p_mfc_dev *dev = video_drvdata(file); - struct s5p_mfc_fmt *fmt; + const struct s5p_mfc_fmt *fmt; struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -1420,9 +1457,12 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) mfc_err("Unsupported format by this MFC version.\n"); return -EINVAL; } - - v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1, - &pix_fmt_mp->height, 4, 1080, 1, 0); + if (IS_MFCV12(dev)) + v4l_bound_align_image(&pix_fmt_mp->width, 8, 3840, 1, &pix_fmt_mp + ->height, 4, 2160, 1, 0); + else + v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1, &pix_fmt_mp + ->height, 4, 1080, 1, 0); } else { mfc_err("invalid buf type\n"); return -EINVAL; @@ -1432,8 +1472,8 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) { + struct s5p_mfc_ctx *ctx = file_to_ctx(file); struct s5p_mfc_dev *dev = video_drvdata(file); - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; int ret = 0; @@ -1467,9 +1507,14 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) s5p_mfc_hw_call(dev->mfc_ops, enc_calc_src_size, ctx); pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size; - pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width; + pix_fmt_mp->plane_fmt[0].bytesperline = ctx->stride[0]; pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size; - pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width; + pix_fmt_mp->plane_fmt[1].bytesperline = ctx->stride[1]; + if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YVU420M) { + pix_fmt_mp->plane_fmt[2].bytesperline = ctx->stride[2]; + pix_fmt_mp->plane_fmt[2].sizeimage = ctx->chroma_size_1; + } ctx->src_bufs_cnt = 0; ctx->output_state = QUEUE_FREE; @@ -1486,12 +1531,13 @@ static int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *reqbufs) { struct s5p_mfc_dev *dev = video_drvdata(file); - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + struct s5p_mfc_ctx *ctx = file_to_ctx(file); int ret = 0; - /* if memory is not mmp or userptr return error */ + /* if memory is not mmp or userptr or dmabuf return error */ if ((reqbufs->memory != V4L2_MEMORY_MMAP) && - (reqbufs->memory != V4L2_MEMORY_USERPTR)) + (reqbufs->memory != V4L2_MEMORY_USERPTR) && + (reqbufs->memory != V4L2_MEMORY_DMABUF)) return -EINVAL; if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (reqbufs->count == 0) { @@ -1514,14 +1560,6 @@ static int vidioc_reqbufs(struct file *file, void *priv, } ctx->capture_state = QUEUE_BUFS_REQUESTED; - ret = s5p_mfc_hw_call(ctx->dev->mfc_ops, - alloc_codec_buffers, ctx); - if (ret) { - mfc_err("Failed to allocate encoding buffers\n"); - reqbufs->count = 0; - ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); - return -ENOMEM; - } } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { if (reqbufs->count == 0) { mfc_debug(2, "Freeing buffers\n"); @@ -1537,15 +1575,13 @@ static int vidioc_reqbufs(struct file *file, void *priv, return -EINVAL; } - if (IS_MFCV6_PLUS(dev)) { + if (IS_MFCV6_PLUS(dev) && (!IS_MFCV12(dev))) { /* Check for min encoder buffers */ if (ctx->pb_count && (reqbufs->count < ctx->pb_count)) { reqbufs->count = ctx->pb_count; mfc_debug(2, "Minimum %d output buffers needed\n", ctx->pb_count); - } else { - ctx->pb_count = reqbufs->count; } } @@ -1565,12 +1601,13 @@ static int vidioc_reqbufs(struct file *file, void *priv, static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + struct s5p_mfc_ctx *ctx = file_to_ctx(file); int ret = 0; - /* if memory is not mmp or userptr return error */ + /* if memory is not mmp or userptr or dmabuf return error */ if ((buf->memory != V4L2_MEMORY_MMAP) && - (buf->memory != V4L2_MEMORY_USERPTR)) + (buf->memory != V4L2_MEMORY_USERPTR) && + (buf->memory != V4L2_MEMORY_DMABUF)) return -EINVAL; if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (ctx->state != MFCINST_GOT_INST) { @@ -1599,7 +1636,7 @@ static int vidioc_querybuf(struct file *file, void *priv, /* Queue a buffer */ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + struct s5p_mfc_ctx *ctx = file_to_ctx(file); if (ctx->state == MFCINST_ERROR) { mfc_err("Call on QBUF after unrecoverable error\n"); @@ -1620,10 +1657,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) /* Dequeue a buffer */ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) { + struct s5p_mfc_ctx *ctx = file_to_ctx(file); const struct v4l2_event ev = { .type = V4L2_EVENT_EOS }; - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); int ret; if (ctx->state == MFCINST_ERROR) { @@ -1648,7 +1685,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) static int vidioc_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *eb) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + struct s5p_mfc_ctx *ctx = file_to_ctx(file); if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) return vb2_expbuf(&ctx->vq_src, eb); @@ -1661,7 +1698,7 @@ static int vidioc_expbuf(struct file *file, void *priv, static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type type) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + struct s5p_mfc_ctx *ctx = file_to_ctx(file); if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) return vb2_streamon(&ctx->vq_src, type); @@ -1674,7 +1711,7 @@ static int vidioc_streamon(struct file *file, void *priv, static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + struct s5p_mfc_ctx *ctx = file_to_ctx(file); if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) return vb2_streamoff(&ctx->vq_src, type); @@ -2247,7 +2284,7 @@ static const struct v4l2_ctrl_ops s5p_mfc_enc_ctrl_ops = { static int vidioc_s_parm(struct file *file, void *priv, struct v4l2_streamparm *a) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + struct s5p_mfc_ctx *ctx = file_to_ctx(file); if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { ctx->enc_params.rc_framerate_num = @@ -2264,7 +2301,7 @@ static int vidioc_s_parm(struct file *file, void *priv, static int vidioc_g_parm(struct file *file, void *priv, struct v4l2_streamparm *a) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + struct s5p_mfc_ctx *ctx = file_to_ctx(file); if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { a->parm.output.timeperframe.denominator = @@ -2281,7 +2318,7 @@ static int vidioc_g_parm(struct file *file, void *priv, static int vidioc_encoder_cmd(struct file *file, void *priv, struct v4l2_encoder_cmd *cmd) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); + struct s5p_mfc_ctx *ctx = file_to_ctx(file); struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_buf *buf; unsigned long flags; @@ -2355,7 +2392,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = { .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb) +static int check_vb_with_fmt(const struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb) { int i; @@ -2381,7 +2418,7 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq, unsigned int *buf_count, unsigned int *plane_count, unsigned int psize[], struct device *alloc_devs[]) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); + struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq); struct s5p_mfc_dev *dev = ctx->dev; if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -2413,10 +2450,18 @@ static int s5p_mfc_queue_setup(struct vb2_queue *vq, psize[0] = ctx->luma_size; psize[1] = ctx->chroma_size; + if (ctx->src_fmt && (ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YVU420M)) + psize[2] = ctx->chroma_size_1; if (IS_MFCV6_PLUS(dev)) { alloc_devs[0] = ctx->dev->mem_dev[BANK_L_CTX]; alloc_devs[1] = ctx->dev->mem_dev[BANK_L_CTX]; + if (ctx->src_fmt && (ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YVU420M)) + alloc_devs[2] = ctx->dev->mem_dev[BANK_L_CTX]; } else { alloc_devs[0] = ctx->dev->mem_dev[BANK_R_CTX]; alloc_devs[1] = ctx->dev->mem_dev[BANK_R_CTX]; @@ -2432,7 +2477,7 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vb2_queue *vq = vb->vb2_queue; - struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); + struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq); unsigned int i; int ret; @@ -2455,6 +2500,11 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb) vb2_dma_contig_plane_dma_addr(vb, 0); ctx->src_bufs[i].cookie.raw.chroma = vb2_dma_contig_plane_dma_addr(vb, 1); + if (ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YUV420M || ctx->src_fmt->fourcc == + V4L2_PIX_FMT_YVU420M) + ctx->src_bufs[i].cookie.raw.chroma_1 = + vb2_dma_contig_plane_dma_addr(vb, 2); ctx->src_bufs_cnt++; } else { mfc_err("invalid queue type: %d\n", vq->type); @@ -2466,7 +2516,7 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb) static int s5p_mfc_buf_prepare(struct vb2_buffer *vb) { struct vb2_queue *vq = vb->vb2_queue; - struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); + struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq); int ret; if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -2492,6 +2542,12 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb) mfc_err("plane size is too small for output\n"); return -EINVAL; } + if ((ctx->src_fmt->fourcc == V4L2_PIX_FMT_YUV420M || + ctx->src_fmt->fourcc == V4L2_PIX_FMT_YVU420M) && + (vb2_plane_size(vb, 2) < ctx->chroma_size_1)) { + mfc_err("plane size is too small for output\n"); + return -EINVAL; + } } else { mfc_err("invalid queue type: %d\n", vq->type); return -EINVAL; @@ -2501,7 +2557,7 @@ static int s5p_mfc_buf_prepare(struct vb2_buffer *vb) static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) { - struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); + struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(q); struct s5p_mfc_dev *dev = ctx->dev; if (IS_MFCV6_PLUS(dev) && @@ -2513,11 +2569,11 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) S5P_MFC_R2H_CMD_SEQ_DONE_RET, 0); } - - if (ctx->src_bufs_cnt < ctx->pb_count) { - mfc_err("Need minimum %d OUTPUT buffers\n", - ctx->pb_count); - return -ENOBUFS; + if (q->memory != V4L2_MEMORY_DMABUF) { + if (ctx->src_bufs_cnt < ctx->pb_count) { + mfc_err("Need minimum %d OUTPUT buffers\n", ctx->pb_count); + return -ENOBUFS; + } } } @@ -2532,7 +2588,7 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) static void s5p_mfc_stop_streaming(struct vb2_queue *q) { unsigned long flags; - struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); + struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(q); struct s5p_mfc_dev *dev = ctx->dev; if ((ctx->state == MFCINST_FINISHING || @@ -2561,7 +2617,7 @@ static void s5p_mfc_stop_streaming(struct vb2_queue *q) static void s5p_mfc_buf_queue(struct vb2_buffer *vb) { struct vb2_queue *vq = vb->vb2_queue; - struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); + struct s5p_mfc_ctx *ctx = vb2_get_drv_priv(vq); struct s5p_mfc_dev *dev = ctx->dev; unsigned long flags; struct s5p_mfc_buf *mfc_buf; @@ -2594,10 +2650,8 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb) s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); } -static struct vb2_ops s5p_mfc_enc_qops = { +static const struct vb2_ops s5p_mfc_enc_qops = { .queue_setup = s5p_mfc_queue_setup, - .wait_prepare = vb2_ops_wait_prepare, - .wait_finish = vb2_ops_wait_finish, .buf_init = s5p_mfc_buf_init, .buf_prepare = s5p_mfc_buf_prepare, .start_streaming = s5p_mfc_start_streaming, @@ -2610,7 +2664,7 @@ const struct s5p_mfc_codec_ops *get_enc_codec_ops(void) return &encoder_codec_ops; } -struct vb2_ops *get_enc_queue_ops(void) +const struct vb2_ops *get_enc_queue_ops(void) { return &s5p_mfc_enc_qops; } |
