Mercurial > mplayer.hg
comparison libmpdemux/stream_pvr.c @ 18997:73b8f5ff772d
added new pvr:// input for ivtv based cards
author | ben |
---|---|
date | Mon, 10 Jul 2006 21:32:19 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
18996:49f158e94fce | 18997:73b8f5ff772d |
---|---|
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 }; |