46
46
#include <asm/types.h>
47
47
#include <linux/videodev2.h>
48
48
#include <jpeglib.h>
49
+ #include <libv4l2.h>
49
50
#include "yuv.h"
50
51
51
52
#define CLEAR (x ) memset (&(x), 0, sizeof (x))
52
53
54
+ #ifndef __GITVERSION
55
+ #define __GITVERSION "unknown"
56
+ #endif
57
+
53
58
#if defined(IO_MMAP ) || defined(IO_USERPTR )
54
59
// minimum number of buffers to request in VIDIOC_REQBUFS call
55
60
#define VIDIOC_REQBUFS_COUNT 2
@@ -76,13 +81,11 @@ static io_method io = IO_METHOD_MMAP;
76
81
static int fd = -1 ;
77
82
struct buffer * buffers = NULL ;
78
83
static unsigned int n_buffers = 0 ;
79
- unsigned int pixelformat = 0 ;
80
84
81
85
// global settings
82
86
static unsigned int width = 640 ;
83
87
static unsigned int height = 480 ;
84
88
static unsigned char jpegQuality = 70 ;
85
- static J_COLOR_SPACE jpegColorSpace = JCS_RGB ;
86
89
static char * jpegFilename = NULL ;
87
90
static char * deviceName = "/dev/video0" ;
88
91
@@ -93,7 +96,7 @@ static char* deviceName = "/dev/video0";
93
96
*/
94
97
static void errno_exit (const char * s )
95
98
{
96
- fprintf (stderr , "%s error %d, %s\n" , s , errno , strerror (errno ));
99
+ fprintf (stderr , "%s error %d, %s\n" , s , errno , strerror (errno ));
97
100
exit (EXIT_FAILURE );
98
101
}
99
102
@@ -109,7 +112,7 @@ static int xioctl(int fd, int request, void* argp)
109
112
{
110
113
int r ;
111
114
112
- do r = ioctl (fd , request , argp );
115
+ do r = v4l2_ioctl (fd , request , argp );
113
116
while (-1 == r && EINTR == errno );
114
117
115
118
return r ;
@@ -142,7 +145,7 @@ static void jpegWrite(unsigned char* img)
142
145
cinfo .image_width = width ;
143
146
cinfo .image_height = height ;
144
147
cinfo .input_components = 3 ;
145
- cinfo .in_color_space = jpegColorSpace ;
148
+ cinfo .in_color_space = JCS_YCbCr ;
146
149
147
150
// set jpeg compression parameters to default
148
151
jpeg_set_defaults (& cinfo );
@@ -176,54 +179,7 @@ static void imageProcess(const void* p)
176
179
unsigned char * src = (unsigned char * )p ;
177
180
unsigned char * dst = malloc (width * height * 3 * sizeof (char ));
178
181
179
- switch (jpegColorSpace ) {
180
- case JCS_GRAYSCALE :
181
- fprintf (stderr , "monochrome color space not supported!\n" );
182
- exit (EXIT_FAILURE );
183
- case JCS_RGB :
184
- switch (pixelformat ) {
185
- case V4L2_PIX_FMT_YUV420 :
186
- // convert from YUV420 to RGB888
187
- YUV420toRGB888 (width , height , src , dst );
188
- break ;
189
-
190
- case V4L2_PIX_FMT_YUYV :
191
- // convert from YUV422 to RGB888
192
- YUV422toRGB888 (width , height , src , dst );
193
- break ;
194
-
195
- default :
196
- fprintf (stderr , "Pixelformat of device not supported with colorspace RGB!\n" );
197
- exit (EXIT_FAILURE );
198
- }
199
- break ;
200
- case JCS_YCbCr :
201
- switch (pixelformat ) {
202
- case V4L2_PIX_FMT_YUV420 :
203
- // convert from YUV420 to YUV444
204
- YUV420toYUV444 (width , height , src , dst );
205
- break ;
206
- case V4L2_PIX_FMT_YUYV :
207
- // convert from YUV422 to YUV444
208
- YUV422toYUV444 (width , height , src , dst );
209
- break ;
210
- default :
211
- fprintf (stderr , "Pixelformat of device not supported with colorspace YUV!\n" );
212
- exit (EXIT_FAILURE );
213
- }
214
- break ;
215
- case JCS_CMYK :
216
- fprintf (stderr , "CMYK color space not supported!\n" );
217
- exit (EXIT_FAILURE );
218
- case JCS_YCCK :
219
- fprintf (stderr , "YCCK color space not supported!\n" );
220
- exit (EXIT_FAILURE );
221
- case JCS_UNKNOWN :
222
- default :
223
- fprintf (stderr , "Color space is unknown and therefore not supported!\n" );
224
- exit (EXIT_FAILURE );
225
- break ;
226
- }
182
+ YUV420toYUV444 (width , height , src , dst );
227
183
228
184
// write jpeg
229
185
jpegWrite (dst );
@@ -245,7 +201,7 @@ static int frameRead(void)
245
201
switch (io ) {
246
202
#ifdef IO_READ
247
203
case IO_METHOD_READ :
248
- if (-1 == read (fd , buffers [0 ].start , buffers [0 ].length )) {
204
+ if (-1 == v4l2_read (fd , buffers [0 ].start , buffers [0 ].length )) {
249
205
switch (errno ) {
250
206
case EAGAIN :
251
207
return 0 ;
@@ -316,7 +272,7 @@ static int frameRead(void)
316
272
}
317
273
318
274
for (i = 0 ; i < n_buffers ; ++ i )
319
- if (buf .m .userptr == (unsigned long ) buffers [i ].start && buf .length == buffers [i ].length )
275
+ if (buf .m .userptr == (unsigned long )buffers [i ].start && buf .length == buffers [i ].length )
320
276
break ;
321
277
322
278
assert (i < n_buffers );
@@ -492,15 +448,15 @@ static void deviceUninit(void)
492
448
#ifdef IO_MMAP
493
449
case IO_METHOD_MMAP :
494
450
for (i = 0 ; i < n_buffers ; ++ i )
495
- if (-1 == munmap (buffers [i ].start , buffers [i ].length ))
451
+ if (-1 == v4l2_munmap (buffers [i ].start , buffers [i ].length ))
496
452
errno_exit ("munmap" );
497
453
break ;
498
454
#endif
499
455
500
456
#ifdef IO_USERPTR
501
457
case IO_METHOD_USERPTR :
502
458
for (i = 0 ; i < n_buffers ; ++ i )
503
- free (buffers [i ].start );
459
+ free (buffers [i ].start );
504
460
break ;
505
461
#endif
506
462
}
@@ -573,7 +529,7 @@ static void mmapInit(void)
573
529
errno_exit ("VIDIOC_QUERYBUF" );
574
530
575
531
buffers [n_buffers ].length = buf .length ;
576
- buffers [n_buffers ].start = mmap (NULL /* start anywhere */ , buf .length , PROT_READ | PROT_WRITE /* required */ , MAP_SHARED /* recommended */ , fd , buf .m .offset );
532
+ buffers [n_buffers ].start = v4l2_mmap (NULL /* start anywhere */ , buf .length , PROT_READ | PROT_WRITE /* required */ , MAP_SHARED /* recommended */ , fd , buf .m .offset );
577
533
578
534
if (MAP_FAILED == buffers [n_buffers ].start )
579
535
errno_exit ("mmap" );
@@ -605,7 +561,7 @@ static void userptrInit(unsigned int buffer_size)
605
561
}
606
562
}
607
563
608
- buffers = calloc (4 , sizeof (* buffers ));
564
+ buffers = calloc (4 , sizeof (* buffers ));
609
565
610
566
if (!buffers ) {
611
567
fprintf (stderr , "Out of memory\n" );
@@ -614,7 +570,7 @@ static void userptrInit(unsigned int buffer_size)
614
570
615
571
for (n_buffers = 0 ; n_buffers < 4 ; ++ n_buffers ) {
616
572
buffers [n_buffers ].length = buffer_size ;
617
- buffers [n_buffers ].start = memalign (/* boundary */ page_size , buffer_size );
573
+ buffers [n_buffers ].start = memalign (/* boundary */ page_size , buffer_size );
618
574
619
575
if (!buffers [n_buffers ].start ) {
620
576
fprintf (stderr , "Out of memory\n" );
@@ -699,63 +655,21 @@ static void deviceInit(void)
699
655
700
656
CLEAR (fmt );
701
657
702
- // query device
703
- fmt .type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
704
- if (-1 == xioctl (fd , VIDIOC_G_FMT , & fmt ))
705
- errno_exit ("VIDIOC_G_FMT" );
706
-
707
- pixelformat = fmt .fmt .pix .pixelformat ;
708
-
709
- switch (pixelformat ) {
710
- case V4L2_PIX_FMT_SBGGR8 :
711
- fprintf (stderr , "Pixel format 4L2_PIX_FMT_SBGGR8 not supported!\n" );
712
- exit (EXIT_FAILURE );
713
- break ;
714
- case V4L2_PIX_FMT_SN9C10X :
715
- fprintf (stderr , "Pixel format V4L2_PIX_FMT_SN9C10X not supported!\n" );
716
- exit (EXIT_FAILURE );
717
- break ;
718
- case V4L2_PIX_FMT_MJPEG :
719
- fprintf (stderr , "Pixel format V4L2_PIX_FMT_MJPEG not supported!\n" );
720
- exit (EXIT_FAILURE );
721
- break ;
722
- case V4L2_PIX_FMT_JPEG :
723
- fprintf (stderr , "Pixel format V4L2_PIX_FMT_JPEG not supported!\n" );
724
- exit (EXIT_FAILURE );
725
- break ;
726
- case V4L2_PIX_FMT_RGB24 :
727
- fprintf (stderr , "Pixel format V4L2_PIX_FMT_RGB24 not supported!\n" );
728
- exit (EXIT_FAILURE );
729
- break ;
730
- case V4L2_PIX_FMT_UYVY :
731
- fprintf (stderr , "Pixel format V4L2_PIX_FMT_UYVY not supported!\n" );
732
- exit (EXIT_FAILURE );
733
- break ;
734
- case V4L2_PIX_FMT_YUV422P :
735
- fprintf (stderr , "Pixel format V4L2_PIX_FMT_YUV422P not supported!\n" );
736
- exit (EXIT_FAILURE );
737
- break ;
738
- case V4L2_PIX_FMT_YUV420 :
739
- printf ("Using pixel format V4L2_PIX_FMT_YUV420.\n" );
740
- break ;
741
- case V4L2_PIX_FMT_YUYV :
742
- printf ("Using pixel format V4L2_PIX_FMT_YUYV.\n" );
743
- break ;
744
- default :
745
- fprintf (stderr , "Unknown pixel format %u!\n" , pixelformat );
746
- exit (EXIT_FAILURE );
747
- break ;
748
- };
749
-
750
658
// v4l2_format
751
659
fmt .type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
752
660
fmt .fmt .pix .width = width ;
753
661
fmt .fmt .pix .height = height ;
754
662
fmt .fmt .pix .field = V4L2_FIELD_INTERLACED ;
663
+ fmt .fmt .pix .pixelformat = V4L2_PIX_FMT_YUV420 ;
755
664
756
665
if (-1 == xioctl (fd , VIDIOC_S_FMT , & fmt ))
757
666
errno_exit ("VIDIOC_S_FMT" );
758
667
668
+ if (fmt .fmt .pix .pixelformat != V4L2_PIX_FMT_YUV420 ) {
669
+ fprintf (stderr ,"Libv4l didn't accept YUV420 format. Can't proceed.\n" );
670
+ exit (EXIT_FAILURE );
671
+ }
672
+
759
673
/* Note VIDIOC_S_FMT may change width and height. */
760
674
if (width != fmt .fmt .pix .width ) {
761
675
width = fmt .fmt .pix .width ;
@@ -801,7 +715,7 @@ static void deviceInit(void)
801
715
*/
802
716
static void deviceClose (void )
803
717
{
804
- if (-1 == close (fd ))
718
+ if (-1 == v4l2_close (fd ))
805
719
errno_exit ("close" );
806
720
807
721
fd = -1 ;
@@ -816,22 +730,22 @@ static void deviceOpen(void)
816
730
817
731
// stat file
818
732
if (-1 == stat (deviceName , & st )) {
819
- fprintf (stderr , "Cannot identify '%s': %d, %s\n" , deviceName , errno , strerror (errno ));
733
+ fprintf (stderr , "Cannot identify '%s': %d, %s\n" , deviceName , errno , strerror (errno ));
820
734
exit (EXIT_FAILURE );
821
735
}
822
736
823
737
// check if its device
824
- if (!S_ISCHR (st .st_mode )) {
738
+ if (!S_ISCHR (st .st_mode )) {
825
739
fprintf (stderr , "%s is no device\n" , deviceName );
826
740
exit (EXIT_FAILURE );
827
741
}
828
742
829
743
// open device
830
- fd = open (deviceName , O_RDWR /* required */ | O_NONBLOCK , 0 );
744
+ fd = v4l2_open (deviceName , O_RDWR /* required */ | O_NONBLOCK , 0 );
831
745
832
746
// check if opening was successfull
833
747
if (-1 == fd ) {
834
- fprintf (stderr , "Cannot open '%s': %d, %s\n" , deviceName , errno , strerror (errno ));
748
+ fprintf (stderr , "Cannot open '%s': %d, %s\n" , deviceName , errno , strerror (errno ));
835
749
exit (EXIT_FAILURE );
836
750
}
837
751
}
@@ -841,37 +755,37 @@ static void deviceOpen(void)
841
755
*/
842
756
static void usage (FILE * fp , int argc , char * * argv )
843
757
{
844
- fprintf (fp ,
758
+ fprintf (fp ,
845
759
"Usage: %s [options]\n\n"
846
760
"Options:\n"
847
761
"-d | --device name Video device name [/dev/video0]\n"
848
762
"-h | --help Print this message\n"
849
763
"-o | --output Set JPEG output filename\n"
850
764
"-q | --quality Set JPEG quality (0-100)\n"
851
- "-y | --jpeg-yuv Set JPEG colorspace to YUV\n"
852
765
"-m | --mmap Use memory mapped buffers\n"
853
766
"-r | --read Use read() calls\n"
854
767
"-u | --userptr Use application allocated buffers\n"
855
- "-W | --width width\n"
856
- "-H | --height height\n"
768
+ "-W | --width Set image width\n"
769
+ "-H | --height Set image height\n"
770
+ "-v | --version Print version"
857
771
"" ,
858
772
argv [0 ]);
859
773
}
860
774
861
- static const char short_options [] = "d:ho:q:ymruW :H:" ;
775
+ static const char short_options [] = "d:ho:q:mruW :H:v " ;
862
776
863
777
static const struct option
864
778
long_options [] = {
865
779
{ "device" , required_argument , NULL , 'd' },
866
780
{ "help" , no_argument , NULL , 'h' },
867
781
{ "output" , required_argument , NULL , 'o' },
868
782
{ "quality" , required_argument , NULL , 'q' },
869
- { "jpeg-yuv" , no_argument , NULL , 'y' },
870
783
{ "mmap" , no_argument , NULL , 'm' },
871
784
{ "read" , no_argument , NULL , 'r' },
872
785
{ "userptr" , no_argument , NULL , 'u' },
873
786
{ "width" , required_argument , NULL , 'W' },
874
787
{ "height" , required_argument , NULL , 'H' },
788
+ { "version" , no_argument , NULL , 'v' },
875
789
{ 0 , 0 , 0 , 0 }
876
790
};
877
791
@@ -909,11 +823,6 @@ int main(int argc, char **argv)
909
823
jpegQuality = atoi (optarg );
910
824
break ;
911
825
912
- case 'y' :
913
- // set jpeg colorspace to YUV
914
- jpegColorSpace = JCS_YCbCr ;
915
- break ;
916
-
917
826
case 'm' :
918
827
#ifdef IO_MMAP
919
828
io = IO_METHOD_MMAP ;
@@ -951,6 +860,11 @@ int main(int argc, char **argv)
951
860
height = atoi (optarg );
952
861
break ;
953
862
863
+ case 'v' :
864
+ printf ("Version: %s\n" , __GITVERSION );
865
+ exit (EXIT_SUCCESS );
866
+ break ;
867
+
954
868
default :
955
869
usage (stderr , argc , argv );
956
870
exit (EXIT_FAILURE );
0 commit comments