1 /*
2  *  probe_v4l.c
3  *
4  *  Copyright (C) Tilmann Bitterberg - January 2004
5  *
6  *  This file is part of transcode, a video stream processing tool
7  *
8  *  transcode is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2, or (at your option)
11  *  any later version.
12  *
13  *  transcode is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with GNU Make; see the file COPYING.  If not, write to
20  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  */
23 
24 #include "transcode.h"
25 #include "tcinfo.h"
26 #include "ioaux.h"
27 #include "tc.h"
28 #include "libtc/libtc.h"
29 
30 #ifdef HAVE_V4L
31 
32 #include <sys/ioctl.h>
33 
34 #include <linux/videodev.h>
35 
36 #if defined(HAVE_LINUX_VIDEODEV2_H) && defined(HAVE_STRUCT_V4L2_BUFFER)
37 #define _LINUX_TIME_H
38 #endif
39 #include <linux/videodev2.h>
40 
41 
probe_v4l(info_t * ipipe)42 void probe_v4l(info_t *ipipe)
43 {
44     int is_v4l2 = 0;
45     struct v4l2_capability caps; // v4l2
46 
47     /* yes, this is a bit sick */
48     close(ipipe->fd_in);
49     ipipe->fd_in = open(ipipe->name, O_RDWR, 0);
50     if (ipipe->fd_in < 0) {
51         tc_log_error(__FILE__, "cannot (reopen) device in RW mode: %s",
52                      strerror(errno));
53         goto error;
54     }
55 
56     /* let's start with good old defaults */
57     ipipe->probe_info->width  = PAL_W;
58     ipipe->probe_info->height = PAL_H;
59     ipipe->probe_info->fps    = 25;
60     ipipe->probe_info->frc    = 3;
61 
62     /* try a v4l2 ioctl */
63     if (ipipe->verbose & TC_DEBUG)
64         tc_log_msg(__FILE__, "Checking if v4l2 ioctls are supported...");
65     if (ioctl(ipipe->fd_in, VIDIOC_QUERYCAP, &caps) < 0) {
66         is_v4l2 = 0;
67         if (ipipe->verbose & TC_DEBUG)
68             tc_log_msg(__FILE__, "... no");
69     } else {
70         is_v4l2 = 1;
71         ipipe->probe_info->magic=TC_MAGIC_V4L2_VIDEO;
72         if (ipipe->verbose & TC_DEBUG)
73             tc_log_msg(__FILE__, "... yes");
74     }
75 
76     /* try v4l first */
77     if (!is_v4l2) {
78         struct video_capability  capability; // v4l1
79         if (ipipe->verbose & TC_DEBUG)
80             tc_log_msg(__FILE__, "Checking if v4l1 ioctls are supported...");
81         if (-1 == ioctl(ipipe->fd_in,VIDIOCGCAP,&capability)) {
82 	        if (ipipe->verbose & TC_DEBUG)
83 	            tc_log_msg(__FILE__, "... no");
84             goto error;
85         } else {
86 	        ipipe->probe_info->magic = TC_MAGIC_V4L_VIDEO;
87             if (ipipe->verbose & TC_DEBUG)
88 	            tc_log_msg(__FILE__, "... yes");
89         }
90 
91         ipipe->probe_info->width  = capability.maxwidth;
92         ipipe->probe_info->height = capability.maxheight;
93         /*
94          * saa7134 sometimes delivers strange (for me) results.
95          * In the case, PAL settings are forced until I figure out
96          * if such results are correct or not.
97          */
98         if (ipipe->probe_info->width == 720 && ipipe->probe_info->height == 578) {
99             ipipe->probe_info->height = 576;
100         }
101     }
102 
103     if (is_v4l2) {
104         v4l2_std_id std;
105 
106         if (ioctl(ipipe->fd_in, VIDIOC_G_STD, &std) >= 0) {
107             if (std & V4L2_STD_525_60) {
108                 ipipe->probe_info->fps = (30000/1001);
109                 ipipe->probe_info->frc = 4;
110                 ipipe->probe_info->width  = 640;
111                 ipipe->probe_info->height = 480;
112             } else if(std & V4L2_STD_625_50) {
113                 ipipe->probe_info->fps = 25;
114                 ipipe->probe_info->frc = 3;
115                 ipipe->probe_info->width  = 720;
116                 ipipe->probe_info->height = 576;
117 	        }
118         }
119     }
120 
121     // FIXME: Check if these settings are actually supported by /dev/dsp
122     ipipe->probe_info->track[0].samplerate = 44100;
123     ipipe->probe_info->track[0].chan = 2;
124     ipipe->probe_info->track[0].bits = 16;
125     ipipe->probe_info->track[0].format = 0x1;
126     if (ipipe->probe_info->track[0].chan > 0)
127         ipipe->probe_info->num_tracks=1;
128 
129   return;
130 
131 error:
132     ipipe->error = 1;
133     ipipe->probe_info->codec=TC_CODEC_UNKNOWN;
134     ipipe->probe_info->magic=TC_MAGIC_UNKNOWN;
135 
136      return;
137 }
138 
139 #else // HAVE_V4L
140 
probe_v4l(info_t * ipipe)141 void probe_v4l(info_t *ipipe)
142 {
143     tc_log_error(__FILE__, "No support for video4linux compiled in");
144     ipipe->probe_info->codec=TC_CODEC_UNKNOWN;
145     ipipe->probe_info->magic=TC_MAGIC_UNKNOWN;
146 }
147 
148 #endif
149