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