aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-03-12 17:43:21 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-25 07:43:34 -0400
commit016afda4fb298aa2e5515048fcba0271ad6f7320 (patch)
tree4c63fc3ec659da65923178aaefd6b28c7342c60e
parentc813bd3c8dce3564166e2c4f839fd36df7b0ba5d (diff)
[media] solo6x10: fix various format-related compliancy issues
- try_fmt should never return -EBUSY. - invalid pix->field values were not mapped to a valid value. - the priv field of struct v4l2_pix_format wasn't zeroed. - the try_fmt error code was not checked in set_fmt. - enum_framesizes/intervals is valid for both MJPEG and MPEG pixel formats. - enum_frameintervals didn't check width and height and reported the wrong range. - s_parm didn't set readbuffers. - don't fail on invalid colorspace, just replace with the valid colorspace. - bytesperline should be 0 for compressed formats. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/staging/media/solo6x10/v4l2-enc.c51
-rw-r--r--drivers/staging/media/solo6x10/v4l2.c30
2 files changed, 46 insertions, 35 deletions
diff --git a/drivers/staging/media/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c
index 8296d8d9dfae..5b2fdfbaef65 100644
--- a/drivers/staging/media/solo6x10/v4l2-enc.c
+++ b/drivers/staging/media/solo6x10/v4l2-enc.c
@@ -1039,13 +1039,6 @@ static int solo_enc_try_fmt_cap(struct file *file, void *priv,
1039 pix->pixelformat != V4L2_PIX_FMT_MJPEG) 1039 pix->pixelformat != V4L2_PIX_FMT_MJPEG)
1040 return -EINVAL; 1040 return -EINVAL;
1041 1041
1042 /* We cannot change width/height in mid mpeg */
1043 if (atomic_read(&solo_enc->mpeg_readers) > 0) {
1044 if (pix->width != solo_enc->width ||
1045 pix->height != solo_enc->height)
1046 return -EBUSY;
1047 }
1048
1049 if (pix->width < solo_dev->video_hsize || 1042 if (pix->width < solo_dev->video_hsize ||
1050 pix->height < solo_dev->video_vsize << 1) { 1043 pix->height < solo_dev->video_vsize << 1) {
1051 /* Default to CIF 1/2 size */ 1044 /* Default to CIF 1/2 size */
@@ -1057,14 +1050,20 @@ static int solo_enc_try_fmt_cap(struct file *file, void *priv,
1057 pix->height = solo_dev->video_vsize << 1; 1050 pix->height = solo_dev->video_vsize << 1;
1058 } 1051 }
1059 1052
1060 if (pix->field == V4L2_FIELD_ANY) 1053 switch (pix->field) {
1061 pix->field = V4L2_FIELD_INTERLACED; 1054 case V4L2_FIELD_NONE:
1062 else if (pix->field != V4L2_FIELD_INTERLACED) 1055 case V4L2_FIELD_INTERLACED:
1056 break;
1057 case V4L2_FIELD_ANY:
1058 default:
1063 pix->field = V4L2_FIELD_INTERLACED; 1059 pix->field = V4L2_FIELD_INTERLACED;
1060 break;
1061 }
1064 1062
1065 /* Just set these */ 1063 /* Just set these */
1066 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 1064 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1067 pix->sizeimage = FRAME_BUF_SIZE; 1065 pix->sizeimage = FRAME_BUF_SIZE;
1066 pix->priv = 0;
1068 1067
1069 return 0; 1068 return 0;
1070} 1069}
@@ -1081,6 +1080,15 @@ static int solo_enc_set_fmt_cap(struct file *file, void *priv,
1081 mutex_lock(&solo_enc->enable_lock); 1080 mutex_lock(&solo_enc->enable_lock);
1082 1081
1083 ret = solo_enc_try_fmt_cap(file, priv, f); 1082 ret = solo_enc_try_fmt_cap(file, priv, f);
1083 if (ret)
1084 return ret;
1085
1086 /* We cannot change width/height in mid read */
1087 if (!ret && atomic_read(&solo_enc->readers) > 0) {
1088 if (pix->width != solo_enc->width ||
1089 pix->height != solo_enc->height)
1090 ret = -EBUSY;
1091 }
1084 if (ret) { 1092 if (ret) {
1085 mutex_unlock(&solo_enc->enable_lock); 1093 mutex_unlock(&solo_enc->enable_lock);
1086 return ret; 1094 return ret;
@@ -1116,6 +1124,7 @@ static int solo_enc_get_fmt_cap(struct file *file, void *priv,
1116 V4L2_FIELD_NONE; 1124 V4L2_FIELD_NONE;
1117 pix->sizeimage = FRAME_BUF_SIZE; 1125 pix->sizeimage = FRAME_BUF_SIZE;
1118 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 1126 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1127 pix->priv = 0;
1119 1128
1120 return 0; 1129 return 0;
1121} 1130}
@@ -1205,7 +1214,8 @@ static int solo_enum_framesizes(struct file *file, void *priv,
1205 struct solo_enc_fh *fh = priv; 1214 struct solo_enc_fh *fh = priv;
1206 struct solo_dev *solo_dev = fh->enc->solo_dev; 1215 struct solo_dev *solo_dev = fh->enc->solo_dev;
1207 1216
1208 if (fsize->pixel_format != V4L2_PIX_FMT_MPEG) 1217 if (fsize->pixel_format != V4L2_PIX_FMT_MPEG &&
1218 fsize->pixel_format != V4L2_PIX_FMT_MJPEG)
1209 return -EINVAL; 1219 return -EINVAL;
1210 1220
1211 switch (fsize->index) { 1221 switch (fsize->index) {
@@ -1232,16 +1242,24 @@ static int solo_enum_frameintervals(struct file *file, void *priv,
1232 struct solo_enc_fh *fh = priv; 1242 struct solo_enc_fh *fh = priv;
1233 struct solo_dev *solo_dev = fh->enc->solo_dev; 1243 struct solo_dev *solo_dev = fh->enc->solo_dev;
1234 1244
1235 if (fintv->pixel_format != V4L2_PIX_FMT_MPEG || fintv->index) 1245 if (fintv->pixel_format != V4L2_PIX_FMT_MPEG &&
1246 fintv->pixel_format != V4L2_PIX_FMT_MJPEG)
1247 return -EINVAL;
1248 if (fintv->index)
1249 return -EINVAL;
1250 if ((fintv->width != solo_dev->video_hsize >> 1 ||
1251 fintv->height != solo_dev->video_vsize) &&
1252 (fintv->width != solo_dev->video_hsize ||
1253 fintv->height != solo_dev->video_vsize << 1))
1236 return -EINVAL; 1254 return -EINVAL;
1237 1255
1238 fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE; 1256 fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE;
1239 1257
1240 fintv->stepwise.min.numerator = solo_dev->fps; 1258 fintv->stepwise.min.denominator = solo_dev->fps;
1241 fintv->stepwise.min.denominator = 1; 1259 fintv->stepwise.min.numerator = 15;
1242 1260
1243 fintv->stepwise.max.numerator = solo_dev->fps; 1261 fintv->stepwise.max.denominator = solo_dev->fps;
1244 fintv->stepwise.max.denominator = 15; 1262 fintv->stepwise.max.numerator = 1;
1245 1263
1246 fintv->stepwise.step.numerator = 1; 1264 fintv->stepwise.step.numerator = 1;
1247 fintv->stepwise.step.denominator = 1; 1265 fintv->stepwise.step.denominator = 1;
@@ -1298,6 +1316,7 @@ static int solo_s_parm(struct file *file, void *priv,
1298 solo_enc->interval = cp->timeperframe.numerator; 1316 solo_enc->interval = cp->timeperframe.numerator;
1299 1317
1300 cp->capability = V4L2_CAP_TIMEPERFRAME; 1318 cp->capability = V4L2_CAP_TIMEPERFRAME;
1319 cp->readbuffers = 2;
1301 1320
1302 solo_update_mode(solo_enc); 1321 solo_update_mode(solo_enc);
1303 1322
diff --git a/drivers/staging/media/solo6x10/v4l2.c b/drivers/staging/media/solo6x10/v4l2.c
index 4243bbe8a3ed..668dc48458a9 100644
--- a/drivers/staging/media/solo6x10/v4l2.c
+++ b/drivers/staging/media/solo6x10/v4l2.c
@@ -34,8 +34,6 @@
34#include "solo6x10.h" 34#include "solo6x10.h"
35#include "tw28.h" 35#include "tw28.h"
36 36
37#define SOLO_DISP_PIX_FIELD V4L2_FIELD_INTERLACED
38
39/* Image size is two fields, SOLO_HW_BPL is one horizontal line in hardware */ 37/* Image size is two fields, SOLO_HW_BPL is one horizontal line in hardware */
40#define SOLO_HW_BPL 2048 38#define SOLO_HW_BPL 2048
41#define solo_vlines(__solo) (__solo->video_vsize * 2) 39#define solo_vlines(__solo) (__solo->video_vsize * 2)
@@ -439,7 +437,7 @@ static int solo_v4l2_open(struct file *file)
439 videobuf_queue_dma_contig_init(&fh->vidq, &solo_video_qops, 437 videobuf_queue_dma_contig_init(&fh->vidq, &solo_video_qops,
440 &solo_dev->pdev->dev, &fh->slock, 438 &solo_dev->pdev->dev, &fh->slock,
441 V4L2_BUF_TYPE_VIDEO_CAPTURE, 439 V4L2_BUF_TYPE_VIDEO_CAPTURE,
442 SOLO_DISP_PIX_FIELD, 440 V4L2_FIELD_INTERLACED,
443 sizeof(struct videobuf_buffer), 441 sizeof(struct videobuf_buffer),
444 fh, NULL); 442 fh, NULL);
445 return 0; 443 return 0;
@@ -581,23 +579,16 @@ static int solo_try_fmt_cap(struct file *file, void *priv,
581 struct v4l2_pix_format *pix = &f->fmt.pix; 579 struct v4l2_pix_format *pix = &f->fmt.pix;
582 int image_size = solo_image_size(solo_dev); 580 int image_size = solo_image_size(solo_dev);
583 581
584 /* Check supported sizes */ 582 if (pix->pixelformat != V4L2_PIX_FMT_UYVY)
585 if (pix->width != solo_dev->video_hsize)
586 pix->width = solo_dev->video_hsize;
587 if (pix->height != solo_vlines(solo_dev))
588 pix->height = solo_vlines(solo_dev);
589 if (pix->sizeimage != image_size)
590 pix->sizeimage = image_size;
591
592 /* Check formats */
593 if (pix->field == V4L2_FIELD_ANY)
594 pix->field = SOLO_DISP_PIX_FIELD;
595
596 if (pix->pixelformat != V4L2_PIX_FMT_UYVY ||
597 pix->field != SOLO_DISP_PIX_FIELD ||
598 pix->colorspace != V4L2_COLORSPACE_SMPTE170M)
599 return -EINVAL; 583 return -EINVAL;
600 584
585 pix->width = solo_dev->video_hsize;
586 pix->height = solo_vlines(solo_dev);
587 pix->sizeimage = image_size;
588 pix->field = V4L2_FIELD_INTERLACED;
589 pix->pixelformat = V4L2_PIX_FMT_UYVY;
590 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
591 pix->priv = 0;
601 return 0; 592 return 0;
602} 593}
603 594
@@ -624,10 +615,11 @@ static int solo_get_fmt_cap(struct file *file, void *priv,
624 pix->width = solo_dev->video_hsize; 615 pix->width = solo_dev->video_hsize;
625 pix->height = solo_vlines(solo_dev); 616 pix->height = solo_vlines(solo_dev);
626 pix->pixelformat = V4L2_PIX_FMT_UYVY; 617 pix->pixelformat = V4L2_PIX_FMT_UYVY;
627 pix->field = SOLO_DISP_PIX_FIELD; 618 pix->field = V4L2_FIELD_INTERLACED;
628 pix->sizeimage = solo_image_size(solo_dev); 619 pix->sizeimage = solo_image_size(solo_dev);
629 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 620 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
630 pix->bytesperline = solo_bytesperline(solo_dev); 621 pix->bytesperline = solo_bytesperline(solo_dev);
622 pix->priv = 0;
631 623
632 return 0; 624 return 0;
633} 625}