Mercurial > mplayer.hg
annotate libmpdemux/tvi_v4l.c @ 7030:660a8439c679
10l
author | michael |
---|---|
date | Fri, 16 Aug 2002 22:39:02 +0000 |
parents | d000112bd06e |
children | 2e5c07262861 |
rev | line source |
---|---|
2802 | 1 /* |
3284 | 2 Video 4 Linux input |
2802 | 3 |
4 (C) Alex Beregszaszi <alex@naxine.org> | |
5 | |
6 Some ideas are based on xawtv/libng's grab-v4l.c written by | |
7 Gerd Knorr <kraxel@bytesex.org> | |
8 | |
9 CODE IS UNDER DEVELOPMENT, NO FEATURE REQUESTS PLEASE! | |
10 */ | |
11 | |
2790 | 12 #include "config.h" |
13 | |
3243 | 14 #if defined(USE_TV) && defined(HAVE_TV_V4L) |
2790 | 15 |
16 #include <stdio.h> | |
17 #include <errno.h> | |
18 #include <fcntl.h> | |
2802 | 19 #include <signal.h> |
2790 | 20 #include <sys/ioctl.h> |
21 #include <sys/types.h> | |
6553
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
22 #include <sys/time.h> |
2790 | 23 #include <linux/videodev.h> |
3815 | 24 #include <linux/soundcard.h> |
2790 | 25 #include <unistd.h> |
26 #include <sys/mman.h> | |
2931 | 27 #include <stdlib.h> |
28 #include <string.h> | |
2790 | 29 |
2830 | 30 #include "mp_msg.h" |
31 #include "../libao2/afmt.h" | |
32 #include "../libvo/img_format.h" | |
33 #include "../libvo/fastmemcpy.h" | |
34 | |
2790 | 35 #include "tv.h" |
36 | |
37 static tvi_info_t info = { | |
3815 | 38 "Video 4 Linux input", |
2790 | 39 "v4l", |
2802 | 40 "Alex Beregszaszi <alex@naxine.org>", |
41 "under development" | |
42 }; | |
43 | |
3815 | 44 #define MAX_AUDIO_CHANNELS 10 |
45 | |
2790 | 46 typedef struct { |
2802 | 47 /* general */ |
2790 | 48 char *video_device; |
3815 | 49 int video_fd; |
2790 | 50 struct video_capability capability; |
51 struct video_channel *channels; | |
2841 | 52 int act_channel; |
2790 | 53 struct video_tuner tuner; |
2802 | 54 |
55 /* video */ | |
2790 | 56 struct video_picture picture; |
2802 | 57 int format; /* output format */ |
2790 | 58 int width; |
59 int height; | |
2802 | 60 int bytesperline; |
5941 | 61 int fps; |
2802 | 62 |
63 struct video_mbuf mbuf; | |
64 unsigned char *mmap; | |
65 struct video_mmap *buf; | |
66 int nbuf; | |
67 int queue; | |
68 | |
69 /* audio */ | |
3815 | 70 int audio_id; |
71 char *audio_device; | |
72 struct video_audio audio[MAX_AUDIO_CHANNELS]; | |
73 int audio_fd; | |
74 int audio_channels[MAX_AUDIO_CHANNELS]; | |
75 int audio_format[MAX_AUDIO_CHANNELS]; | |
76 int audio_samplesize[MAX_AUDIO_CHANNELS]; | |
77 int audio_samplerate[MAX_AUDIO_CHANNELS]; | |
78 int audio_blocksize; | |
6553
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
79 |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
80 /* other */ |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
81 double starttime; |
2790 | 82 } priv_t; |
83 | |
84 #include "tvi_def.h" | |
85 | |
2841 | 86 static const char *device_cap2name[] = { |
2790 | 87 "capture", "tuner", "teletext", "overlay", "chromakey", "clipping", |
2802 | 88 "frameram", "scales", "monochrome", "subcapture", "mpeg-decoder", |
89 "mpeg-encoder", "mjpeg-decoder", "mjpeg-encoder", NULL | |
90 }; | |
91 | |
2841 | 92 static const char *device_palette2name[] = { |
2802 | 93 "-", "grey", "hi240", "rgb16", "rgb24", "rgb32", "rgb15", "yuv422", |
94 "yuyv", "uyvy", "yuv420", "yuv411", "raw", "yuv422p", "yuv411p", | |
95 "yuv420p", "yuv410p", NULL | |
96 }; | |
97 #define PALETTE(x) ((x < sizeof(device_pal)/sizeof(char*)) ? device_pal[x] : "UNKNOWN") | |
98 | |
2841 | 99 static const char *audio_mode2name[] = { |
100 "unknown", "mono", "stereo", "language1", "language2", NULL | |
101 }; | |
102 | |
2802 | 103 static int palette2depth(int palette) |
104 { | |
2810 | 105 switch(palette) |
106 { | |
3220 | 107 /* component */ |
2810 | 108 case VIDEO_PALETTE_RGB555: |
109 return(15); | |
110 case VIDEO_PALETTE_RGB565: | |
111 return(16); | |
112 case VIDEO_PALETTE_RGB24: | |
113 return(24); | |
114 case VIDEO_PALETTE_RGB32: | |
115 return(32); | |
3220 | 116 /* planar */ |
117 case VIDEO_PALETTE_YUV411P: | |
2810 | 118 case VIDEO_PALETTE_YUV420P: |
3220 | 119 case VIDEO_PALETTE_YUV410P: |
2810 | 120 return(12); |
3220 | 121 /* packed */ |
3815 | 122 case VIDEO_PALETTE_YUV422P: |
2810 | 123 case VIDEO_PALETTE_YUV422: |
3220 | 124 case VIDEO_PALETTE_YUYV: |
2810 | 125 case VIDEO_PALETTE_UYVY: |
3220 | 126 case VIDEO_PALETTE_YUV420: |
127 case VIDEO_PALETTE_YUV411: | |
2810 | 128 return(16); |
129 } | |
130 return(-1); | |
2802 | 131 } |
132 | |
133 static int format2palette(int format) | |
134 { | |
2810 | 135 switch(format) |
136 { | |
137 case IMGFMT_RGB15: | |
138 return(VIDEO_PALETTE_RGB555); | |
139 case IMGFMT_RGB16: | |
140 return(VIDEO_PALETTE_RGB565); | |
141 case IMGFMT_RGB24: | |
142 return(VIDEO_PALETTE_RGB24); | |
143 case IMGFMT_RGB32: | |
144 return(VIDEO_PALETTE_RGB32); | |
145 case IMGFMT_YV12: | |
3703 | 146 case IMGFMT_I420: |
2810 | 147 return(VIDEO_PALETTE_YUV420P); |
148 case IMGFMT_UYVY: | |
149 return(VIDEO_PALETTE_YUV422); | |
3815 | 150 case IMGFMT_YUY2: |
151 return(VIDEO_PALETTE_YUYV); | |
2810 | 152 } |
153 return(-1); | |
2802 | 154 } |
155 | |
156 static int one = 1, zero = 0; | |
157 | |
2790 | 158 tvi_handle_t *tvi_init_v4l(char *device) |
159 { | |
160 tvi_handle_t *h; | |
161 priv_t *priv; | |
162 | |
163 h = new_handle(); | |
164 if (!h) | |
165 return(NULL); | |
166 | |
167 priv = h->priv; | |
168 | |
2802 | 169 /* set video device name */ |
2790 | 170 if (!device) |
5088 | 171 priv->video_device = strdup("/dev/video"); |
2790 | 172 else |
3611 | 173 priv->video_device = strdup(device); |
174 | |
175 /* allocation failed */ | |
176 if (!priv->video_device) { | |
177 free_handle(h); | |
178 return(NULL); | |
2790 | 179 } |
180 | |
3815 | 181 /* set audio device name */ |
5941 | 182 priv->audio_device = strdup("/dev/dsp"); |
3815 | 183 |
2790 | 184 return(h); |
185 } | |
186 | |
3815 | 187 static int init(priv_t *priv) |
2790 | 188 { |
189 int i; | |
190 | |
3815 | 191 priv->video_fd = open(priv->video_device, O_RDWR); |
5088 | 192 mp_msg(MSGT_TV, MSGL_DBG2, "Video fd: %d, %x\n", priv->video_fd, |
193 priv->video_device); | |
3815 | 194 if (priv->video_fd == -1) |
2790 | 195 { |
2818 | 196 mp_msg(MSGT_TV, MSGL_ERR, "unable to open '%s': %s\n", |
2802 | 197 priv->video_device, strerror(errno)); |
2790 | 198 goto err; |
199 } | |
5941 | 200 |
201 priv->fps = 25; /* pal */ | |
2790 | 202 |
2802 | 203 /* get capabilities (priv->capability is needed!) */ |
3815 | 204 if (ioctl(priv->video_fd, VIDIOCGCAP, &priv->capability) == -1) |
2790 | 205 { |
2818 | 206 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get capabilites failed: %s\n", strerror(errno)); |
2790 | 207 goto err; |
208 } | |
209 | |
3815 | 210 fcntl(priv->video_fd, F_SETFD, FD_CLOEXEC); |
2802 | 211 |
2818 | 212 mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.name); |
213 mp_msg(MSGT_TV, MSGL_INFO, " Capabilites: "); | |
2841 | 214 for (i = 0; device_cap2name[i] != NULL; i++) |
2790 | 215 if (priv->capability.type & (1 << i)) |
2841 | 216 mp_msg(MSGT_TV, MSGL_INFO, "%s ", device_cap2name[i]); |
2818 | 217 mp_msg(MSGT_TV, MSGL_INFO, "\n"); |
218 mp_msg(MSGT_TV, MSGL_INFO, " Device type: %d\n", priv->capability.type); | |
219 mp_msg(MSGT_TV, MSGL_INFO, " Supported sizes: %dx%d => %dx%d\n", | |
2790 | 220 priv->capability.minwidth, priv->capability.minheight, |
221 priv->capability.maxwidth, priv->capability.maxheight); | |
222 priv->width = priv->capability.minwidth; | |
223 priv->height = priv->capability.minheight; | |
2818 | 224 mp_msg(MSGT_TV, MSGL_INFO, " Inputs: %d\n", priv->capability.channels); |
2790 | 225 |
2819
2e58962dc9fe
cleaned up some warnings, and tv_param_on moved out from #ifdef USE_TV
alex
parents:
2818
diff
changeset
|
226 priv->channels = (struct video_channel *)malloc(sizeof(struct video_channel)*priv->capability.channels); |
3611 | 227 if (!priv->channels) |
228 goto malloc_failed; | |
2790 | 229 memset(priv->channels, 0, sizeof(struct video_channel)*priv->capability.channels); |
230 for (i = 0; i < priv->capability.channels; i++) | |
231 { | |
232 priv->channels[i].channel = i; | |
3815 | 233 if (ioctl(priv->video_fd, VIDIOCGCHAN, &priv->channels[i]) == -1) |
2841 | 234 { |
235 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get channel failed: %s\n", strerror(errno)); | |
236 break; | |
237 } | |
2818 | 238 mp_msg(MSGT_TV, MSGL_INFO, " %d: %s: %s%s%s%s (tuner:%d, norm:%d)\n", i, |
2790 | 239 priv->channels[i].name, |
240 (priv->channels[i].flags & VIDEO_VC_TUNER) ? "tuner " : "", | |
241 (priv->channels[i].flags & VIDEO_VC_AUDIO) ? "audio " : "", | |
242 (priv->channels[i].flags & VIDEO_TYPE_TV) ? "tv " : "", | |
2802 | 243 (priv->channels[i].flags & VIDEO_TYPE_CAMERA) ? "camera " : "", |
244 priv->channels[i].tuners, | |
245 priv->channels[i].norm); | |
246 } | |
247 | |
3815 | 248 /* audio chanlist */ |
2841 | 249 if (priv->capability.audios) |
250 { | |
251 mp_msg(MSGT_TV, MSGL_INFO, " Audio devices: %d\n", priv->capability.audios); | |
252 | |
253 for (i = 0; i < priv->capability.audios; i++) | |
254 { | |
3815 | 255 if (i >= MAX_AUDIO_CHANNELS) |
256 { | |
257 mp_msg(MSGT_TV, MSGL_ERR, "no space for more audio channels (incrase in source!) (%d > %d)\n", | |
258 i, MAX_AUDIO_CHANNELS); | |
259 i = priv->capability.audios; | |
260 break; | |
261 } | |
262 | |
3284 | 263 priv->audio[i].audio = i; |
3815 | 264 if (ioctl(priv->video_fd, VIDIOCGAUDIO, &priv->audio[i]) == -1) |
2841 | 265 { |
266 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get audio failed: %s\n", strerror(errno)); | |
267 break; | |
268 } | |
269 | |
3815 | 270 if (priv->audio[i].volume <= 0) |
271 priv->audio[i].volume = 100; | |
272 priv->audio[i].flags &= ~VIDEO_AUDIO_MUTE; | |
273 ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[i]); | |
274 | |
275 switch(priv->audio[i].mode) | |
276 { | |
277 case VIDEO_SOUND_MONO: | |
278 case VIDEO_SOUND_LANG1: | |
279 case VIDEO_SOUND_LANG2: | |
280 priv->audio_channels[i] = 1; | |
281 break; | |
282 case VIDEO_SOUND_STEREO: | |
283 priv->audio_channels[i] = 2; | |
284 break; | |
285 } | |
286 | |
287 priv->audio_format[i] = AFMT_S16_LE; | |
288 priv->audio_samplerate[i] = 44100; | |
5941 | 289 priv->audio_samplesize[i] = |
290 priv->audio_samplerate[i]/8/priv->fps* | |
291 priv->audio_channels[i]; | |
3815 | 292 |
293 /* display stuff */ | |
3284 | 294 mp_msg(MSGT_TV, MSGL_V, " %d: %s: ", priv->audio[i].audio, |
295 priv->audio[i].name); | |
296 if (priv->audio[i].flags & VIDEO_AUDIO_MUTABLE) | |
2841 | 297 mp_msg(MSGT_TV, MSGL_V, "muted=%s ", |
3284 | 298 (priv->audio[i].flags & VIDEO_AUDIO_MUTE) ? "yes" : "no"); |
2841 | 299 mp_msg(MSGT_TV, MSGL_V, "volume=%d bass=%d treble=%d balance=%d mode=%s\n", |
3284 | 300 priv->audio[i].volume, priv->audio[i].bass, priv->audio[i].treble, |
301 priv->audio[i].balance, audio_mode2name[priv->audio[i].mode]); | |
3815 | 302 mp_msg(MSGT_TV, MSGL_V, " channels: %d, samplerate: %d, samplesize: %d, format: %s\n", |
303 priv->audio_channels[i], priv->audio_samplerate[i], priv->audio_samplesize[i], | |
304 audio_out_format_name(priv->audio_format[i])); | |
2841 | 305 } |
306 } | |
307 | |
2802 | 308 if (!(priv->capability.type & VID_TYPE_CAPTURE)) |
309 { | |
2818 | 310 mp_msg(MSGT_TV, MSGL_ERR, "Only grabbing supported (for overlay use another program)\n"); |
2802 | 311 goto err; |
312 } | |
313 | |
314 /* map grab buffer */ | |
3815 | 315 if (ioctl(priv->video_fd, VIDIOCGMBUF, &priv->mbuf) == -1) |
2802 | 316 { |
2818 | 317 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get mbuf failed: %s\n", strerror(errno)); |
2802 | 318 goto err; |
2790 | 319 } |
320 | |
2818 | 321 mp_msg(MSGT_TV, MSGL_V, "mbuf: size=%d, frames=%d\n", |
2802 | 322 priv->mbuf.size, priv->mbuf.frames); |
323 priv->mmap = mmap(0, priv->mbuf.size, PROT_READ|PROT_WRITE, | |
3815 | 324 MAP_SHARED, priv->video_fd, 0); |
2819
2e58962dc9fe
cleaned up some warnings, and tv_param_on moved out from #ifdef USE_TV
alex
parents:
2818
diff
changeset
|
325 if (priv->mmap == (unsigned char *)-1) |
2802 | 326 { |
3815 | 327 mp_msg(MSGT_TV, MSGL_ERR, "Unable to map memory for buffers: %s\n", strerror(errno)); |
2802 | 328 goto err; |
329 } | |
2818 | 330 mp_msg(MSGT_TV, MSGL_DBG2, "our buffer: %p\n", priv->mmap); |
2790 | 331 |
2802 | 332 /* num of buffers */ |
333 priv->nbuf = priv->mbuf.frames; | |
2790 | 334 |
2802 | 335 /* video buffers */ |
2819
2e58962dc9fe
cleaned up some warnings, and tv_param_on moved out from #ifdef USE_TV
alex
parents:
2818
diff
changeset
|
336 priv->buf = (struct video_mmap *)malloc(priv->nbuf * sizeof(struct video_mmap)); |
3611 | 337 if (!priv->buf) |
338 goto malloc_failed; | |
2802 | 339 memset(priv->buf, 0, priv->nbuf * sizeof(struct video_mmap)); |
2790 | 340 |
3815 | 341 /* audio init */ |
5088 | 342 #if 1 |
3815 | 343 priv->audio_fd = open(priv->audio_device, O_RDONLY); |
344 if (priv->audio_fd < 0) | |
345 { | |
346 mp_msg(MSGT_TV, MSGL_ERR, "unable to open '%s': %s\n", | |
347 priv->audio_device, strerror(errno)); | |
348 } | |
349 else | |
350 { | |
351 int ioctl_param; | |
352 | |
353 fcntl(priv->audio_fd, F_SETFL, O_NONBLOCK); | |
354 | |
355 #if 0 | |
356 ioctl_param = 0x7fff000d; /* 8k */ | |
357 printf("ioctl dsp setfragment: %d\n", | |
358 ioctl(priv->audio_fd, SNDCTL_DSP_SETFRAGMENT, &ioctl_param)); | |
359 #endif | |
360 | |
361 ioctl_param = 0 ; | |
362 printf("ioctl dsp getfmt: %d\n", | |
363 ioctl(priv->audio_fd, SNDCTL_DSP_GETFMTS, &ioctl_param)); | |
364 | |
365 printf("Supported formats: %x\n", ioctl_param); | |
366 if (!(ioctl_param & priv->audio_format[priv->audio_id])) | |
367 printf("notsupported format\n"); | |
368 | |
369 ioctl_param = priv->audio_format[priv->audio_id]; | |
370 printf("ioctl dsp setfmt: %d\n", | |
371 ioctl(priv->audio_fd, SNDCTL_DSP_SETFMT, &ioctl_param)); | |
372 | |
373 // ioctl(priv->audio_fd, SNDCTL_DSP_GETISPACE, &ioctl_param); | |
374 // printf("getispace: %d\n", ioctl_param); | |
375 | |
376 if (priv->audio_channels[priv->audio_id] > 2) | |
377 { | |
378 ioctl_param = priv->audio_channels[priv->audio_id]; | |
379 printf("ioctl dsp channels: %d\n", | |
380 ioctl(priv->audio_fd, SNDCTL_DSP_CHANNELS, &ioctl_param)); | |
381 } | |
382 else | |
383 { | |
384 // if (priv->audio_channels[priv->audio_id] == 2) | |
385 // ioctl_param = 1; | |
386 // else | |
387 // ioctl_param = 0; | |
388 | |
389 ioctl_param = (priv->audio_channels[priv->audio_id] == 2); | |
390 printf("ioctl dsp stereo: %d (req: %d)\n", | |
391 ioctl(priv->audio_fd, SNDCTL_DSP_STEREO, &ioctl_param), | |
392 ioctl_param); | |
393 } | |
394 | |
395 ioctl_param = priv->audio_samplerate[priv->audio_id]; | |
396 printf("ioctl dsp speed: %d\n", | |
397 ioctl(priv->audio_fd, SNDCTL_DSP_SPEED, &ioctl_param)); | |
398 | |
399 #if 0 | |
400 ioctl_param = 0; | |
401 ioctl_param = ~PCM_ENABLE_INPUT; | |
402 printf("ioctl dsp trigger: %d\n", | |
403 ioctl(priv->audio_fd, SNDCTL_DSP_SETTRIGGER, &ioctl_param)); | |
404 ioctl_param = PCM_ENABLE_INPUT; | |
405 printf("ioctl dsp trigger: %d\n", | |
406 ioctl(priv->audio_fd, SNDCTL_DSP_SETTRIGGER, &ioctl_param)); | |
407 #endif | |
408 | |
409 printf("ioctl dsp trigger: %d\n", | |
410 ioctl(priv->audio_fd, SNDCTL_DSP_GETTRIGGER, &ioctl_param)); | |
411 printf("trigger: %x\n", ioctl_param); | |
412 ioctl_param = PCM_ENABLE_INPUT; | |
413 printf("ioctl dsp trigger: %d\n", | |
414 ioctl(priv->audio_fd, SNDCTL_DSP_SETTRIGGER, &ioctl_param)); | |
415 | |
416 printf("ioctl dsp getblocksize: %d\n", | |
417 ioctl(priv->audio_fd, SNDCTL_DSP_GETBLKSIZE, &priv->audio_blocksize)); | |
418 printf("blocksize: %d\n", priv->audio_blocksize); | |
419 } | |
420 #endif | |
2790 | 421 return(1); |
422 | |
3611 | 423 |
424 malloc_failed: | |
425 if (priv->channels) | |
426 free(priv->channels); | |
427 if (priv->buf) | |
428 free(priv->buf); | |
2790 | 429 err: |
3815 | 430 if (priv->video_fd != -1) |
431 close(priv->video_fd); | |
2790 | 432 return(0); |
433 } | |
434 | |
2802 | 435 static int uninit(priv_t *priv) |
2790 | 436 { |
3815 | 437 close(priv->video_fd); |
438 | |
439 priv->audio[priv->audio_id].volume = 0; | |
440 priv->audio[priv->audio_id].flags |= VIDEO_AUDIO_MUTE; | |
441 ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]); | |
442 close(priv->audio_fd); | |
2931 | 443 |
444 return(1); | |
2790 | 445 } |
446 | |
2802 | 447 static int start(priv_t *priv) |
2790 | 448 { |
2802 | 449 int i; |
450 | |
451 | |
3815 | 452 if (ioctl(priv->video_fd, VIDIOCGPICT, &priv->picture) == -1) |
2790 | 453 { |
2818 | 454 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get picture failed: %s\n", strerror(errno)); |
2802 | 455 return(0); |
2790 | 456 } |
457 | |
2802 | 458 priv->picture.palette = format2palette(priv->format); |
459 priv->picture.depth = palette2depth(priv->picture.palette); | |
460 priv->bytesperline = priv->width * priv->picture.depth / 8; | |
3815 | 461 // if (IMGFMT_IS_BGR(priv->format) || IMGFMT_IS_RGB(priv->format)) |
462 // priv->bytesperline = priv->width * priv->picture.depth / 8; | |
463 // if ((priv->format == IMGFMT_YV12) || (priv->format == IMGFMT_I420) || (priv->format == IMGFMT_IYUV)) | |
464 // priv->bytesperline = priv->width * 3 / 2; | |
465 | |
466 printf("palette: %d, depth: %d, bytesperline: %d\n", | |
467 priv->picture.palette, priv->picture.depth, priv->bytesperline); | |
468 | |
2818 | 469 mp_msg(MSGT_TV, MSGL_INFO, "Picture values:\n"); |
470 mp_msg(MSGT_TV, MSGL_INFO, " Depth: %d, Palette: %d (Format: %s)\n", priv->picture.depth, | |
2802 | 471 priv->picture.palette, vo_format_name(priv->format)); |
2818 | 472 mp_msg(MSGT_TV, MSGL_INFO, " Brightness: %d, Hue: %d, Colour: %d, Contrast: %d\n", |
2802 | 473 priv->picture.brightness, priv->picture.hue, |
474 priv->picture.colour, priv->picture.contrast); | |
475 | |
476 | |
3815 | 477 if (ioctl(priv->video_fd, VIDIOCSPICT, &priv->picture) == -1) |
2790 | 478 { |
2818 | 479 mp_msg(MSGT_TV, MSGL_ERR, "ioctl set picture failed: %s\n", strerror(errno)); |
2802 | 480 return(0); |
2790 | 481 } |
482 | |
2802 | 483 priv->nbuf = priv->mbuf.frames; |
484 for (i=0; i < priv->nbuf; i++) | |
485 { | |
486 priv->buf[i].format = priv->picture.palette; | |
487 priv->buf[i].frame = i; | |
488 priv->buf[i].width = priv->width; | |
489 priv->buf[i].height = priv->height; | |
2818 | 490 mp_msg(MSGT_TV, MSGL_DBG2, "buffer: %d => %p\n", i, &priv->buf[i]); |
2802 | 491 } |
2837 | 492 |
2931 | 493 #if 0 |
494 { | |
495 struct video_play_mode pmode; | |
496 | |
497 pmode.mode = VID_PLAY_NORMAL; | |
498 pmode.p1 = 1; | |
499 pmode.p2 = 0; | |
3815 | 500 if (ioctl(priv->video_fd, VIDIOCSPLAYMODE, &pmode) == -1) |
2931 | 501 { |
502 mp_msg(MSGT_TV, MSGL_ERR, "ioctl set play mode failed: %s\n", strerror(errno)); | |
503 // return(0); | |
504 } | |
505 } | |
506 #endif | |
2837 | 507 |
508 #if 0 | |
509 { | |
510 struct video_window win; | |
511 | |
512 win.x = 0; | |
513 win.y = 0; | |
514 win.width = priv->width; | |
515 win.height = priv->height; | |
516 win.chromakey = -1; | |
517 win.flags = 0; | |
5088 | 518 //win.clipcount = 0; |
2837 | 519 |
3815 | 520 ioctl(priv->video_fd, VIDIOCSWIN, &win); |
2837 | 521 } |
522 | |
2802 | 523 /* start capture */ |
3815 | 524 if (ioctl(priv->video_fd, VIDIOCCAPTURE, &one) == -1) |
2802 | 525 { |
2818 | 526 mp_msg(MSGT_TV, MSGL_ERR, "ioctl capture failed: %s\n", strerror(errno)); |
2802 | 527 return(0); |
528 } | |
2837 | 529 #endif |
530 | |
6553
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
531 { |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
532 struct timeval curtime; |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
533 gettimeofday(&curtime, NULL); |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
534 priv->starttime=curtime.tv_sec + curtime.tv_usec*.000001; |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
535 } |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
536 |
2837 | 537 return(1); |
2790 | 538 } |
539 | |
540 static int control(priv_t *priv, int cmd, void *arg) | |
541 { | |
2818 | 542 mp_msg(MSGT_TV, MSGL_DBG2, "debug: control(priv=%p, cmd=%d, arg=%p)\n", |
2802 | 543 priv, cmd, arg); |
2790 | 544 switch(cmd) |
545 { | |
2802 | 546 /* ========== GENERIC controls =========== */ |
547 case TVI_CONTROL_IS_VIDEO: | |
548 { | |
549 if (priv->capability.type & VID_TYPE_CAPTURE) | |
550 return(TVI_CONTROL_TRUE); | |
551 return(TVI_CONTROL_FALSE); | |
552 } | |
553 case TVI_CONTROL_IS_AUDIO: | |
2841 | 554 if (priv->channels[priv->act_channel].flags & VIDEO_VC_AUDIO) |
3815 | 555 { |
2841 | 556 return(TVI_CONTROL_TRUE); |
3815 | 557 } |
558 return(TVI_CONTROL_TRUE); | |
2802 | 559 case TVI_CONTROL_IS_TUNER: |
560 { | |
2841 | 561 // if (priv->capability.type & VID_TYPE_TUNER) |
562 if (priv->channels[priv->act_channel].flags & VIDEO_VC_TUNER) | |
2802 | 563 return(TVI_CONTROL_TRUE); |
564 return(TVI_CONTROL_FALSE); | |
565 } | |
566 | |
567 /* ========== VIDEO controls =========== */ | |
2790 | 568 case TVI_CONTROL_VID_GET_FORMAT: |
2802 | 569 { |
570 int output_fmt = -1; | |
571 | |
572 output_fmt = priv->format; | |
573 (int)*(void **)arg = output_fmt; | |
2818 | 574 mp_msg(MSGT_TV, MSGL_INFO, "Output format: %s\n", vo_format_name(output_fmt)); |
2802 | 575 return(TVI_CONTROL_TRUE); |
576 } | |
577 case TVI_CONTROL_VID_SET_FORMAT: | |
578 priv->format = (int)*(void **)arg; | |
2790 | 579 return(TVI_CONTROL_TRUE); |
580 case TVI_CONTROL_VID_GET_PLANES: | |
3220 | 581 (int)*(void **)arg = 1; /* FIXME, also not needed at this time */ |
2790 | 582 return(TVI_CONTROL_TRUE); |
583 case TVI_CONTROL_VID_GET_BITS: | |
2810 | 584 (int)*(void **)arg = palette2depth(format2palette(priv->format)); |
2790 | 585 return(TVI_CONTROL_TRUE); |
586 case TVI_CONTROL_VID_GET_WIDTH: | |
587 (int)*(void **)arg = priv->width; | |
588 return(TVI_CONTROL_TRUE); | |
589 case TVI_CONTROL_VID_CHK_WIDTH: | |
590 { | |
591 int req_width = (int)*(void **)arg; | |
592 | |
2818 | 593 mp_msg(MSGT_TV, MSGL_INFO, "Requested width: %d\n", req_width); |
2810 | 594 if ((req_width >= priv->capability.minwidth) && |
595 (req_width <= priv->capability.maxwidth)) | |
2790 | 596 return(TVI_CONTROL_TRUE); |
597 return(TVI_CONTROL_FALSE); | |
598 } | |
599 case TVI_CONTROL_VID_SET_WIDTH: | |
600 priv->width = (int)*(void **)arg; | |
601 return(TVI_CONTROL_TRUE); | |
602 case TVI_CONTROL_VID_GET_HEIGHT: | |
603 (int)*(void **)arg = priv->height; | |
604 return(TVI_CONTROL_TRUE); | |
605 case TVI_CONTROL_VID_CHK_HEIGHT: | |
606 { | |
607 int req_height = (int)*(void **)arg; | |
608 | |
2818 | 609 mp_msg(MSGT_TV, MSGL_INFO, "Requested height: %d\n", req_height); |
2810 | 610 if ((req_height >= priv->capability.minheight) && |
611 (req_height <= priv->capability.maxheight)) | |
2790 | 612 return(TVI_CONTROL_TRUE); |
613 return(TVI_CONTROL_FALSE); | |
614 } | |
615 case TVI_CONTROL_VID_SET_HEIGHT: | |
616 priv->height = (int)*(void **)arg; | |
617 return(TVI_CONTROL_TRUE); | |
2937 | 618 case TVI_CONTROL_VID_GET_PICTURE: |
3815 | 619 if (ioctl(priv->video_fd, VIDIOCGPICT, &priv->picture) == -1) |
2937 | 620 { |
621 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get picture failed: %s\n", strerror(errno)); | |
622 return(TVI_CONTROL_FALSE); | |
623 } | |
624 return(TVI_CONTROL_TRUE); | |
625 case TVI_CONTROL_VID_SET_PICTURE: | |
3815 | 626 if (ioctl(priv->video_fd, VIDIOCSPICT, &priv->picture) == -1) |
2937 | 627 { |
628 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get picture failed: %s\n", strerror(errno)); | |
629 return(TVI_CONTROL_FALSE); | |
630 } | |
631 return(TVI_CONTROL_TRUE); | |
632 case TVI_CONTROL_VID_SET_BRIGHTNESS: | |
633 priv->picture.brightness = (int)*(void **)arg; | |
634 control(priv, TVI_CONTROL_VID_SET_PICTURE, 0); | |
635 return(TVI_CONTROL_TRUE); | |
636 case TVI_CONTROL_VID_SET_HUE: | |
637 priv->picture.hue = (int)*(void **)arg; | |
638 control(priv, TVI_CONTROL_VID_SET_PICTURE, 0); | |
639 return(TVI_CONTROL_TRUE); | |
640 case TVI_CONTROL_VID_SET_SATURATION: | |
641 priv->picture.colour = (int)*(void **)arg; | |
642 control(priv, TVI_CONTROL_VID_SET_PICTURE, 0); | |
643 return(TVI_CONTROL_TRUE); | |
644 case TVI_CONTROL_VID_SET_CONTRAST: | |
645 priv->picture.contrast = (int)*(void **)arg; | |
646 control(priv, TVI_CONTROL_VID_SET_PICTURE, 0); | |
647 return(TVI_CONTROL_TRUE); | |
6529
8552767dbb46
tv audio fixing patch by Paul Ortyl <ortylp at 3miasto.net>
alex
parents:
6305
diff
changeset
|
648 case TVI_CONTROL_VID_GET_FPS: |
8552767dbb46
tv audio fixing patch by Paul Ortyl <ortylp at 3miasto.net>
alex
parents:
6305
diff
changeset
|
649 (int)*(void **)arg=priv->fps; |
8552767dbb46
tv audio fixing patch by Paul Ortyl <ortylp at 3miasto.net>
alex
parents:
6305
diff
changeset
|
650 return(TVI_CONTROL_TRUE); |
2790 | 651 |
2802 | 652 /* ========== TUNER controls =========== */ |
653 case TVI_CONTROL_TUN_GET_FREQ: | |
654 { | |
655 unsigned long freq; | |
656 | |
3815 | 657 if (ioctl(priv->video_fd, VIDIOCGFREQ, &freq) == -1) |
2802 | 658 { |
2818 | 659 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get freq failed: %s\n", strerror(errno)); |
2802 | 660 return(TVI_CONTROL_FALSE); |
661 } | |
662 | |
663 /* tuner uses khz not mhz ! */ | |
2837 | 664 // if (priv->tuner.flags & VIDEO_TUNER_LOW) |
665 // freq /= 1000; | |
2802 | 666 (unsigned long)*(void **)arg = freq; |
667 return(TVI_CONTROL_TRUE); | |
668 } | |
2790 | 669 case TVI_CONTROL_TUN_SET_FREQ: |
670 { | |
2802 | 671 /* argument is in MHz ! */ |
672 unsigned long freq = (unsigned long)*(void **)arg; | |
673 | |
2837 | 674 mp_msg(MSGT_TV, MSGL_V, "requested frequency: %.3f\n", (float)freq/16); |
2802 | 675 |
676 /* tuner uses khz not mhz ! */ | |
2837 | 677 // if (priv->tuner.flags & VIDEO_TUNER_LOW) |
678 // freq *= 1000; | |
679 // mp_msg(MSGT_TV, MSGL_V, " requesting from driver: freq=%.3f\n", (float)freq/16); | |
3815 | 680 if (ioctl(priv->video_fd, VIDIOCSFREQ, &freq) == -1) |
2802 | 681 { |
2818 | 682 mp_msg(MSGT_TV, MSGL_ERR, "ioctl set freq failed: %s\n", strerror(errno)); |
2802 | 683 return(TVI_CONTROL_FALSE); |
684 } | |
685 return(TVI_CONTROL_TRUE); | |
686 } | |
687 case TVI_CONTROL_TUN_GET_TUNER: | |
688 { | |
3815 | 689 if (ioctl(priv->video_fd, VIDIOCGTUNER, &priv->tuner) == -1) |
2802 | 690 { |
2818 | 691 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get tuner failed: %s\n", strerror(errno)); |
2802 | 692 return(TVI_CONTROL_FALSE); |
693 } | |
694 | |
2818 | 695 mp_msg(MSGT_TV, MSGL_INFO, "Tuner (%s) range: %lu -> %lu\n", priv->tuner.name, |
2802 | 696 priv->tuner.rangelow, priv->tuner.rangehigh); |
697 return(TVI_CONTROL_TRUE); | |
698 } | |
699 case TVI_CONTROL_TUN_SET_TUNER: | |
700 { | |
3815 | 701 if (ioctl(priv->video_fd, VIDIOCSTUNER, &priv->tuner) == -1) |
2802 | 702 { |
2818 | 703 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get tuner failed: %s\n", strerror(errno)); |
2802 | 704 return(TVI_CONTROL_FALSE); |
705 } | |
706 return(TVI_CONTROL_TRUE); | |
707 } | |
708 case TVI_CONTROL_TUN_SET_NORM: | |
709 { | |
710 int req_mode = (int)*(void **)arg; | |
711 | |
712 if ((!(priv->tuner.flags & VIDEO_TUNER_NORM)) || | |
713 ((req_mode == VIDEO_MODE_PAL) && !(priv->tuner.flags & VIDEO_TUNER_PAL)) || | |
714 ((req_mode == VIDEO_MODE_NTSC) && !(priv->tuner.flags & VIDEO_TUNER_NTSC)) || | |
715 ((req_mode == VIDEO_MODE_SECAM) && !(priv->tuner.flags & VIDEO_TUNER_SECAM))) | |
716 { | |
2818 | 717 mp_msg(MSGT_TV, MSGL_ERR, "Tuner isn't capable to set norm!\n"); |
2802 | 718 return(TVI_CONTROL_FALSE); |
719 } | |
720 | |
721 priv->tuner.mode = req_mode; | |
2790 | 722 |
6305
bd8e39725cfd
Fix by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>.
atmos4
parents:
5941
diff
changeset
|
723 if (control(priv, TVI_CONTROL_TUN_SET_TUNER, &priv->tuner) != TVI_CONTROL_TRUE) |
2802 | 724 return(TVI_CONTROL_FALSE); |
725 return(TVI_CONTROL_TRUE); | |
726 } | |
727 case TVI_CONTROL_TUN_GET_NORM: | |
728 { | |
729 (int)*(void **)arg = priv->tuner.mode; | |
730 | |
731 return(TVI_CONTROL_TRUE); | |
732 } | |
733 | |
734 /* ========== AUDIO controls =========== */ | |
735 case TVI_CONTROL_AUD_GET_FORMAT: | |
736 { | |
3815 | 737 (int)*(void **)arg = priv->audio_format[priv->audio_id]; |
2802 | 738 return(TVI_CONTROL_TRUE); |
739 } | |
740 case TVI_CONTROL_AUD_GET_CHANNELS: | |
741 { | |
3815 | 742 (int)*(void **)arg = priv->audio_channels[priv->audio_id]; |
2802 | 743 return(TVI_CONTROL_TRUE); |
744 } | |
745 case TVI_CONTROL_AUD_GET_SAMPLERATE: | |
746 { | |
3815 | 747 (int)*(void **)arg = priv->audio_samplerate[priv->audio_id]; |
2802 | 748 return(TVI_CONTROL_TRUE); |
749 } | |
750 case TVI_CONTROL_AUD_GET_SAMPLESIZE: | |
751 { | |
5941 | 752 (int)*(void **)arg = priv->audio_samplesize[priv->audio_id]/8; |
2802 | 753 return(TVI_CONTROL_TRUE); |
754 } | |
5941 | 755 case TVI_CONTROL_AUD_SET_SAMPLERATE: |
756 { | |
6529
8552767dbb46
tv audio fixing patch by Paul Ortyl <ortylp at 3miasto.net>
alex
parents:
6305
diff
changeset
|
757 int tmp = priv->audio_samplerate[priv->audio_id] = (int)*(void **)arg; |
5941 | 758 |
6529
8552767dbb46
tv audio fixing patch by Paul Ortyl <ortylp at 3miasto.net>
alex
parents:
6305
diff
changeset
|
759 if (ioctl(priv->audio_fd, SNDCTL_DSP_SPEED, &tmp) == -1) |
5941 | 760 return(TVI_CONTROL_FALSE); |
761 priv->audio_samplesize[priv->audio_id] = | |
762 priv->audio_samplerate[priv->audio_id]/8/priv->fps* | |
763 priv->audio_channels[priv->audio_id]; | |
764 return(TVI_CONTROL_TRUE); | |
765 } | |
2802 | 766 /* ========== SPECIFIC controls =========== */ |
767 case TVI_CONTROL_SPC_GET_INPUT: | |
768 { | |
769 int req_chan = (int)*(void **)arg; | |
770 int i; | |
771 | |
772 for (i = 0; i < priv->capability.channels; i++) | |
773 { | |
774 if (priv->channels[i].channel == req_chan) | |
775 break; | |
776 } | |
2841 | 777 |
778 priv->act_channel = i; | |
2802 | 779 |
3815 | 780 if (ioctl(priv->video_fd, VIDIOCGCHAN, &priv->channels[i]) == -1) |
2802 | 781 { |
2818 | 782 mp_msg(MSGT_TV, MSGL_ERR, "ioctl get channel failed: %s\n", strerror(errno)); |
2802 | 783 return(TVI_CONTROL_FALSE); |
784 } | |
785 return(TVI_CONTROL_TRUE); | |
786 } | |
787 | |
788 case TVI_CONTROL_SPC_SET_INPUT: | |
789 { | |
790 struct video_channel chan; | |
791 int req_chan = (int)*(void **)arg; | |
792 int i; | |
793 | |
794 if (req_chan >= priv->capability.channels) | |
795 { | |
2818 | 796 mp_msg(MSGT_TV, MSGL_ERR, "Invalid input requested: %d, valid: 0-%d\n", |
2802 | 797 req_chan, priv->capability.channels); |
798 return(TVI_CONTROL_FALSE); | |
799 } | |
800 | |
801 for (i = 0; i < priv->capability.channels; i++) | |
802 { | |
803 if (priv->channels[i].channel == req_chan) | |
804 chan = priv->channels[i]; | |
805 } | |
806 | |
3815 | 807 if (ioctl(priv->video_fd, VIDIOCSCHAN, &chan) == -1) |
2802 | 808 { |
2818 | 809 mp_msg(MSGT_TV, MSGL_ERR, "ioctl set chan failed: %s\n", strerror(errno)); |
2802 | 810 return(TVI_CONTROL_FALSE); |
811 } | |
2818 | 812 mp_msg(MSGT_TV, MSGL_INFO, "Using input '%s'\n", chan.name); |
2802 | 813 |
2841 | 814 priv->act_channel = i; |
815 | |
2802 | 816 /* update tuner state */ |
2841 | 817 // if (priv->capability.type & VID_TYPE_TUNER) |
818 if (priv->channels[priv->act_channel].flags & VIDEO_VC_TUNER) | |
2802 | 819 control(priv, TVI_CONTROL_TUN_GET_TUNER, 0); |
820 | |
821 /* update local channel list */ | |
822 control(priv, TVI_CONTROL_SPC_GET_INPUT, &req_chan); | |
823 return(TVI_CONTROL_TRUE); | |
2790 | 824 } |
825 } | |
826 | |
827 return(TVI_CONTROL_UNKNOWN); | |
828 } | |
829 | |
5572
8cd761968f35
BSD-BT848 TV update patch by Charles Henrich <henrich@sigbus.com>
arpi
parents:
5088
diff
changeset
|
830 static double grab_video_frame(priv_t *priv, char *buffer, int len) |
2790 | 831 { |
6553
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
832 struct timeval curtime; |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
833 double timestamp; |
2802 | 834 int frame = priv->queue % priv->nbuf; |
2814 | 835 int nextframe = (priv->queue+1) % priv->nbuf; |
2802 | 836 |
3284 | 837 mp_dbg(MSGT_TV, MSGL_DBG2, "grab_video_frame(priv=%p, buffer=%p, len=%d)\n", |
2802 | 838 priv, buffer, len); |
839 | |
2931 | 840 mp_dbg(MSGT_TV, MSGL_DBG3, "buf: %p + frame: %d => %p\n", |
2814 | 841 priv->buf, nextframe, &priv->buf[nextframe]); |
3815 | 842 if (ioctl(priv->video_fd, VIDIOCMCAPTURE, &priv->buf[nextframe]) == -1) |
2790 | 843 { |
2818 | 844 mp_msg(MSGT_TV, MSGL_ERR, "ioctl mcapture failed: %s\n", strerror(errno)); |
2802 | 845 return(0); |
2790 | 846 } |
3711 | 847 |
3815 | 848 while (ioctl(priv->video_fd, VIDIOCSYNC, &priv->buf[frame].frame) < 0 && |
3711 | 849 (errno == EAGAIN || errno == EINTR)); |
850 mp_dbg(MSGT_TV, MSGL_DBG3, "picture sync failed\n"); | |
851 | |
2802 | 852 priv->queue++; |
853 | |
6553
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
854 gettimeofday(&curtime, NULL); |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
855 timestamp=curtime.tv_sec + curtime.tv_usec*.000001; |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
856 |
2931 | 857 mp_dbg(MSGT_TV, MSGL_DBG3, "mmap: %p + offset: %d => %p\n", |
2802 | 858 priv->mmap, priv->mbuf.offsets[frame], |
859 priv->mmap+priv->mbuf.offsets[frame]); | |
2931 | 860 |
861 /* XXX also directrendering would be nicer! */ | |
862 /* 3 times copying the same picture to other buffer :( */ | |
863 | |
864 /* copy the actual frame */ | |
2802 | 865 memcpy(buffer, priv->mmap+priv->mbuf.offsets[frame], len); |
866 | |
6553
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
867 return(timestamp-priv->starttime); |
2790 | 868 } |
869 | |
870 static int get_video_framesize(priv_t *priv) | |
871 { | |
2931 | 872 return(priv->bytesperline * priv->height); |
2790 | 873 } |
874 | |
5572
8cd761968f35
BSD-BT848 TV update patch by Charles Henrich <henrich@sigbus.com>
arpi
parents:
5088
diff
changeset
|
875 static double grab_audio_frame(priv_t *priv, char *buffer, int len) |
2790 | 876 { |
3815 | 877 int in_len = 0; |
6553
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
878 int max_tries = 2; |
3815 | 879 |
5088 | 880 mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n", |
3815 | 881 priv, buffer, len); |
882 | |
6553
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
883 while (--max_tries > 0) |
d000112bd06e
Paul Ortyl's patch - tv4l timestamps (not so precise :()
alex
parents:
6529
diff
changeset
|
884 // for (;;) |
3815 | 885 { |
886 in_len = read(priv->audio_fd, buffer, len); | |
887 // printf("in_len: %d\n", in_len); | |
888 // fflush(NULL); | |
889 | |
890 if (in_len > 0) | |
891 break; | |
892 if (!((in_len == 0) || (in_len == -1 && (errno == EAGAIN || errno == EINTR)))) | |
893 { | |
894 in_len = 0; /* -EIO */ | |
895 break; | |
896 } | |
897 } | |
898 | |
5572
8cd761968f35
BSD-BT848 TV update patch by Charles Henrich <henrich@sigbus.com>
arpi
parents:
5088
diff
changeset
|
899 return 0; //(in_len); // FIXME! |
2790 | 900 } |
901 | |
902 static int get_audio_framesize(priv_t *priv) | |
903 { | |
3815 | 904 return(priv->audio_blocksize); |
905 // return(priv->audio_samplesize[priv->audio_id]); | |
2790 | 906 } |
907 | |
908 #endif /* USE_TV */ |