diff options
Diffstat (limited to 'drivers/media/platform/s5p-mfc/s5p_mfc_enc.c')
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 96 |
1 files changed, 47 insertions, 49 deletions
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index df83cd157bab..d26b2484ca10 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -26,6 +26,7 @@ #include <media/v4l2-ctrls.h> #include <media/videobuf2-core.h> #include "s5p_mfc_common.h" +#include "s5p_mfc_ctrl.h" #include "s5p_mfc_debug.h" #include "s5p_mfc_enc.h" #include "s5p_mfc_intr.h" @@ -41,6 +42,7 @@ static struct s5p_mfc_fmt formats[] = { .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, .num_planes = 2, + .versions = MFC_V6_BIT | MFC_V7_BIT, }, { .name = "4:2:0 2 Planes 64x32 Tiles", @@ -48,6 +50,7 @@ static struct s5p_mfc_fmt formats[] = { .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, .num_planes = 2, + .versions = MFC_V5_BIT, }, { .name = "4:2:0 2 Planes Y/CbCr", @@ -55,6 +58,8 @@ static struct s5p_mfc_fmt formats[] = { .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, .num_planes = 2, + .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | + MFC_V8_BIT, }, { .name = "4:2:0 2 Planes Y/CrCb", @@ -62,6 +67,8 @@ static struct s5p_mfc_fmt formats[] = { .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, .num_planes = 2, + .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | + MFC_V8_BIT, }, { .name = "H264 Encoded Stream", @@ -69,6 +76,8 @@ static struct s5p_mfc_fmt formats[] = { .codec_mode = S5P_MFC_CODEC_H264_ENC, .type = MFC_FMT_ENC, .num_planes = 1, + .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | + MFC_V8_BIT, }, { .name = "MPEG4 Encoded Stream", @@ -76,6 +85,8 @@ static struct s5p_mfc_fmt formats[] = { .codec_mode = S5P_MFC_CODEC_MPEG4_ENC, .type = MFC_FMT_ENC, .num_planes = 1, + .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | + MFC_V8_BIT, }, { .name = "H263 Encoded Stream", @@ -83,6 +94,8 @@ static struct s5p_mfc_fmt formats[] = { .codec_mode = S5P_MFC_CODEC_H263_ENC, .type = MFC_FMT_ENC, .num_planes = 1, + .versions = MFC_V5_BIT | MFC_V6_BIT | MFC_V7_BIT | + MFC_V8_BIT, }, { .name = "VP8 Encoded Stream", @@ -90,6 +103,7 @@ static struct s5p_mfc_fmt formats[] = { .codec_mode = S5P_MFC_CODEC_VP8_ENC, .type = MFC_FMT_ENC, .num_planes = 1, + .versions = MFC_V7_BIT | MFC_V8_BIT, }, }; @@ -772,13 +786,16 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) { spin_lock_irqsave(&dev->irqlock, flags); - dst_mb = list_entry(ctx->dst_queue.next, - struct s5p_mfc_buf, list); - list_del(&dst_mb->list); - ctx->dst_queue_cnt--; - vb2_set_plane_payload(dst_mb->b, 0, - s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev)); - vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); + if (!list_empty(&ctx->dst_queue)) { + dst_mb = list_entry(ctx->dst_queue.next, + struct s5p_mfc_buf, list); + list_del(&dst_mb->list); + ctx->dst_queue_cnt--; + vb2_set_plane_payload(dst_mb->b, 0, + s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, + dev)); + vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); + } spin_unlock_irqrestore(&dev->irqlock, flags); } @@ -883,8 +900,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) mfc_debug(2, "enc src count: %d, enc ref count: %d\n", ctx->src_queue_cnt, ctx->ref_queue_cnt); } - if (strm_size > 0) { - /* at least one more dest. buffers exist always */ + if ((ctx->dst_queue_cnt > 0) && (strm_size > 0)) { mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); list_del(&mb_entry->list); @@ -937,8 +953,10 @@ static int vidioc_querycap(struct file *file, void *priv, return 0; } -static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out) +static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, + bool mplane, bool out) { + struct s5p_mfc_dev *dev = video_drvdata(file); struct s5p_mfc_fmt *fmt; int i, j = 0; @@ -951,6 +969,9 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out) continue; else if (!out && formats[i].type != MFC_FMT_ENC) continue; + else if ((dev->variant->version_bit & formats[i].versions) == 0) + continue; + if (j == f->index) { fmt = &formats[i]; strlcpy(f->description, fmt->name, @@ -966,25 +987,25 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out) static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv, struct v4l2_fmtdesc *f) { - return vidioc_enum_fmt(f, false, false); + return vidioc_enum_fmt(file, f, false, false); } static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, struct v4l2_fmtdesc *f) { - return vidioc_enum_fmt(f, true, false); + return vidioc_enum_fmt(file, f, true, false); } static int vidioc_enum_fmt_vid_out(struct file *file, void *prov, struct v4l2_fmtdesc *f) { - return vidioc_enum_fmt(f, false, true); + return vidioc_enum_fmt(file, f, false, true); } static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov, struct v4l2_fmtdesc *f) { - return vidioc_enum_fmt(f, true, true); + return vidioc_enum_fmt(file, f, true, true); } static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) @@ -1035,16 +1056,14 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) mfc_err("failed to try output format\n"); return -EINVAL; } - - if (!IS_MFCV7(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) { - mfc_err("VP8 is supported only in MFC v7\n"); - return -EINVAL; - } - if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { mfc_err("must be set encoding output size\n"); return -EINVAL; } + if ((dev->variant->version_bit & fmt->versions) == 0) { + mfc_err("Unsupported format by this MFC version.\n"); + return -EINVAL; + } pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->plane_fmt[0].sizeimage; @@ -1055,22 +1074,15 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) return -EINVAL; } - if (!IS_MFCV6_PLUS(dev)) { - if (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) { - mfc_err("Not supported format.\n"); - return -EINVAL; - } - } else if (IS_MFCV6_PLUS(dev)) { - if (fmt->fourcc == V4L2_PIX_FMT_NV12MT) { - mfc_err("Not supported format.\n"); - return -EINVAL; - } - } - if (fmt->num_planes != pix_fmt_mp->num_planes) { mfc_err("failed to try output format\n"); return -EINVAL; } + if ((dev->variant->version_bit & fmt->versions) == 0) { + 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); } else { @@ -1104,20 +1116,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) pix_fmt_mp->plane_fmt[0].bytesperline = 0; ctx->dst_bufs_cnt = 0; ctx->capture_state = QUEUE_FREE; - s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx); - set_work_bit_irqsave(ctx); - s5p_mfc_clean_ctx_int_flags(ctx); - s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); - if (s5p_mfc_wait_for_done_ctx(ctx, \ - S5P_MFC_R2H_CMD_OPEN_INSTANCE_RET, 1)) { - /* Error or timeout */ - mfc_err("Error getting instance from hardware\n"); - s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, - ctx); - ret = -EIO; - goto out; - } - mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); + ret = s5p_mfc_open_mfc_inst(dev, ctx); } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { /* src_fmt is validated by call to vidioc_try_fmt */ ctx->src_fmt = find_format(f, MFC_FMT_RAW); @@ -1138,7 +1137,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) ctx->output_state = QUEUE_FREE; } else { mfc_err("invalid buf type\n"); - return -EINVAL; + ret = -EINVAL; } out: mfc_debug_leave(); @@ -1954,7 +1953,7 @@ static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) return 0; } -static int s5p_mfc_stop_streaming(struct vb2_queue *q) +static void s5p_mfc_stop_streaming(struct vb2_queue *q) { unsigned long flags; struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); @@ -1983,7 +1982,6 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q) ctx->src_queue_cnt = 0; } spin_unlock_irqrestore(&dev->irqlock, flags); - return 0; } static void s5p_mfc_buf_queue(struct vb2_buffer *vb) |