diff options
author | John Sheu <sheu@chromium.org> | 2013-09-03 07:26:42 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-09-03 08:24:08 -0400 |
commit | 19c2813c2882c7ecc6e1e8813f54ace495cfbe9a (patch) | |
tree | 6a393d57b2ea2f7a03f6b238412f4b9f52c6f109 /drivers/media | |
parent | 26a20eb09d44dc064c4f5d1f024bd501c09edb4b (diff) |
[media] s5p-mfc: Fix input/output format reporting
The video encode/decode paths have duplicated logic between
VIDIOC_TRY_FMT and VIDIOC_S_FMT that should be de-duped. Also, video
decode reports V4L2_PIX_FMT_NV12MT_16X16 output format, regardless of
what the actual output has been set at. Fix this.
Signed-off-by: John Sheu <sheu@google.com>
Signed-off-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 80 | ||||
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 55 |
2 files changed, 55 insertions, 80 deletions
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index e2f221254bd0..5c764f9e8a1a 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | |||
@@ -344,7 +344,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
344 | pix_mp->num_planes = 2; | 344 | pix_mp->num_planes = 2; |
345 | /* Set pixelformat to the format in which MFC | 345 | /* Set pixelformat to the format in which MFC |
346 | outputs the decoded frame */ | 346 | outputs the decoded frame */ |
347 | pix_mp->pixelformat = V4L2_PIX_FMT_NV12MT; | 347 | pix_mp->pixelformat = ctx->dst_fmt->fourcc; |
348 | pix_mp->plane_fmt[0].bytesperline = ctx->buf_width; | 348 | pix_mp->plane_fmt[0].bytesperline = ctx->buf_width; |
349 | pix_mp->plane_fmt[0].sizeimage = ctx->luma_size; | 349 | pix_mp->plane_fmt[0].sizeimage = ctx->luma_size; |
350 | pix_mp->plane_fmt[1].bytesperline = ctx->buf_width; | 350 | pix_mp->plane_fmt[1].bytesperline = ctx->buf_width; |
@@ -382,10 +382,20 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
382 | mfc_err("Unsupported format for source.\n"); | 382 | mfc_err("Unsupported format for source.\n"); |
383 | return -EINVAL; | 383 | return -EINVAL; |
384 | } | 384 | } |
385 | if (fmt->codec_mode == S5P_FIMV_CODEC_NONE) { | ||
386 | mfc_err("Unknown codec\n"); | ||
387 | return -EINVAL; | ||
388 | } | ||
385 | if (!IS_MFCV6_PLUS(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) { | 389 | if (!IS_MFCV6_PLUS(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) { |
386 | mfc_err("Not supported format.\n"); | 390 | mfc_err("Not supported format.\n"); |
387 | return -EINVAL; | 391 | return -EINVAL; |
388 | } | 392 | } |
393 | if (!IS_MFCV6_PLUS(dev)) { | ||
394 | if (fmt->fourcc == V4L2_PIX_FMT_VP8) { | ||
395 | mfc_err("Not supported format.\n"); | ||
396 | return -EINVAL; | ||
397 | } | ||
398 | } | ||
389 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 399 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
390 | fmt = find_format(f, MFC_FMT_RAW); | 400 | fmt = find_format(f, MFC_FMT_RAW); |
391 | if (!fmt) { | 401 | if (!fmt) { |
@@ -412,7 +422,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
412 | struct s5p_mfc_dev *dev = video_drvdata(file); | 422 | struct s5p_mfc_dev *dev = video_drvdata(file); |
413 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); | 423 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); |
414 | int ret = 0; | 424 | int ret = 0; |
415 | struct s5p_mfc_fmt *fmt; | ||
416 | struct v4l2_pix_format_mplane *pix_mp; | 425 | struct v4l2_pix_format_mplane *pix_mp; |
417 | 426 | ||
418 | mfc_debug_enter(); | 427 | mfc_debug_enter(); |
@@ -426,55 +435,32 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
426 | goto out; | 435 | goto out; |
427 | } | 436 | } |
428 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 437 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
429 | fmt = find_format(f, MFC_FMT_RAW); | 438 | /* dst_fmt is validated by call to vidioc_try_fmt */ |
430 | if (!fmt) { | 439 | ctx->dst_fmt = find_format(f, MFC_FMT_RAW); |
431 | mfc_err("Unsupported format for source.\n"); | 440 | ret = 0; |
432 | return -EINVAL; | ||
433 | } | ||
434 | if (!IS_MFCV6_PLUS(dev) && | ||
435 | (fmt->fourcc != V4L2_PIX_FMT_NV12MT)) { | ||
436 | mfc_err("Not supported format.\n"); | ||
437 | return -EINVAL; | ||
438 | } else if (IS_MFCV6_PLUS(dev) && | ||
439 | (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) { | ||
440 | mfc_err("Not supported format.\n"); | ||
441 | return -EINVAL; | ||
442 | } | ||
443 | ctx->dst_fmt = fmt; | ||
444 | mfc_debug_leave(); | ||
445 | return ret; | ||
446 | } else if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | ||
447 | mfc_err("Wrong type error for S_FMT : %d", f->type); | ||
448 | return -EINVAL; | ||
449 | } | ||
450 | fmt = find_format(f, MFC_FMT_DEC); | ||
451 | if (!fmt || fmt->codec_mode == S5P_MFC_CODEC_NONE) { | ||
452 | mfc_err("Unknown codec\n"); | ||
453 | ret = -EINVAL; | ||
454 | goto out; | 441 | goto out; |
455 | } | 442 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
456 | if (fmt->type != MFC_FMT_DEC) { | 443 | /* src_fmt is validated by call to vidioc_try_fmt */ |
457 | mfc_err("Wrong format selected, you should choose " | 444 | ctx->src_fmt = find_format(f, MFC_FMT_DEC); |
458 | "format for decoding\n"); | 445 | ctx->codec_mode = ctx->src_fmt->codec_mode; |
446 | mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode); | ||
447 | pix_mp->height = 0; | ||
448 | pix_mp->width = 0; | ||
449 | if (pix_mp->plane_fmt[0].sizeimage) | ||
450 | ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage; | ||
451 | else | ||
452 | pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size = | ||
453 | DEF_CPB_SIZE; | ||
454 | pix_mp->plane_fmt[0].bytesperline = 0; | ||
455 | ctx->state = MFCINST_INIT; | ||
456 | ret = 0; | ||
457 | goto out; | ||
458 | } else { | ||
459 | mfc_err("Wrong type error for S_FMT : %d", f->type); | ||
459 | ret = -EINVAL; | 460 | ret = -EINVAL; |
460 | goto out; | 461 | goto out; |
461 | } | 462 | } |
462 | if (!IS_MFCV6_PLUS(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) { | 463 | |
463 | mfc_err("Not supported format.\n"); | ||
464 | return -EINVAL; | ||
465 | } | ||
466 | ctx->src_fmt = fmt; | ||
467 | ctx->codec_mode = fmt->codec_mode; | ||
468 | mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode); | ||
469 | pix_mp->height = 0; | ||
470 | pix_mp->width = 0; | ||
471 | if (pix_mp->plane_fmt[0].sizeimage) | ||
472 | ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage; | ||
473 | else | ||
474 | pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size = | ||
475 | DEF_CPB_SIZE; | ||
476 | pix_mp->plane_fmt[0].bytesperline = 0; | ||
477 | ctx->state = MFCINST_INIT; | ||
478 | out: | 464 | out: |
479 | mfc_debug_leave(); | 465 | mfc_debug_leave(); |
480 | return ret; | 466 | return ret; |
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index fb077b32975d..41f5a3c10dbd 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |||
@@ -967,6 +967,7 @@ static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
967 | 967 | ||
968 | static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | 968 | static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) |
969 | { | 969 | { |
970 | struct s5p_mfc_dev *dev = video_drvdata(file); | ||
970 | struct s5p_mfc_fmt *fmt; | 971 | struct s5p_mfc_fmt *fmt; |
971 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; | 972 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; |
972 | 973 | ||
@@ -977,6 +978,11 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
977 | return -EINVAL; | 978 | return -EINVAL; |
978 | } | 979 | } |
979 | 980 | ||
981 | if (!IS_MFCV7(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) { | ||
982 | mfc_err("VP8 is supported only in MFC v7\n"); | ||
983 | return -EINVAL; | ||
984 | } | ||
985 | |||
980 | if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { | 986 | if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { |
981 | mfc_err("must be set encoding output size\n"); | 987 | mfc_err("must be set encoding output size\n"); |
982 | return -EINVAL; | 988 | return -EINVAL; |
@@ -991,6 +997,18 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
991 | return -EINVAL; | 997 | return -EINVAL; |
992 | } | 998 | } |
993 | 999 | ||
1000 | if (!IS_MFCV6_PLUS(dev)) { | ||
1001 | if (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) { | ||
1002 | mfc_err("Not supported format.\n"); | ||
1003 | return -EINVAL; | ||
1004 | } | ||
1005 | } else if (IS_MFCV6_PLUS(dev)) { | ||
1006 | if (fmt->fourcc == V4L2_PIX_FMT_NV12MT) { | ||
1007 | mfc_err("Not supported format.\n"); | ||
1008 | return -EINVAL; | ||
1009 | } | ||
1010 | } | ||
1011 | |||
994 | if (fmt->num_planes != pix_fmt_mp->num_planes) { | 1012 | if (fmt->num_planes != pix_fmt_mp->num_planes) { |
995 | mfc_err("failed to try output format\n"); | 1013 | mfc_err("failed to try output format\n"); |
996 | return -EINVAL; | 1014 | return -EINVAL; |
@@ -1008,7 +1026,6 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
1008 | { | 1026 | { |
1009 | struct s5p_mfc_dev *dev = video_drvdata(file); | 1027 | struct s5p_mfc_dev *dev = video_drvdata(file); |
1010 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); | 1028 | struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); |
1011 | struct s5p_mfc_fmt *fmt; | ||
1012 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; | 1029 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; |
1013 | int ret = 0; | 1030 | int ret = 0; |
1014 | 1031 | ||
@@ -1021,17 +1038,9 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
1021 | goto out; | 1038 | goto out; |
1022 | } | 1039 | } |
1023 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 1040 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
1024 | fmt = find_format(f, MFC_FMT_ENC); | 1041 | /* dst_fmt is validated by call to vidioc_try_fmt */ |
1025 | if (!fmt) { | 1042 | ctx->dst_fmt = find_format(f, MFC_FMT_ENC); |
1026 | mfc_err("failed to set capture format\n"); | ||
1027 | return -EINVAL; | ||
1028 | } | ||
1029 | if (!IS_MFCV7(dev) && (fmt->fourcc == V4L2_PIX_FMT_VP8)) { | ||
1030 | mfc_err("VP8 is supported only in MFC v7\n"); | ||
1031 | return -EINVAL; | ||
1032 | } | ||
1033 | ctx->state = MFCINST_INIT; | 1043 | ctx->state = MFCINST_INIT; |
1034 | ctx->dst_fmt = fmt; | ||
1035 | ctx->codec_mode = ctx->dst_fmt->codec_mode; | 1044 | ctx->codec_mode = ctx->dst_fmt->codec_mode; |
1036 | ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage; | 1045 | ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage; |
1037 | pix_fmt_mp->plane_fmt[0].bytesperline = 0; | 1046 | pix_fmt_mp->plane_fmt[0].bytesperline = 0; |
@@ -1052,28 +1061,8 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) | |||
1052 | } | 1061 | } |
1053 | mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); | 1062 | mfc_debug(2, "Got instance number: %d\n", ctx->inst_no); |
1054 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 1063 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
1055 | fmt = find_format(f, MFC_FMT_RAW); | 1064 | /* src_fmt is validated by call to vidioc_try_fmt */ |
1056 | if (!fmt) { | 1065 | ctx->src_fmt = find_format(f, MFC_FMT_RAW); |
1057 | mfc_err("failed to set output format\n"); | ||
1058 | return -EINVAL; | ||
1059 | } | ||
1060 | |||
1061 | if (!IS_MFCV6_PLUS(dev) && | ||
1062 | (fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16)) { | ||
1063 | mfc_err("Not supported format.\n"); | ||
1064 | return -EINVAL; | ||
1065 | } else if (IS_MFCV6_PLUS(dev) && | ||
1066 | (fmt->fourcc == V4L2_PIX_FMT_NV12MT)) { | ||
1067 | mfc_err("Not supported format.\n"); | ||
1068 | return -EINVAL; | ||
1069 | } | ||
1070 | |||
1071 | if (fmt->num_planes != pix_fmt_mp->num_planes) { | ||
1072 | mfc_err("failed to set output format\n"); | ||
1073 | ret = -EINVAL; | ||
1074 | goto out; | ||
1075 | } | ||
1076 | ctx->src_fmt = fmt; | ||
1077 | ctx->img_width = pix_fmt_mp->width; | 1066 | ctx->img_width = pix_fmt_mp->width; |
1078 | ctx->img_height = pix_fmt_mp->height; | 1067 | ctx->img_height = pix_fmt_mp->height; |
1079 | mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode); | 1068 | mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode); |