@@ -96,6 +96,16 @@ MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
96
96
/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
97
97
static unsigned long em28xx_devused ;
98
98
99
+ /* supported video standards */
100
+ static struct em28xx_fmt format [] = {
101
+ {
102
+ .name = "16bpp YUY2, 4:2:2, packed" ,
103
+ .fourcc = V4L2_PIX_FMT_YUYV ,
104
+ .depth = 16 ,
105
+ .reg = 0x14 ,
106
+ },
107
+ };
108
+
99
109
/* supported controls */
100
110
/* Common to all boards */
101
111
static struct v4l2_queryctrl em28xx_qctrl [] = {
@@ -386,7 +396,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
386
396
struct em28xx * dev = fh -> dev ;
387
397
struct v4l2_frequency f ;
388
398
389
- * size = 16 * fh -> dev -> width * fh -> dev -> height >> 3 ;
399
+ * size = (fh -> dev -> width * fh -> dev -> height * dev -> format -> depth + 7 ) >> 3 ;
400
+
390
401
if (0 == * count )
391
402
* count = EM28XX_DEF_BUF ;
392
403
@@ -439,9 +450,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
439
450
struct em28xx * dev = fh -> dev ;
440
451
int rc = 0 , urb_init = 0 ;
441
452
442
- /* FIXME: It assumes depth = 16 */
443
- /* The only currently supported format is 16 bits/pixel */
444
- buf -> vb .size = 16 * dev -> width * dev -> height >> 3 ;
453
+ buf -> vb .size = (fh -> dev -> width * fh -> dev -> height * dev -> format -> depth + 7 ) >> 3 ;
445
454
446
455
if (0 != buf -> vb .baddr && buf -> vb .bsize < buf -> vb .size )
447
456
return - EINVAL ;
@@ -536,7 +545,7 @@ static int em28xx_config(struct em28xx *dev)
536
545
dev -> mute = 1 ; /* maybe not the right place... */
537
546
dev -> volume = 0x1f ;
538
547
539
- em28xx_outfmt_set_yuv422 (dev );
548
+ em28xx_set_outfmt (dev );
540
549
em28xx_colorlevels_set_default (dev );
541
550
em28xx_compression_disable (dev );
542
551
@@ -704,8 +713,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
704
713
705
714
f -> fmt .pix .width = dev -> width ;
706
715
f -> fmt .pix .height = dev -> height ;
707
- f -> fmt .pix .pixelformat = V4L2_PIX_FMT_YUYV ;
708
- f -> fmt .pix .bytesperline = dev -> width * 2 ;
716
+ f -> fmt .pix .pixelformat = dev -> format -> fourcc ;
717
+ f -> fmt .pix .bytesperline = ( dev -> width * dev -> format -> depth + 7 ) >> 3 ;
709
718
f -> fmt .pix .sizeimage = f -> fmt .pix .bytesperline * dev -> height ;
710
719
f -> fmt .pix .colorspace = V4L2_COLORSPACE_SMPTE170M ;
711
720
@@ -717,6 +726,17 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
717
726
return 0 ;
718
727
}
719
728
729
+ static struct em28xx_fmt * format_by_fourcc (unsigned int fourcc )
730
+ {
731
+ unsigned int i ;
732
+
733
+ for (i = 0 ; i < ARRAY_SIZE (format ); i ++ )
734
+ if (format [i ].fourcc == fourcc )
735
+ return & format [i ];
736
+
737
+ return NULL ;
738
+ }
739
+
720
740
static int vidioc_try_fmt_vid_cap (struct file * file , void * priv ,
721
741
struct v4l2_format * f )
722
742
{
@@ -727,6 +747,14 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
727
747
unsigned int maxw = norm_maxw (dev );
728
748
unsigned int maxh = norm_maxh (dev );
729
749
unsigned int hscale , vscale ;
750
+ struct em28xx_fmt * fmt ;
751
+
752
+ fmt = format_by_fourcc (f -> fmt .pix .pixelformat );
753
+ if (!fmt ) {
754
+ em28xx_videodbg ("Fourcc format (%08x) invalid.\n" ,
755
+ f -> fmt .pix .pixelformat );
756
+ return - EINVAL ;
757
+ }
730
758
731
759
/* width must even because of the YUYV format
732
760
height must be even because of interlacing */
@@ -765,9 +793,9 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
765
793
766
794
f -> fmt .pix .width = width ;
767
795
f -> fmt .pix .height = height ;
768
- f -> fmt .pix .pixelformat = V4L2_PIX_FMT_YUYV ;
769
- f -> fmt .pix .bytesperline = width * 2 ;
770
- f -> fmt .pix .sizeimage = width * 2 * height ;
796
+ f -> fmt .pix .pixelformat = fmt -> fourcc ;
797
+ f -> fmt .pix .bytesperline = ( dev -> width * fmt -> depth + 7 ) >> 3 ;
798
+ f -> fmt .pix .sizeimage = f -> fmt . pix . bytesperline * height ;
771
799
f -> fmt .pix .colorspace = V4L2_COLORSPACE_SMPTE170M ;
772
800
f -> fmt .pix .field = V4L2_FIELD_INTERLACED ;
773
801
@@ -780,6 +808,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
780
808
struct em28xx_fh * fh = priv ;
781
809
struct em28xx * dev = fh -> dev ;
782
810
int rc ;
811
+ struct em28xx_fmt * fmt ;
783
812
784
813
rc = check_dev (dev );
785
814
if (rc < 0 )
@@ -789,6 +818,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
789
818
790
819
vidioc_try_fmt_vid_cap (file , priv , f );
791
820
821
+ fmt = format_by_fourcc (f -> fmt .pix .pixelformat );
822
+ if (!fmt )
823
+ return - EINVAL ;
824
+
792
825
if (videobuf_queue_is_busy (& fh -> vb_vidq )) {
793
826
em28xx_errdev ("%s queue busy\n" , __func__ );
794
827
rc = - EBUSY ;
@@ -804,6 +837,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
804
837
/* set new image size */
805
838
dev -> width = f -> fmt .pix .width ;
806
839
dev -> height = f -> fmt .pix .height ;
840
+ dev -> format = fmt ;
807
841
get_scale (dev , dev -> width , dev -> height , & dev -> hscale , & dev -> vscale );
808
842
809
843
em28xx_set_alternate (dev );
@@ -1332,15 +1366,13 @@ static int vidioc_querycap(struct file *file, void *priv,
1332
1366
}
1333
1367
1334
1368
static int vidioc_enum_fmt_vid_cap (struct file * file , void * priv ,
1335
- struct v4l2_fmtdesc * fmtd )
1369
+ struct v4l2_fmtdesc * f )
1336
1370
{
1337
- if (fmtd -> index != 0 )
1371
+ if (unlikely ( f -> index >= ARRAY_SIZE ( format )) )
1338
1372
return - EINVAL ;
1339
1373
1340
- fmtd -> type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
1341
- strcpy (fmtd -> description , "Packed YUY2" );
1342
- fmtd -> pixelformat = V4L2_PIX_FMT_YUYV ;
1343
- memset (fmtd -> reserved , 0 , sizeof (fmtd -> reserved ));
1374
+ strlcpy (f -> description , format [f -> index ].name , sizeof (f -> description ));
1375
+ f -> pixelformat = format [f -> index ].fourcc ;
1344
1376
1345
1377
return 0 ;
1346
1378
}
@@ -2075,6 +2107,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2075
2107
dev -> em28xx_write_regs_req = em28xx_write_regs_req ;
2076
2108
dev -> em28xx_read_reg_req = em28xx_read_reg_req ;
2077
2109
dev -> board .is_em2800 = em28xx_boards [dev -> model ].is_em2800 ;
2110
+ dev -> format = & format [0 ];
2078
2111
2079
2112
em28xx_pre_card_setup (dev );
2080
2113
@@ -2482,3 +2515,4 @@ static void __exit em28xx_module_exit(void)
2482
2515
2483
2516
module_init (em28xx_module_init );
2484
2517
module_exit (em28xx_module_exit );
2518
+
0 commit comments