diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-03-12 17:43:21 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-25 07:43:34 -0400 |
commit | 016afda4fb298aa2e5515048fcba0271ad6f7320 (patch) | |
tree | 4c63fc3ec659da65923178aaefd6b28c7342c60e | |
parent | c813bd3c8dce3564166e2c4f839fd36df7b0ba5d (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.c | 51 | ||||
-rw-r--r-- | drivers/staging/media/solo6x10/v4l2.c | 30 |
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 | } |