18997
|
1 /*
|
|
2 * Copyright (C) 2006 Benjamin Zores
|
|
3 * Stream layer for WinTV PVR-150/250/350 (a.k.a IVTV) PVR cards.
|
|
4 * See http://ivtvdriver.org/index.php/Main_Page for more details on the
|
|
5 * cards supported by the ivtv driver.
|
|
6 *
|
|
7 * This program is free software; you can redistribute it and/or modify
|
|
8 * it under the terms of the GNU General Public License as published by
|
|
9 * the Free Software Foundation; either version 2 of the License, or
|
|
10 * (at your option) any later version.
|
|
11 *
|
|
12 * This program is distributed in the hope that it will be useful,
|
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 * GNU General Public License for more details.
|
|
16 *
|
|
17 * You should have received a copy of the GNU General Public License
|
|
18 * along with this program; if not, write to the Free Software Foundation,
|
|
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
20 */
|
|
21
|
|
22 #include "config.h"
|
|
23
|
|
24 #include <stdio.h>
|
|
25 #include <stdlib.h>
|
|
26 #include <unistd.h>
|
|
27 #include <string.h>
|
|
28 #include <ctype.h>
|
|
29 #include <sys/time.h>
|
|
30 #include <errno.h>
|
|
31 #include <sys/ioctl.h>
|
|
32 #include <sys/fcntl.h>
|
|
33 #include <inttypes.h>
|
|
34 #include <sys/poll.h>
|
|
35 #include <linux/videodev2.h>
|
|
36 #include <linux/ivtv.h>
|
|
37
|
|
38 #include "mp_msg.h"
|
|
39 #include "help_mp.h"
|
|
40
|
|
41 #include "stream.h"
|
|
42 #include "tv.h"
|
|
43
|
|
44 #define PVR_DEFAULT_DEVICE "/dev/video0"
|
|
45
|
|
46 /* logging mechanisms */
|
|
47 #define LOG_LEVEL_PVR "[pvr]"
|
|
48 #define LOG_LEVEL_V4L2 "[v4l2]"
|
|
49 #define LOG_LEVEL_IVTV "[ivtv]"
|
|
50
|
|
51 /* IVTV driver settings (see http://ivtvdriver.org/index.php/Ivtvctl ) */
|
|
52
|
|
53 /* codec aspect ratio (1:1, 4:3, 16:9, 2.21:1) */
|
|
54 #define PVR_ASPECT_RATIO_1_1 1
|
|
55 #define PVR_ASPECT_RATIO_4_3 2
|
|
56 #define PVR_ASPECT_RATIO_16_9 3
|
|
57 #define PVR_ASPECT_RATIO_2_21_1 4
|
|
58
|
|
59 /* audio codec sample rate (32KHz, CD 44.1 KHz, AC97 48 KHz) */
|
|
60 #define PVR_AUDIO_SAMPLE_RATE_44_1_KHZ 0x0000
|
|
61 #define PVR_AUDIO_SAMPLE_RATE_48_KHZ 0x0001
|
|
62 #define PVR_AUDIO_SAMPLE_RATE_32_KHZ 0x0002
|
|
63
|
|
64 /* audio codec layer (1 or 2) */
|
|
65 #define PVR_AUDIO_LAYER_1 0x0004
|
|
66 #define PVR_AUDIO_LAYER_2 0x0008
|
|
67
|
|
68 /* audio codec bitrate */
|
|
69 #define PVR_AUDIO_BITRATE_32 0x0010
|
|
70 #define PVR_AUDIO_BITRATE_L1_64 0x0020
|
|
71 #define PVR_AUDIO_BITRATE_L1_96 0x0030
|
|
72 #define PVR_AUDIO_BITRATE_L1_128 0x0040
|
|
73 #define PVR_AUDIO_BITRATE_L1_160 0x0050
|
|
74 #define PVR_AUDIO_BITRATE_L1_192 0x0060
|
|
75 #define PVR_AUDIO_BITRATE_L1_224 0x0070
|
|
76 #define PVR_AUDIO_BITRATE_L1_256 0x0080
|
|
77 #define PVR_AUDIO_BITRATE_L1_288 0x0090
|
|
78 #define PVR_AUDIO_BITRATE_L1_320 0x00A0
|
|
79 #define PVR_AUDIO_BITRATE_L1_352 0x00B0
|
|
80 #define PVR_AUDIO_BITRATE_L1_384 0x00C0
|
|
81 #define PVR_AUDIO_BITRATE_L1_416 0x00D0
|
|
82 #define PVR_AUDIO_BITRATE_L1_448 0x00E0
|
|
83 #define PVR_AUDIO_BITRATE_L2_48 0x0020
|
|
84 #define PVR_AUDIO_BITRATE_L2_56 0x0030
|
|
85 #define PVR_AUDIO_BITRATE_L2_64 0x0040
|
|
86 #define PVR_AUDIO_BITRATE_L2_80 0x0050
|
|
87 #define PVR_AUDIO_BITRATE_L2_96 0x0060
|
|
88 #define PVR_AUDIO_BITRATE_L2_112 0x0070
|
|
89 #define PVR_AUDIO_BITRATE_L2_128 0x0080
|
|
90 #define PVR_AUDIO_BITRATE_L2_160 0x0090
|
|
91 #define PVR_AUDIO_BITRATE_L2_192 0x00A0
|
|
92 #define PVR_AUDIO_BITRATE_L2_224 0x00B0
|
|
93 #define PVR_AUDIO_BITRATE_L2_256 0x00C0
|
|
94 #define PVR_AUDIO_BITRATE_L2_320 0x00D0
|
|
95 #define PVR_AUDIO_BITRATE_L2_384 0x00E0
|
|
96
|
|
97 /* audio codec mode */
|
|
98 #define PVR_AUDIO_MODE_ARG_STEREO "stereo"
|
|
99 #define PVR_AUDIO_MODE_ARG_JOINT_STEREO "joint_stereo"
|
|
100 #define PVR_AUDIO_MODE_ARG_DUAL "dual"
|
|
101 #define PVR_AUDIO_MODE_ARG_MONO "mono"
|
|
102 #define PVR_AUDIO_MODE_STEREO 0x0000
|
|
103 #define PVR_AUDIO_MODE_JOINT_STEREO 0x0100
|
|
104 #define PVR_AUDIO_MODE_DUAL 0x0200
|
|
105 #define PVR_AUDIO_MODE_MONO 0x0300
|
|
106
|
|
107 /* video codec bitrate mode */
|
|
108 #define PVR_VIDEO_BITRATE_MODE_ARG_VBR "vbr"
|
|
109 #define PVR_VIDEO_BITRATE_MODE_ARG_CBR "cbr"
|
|
110 #define PVR_VIDEO_BITRATE_MODE_VBR 0
|
|
111 #define PVR_VIDEO_BITRATE_MODE_CBR 1
|
|
112
|
|
113 /* video codec stream type */
|
|
114 #define PVR_VIDEO_STREAM_TYPE_PS "ps"
|
|
115 #define PVR_VIDEO_STREAM_TYPE_TS "ts"
|
|
116 #define PVR_VIDEO_STREAM_TYPE_MPEG1 "mpeg1"
|
|
117 #define PVR_VIDEO_STREAM_TYPE_DVD "dvd"
|
|
118 #define PVR_VIDEO_STREAM_TYPE_VCD "vcd"
|
|
119 #define PVR_VIDEO_STREAM_TYPE_SVCD "svcd"
|
|
120 #define PVR_VIDEO_STREAM_TYPE_DVD_S1 "dvds1"
|
|
121 #define PVR_VIDEO_STREAM_TYPE_DVD_S2 "dvds2"
|
|
122
|
|
123 /* command line arguments */
|
|
124 int pvr_param_aspect_ratio = 0;
|
|
125 int pvr_param_sample_rate = 0;
|
|
126 int pvr_param_audio_layer = 0;
|
|
127 int pvr_param_audio_bitrate = 0;
|
|
128 char *pvr_param_audio_mode = NULL;
|
|
129 int pvr_param_bitrate = 0;
|
|
130 char *pvr_param_bitrate_mode = NULL;
|
|
131 int pvr_param_bitrate_peak = 0;
|
|
132 char *pvr_param_stream_type = NULL;
|
|
133
|
|
134 struct pvr_t {
|
|
135 int dev_fd;
|
|
136 char *video_dev;
|
|
137
|
|
138 /* v4l2 params */
|
|
139 int mute;
|
|
140 int input;
|
|
141 int normid;
|
|
142 int brightness;
|
|
143 int contrast;
|
|
144 int hue;
|
|
145 int saturation;
|
|
146 int width;
|
|
147 int height;
|
|
148 char *freq;
|
|
149
|
|
150 /* ivtv params */
|
|
151 int aspect;
|
|
152 int samplerate;
|
|
153 int layer;
|
|
154 int audio_rate;
|
|
155 int audio_mode;
|
|
156 int bitrate;
|
|
157 int bitrate_mode;
|
|
158 int bitrate_peak;
|
|
159 int stream_type;
|
|
160 };
|
|
161
|
|
162 static struct pvr_t *
|
|
163 pvr_init (void)
|
|
164 {
|
|
165 struct pvr_t *pvr = NULL;
|
|
166
|
|
167 pvr = malloc (sizeof (struct pvr_t));
|
|
168 pvr->dev_fd = -1;
|
|
169 pvr->video_dev = strdup (PVR_DEFAULT_DEVICE);
|
|
170
|
|
171 /* v4l2 params */
|
|
172 pvr->mute = 0;
|
|
173 pvr->input = 0;
|
|
174 pvr->normid = -1;
|
|
175 pvr->brightness = 0;
|
|
176 pvr->contrast = 0;
|
|
177 pvr->hue = 0;
|
|
178 pvr->saturation = 0;
|
|
179 pvr->width = -1;
|
|
180 pvr->height = -1;
|
|
181 pvr->freq = NULL;
|
|
182
|
|
183 /* ivtv params */
|
|
184 pvr->aspect = -1;
|
|
185 pvr->samplerate = -1;
|
|
186 pvr->layer = -1;
|
|
187 pvr->audio_rate = -1;
|
|
188 pvr->audio_mode = -1;
|
|
189 pvr->bitrate = -1;
|
|
190 pvr->bitrate_mode = -1;
|
|
191 pvr->bitrate_peak = -1;
|
|
192 pvr->stream_type = -1;
|
|
193
|
|
194 return pvr;
|
|
195 }
|
|
196
|
|
197 static void
|
|
198 pvr_uninit (struct pvr_t *pvr)
|
|
199 {
|
|
200 if (!pvr)
|
|
201 return;
|
|
202
|
|
203 /* close device */
|
|
204 if (pvr->dev_fd)
|
|
205 close (pvr->dev_fd);
|
|
206
|
|
207 if (pvr->video_dev)
|
|
208 free (pvr->video_dev);
|
|
209 if (pvr->freq)
|
|
210 free (pvr->freq);
|
|
211 free (pvr);
|
|
212 }
|
|
213
|
|
214 /* IVTV layer */
|
|
215
|
|
216 static void
|
|
217 parse_ivtv_options (struct pvr_t *pvr)
|
|
218 {
|
|
219 if (!pvr)
|
|
220 return;
|
|
221
|
|
222 /* -pvr aspect=digit */
|
|
223 if (pvr_param_aspect_ratio >= 1 && pvr_param_aspect_ratio <= 4)
|
|
224 pvr->aspect = pvr_param_aspect_ratio;
|
|
225
|
|
226 /* -pvr arate=x */
|
|
227 if (pvr_param_sample_rate != 0)
|
|
228 {
|
|
229 switch (pvr_param_sample_rate)
|
|
230 {
|
|
231 case 32000:
|
|
232 pvr->samplerate = PVR_AUDIO_SAMPLE_RATE_32_KHZ;
|
|
233 break;
|
|
234 case 44100:
|
|
235 pvr->samplerate = PVR_AUDIO_SAMPLE_RATE_44_1_KHZ;
|
|
236 break;
|
|
237 case 48000:
|
|
238 pvr->samplerate = PVR_AUDIO_SAMPLE_RATE_48_KHZ;
|
|
239 break;
|
|
240 default:
|
|
241 break;
|
|
242 }
|
|
243 }
|
|
244
|
|
245 /* -pvr alayer=x */
|
|
246 if (pvr_param_audio_layer == 1)
|
|
247 pvr->layer = PVR_AUDIO_LAYER_1;
|
|
248 else if (pvr_param_audio_layer == 2)
|
|
249 pvr->layer = PVR_AUDIO_LAYER_2;
|
|
250
|
|
251 /* -pvr abitrate=x */
|
|
252 if (pvr_param_audio_bitrate != 0)
|
|
253 {
|
|
254 /* set according to layer or use layer 1 by default if not specified */
|
|
255 switch (pvr_param_audio_bitrate)
|
|
256 {
|
|
257 case 32:
|
|
258 pvr->audio_rate = PVR_AUDIO_BITRATE_32;
|
|
259 break;
|
|
260 case 48:
|
|
261 pvr->audio_rate = PVR_AUDIO_BITRATE_L2_48;
|
|
262 break;
|
|
263 case 56:
|
|
264 pvr->audio_rate = PVR_AUDIO_BITRATE_L2_56;
|
|
265 break;
|
|
266 case 64:
|
|
267 pvr->audio_rate = (pvr_param_audio_layer == 2) ?
|
|
268 PVR_AUDIO_BITRATE_L2_64 : PVR_AUDIO_BITRATE_L1_64;
|
|
269 break;
|
|
270 case 80:
|
|
271 pvr->audio_rate = PVR_AUDIO_BITRATE_L2_80;
|
|
272 break;
|
|
273 case 96:
|
|
274 pvr->audio_rate = (pvr_param_audio_layer == 2) ?
|
|
275 PVR_AUDIO_BITRATE_L2_96 : PVR_AUDIO_BITRATE_L1_96;
|
|
276 break;
|
|
277 case 112:
|
|
278 pvr->audio_rate = PVR_AUDIO_BITRATE_L2_112;
|
|
279 break;
|
|
280 case 128:
|
|
281 pvr->audio_rate = (pvr_param_audio_layer == 2) ?
|
|
282 PVR_AUDIO_BITRATE_L2_128 : PVR_AUDIO_BITRATE_L1_128;
|
|
283 break;
|
|
284 case 160:
|
|
285 pvr->audio_rate = (pvr_param_audio_layer == 2) ?
|
|
286 PVR_AUDIO_BITRATE_L2_160 : PVR_AUDIO_BITRATE_L1_160;
|
|
287 break;
|
|
288 case 192:
|
|
289 pvr->audio_rate = (pvr_param_audio_layer == 2) ?
|
|
290 PVR_AUDIO_BITRATE_L2_192 : PVR_AUDIO_BITRATE_L1_192;
|
|
291 break;
|
|
292 case 224:
|
|
293 pvr->audio_rate = (pvr_param_audio_layer == 2) ?
|
|
294 PVR_AUDIO_BITRATE_L2_224 : PVR_AUDIO_BITRATE_L1_224;
|
|
295 break;
|
|
296 case 256:
|
|
297 pvr->audio_rate = (pvr_param_audio_layer == 2) ?
|
|
298 PVR_AUDIO_BITRATE_L2_256 : PVR_AUDIO_BITRATE_L1_256;
|
|
299 break;
|
|
300 case 288:
|
|
301 pvr->audio_rate = PVR_AUDIO_BITRATE_L1_288;
|
|
302 break;
|
|
303 case 320:
|
|
304 pvr->audio_rate = (pvr_param_audio_layer == 2) ?
|
|
305 PVR_AUDIO_BITRATE_L2_320 : PVR_AUDIO_BITRATE_L1_320;
|
|
306 break;
|
|
307 case 352:
|
|
308 pvr->audio_rate = PVR_AUDIO_BITRATE_L1_352;
|
|
309 break;
|
|
310 case 384:
|
|
311 pvr->audio_rate = (pvr_param_audio_layer == 2) ?
|
|
312 PVR_AUDIO_BITRATE_L2_384 : PVR_AUDIO_BITRATE_L1_384;
|
|
313 break;
|
|
314 case 416:
|
|
315 pvr->audio_rate = PVR_AUDIO_BITRATE_L1_416;
|
|
316 break;
|
|
317 case 448:
|
|
318 pvr->audio_rate = PVR_AUDIO_BITRATE_L1_448;
|
|
319 break;
|
|
320 default:
|
|
321 break;
|
|
322 }
|
|
323 }
|
|
324
|
|
325 /* -pvr amode=x */
|
|
326 if (pvr_param_audio_mode)
|
|
327 {
|
|
328 if (!strcmp (pvr_param_audio_mode, PVR_AUDIO_MODE_ARG_STEREO))
|
|
329 pvr->audio_mode = PVR_AUDIO_MODE_STEREO;
|
|
330 else if (!strcmp (pvr_param_audio_mode, PVR_AUDIO_MODE_ARG_JOINT_STEREO))
|
|
331 pvr->audio_mode = PVR_AUDIO_MODE_JOINT_STEREO;
|
|
332 else if (!strcmp (pvr_param_audio_mode, PVR_AUDIO_MODE_ARG_DUAL))
|
|
333 pvr->audio_mode = PVR_AUDIO_MODE_DUAL;
|
|
334 else if (!strcmp (pvr_param_audio_mode, PVR_AUDIO_MODE_ARG_MONO))
|
|
335 pvr->audio_mode = PVR_AUDIO_MODE_MONO;
|
|
336 else /* for anything else, set to stereo */
|
|
337 pvr->audio_mode = PVR_AUDIO_MODE_STEREO;
|
|
338 }
|
|
339
|
|
340 /* -pvr vbitrate=x */
|
|
341 if (pvr_param_bitrate)
|
|
342 pvr->bitrate = pvr_param_bitrate;
|
|
343
|
|
344 /* -pvr vmode=x */
|
|
345 if (pvr_param_bitrate_mode)
|
|
346 {
|
|
347 if (!strcmp (pvr_param_bitrate_mode, PVR_VIDEO_BITRATE_MODE_ARG_VBR))
|
|
348 pvr->bitrate_mode = PVR_VIDEO_BITRATE_MODE_VBR;
|
|
349 else if (!strcmp (pvr_param_bitrate_mode, PVR_VIDEO_BITRATE_MODE_ARG_CBR))
|
|
350 pvr->bitrate_mode = PVR_VIDEO_BITRATE_MODE_CBR;
|
|
351 else /* for anything else, set to VBR */
|
|
352 pvr->bitrate_mode = PVR_VIDEO_BITRATE_MODE_VBR;
|
|
353 }
|
|
354
|
|
355 /* -pvr vpeak=x */
|
|
356 if (pvr_param_bitrate_peak)
|
|
357 pvr->bitrate_peak = pvr_param_bitrate_peak;
|
|
358
|
|
359 /* -pvr fmt=x */
|
|
360 if (pvr_param_stream_type)
|
|
361 {
|
|
362 if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_PS))
|
|
363 pvr->stream_type = IVTV_STREAM_PS;
|
|
364 else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_TS))
|
|
365 pvr->stream_type = IVTV_STREAM_TS;
|
|
366 else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_MPEG1))
|
|
367 pvr->stream_type = IVTV_STREAM_MPEG1;
|
|
368 else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_DVD))
|
|
369 pvr->stream_type = IVTV_STREAM_DVD;
|
|
370 else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_VCD))
|
|
371 pvr->stream_type = IVTV_STREAM_VCD;
|
|
372 else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_SVCD))
|
|
373 pvr->stream_type = IVTV_STREAM_SVCD;
|
|
374 else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_DVD_S1))
|
|
375 pvr->stream_type = IVTV_STREAM_DVD_S1;
|
|
376 else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_DVD_S2))
|
|
377 pvr->stream_type = IVTV_STREAM_DVD_S2;
|
|
378 else /* for anything else, set to MPEG PS */
|
|
379 pvr->stream_type = IVTV_STREAM_PS;
|
|
380 }
|
|
381 }
|
|
382
|
|
383 static int
|
|
384 set_ivtv_settings (struct pvr_t *pvr)
|
|
385 {
|
|
386 struct ivtv_ioctl_codec codec;
|
|
387
|
|
388 if (!pvr)
|
|
389 return -1;
|
|
390
|
|
391 if (pvr->dev_fd < 0)
|
|
392 return -1;
|
|
393
|
|
394 /* get current settings */
|
|
395 if (ioctl (pvr->dev_fd, IVTV_IOC_G_CODEC, &codec) < 0)
|
|
396 {
|
|
397 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
398 "%s can't get codec (%s).\n", LOG_LEVEL_IVTV, strerror (errno));
|
|
399 return -1;
|
|
400 }
|
|
401
|
|
402 /* set default encoding settings
|
|
403 * may be overlapped by user parameters
|
|
404 * Use VBR MPEG_PS encoding at 6 Mbps (peak at 9.6 Mbps)
|
|
405 * with 48 KHz L2 384 kbps audio.
|
|
406 */
|
|
407 codec.aspect = PVR_ASPECT_RATIO_4_3;
|
|
408 codec.bitrate_mode = PVR_VIDEO_BITRATE_MODE_VBR;
|
|
409 codec.bitrate = 6000000;
|
|
410 codec.bitrate_peak = 9600000;
|
|
411 codec.stream_type = IVTV_STREAM_PS;
|
|
412 codec.audio_bitmask = PVR_AUDIO_LAYER_2
|
|
413 | PVR_AUDIO_BITRATE_L2_384 | PVR_AUDIO_SAMPLE_RATE_48_KHZ;
|
|
414
|
|
415 /* set aspect ratio */
|
|
416 if (pvr->aspect != -1)
|
|
417 codec.aspect = pvr->aspect;
|
|
418
|
|
419 /* if user value is given, we need to reset audio bitmask */
|
|
420 if ((pvr->samplerate != -1) || (pvr->layer != -1)
|
|
421 || (pvr->audio_rate != -1) || (pvr->audio_mode != -1))
|
|
422 codec.audio_bitmask = 0;
|
|
423
|
|
424 /* set audio samplerate */
|
|
425 if (pvr->samplerate != -1)
|
|
426 codec.audio_bitmask |= pvr->samplerate;
|
|
427
|
|
428 /* set audio layer */
|
|
429 if (pvr->layer != -1)
|
|
430 codec.audio_bitmask |= pvr->layer;
|
|
431
|
|
432 /* set audio bitrate */
|
|
433 if (pvr->audio_rate != -1)
|
|
434 codec.audio_bitmask |= pvr->audio_rate;
|
|
435
|
|
436 /* set audio mode */
|
|
437 if (pvr->audio_mode != -1)
|
|
438 codec.audio_bitmask |= pvr->audio_mode;
|
|
439
|
|
440 /* set video bitrate */
|
|
441 if (pvr->bitrate != -1)
|
|
442 codec.bitrate = pvr->bitrate;
|
|
443
|
|
444 /* set video bitrate mode */
|
|
445 if (pvr->bitrate_mode != -1)
|
|
446 codec.bitrate_mode = pvr->bitrate_mode;
|
|
447
|
|
448 /* set video bitrate peak */
|
|
449 if (pvr->bitrate != -1)
|
|
450 codec.bitrate_peak = pvr->bitrate_peak;
|
|
451
|
|
452 /* set video stream type */
|
|
453 if (pvr->stream_type != -1)
|
|
454 codec.stream_type = pvr->stream_type;
|
|
455
|
|
456 /* set new encoding settings */
|
|
457 if (ioctl (pvr->dev_fd, IVTV_IOC_S_CODEC, &codec) < 0)
|
|
458 {
|
|
459 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
460 "%s can't set codec (%s).\n", LOG_LEVEL_IVTV, strerror (errno));
|
|
461 return -1;
|
|
462 }
|
|
463
|
|
464 return 0;
|
|
465 }
|
|
466
|
|
467 /* V4L2 layer */
|
|
468
|
|
469 static void
|
|
470 parse_v4l2_tv_options (struct pvr_t *pvr)
|
|
471 {
|
|
472 if (!pvr)
|
|
473 return;
|
|
474
|
|
475 if (tv_param_device)
|
|
476 {
|
|
477 if (pvr->video_dev)
|
|
478 free (pvr->video_dev);
|
|
479 pvr->video_dev = strdup (tv_param_device);
|
|
480 }
|
|
481
|
|
482 if (tv_param_noaudio)
|
|
483 pvr->mute = tv_param_noaudio;
|
|
484
|
|
485 if (tv_param_input)
|
|
486 pvr->input = tv_param_input;
|
|
487
|
|
488 if (tv_param_normid)
|
|
489 pvr->normid = tv_param_normid;
|
|
490
|
|
491 if (tv_param_brightness)
|
|
492 pvr->brightness = tv_param_brightness;
|
|
493
|
|
494 if (tv_param_contrast)
|
|
495 pvr->contrast = tv_param_contrast;
|
|
496
|
|
497 if (tv_param_hue)
|
|
498 pvr->hue = tv_param_hue;
|
|
499
|
|
500 if (tv_param_saturation)
|
|
501 pvr->saturation = tv_param_saturation;
|
|
502
|
|
503 if (tv_param_width)
|
|
504 pvr->width = tv_param_width;
|
|
505
|
|
506 if (tv_param_height)
|
|
507 pvr->height = tv_param_height;
|
|
508
|
|
509 if (tv_param_freq)
|
|
510 pvr->freq = strdup (tv_param_freq);
|
|
511 }
|
|
512
|
|
513 static int
|
|
514 set_v4l2_settings (struct pvr_t *pvr)
|
|
515 {
|
|
516 if (!pvr)
|
|
517 return -1;
|
|
518
|
|
519 if (pvr->dev_fd < 0)
|
|
520 return -1;
|
|
521
|
|
522 /* -tv noaudio */
|
|
523 if (pvr->mute)
|
|
524 {
|
|
525 struct v4l2_control ctrl;
|
|
526 ctrl.id = V4L2_CID_AUDIO_MUTE;
|
|
527 ctrl.value = 1;
|
|
528 if (ioctl (pvr->dev_fd, VIDIOC_S_CTRL, &ctrl) < 0)
|
|
529 {
|
|
530 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
531 "%s can't mute (%s).\n", LOG_LEVEL_V4L2, strerror (errno));
|
|
532 return -1;
|
|
533 }
|
|
534 }
|
|
535
|
|
536 /* -tv input=x */
|
|
537 if (pvr->input != 0)
|
|
538 {
|
|
539 if (ioctl (pvr->dev_fd, VIDIOC_S_INPUT, &pvr->input) < 0)
|
|
540 {
|
|
541 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
542 "%s can't set input (%s)\n", LOG_LEVEL_V4L2, strerror (errno));
|
|
543 return -1;
|
|
544 }
|
|
545 }
|
|
546
|
|
547 /* -tv normid=x */
|
|
548 if (pvr->normid != -1)
|
|
549 {
|
|
550 struct v4l2_standard std;
|
|
551 std.index = pvr->normid;
|
|
552
|
|
553 if (ioctl (pvr->dev_fd, VIDIOC_ENUMSTD, &std) < 0)
|
|
554 {
|
|
555 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
556 "%s can't set norm (%s)\n", LOG_LEVEL_V4L2, strerror (errno));
|
|
557 return -1;
|
|
558 }
|
|
559
|
|
560 mp_msg (MSGT_OPEN, MSGL_V,
|
|
561 "%s set norm to %s\n", LOG_LEVEL_V4L2, std.name);
|
|
562
|
|
563 if (ioctl (pvr->dev_fd, VIDIOC_S_STD, &std.id) < 0)
|
|
564 {
|
|
565 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
566 "%s can't set norm (%s)\n", LOG_LEVEL_V4L2, strerror (errno));
|
|
567 return -1;
|
|
568 }
|
|
569 }
|
|
570
|
|
571 /* -tv brightness=x */
|
|
572 if (pvr->brightness != 0)
|
|
573 {
|
|
574 struct v4l2_control ctrl;
|
|
575 ctrl.id = V4L2_CID_BRIGHTNESS;
|
|
576 ctrl.value = pvr->brightness;
|
|
577
|
|
578 if (ctrl.value < 0)
|
|
579 ctrl.value = 0;
|
|
580 if (ctrl.value > 255)
|
|
581 ctrl.value = 255;
|
|
582
|
|
583 if (ioctl (pvr->dev_fd, VIDIOC_S_CTRL, &ctrl) < 0)
|
|
584 {
|
|
585 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
586 "%s can't set brightness to %d (%s).\n",
|
|
587 LOG_LEVEL_V4L2, ctrl.value, strerror (errno));
|
|
588 return -1;
|
|
589 }
|
|
590 }
|
|
591
|
|
592 /* -tv contrast=x */
|
|
593 if (pvr->contrast != 0)
|
|
594 {
|
|
595 struct v4l2_control ctrl;
|
|
596 ctrl.id = V4L2_CID_CONTRAST;
|
|
597 ctrl.value = pvr->contrast;
|
|
598
|
|
599 if (ctrl.value < 0)
|
|
600 ctrl.value = 0;
|
|
601 if (ctrl.value > 127)
|
|
602 ctrl.value = 127;
|
|
603
|
|
604 if (ioctl (pvr->dev_fd, VIDIOC_S_CTRL, &ctrl) < 0)
|
|
605 {
|
|
606 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
607 "%s can't set contrast to %d (%s).\n",
|
|
608 LOG_LEVEL_V4L2, ctrl.value, strerror (errno));
|
|
609 return -1;
|
|
610 }
|
|
611 }
|
|
612
|
|
613 /* -tv hue=x */
|
|
614 if (pvr->hue != 0)
|
|
615 {
|
|
616 struct v4l2_control ctrl;
|
|
617 ctrl.id = V4L2_CID_HUE;
|
|
618 ctrl.value = pvr->hue;
|
|
619
|
|
620 if (ctrl.value < -128)
|
|
621 ctrl.value = -128;
|
|
622 if (ctrl.value > 127)
|
|
623 ctrl.value = 127;
|
|
624
|
|
625 if (ioctl (pvr->dev_fd, VIDIOC_S_CTRL, &ctrl) < 0)
|
|
626 {
|
|
627 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
628 "%s can't set hue to %d (%s).\n",
|
|
629 LOG_LEVEL_V4L2, ctrl.value, strerror (errno));
|
|
630 return -1;
|
|
631 }
|
|
632 }
|
|
633
|
|
634 /* -tv saturation=x */
|
|
635 if (pvr->saturation != 0)
|
|
636 {
|
|
637 struct v4l2_control ctrl;
|
|
638 ctrl.id = V4L2_CID_SATURATION;
|
|
639 ctrl.value = pvr->saturation;
|
|
640
|
|
641 if (ctrl.value < 0)
|
|
642 ctrl.value = 0;
|
|
643 if (ctrl.value > 127)
|
|
644 ctrl.value = 127;
|
|
645
|
|
646 if (ioctl (pvr->dev_fd, VIDIOC_S_CTRL, &ctrl) < 0)
|
|
647 {
|
|
648 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
649 "%s can't set saturation to %d (%s).\n",
|
|
650 LOG_LEVEL_V4L2, ctrl.value, strerror (errno));
|
|
651 return -1;
|
|
652 }
|
|
653 }
|
|
654
|
|
655 /* -tv width=x:height=y */
|
|
656 if (pvr->width && pvr->height)
|
|
657 {
|
|
658 struct v4l2_format vfmt;
|
|
659 vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
660 vfmt.fmt.pix.width = pvr->width;
|
|
661 vfmt.fmt.pix.height = pvr->height;
|
|
662
|
|
663 if (ioctl (pvr->dev_fd, VIDIOC_S_FMT, &vfmt) < 0)
|
|
664 {
|
|
665 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
666 "%s can't set resolution to %dx%d (%s).\n",
|
|
667 LOG_LEVEL_V4L2, pvr->width, pvr->height, strerror (errno));
|
|
668 return -1;
|
|
669 }
|
|
670 }
|
|
671
|
|
672 /* -tv freq=x */
|
|
673 if (pvr->freq)
|
|
674 {
|
|
675 struct v4l2_frequency vf;
|
|
676 vf.tuner = 0;
|
|
677 vf.type = 0;
|
|
678 vf.frequency = strtol (pvr->freq, 0L, 0);
|
|
679 mp_msg (MSGT_OPEN, MSGL_INFO,
|
|
680 "%s setting frequency to %d\n", LOG_LEVEL_V4L2, vf.frequency);
|
|
681
|
|
682 if (ioctl (pvr->dev_fd, VIDIOC_S_FREQUENCY, &vf) < 0)
|
|
683 {
|
|
684 mp_msg (MSGT_OPEN, MSGL_ERR, "%s can't set frequency (%s).\n",
|
|
685 LOG_LEVEL_V4L2, strerror (errno));
|
|
686 return -1;
|
|
687 }
|
|
688 }
|
|
689
|
|
690 return 0;
|
|
691 }
|
|
692
|
|
693 static int
|
|
694 v4l2_list_capabilities (struct pvr_t *pvr)
|
|
695 {
|
|
696 struct v4l2_audio vaudio;
|
|
697 struct v4l2_standard vs;
|
|
698 struct v4l2_input vin;
|
|
699 int err = 0;
|
|
700
|
|
701 if (!pvr)
|
|
702 return -1;
|
|
703
|
|
704 if (pvr->dev_fd < 0)
|
|
705 return -1;
|
|
706
|
|
707 /* list available video inputs */
|
|
708 vin.index = 0;
|
|
709 err = 1;
|
|
710 mp_msg (MSGT_OPEN, MSGL_INFO,
|
|
711 "%s Available video inputs: ", LOG_LEVEL_V4L2);
|
|
712 while (ioctl (pvr->dev_fd, VIDIOC_ENUMINPUT, &vin) >= 0)
|
|
713 {
|
|
714 err = 0;
|
|
715 mp_msg (MSGT_OPEN, MSGL_INFO, "'#%d, %s' ", vin.index, vin.name);
|
|
716 vin.index++;
|
|
717 }
|
|
718 if (err)
|
|
719 {
|
|
720 mp_msg (MSGT_OPEN, MSGL_INFO, "none\n");
|
|
721 return -1;
|
|
722 }
|
|
723 else
|
|
724 mp_msg (MSGT_OPEN, MSGL_INFO, "\n");
|
|
725
|
|
726 /* list available audio inputs */
|
|
727 vaudio.index = 0;
|
|
728 err = 1;
|
|
729 mp_msg (MSGT_OPEN, MSGL_INFO,
|
|
730 "%s Available audio inputs: ", LOG_LEVEL_V4L2);
|
|
731 while (ioctl (pvr->dev_fd, VIDIOC_ENUMAUDIO, &vaudio) >= 0)
|
|
732 {
|
|
733 err = 0;
|
|
734 mp_msg (MSGT_OPEN, MSGL_INFO, "'#%d, %s' ", vaudio.index, vaudio.name);
|
|
735 vaudio.index++;
|
|
736 }
|
|
737 if (err)
|
|
738 {
|
|
739 mp_msg (MSGT_OPEN, MSGL_INFO, "none\n");
|
|
740 return -1;
|
|
741 }
|
|
742 else
|
|
743 mp_msg (MSGT_OPEN, MSGL_INFO, "\n");
|
|
744
|
|
745 /* list available norms */
|
|
746 vs.index = 0;
|
|
747 mp_msg (MSGT_OPEN, MSGL_INFO, "%s Available norms: ", LOG_LEVEL_V4L2);
|
|
748 while (ioctl (pvr->dev_fd, VIDIOC_ENUMSTD, &vs) >= 0)
|
|
749 {
|
|
750 err = 0;
|
|
751 mp_msg (MSGT_OPEN, MSGL_INFO, "'#%d, %s' ", vs.index, vs.name);
|
|
752 vs.index++;
|
|
753 }
|
|
754 if (err)
|
|
755 {
|
|
756 mp_msg (MSGT_OPEN, MSGL_INFO, "none\n");
|
|
757 return -1;
|
|
758 }
|
|
759 else
|
|
760 mp_msg (MSGT_OPEN, MSGL_INFO, "\n");
|
|
761
|
|
762 return 0;
|
|
763 }
|
|
764
|
|
765 static int
|
|
766 v4l2_display_settings (struct pvr_t *pvr)
|
|
767 {
|
|
768 struct v4l2_audio vaudio;
|
|
769 struct v4l2_standard vs;
|
|
770 struct v4l2_input vin;
|
|
771 v4l2_std_id std;
|
|
772 int input;
|
|
773
|
|
774 if (!pvr)
|
|
775 return -1;
|
|
776
|
|
777 if (pvr->dev_fd < 0)
|
|
778 return -1;
|
|
779
|
|
780 /* get current video input */
|
|
781 if (ioctl (pvr->dev_fd, VIDIOC_G_INPUT, &input) == 0)
|
|
782 {
|
|
783 vin.index = input;
|
|
784 if (ioctl (pvr->dev_fd, VIDIOC_ENUMINPUT, &vin) < 0)
|
|
785 {
|
|
786 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
787 "%s can't get input (%s).\n", LOG_LEVEL_V4L2, strerror (errno));
|
|
788 return -1;
|
|
789 }
|
|
790 else
|
|
791 mp_msg (MSGT_OPEN, MSGL_INFO,
|
|
792 "%s Video input: %s\n", LOG_LEVEL_V4L2, vin.name);
|
|
793 }
|
|
794 else
|
|
795 {
|
|
796 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
797 "%s can't get input (%s).\n", LOG_LEVEL_V4L2, strerror (errno));
|
|
798 return -1;
|
|
799 }
|
|
800
|
|
801 /* get current audio input */
|
|
802 if (ioctl (pvr->dev_fd, VIDIOC_G_AUDIO, &vaudio) == 0)
|
|
803 {
|
|
804 vaudio.index = input;
|
|
805 if (ioctl (pvr->dev_fd, VIDIOC_ENUMAUDIO, &vaudio) < 0)
|
|
806 {
|
|
807 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
808 "%s can't get input (%s).\n", LOG_LEVEL_V4L2, strerror (errno));
|
|
809 return -1;
|
|
810 }
|
|
811 else
|
|
812 mp_msg (MSGT_OPEN, MSGL_INFO,
|
|
813 "%s Audio input: %s\n", LOG_LEVEL_V4L2, vaudio.name);
|
|
814 }
|
|
815 else
|
|
816 {
|
|
817 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
818 "%s can't get input (%s).\n", LOG_LEVEL_V4L2, strerror (errno));
|
|
819 return -1;
|
|
820 }
|
|
821
|
|
822 /* get current video format */
|
|
823 if (ioctl (pvr->dev_fd, VIDIOC_G_STD, &std) == 0)
|
|
824 {
|
|
825 vs.index = 0;
|
|
826
|
|
827 while (ioctl (pvr->dev_fd, VIDIOC_ENUMSTD, &vs) >= 0)
|
|
828 {
|
|
829 if (vs.id == std)
|
|
830 {
|
|
831 mp_msg (MSGT_OPEN, MSGL_INFO,
|
|
832 "%s Norm: %s.\n", LOG_LEVEL_V4L2, vs.name);
|
|
833 break;
|
|
834 }
|
|
835 vs.index++;
|
|
836 }
|
|
837 }
|
|
838 else
|
|
839 {
|
|
840 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
841 "%s can't get norm (%s)\n", LOG_LEVEL_V4L2, strerror (errno));
|
|
842 return -1;
|
|
843 }
|
|
844
|
|
845 return 0;
|
|
846 }
|
|
847
|
|
848 /* stream layer */
|
|
849
|
|
850 static void
|
|
851 pvr_stream_close (stream_t *stream)
|
|
852 {
|
|
853 struct pvr_t *pvr;
|
|
854
|
|
855 if (!stream)
|
|
856 return;
|
|
857
|
|
858 pvr = (struct pvr_t *) stream->priv;
|
|
859 pvr_uninit (pvr);
|
|
860 }
|
|
861
|
|
862 static int
|
|
863 pvr_stream_read (stream_t *stream, char *buffer, int size)
|
|
864 {
|
|
865 struct pollfd pfds[1];
|
|
866 struct pvr_t *pvr;
|
|
867 int rk, fd, pos;
|
|
868
|
|
869 if (!stream || !buffer)
|
|
870 return 0;
|
|
871
|
|
872 pvr = (struct pvr_t *) stream->priv;
|
|
873 fd = pvr->dev_fd;
|
|
874 pos = 0;
|
|
875
|
|
876 if (fd < 0)
|
|
877 return 0;
|
|
878
|
|
879 while (pos < size)
|
|
880 {
|
|
881 pfds[0].fd = fd;
|
|
882 pfds[0].events = POLLIN | POLLPRI;
|
|
883
|
|
884 rk = size - pos;
|
|
885
|
|
886 if (poll (pfds, 1, 500) <= 0)
|
|
887 {
|
|
888 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
889 "%s failed with errno %d when reading %d bytes\n",
|
|
890 LOG_LEVEL_PVR, errno, size-pos);
|
|
891 break;
|
|
892 }
|
|
893
|
|
894 rk = read (fd, &buffer[pos], rk);
|
|
895 if (rk > 0)
|
|
896 {
|
|
897 pos += rk;
|
|
898 mp_msg (MSGT_OPEN, MSGL_DBG3,
|
|
899 "%s read (%d) bytes\n", LOG_LEVEL_PVR, pos);
|
|
900 }
|
|
901 }
|
|
902
|
|
903 if (!pos)
|
|
904 mp_msg (MSGT_OPEN, MSGL_ERR, "%s read %d bytes\n", LOG_LEVEL_PVR, pos);
|
|
905
|
|
906 return pos;
|
|
907 }
|
|
908
|
|
909 static int
|
|
910 pvr_stream_open (stream_t *stream, int mode, void *opts, int *file_format)
|
|
911 {
|
|
912 struct ivtv_ioctl_codec codec;
|
|
913 struct ivtv_driver_info info;
|
|
914 struct v4l2_capability vcap;
|
|
915 struct pvr_t *pvr = NULL;
|
|
916
|
|
917 if (mode != STREAM_READ)
|
|
918 return STREAM_UNSUPORTED;
|
|
919
|
|
920 pvr = pvr_init ();
|
|
921
|
|
922 parse_v4l2_tv_options (pvr);
|
|
923 parse_ivtv_options (pvr);
|
|
924
|
|
925 /* open device */
|
|
926 pvr->dev_fd = open (pvr->video_dev, O_RDWR);
|
|
927 mp_msg (MSGT_OPEN, MSGL_INFO,
|
|
928 "%s Using device %s\n", LOG_LEVEL_PVR, pvr->video_dev);
|
|
929 if (pvr->dev_fd == -1)
|
|
930 {
|
|
931 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
932 "%s error opening device %s\n", LOG_LEVEL_PVR, pvr->video_dev);
|
|
933 pvr_uninit (pvr);
|
|
934 return STREAM_ERROR;
|
|
935 }
|
|
936
|
|
937 /* query capabilities (i.e test V4L2 support) */
|
|
938 if (ioctl (pvr->dev_fd, VIDIOC_QUERYCAP, &vcap) < 0)
|
|
939 {
|
|
940 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
941 "%s device is not V4L2 compliant (%s).\n",
|
|
942 LOG_LEVEL_PVR, strerror (errno));
|
|
943 pvr_uninit (pvr);
|
|
944 return STREAM_ERROR;
|
|
945 }
|
|
946 else
|
|
947 mp_msg (MSGT_OPEN, MSGL_INFO,
|
|
948 "%s Detected %s\n", LOG_LEVEL_PVR, vcap.card);
|
|
949
|
|
950 /* get codec and initialize card (i.e test IVTV support) */
|
|
951 if (ioctl (pvr->dev_fd, IVTV_IOC_G_CODEC, &codec) < 0)
|
|
952 {
|
|
953 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
954 "%s device is not IVTV compliant (%s).\n",
|
|
955 LOG_LEVEL_PVR, strerror (errno));
|
|
956 pvr_uninit (pvr);
|
|
957 return STREAM_ERROR;
|
|
958 }
|
|
959
|
|
960 /* get ivtv driver info */
|
|
961 if (ioctl (pvr->dev_fd, IVTV_IOC_G_DRIVER_INFO, &info) < 0)
|
|
962 {
|
|
963 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
964 "%s device is not IVTV compliant (%s).\n",
|
|
965 LOG_LEVEL_PVR, strerror (errno));
|
|
966 pvr_uninit (pvr);
|
|
967 return STREAM_ERROR;
|
|
968 }
|
|
969 else
|
|
970 mp_msg (MSGT_OPEN, MSGL_INFO,
|
|
971 "%s Detected ivtv driver: %s\n", LOG_LEVEL_PVR, info.comment);
|
|
972
|
|
973 /* list V4L2 capabilities */
|
|
974 if (v4l2_list_capabilities (pvr) == -1)
|
|
975 {
|
|
976 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
977 "%s can't get v4l2 capabilities\n", LOG_LEVEL_PVR);
|
|
978 pvr_uninit (pvr);
|
|
979 return STREAM_ERROR;
|
|
980 }
|
|
981
|
|
982 /* apply V4L2 settings */
|
|
983 if (set_v4l2_settings (pvr) == -1)
|
|
984 {
|
|
985 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
986 "%s can't set v4l2 settings\n", LOG_LEVEL_PVR);
|
|
987 pvr_uninit (pvr);
|
|
988 return STREAM_ERROR;
|
|
989 }
|
|
990
|
|
991 /* apply IVTV settings */
|
|
992 if (set_ivtv_settings (pvr) == -1)
|
|
993 {
|
|
994 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
995 "%s can't set ivtv settings\n", LOG_LEVEL_PVR);
|
|
996 pvr_uninit (pvr);
|
|
997 return STREAM_ERROR;
|
|
998 }
|
|
999
|
|
1000 /* display current V4L2 settings */
|
|
1001 if (v4l2_display_settings (pvr) == -1)
|
|
1002 {
|
|
1003 mp_msg (MSGT_OPEN, MSGL_ERR,
|
|
1004 "%s can't get v4l2 settings\n", LOG_LEVEL_PVR);
|
|
1005 pvr_uninit (pvr);
|
|
1006 return STREAM_ERROR;
|
|
1007 }
|
|
1008
|
|
1009 stream->priv = pvr;
|
|
1010 stream->type = STREAMTYPE_PVR;
|
|
1011 stream->fill_buffer = pvr_stream_read;
|
|
1012 stream->close = pvr_stream_close;
|
|
1013
|
|
1014 return STREAM_OK;
|
|
1015 }
|
|
1016
|
|
1017 stream_info_t stream_info_pvr = {
|
|
1018 "PVR (V4L2/IVTV) Input",
|
|
1019 "pvr",
|
|
1020 "Benjamin Zores",
|
|
1021 "",
|
|
1022 pvr_stream_open,
|
|
1023 { "pvr", NULL },
|
|
1024 NULL,
|
|
1025 1
|
|
1026 };
|