aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJohn Sheu <sheu@chromium.org>2013-09-03 07:26:42 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-09-03 08:24:08 -0400
commit19c2813c2882c7ecc6e1e8813f54ace495cfbe9a (patch)
tree6a393d57b2ea2f7a03f6b238412f4b9f52c6f109 /drivers/media
parent26a20eb09d44dc064c4f5d1f024bd501c09edb4b (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.c80
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c55
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;
478out: 464out:
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
968static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) 968static 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);