comparison stream/tvi_v4l2.c @ 19271:64d82a45a05d

introduce new 'stream' directory for all stream layer related components and split them from libmpdemux
author ben
date Mon, 31 Jul 2006 17:39:17 +0000
parents libmpdemux/tvi_v4l2.c@5e767cabf4cd
children ac69ba536915
comparison
equal deleted inserted replaced
19270:7d39b911f0bd 19271:64d82a45a05d
1 /*
2 ** Video 4 Linux 2 input
3 **
4 ** This file is part of MPlayer, see http://mplayerhq.hu/ for info.
5 **
6 ** (c) 2003 Martin Olschewski <olschewski@zpr.uni-koeln.de>
7 ** (c) 2003 Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
8 **
9 ** File licensed under the GPL, see http://www.fsf.org/ for more info.
10 **
11 ** Some ideas are based on works from
12 ** Alex Beregszaszi <alex@fsn.hu>
13 ** Gerd Knorr <kraxel@bytesex.org>
14 **
15 ** CODE IS UNDER DEVELOPMENT, NO FEATURE REQUESTS PLEASE!
16 */
17
18 /*
19
20 known issues:
21 - norm setting isn't consistent with tvi_v4l
22 - the same for volume/bass/treble/balance
23
24 */
25
26 #include "config.h"
27
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <pthread.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <sys/ioctl.h>
34 #include <sys/mman.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #include <unistd.h>
38 #ifdef HAVE_SYS_SYSINFO_H
39 #include <sys/sysinfo.h>
40 #endif
41 #include <linux/types.h>
42 #include <linux/videodev2.h>
43 #include "mp_msg.h"
44 #include "libvo/img_format.h"
45 #include "libaf/af_format.h"
46 #include "tv.h"
47 #include "audio_in.h"
48
49 /* information about this file */
50 static tvi_info_t info = {
51 "Video 4 Linux 2 input",
52 "v4l2",
53 "Martin Olschewski <olschewski@zpr.uni-koeln.de>",
54 "first try, more to come ;-)"
55 };
56
57 struct map {
58 struct v4l2_buffer buf;
59 void *addr;
60 size_t len;
61 };
62
63 #define BUFFER_COUNT 6
64
65 /* private data */
66 typedef struct {
67 /* video */
68 char *video_dev;
69 int video_fd;
70 int mp_format;
71 struct v4l2_capability capability;
72 struct v4l2_input input;
73 struct v4l2_format format;
74 struct v4l2_standard standard;
75 struct v4l2_tuner tuner;
76 struct map *map;
77 int mapcount;
78 int frames;
79 volatile long long first_frame;
80 long long curr_frame;
81 /* audio video interleaving ;-) */
82 volatile int streamon;
83 pthread_t audio_grabber_thread;
84 pthread_mutex_t skew_mutex;
85
86 /* 2nd level video buffers */
87 int first;
88 int immediate_mode;
89
90 int video_buffer_size_max;
91 volatile int video_buffer_size_current;
92 unsigned char **video_ringbuffer;
93 long long *video_timebuffer;
94 volatile int video_head;
95 volatile int video_tail;
96 volatile int video_cnt;
97 pthread_t video_grabber_thread;
98 pthread_mutex_t video_buffer_mutex;
99
100 /* audio */
101 char *audio_dev;
102 audio_in_t audio_in;
103
104 long long audio_start_time;
105 int audio_buffer_size;
106 int aud_skew_cnt;
107 unsigned char *audio_ringbuffer;
108 long long *audio_skew_buffer;
109 long long *audio_skew_delta_buffer;
110 volatile int audio_head;
111 volatile int audio_tail;
112 volatile int audio_cnt;
113 volatile long long audio_skew;
114 volatile double audio_skew_factor;
115 volatile long long audio_skew_measure_time;
116 volatile int audio_drop;
117 volatile int shutdown;
118
119 int audio_inited;
120 double audio_secs_per_block;
121 long long audio_usecs_per_block;
122 long long audio_skew_total;
123 long long audio_skew_delta_total;
124 long audio_recv_blocks_total;
125 long audio_sent_blocks_total;
126 pthread_mutex_t audio_mutex;
127 int audio_insert_null_samples;
128 volatile long audio_null_blocks_inserted;
129 volatile long long dropped_frames_timeshift;
130 long long dropped_frames_compensated;
131 } priv_t;
132
133 #include "tvi_def.h"
134
135 static void *audio_grabber(void *data);
136 static void *video_grabber(void *data);
137
138 /**********************************************************************\
139
140 Only few of the fourccs are the same in v4l2 and mplayer:
141
142 IMGFMT_YVU9 == V4L2_PIX_FMT_YVU410
143 IMGFMT_YV12 == V4L2_PIX_FMT_YVU420
144 IMGFMT_NV12 == V4L2_PIX_FMT_NV12
145 IMGFMT_422P == V4L2_PIX_FMT_YUV422P
146 IMGFMT_411P == V4L2_PIX_FMT_YUV411P
147 IMGFMT_UYVY == V4L2_PIX_FMT_UYVY
148 IMGFMT_Y41P == V4L2_PIX_FMT_Y41P
149
150 This may be an useful translation table for some others:
151
152 IMGFMT_RGB8 == V4L2_PIX_FMT_RGB332
153 IMGFMT_BGR15 == V4L2_PIX_FMT_RGB555
154 IMGFMT_BGR16 == V4L2_PIX_FMT_RGB565
155 IMGFMT_RGB24 == V4L2_PIX_FMT_RGB24
156 IMGFMT_RGB32 == V4L2_PIX_FMT_RGB32
157 IMGFMT_BGR24 == V4L2_PIX_FMT_BGR24
158 IMGFMT_BGR32 == V4L2_PIX_FMT_BGR32
159 IMGFMT_Y800 == V4L2_PIX_FMT_GREY
160 IMGFMT_IF09 == V4L2_PIX_FMT_YUV410
161 IMGFMT_I420 == V4L2_PIX_FMT_YUV420
162 IMGFMT_YUY2 == V4L2_PIX_FMT_YUYV
163
164 \**********************************************************************/
165
166 /*
167 ** Translate a mplayer fourcc to a video4linux2 pixel format.
168 */
169 static int fcc_mp2vl(int fcc)
170 {
171 switch (fcc) {
172 case IMGFMT_RGB8: return V4L2_PIX_FMT_RGB332;
173 case IMGFMT_BGR15: return V4L2_PIX_FMT_RGB555;
174 case IMGFMT_BGR16: return V4L2_PIX_FMT_RGB565;
175 case IMGFMT_RGB24: return V4L2_PIX_FMT_RGB24;
176 case IMGFMT_RGB32: return V4L2_PIX_FMT_RGB32;
177 case IMGFMT_BGR24: return V4L2_PIX_FMT_BGR24;
178 case IMGFMT_BGR32: return V4L2_PIX_FMT_BGR32;
179 case IMGFMT_Y800: return V4L2_PIX_FMT_GREY;
180 case IMGFMT_IF09: return V4L2_PIX_FMT_YUV410;
181 case IMGFMT_I420: return V4L2_PIX_FMT_YUV420;
182 case IMGFMT_YUY2: return V4L2_PIX_FMT_YUYV;
183 case IMGFMT_YV12: return V4L2_PIX_FMT_YVU420;
184 case IMGFMT_UYVY: return V4L2_PIX_FMT_UYVY;
185 }
186 return fcc;
187 }
188
189 /*
190 ** Translate a video4linux2 fourcc aka pixel format to mplayer.
191 */
192 static int fcc_vl2mp(int fcc)
193 {
194 switch (fcc) {
195 case V4L2_PIX_FMT_RGB332: return IMGFMT_RGB8;
196 case V4L2_PIX_FMT_RGB555: return IMGFMT_BGR15;
197 case V4L2_PIX_FMT_RGB565: return IMGFMT_BGR16;
198 case V4L2_PIX_FMT_RGB24: return IMGFMT_RGB24;
199 case V4L2_PIX_FMT_RGB32: return IMGFMT_RGB32;
200 case V4L2_PIX_FMT_BGR24: return IMGFMT_BGR24;
201 case V4L2_PIX_FMT_BGR32: return IMGFMT_BGR32;
202 case V4L2_PIX_FMT_GREY: return IMGFMT_Y800;
203 case V4L2_PIX_FMT_YUV410: return IMGFMT_IF09;
204 case V4L2_PIX_FMT_YUV420: return IMGFMT_I420;
205 case V4L2_PIX_FMT_YVU420: return IMGFMT_YV12;
206 case V4L2_PIX_FMT_YUYV: return IMGFMT_YUY2;
207 case V4L2_PIX_FMT_UYVY: return IMGFMT_UYVY;
208 }
209 return fcc;
210 }
211
212 /*
213 ** Translate a video4linux2 fourcc aka pixel format
214 ** to a human readable string.
215 */
216 static const char *pixfmt2name(int pixfmt)
217 {
218 static char unknown[24];
219
220 switch (pixfmt) {
221 case V4L2_PIX_FMT_RGB332: return "RGB332";
222 case V4L2_PIX_FMT_RGB555: return "RGB555";
223 case V4L2_PIX_FMT_RGB565: return "RGB565";
224 case V4L2_PIX_FMT_RGB555X: return "RGB555X";
225 case V4L2_PIX_FMT_RGB565X: return "RGB565X";
226 case V4L2_PIX_FMT_BGR24: return "BGR24";
227 case V4L2_PIX_FMT_RGB24: return "RGB24";
228 case V4L2_PIX_FMT_BGR32: return "BGR32";
229 case V4L2_PIX_FMT_RGB32: return "RGB32";
230 case V4L2_PIX_FMT_GREY: return "GREY";
231 case V4L2_PIX_FMT_YVU410: return "YVU410";
232 case V4L2_PIX_FMT_YVU420: return "YVU420";
233 case V4L2_PIX_FMT_YUYV: return "YUYV";
234 case V4L2_PIX_FMT_UYVY: return "UYVY";
235 /* case V4L2_PIX_FMT_YVU422P: return "YVU422P"; */
236 /* case V4L2_PIX_FMT_YVU411P: return "YVU411P"; */
237 case V4L2_PIX_FMT_YUV422P: return "YUV422P";
238 case V4L2_PIX_FMT_YUV411P: return "YUV411P";
239 case V4L2_PIX_FMT_Y41P: return "Y41P";
240 case V4L2_PIX_FMT_NV12: return "NV12";
241 case V4L2_PIX_FMT_NV21: return "NV21";
242 case V4L2_PIX_FMT_YUV410: return "YUV410";
243 case V4L2_PIX_FMT_YUV420: return "YUV420";
244 case V4L2_PIX_FMT_YYUV: return "YYUV";
245 case V4L2_PIX_FMT_HI240: return "HI240";
246 case V4L2_PIX_FMT_WNVA: return "WNVA";
247 }
248 sprintf(unknown, "unknown (0x%x)", pixfmt);
249 return unknown;
250 }
251
252
253 /*
254 ** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
255 */
256 static int pixfmt2depth(int pixfmt)
257 {
258 switch (pixfmt) {
259 case V4L2_PIX_FMT_RGB332:
260 return 8;
261 case V4L2_PIX_FMT_RGB555:
262 case V4L2_PIX_FMT_RGB565:
263 case V4L2_PIX_FMT_RGB555X:
264 case V4L2_PIX_FMT_RGB565X:
265 return 16;
266 case V4L2_PIX_FMT_BGR24:
267 case V4L2_PIX_FMT_RGB24:
268 return 24;
269 case V4L2_PIX_FMT_BGR32:
270 case V4L2_PIX_FMT_RGB32:
271 return 32;
272 case V4L2_PIX_FMT_GREY:
273 return 8;
274 case V4L2_PIX_FMT_YVU410:
275 return 9;
276 case V4L2_PIX_FMT_YVU420:
277 return 12;
278 case V4L2_PIX_FMT_YUYV:
279 case V4L2_PIX_FMT_UYVY:
280 case V4L2_PIX_FMT_YUV422P:
281 case V4L2_PIX_FMT_YUV411P:
282 return 16;
283 case V4L2_PIX_FMT_Y41P:
284 case V4L2_PIX_FMT_NV12:
285 case V4L2_PIX_FMT_NV21:
286 return 12;
287 case V4L2_PIX_FMT_YUV410:
288 return 9;
289 case V4L2_PIX_FMT_YUV420:
290 return 12;
291 case V4L2_PIX_FMT_YYUV:
292 return 16;
293 case V4L2_PIX_FMT_HI240:
294 return 8;
295
296 }
297 return 0;
298 }
299
300 static int amode2v4l(int amode)
301 {
302 switch (amode) {
303 case 0:
304 return V4L2_TUNER_MODE_MONO;
305 case 1:
306 return V4L2_TUNER_MODE_STEREO;
307 case 2:
308 return V4L2_TUNER_MODE_LANG1;
309 case 3:
310 return V4L2_TUNER_MODE_LANG2;
311 default:
312 return -1;
313 }
314 }
315
316
317 // sets and sanitizes audio buffer/block sizes
318 static void setup_audio_buffer_sizes(priv_t *priv)
319 {
320 int bytes_per_sample = priv->audio_in.bytes_per_sample;
321 double fps = (double)priv->standard.frameperiod.denominator /
322 priv->standard.frameperiod.numerator;
323 int seconds = priv->video_buffer_size_max/fps;
324
325 if (seconds < 5) seconds = 5;
326 if (seconds > 500) seconds = 500;
327
328 // make the audio buffer at least as the video buffer capacity (or 5 seconds) long
329 priv->audio_buffer_size = 1 + seconds*priv->audio_in.samplerate
330 *priv->audio_in.channels
331 *bytes_per_sample/priv->audio_in.blocksize;
332 if (priv->audio_buffer_size < 256) priv->audio_buffer_size = 256;
333
334 // make the skew buffer at least 1 second long
335 priv->aud_skew_cnt = 1 + 1*priv->audio_in.samplerate
336 *priv->audio_in.channels
337 *bytes_per_sample/priv->audio_in.blocksize;
338 if (priv->aud_skew_cnt < 16) priv->aud_skew_cnt = 16;
339
340 mp_msg(MSGT_TV, MSGL_V, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
341 priv->audio_buffer_size, priv->audio_in.blocksize, priv->aud_skew_cnt);
342 }
343
344 static void init_audio(priv_t *priv)
345 {
346 if (priv->audio_inited) return;
347
348 if (!tv_param_noaudio) {
349 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
350 if (tv_param_alsa)
351 audio_in_init(&priv->audio_in, AUDIO_IN_ALSA);
352 else
353 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
354 #else
355 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
356 #endif
357
358 if (priv->audio_dev) {
359 audio_in_set_device(&priv->audio_in, priv->audio_dev);
360 }
361
362 audio_in_set_samplerate(&priv->audio_in, 44100);
363 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
364 if (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) {
365 audio_in_set_channels(&priv->audio_in, 2);
366 } else {
367 audio_in_set_channels(&priv->audio_in, 1);
368 }
369 } else {
370 if (tv_param_forcechan >= 0) {
371 audio_in_set_channels(&priv->audio_in, tv_param_forcechan);
372 } else {
373 audio_in_set_channels(&priv->audio_in, 2);
374 }
375 }
376
377 if (audio_in_setup(&priv->audio_in) < 0) return;
378
379 priv->audio_inited = 1;
380 }
381 }
382
383 #if 0
384 /*
385 ** the number of milliseconds elapsed between time0 and time1
386 */
387 static size_t difftv(struct timeval time1, struct timeval time0)
388 {
389 return (time1.tv_sec - time0.tv_sec) * 1000 +
390 (time1.tv_usec - time0.tv_usec) / 1000;
391 }
392 #endif
393
394 /*
395 ** Get current video capture format.
396 */
397 static int getfmt(priv_t *priv)
398 {
399 int i;
400
401 priv->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
402 if ((i = ioctl(priv->video_fd, VIDIOC_G_FMT, &priv->format)) < 0) {
403 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get format failed: %s\n",
404 info.short_name, strerror(errno));
405 }
406 return i;
407 }
408
409
410 /*
411 ** Get current video capture standard.
412 */
413 static int getstd(priv_t *priv)
414 {
415 v4l2_std_id id;
416 int i=0;
417
418 if (ioctl(priv->video_fd, VIDIOC_G_STD, &id) < 0) {
419 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get standard failed: %s\n",
420 info.short_name, strerror(errno));
421 return -1;
422 }
423 do {
424 priv->standard.index = i++;
425 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
426 return -1;
427 }
428 } while (priv->standard.id != id);
429 return 0;
430 }
431
432 /***********************************************************************\
433 * *
434 * *
435 * Interface to mplayer *
436 * *
437 * *
438 \***********************************************************************/
439
440 static int set_mute(priv_t *priv, int value)
441 {
442 struct v4l2_control control;
443 control.id = V4L2_CID_AUDIO_MUTE;
444 control.value = value;
445 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, &control) < 0) {
446 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set mute failed: %s\n",
447 info.short_name, strerror(errno));
448 return 0;
449 }
450 return 1;
451 }
452
453 /*
454 ** MPlayer uses values from -100 up to 100 for controls.
455 ** Here they are scaled to what the tv card needs and applied.
456 */
457 static int set_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
458 struct v4l2_queryctrl qctrl;
459
460 qctrl.id = control->id;
461 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
462 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
463 info.short_name, strerror(errno));
464 return TVI_CONTROL_FALSE;
465 }
466
467 if (val_signed) {
468 if (control->value < 0) {
469 control->value = qctrl.default_value + control->value *
470 (qctrl.default_value - qctrl.minimum) / 100;
471 } else {
472 control->value = qctrl.default_value + control->value *
473 (qctrl.maximum - qctrl.default_value) / 100;
474 }
475 } else {
476 if (control->value < 50) {
477 control->value = qctrl.default_value + (control->value-50) *
478 (qctrl.default_value - qctrl.minimum) / 50;
479 } else {
480 control->value = qctrl.default_value + (control->value-50) *
481 (qctrl.maximum - qctrl.default_value) / 50;
482 }
483 }
484
485
486 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, control) < 0) {
487 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl set %s %d failed: %s\n",
488 info.short_name, qctrl.name, control->value, strerror(errno));
489 return TVI_CONTROL_FALSE;
490 }
491 mp_msg(MSGT_TV, MSGL_V, "%s: set %s: %d [%d, %d]\n", info.short_name,
492 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
493
494 return TVI_CONTROL_TRUE;
495 }
496
497
498 /*
499 ** Scale the control values back to what mplayer needs.
500 */
501 static int get_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
502 struct v4l2_queryctrl qctrl;
503
504 qctrl.id = control->id;
505 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
506 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
507 info.short_name, strerror(errno));
508 return TVI_CONTROL_FALSE;
509 }
510
511 if (ioctl(priv->video_fd, VIDIOC_G_CTRL, control) < 0) {
512 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl get %s failed: %s\n",
513 info.short_name, qctrl.name, strerror(errno));
514 return TVI_CONTROL_FALSE;
515 }
516 mp_msg(MSGT_TV, MSGL_V, "%s: get %s: %d [%d, %d]\n", info.short_name,
517 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
518
519 if (val_signed) {
520 if (control->value < qctrl.default_value) {
521 control->value = (control->value - qctrl.default_value) * 100 /
522 (qctrl.default_value - qctrl.minimum);
523 } else {
524 control->value = (control->value - qctrl.default_value) * 100 /
525 (qctrl.maximum - qctrl.default_value);
526 }
527 } else {
528 if (control->value < qctrl.default_value) {
529 control->value = (control->value - qctrl.default_value) * 50 /
530 (qctrl.default_value - qctrl.minimum) + 50;
531 } else {
532 control->value = (control->value - qctrl.default_value) * 50 /
533 (qctrl.maximum - qctrl.default_value) + 50;
534 }
535 }
536
537 return TVI_CONTROL_TRUE;
538 }
539
540 static int control(priv_t *priv, int cmd, void *arg)
541 {
542 struct v4l2_control control;
543 struct v4l2_frequency frequency;
544
545 switch(cmd) {
546 case TVI_CONTROL_IS_VIDEO:
547 return priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
548 TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
549 case TVI_CONTROL_IS_AUDIO:
550 if (tv_param_force_audio) return TVI_CONTROL_TRUE;
551 case TVI_CONTROL_IS_TUNER:
552 return priv->capability.capabilities & V4L2_CAP_TUNER?
553 TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
554 case TVI_CONTROL_IMMEDIATE:
555 priv->immediate_mode = 1;
556 return TVI_CONTROL_TRUE;
557 case TVI_CONTROL_VID_GET_FPS:
558 *(float *)arg = (float)priv->standard.frameperiod.denominator /
559 priv->standard.frameperiod.numerator;
560 mp_msg(MSGT_TV, MSGL_V, "%s: get fps: %f\n", info.short_name,
561 *(float *)arg);
562 return TVI_CONTROL_TRUE;
563 case TVI_CONTROL_VID_GET_BITS:
564 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
565 *(int *)arg = pixfmt2depth(priv->format.fmt.pix.pixelformat);
566 mp_msg(MSGT_TV, MSGL_V, "%s: get depth: %d\n", info.short_name,
567 *(int *)arg);
568 return TVI_CONTROL_TRUE;
569 case TVI_CONTROL_VID_GET_FORMAT:
570 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
571 *(int *)arg = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
572 mp_msg(MSGT_TV, MSGL_V, "%s: get format: %s\n", info.short_name,
573 pixfmt2name(priv->format.fmt.pix.pixelformat));
574 return TVI_CONTROL_TRUE;
575 case TVI_CONTROL_VID_SET_FORMAT:
576 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
577 priv->format.fmt.pix.pixelformat = fcc_mp2vl(*(int *)arg);
578 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
579
580 priv->mp_format = *(int *)arg;
581 mp_msg(MSGT_TV, MSGL_V, "%s: set format: %s\n", info.short_name,
582 pixfmt2name(priv->format.fmt.pix.pixelformat));
583 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
584 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
585 info.short_name, strerror(errno));
586 return TVI_CONTROL_FALSE;
587 }
588 /* according to the v4l2 specs VIDIOC_S_FMT should not fail, inflexible drivers
589 might even always return the default parameters -> update the format here*/
590 priv->mp_format = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
591 return TVI_CONTROL_TRUE;
592 case TVI_CONTROL_VID_GET_WIDTH:
593 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
594 *(int *)arg = priv->format.fmt.pix.width;
595 mp_msg(MSGT_TV, MSGL_V, "%s: get width: %d\n", info.short_name,
596 *(int *)arg);
597 return TVI_CONTROL_TRUE;
598 case TVI_CONTROL_VID_CHK_WIDTH:
599 return TVI_CONTROL_TRUE;
600 case TVI_CONTROL_VID_SET_WIDTH:
601 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
602 priv->format.fmt.pix.width = *(int *)arg;
603 mp_msg(MSGT_TV, MSGL_V, "%s: set width: %d\n", info.short_name,
604 *(int *)arg);
605 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
606 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set width failed: %s\n",
607 info.short_name, strerror(errno));
608 return TVI_CONTROL_FALSE;
609 }
610 return TVI_CONTROL_TRUE;
611 case TVI_CONTROL_VID_GET_HEIGHT:
612 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
613 *(int *)arg = priv->format.fmt.pix.height;
614 mp_msg(MSGT_TV, MSGL_V, "%s: get height: %d\n", info.short_name,
615 *(int *)arg);
616 return TVI_CONTROL_TRUE;
617 case TVI_CONTROL_VID_CHK_HEIGHT:
618 return TVI_CONTROL_TRUE;
619 case TVI_CONTROL_VID_SET_HEIGHT:
620 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
621 priv->format.fmt.pix.height = *(int *)arg;
622 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
623 mp_msg(MSGT_TV, MSGL_V, "%s: set height: %d\n", info.short_name,
624 *(int *)arg);
625 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
626 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set height failed: %s\n",
627 info.short_name, strerror(errno));
628 return TVI_CONTROL_FALSE;
629 }
630 return TVI_CONTROL_TRUE;
631 case TVI_CONTROL_VID_GET_BRIGHTNESS:
632 control.id = V4L2_CID_BRIGHTNESS;
633 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
634 *(int *)arg = control.value;
635 return TVI_CONTROL_TRUE;
636 }
637 return TVI_CONTROL_FALSE;
638 case TVI_CONTROL_VID_SET_BRIGHTNESS:
639 control.id = V4L2_CID_BRIGHTNESS;
640 control.value = *(int *)arg;
641 return set_control(priv, &control, 1);
642 case TVI_CONTROL_VID_GET_HUE:
643 control.id = V4L2_CID_HUE;
644 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
645 *(int *)arg = control.value;
646 return TVI_CONTROL_TRUE;
647 }
648 return TVI_CONTROL_FALSE;
649 case TVI_CONTROL_VID_SET_HUE:
650 control.id = V4L2_CID_HUE;
651 control.value = *(int *)arg;
652 return set_control(priv, &control, 1);
653 case TVI_CONTROL_VID_GET_SATURATION:
654 control.id = V4L2_CID_SATURATION;
655 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
656 *(int *)arg = control.value;
657 return TVI_CONTROL_TRUE;
658 }
659 return TVI_CONTROL_FALSE;
660 case TVI_CONTROL_VID_SET_SATURATION:
661 control.id = V4L2_CID_SATURATION;
662 control.value = *(int *)arg;
663 return set_control(priv, &control, 1);
664 case TVI_CONTROL_VID_GET_CONTRAST:
665 control.id = V4L2_CID_CONTRAST;
666 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
667 *(int *)arg = control.value;
668 return TVI_CONTROL_TRUE;
669 }
670 return TVI_CONTROL_FALSE;
671 case TVI_CONTROL_VID_SET_CONTRAST:
672 control.id = V4L2_CID_CONTRAST;
673 control.value = *(int *)arg;
674 return set_control(priv, &control, 1);
675 case TVI_CONTROL_TUN_GET_FREQ:
676 frequency.tuner = 0;
677 frequency.type = V4L2_TUNER_ANALOG_TV;
678 if (ioctl(priv->video_fd, VIDIOC_G_FREQUENCY, &frequency) < 0) {
679 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl get frequency failed: %s\n",
680 info.short_name, strerror(errno));
681 return TVI_CONTROL_FALSE;
682 }
683 *(int *)arg = frequency.frequency;
684 return TVI_CONTROL_TRUE;
685 case TVI_CONTROL_TUN_SET_FREQ:
686 #if 0
687 set_mute(priv, 1);
688 usleep(100000); // wait to suppress noise during switching
689 #endif
690 frequency.tuner = 0;
691 frequency.type = V4L2_TUNER_ANALOG_TV;
692 frequency.frequency = *(int *)arg;
693 if (ioctl(priv->video_fd, VIDIOC_S_FREQUENCY, &frequency) < 0) {
694 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set frequency failed: %s\n",
695 info.short_name, strerror(errno));
696 return TVI_CONTROL_FALSE;
697 }
698 #if 0
699 usleep(100000); // wait to suppress noise during switching
700 set_mute(priv, 0);
701 #endif
702 return TVI_CONTROL_TRUE;
703 case TVI_CONTROL_TUN_GET_TUNER:
704 mp_msg(MSGT_TV, MSGL_V, "%s: get tuner\n",info.short_name);
705 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
706 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
707 info.short_name, strerror(errno));
708 return TVI_CONTROL_FALSE;
709 }
710 return TVI_CONTROL_TRUE;
711 case TVI_CONTROL_TUN_SET_TUNER:
712 mp_msg(MSGT_TV, MSGL_V, "%s: set tuner\n",info.short_name);
713 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
714 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
715 info.short_name, strerror(errno));
716 return TVI_CONTROL_FALSE;
717 }
718 return TVI_CONTROL_TRUE;
719 case TVI_CONTROL_TUN_GET_NORM:
720 *(int *)arg = priv->standard.index;
721 return TVI_CONTROL_TRUE;
722 case TVI_CONTROL_TUN_SET_NORM:
723 priv->standard.index = *(int *)arg;
724 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
725 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum norm failed: %s\n",
726 info.short_name, strerror(errno));
727 return TVI_CONTROL_FALSE;
728 }
729 mp_msg(MSGT_TV, MSGL_V, "%s: set norm: %s\n", info.short_name, priv->standard.name);
730 if (ioctl(priv->video_fd, VIDIOC_S_STD, &priv->standard.id) < 0) {
731 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set norm failed: %s\n",
732 info.short_name, strerror(errno));
733 return TVI_CONTROL_FALSE;
734 }
735 return TVI_CONTROL_TRUE;
736 case TVI_CONTROL_SPC_GET_NORMID:
737 {
738 int i;
739 for (i = 0;; i++) {
740 struct v4l2_standard standard;
741 memset(&standard, 0, sizeof(standard));
742 standard.index = i;
743 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
744 return TVI_CONTROL_FALSE;
745 if (!strcasecmp(standard.name, (char *)arg)) {
746 *(int *)arg = i;
747 return TVI_CONTROL_TRUE;
748 }
749 }
750 return TVI_CONTROL_FALSE;
751 }
752 case TVI_CONTROL_SPC_GET_INPUT:
753 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, (int *)arg) < 0) {
754 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
755 info.short_name, strerror(errno));
756 return TVI_CONTROL_FALSE;
757 }
758 return TVI_CONTROL_TRUE;
759 case TVI_CONTROL_SPC_SET_INPUT:
760 mp_msg(MSGT_TV, MSGL_V, "%s: set input: %d\n", info.short_name, *(int *)arg);
761 priv->input.index = *(int *)arg;
762 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &priv->input) < 0) {
763 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum input failed: %s\n",
764 info.short_name, strerror(errno));
765 return TVI_CONTROL_FALSE;
766 }
767 if (ioctl(priv->video_fd, VIDIOC_S_INPUT, (int *)arg) < 0) {
768 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set input failed: %s\n",
769 info.short_name, strerror(errno));
770 return TVI_CONTROL_FALSE;
771 }
772 return TVI_CONTROL_TRUE;
773 case TVI_CONTROL_AUD_GET_FORMAT:
774 init_audio(priv);
775 if (!priv->audio_inited) return TVI_CONTROL_FALSE;
776 *(int *)arg = AF_FORMAT_S16_LE;
777 mp_msg(MSGT_TV, MSGL_V, "%s: get audio format: %d\n",
778 info.short_name, *(int *)arg);
779 return TVI_CONTROL_TRUE;
780 case TVI_CONTROL_AUD_GET_SAMPLERATE:
781 init_audio(priv);
782 if (!priv->audio_inited) return TVI_CONTROL_FALSE;
783 *(int *)arg = priv->audio_in.samplerate;
784 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplerate: %d\n",
785 info.short_name, *(int *)arg);
786 return TVI_CONTROL_TRUE;
787 case TVI_CONTROL_AUD_GET_SAMPLESIZE:
788 init_audio(priv);
789 if (!priv->audio_inited) return TVI_CONTROL_FALSE;
790 *(int *)arg = priv->audio_in.bytes_per_sample;
791 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplesize: %d\n",
792 info.short_name, *(int *)arg);
793 return TVI_CONTROL_TRUE;
794 case TVI_CONTROL_AUD_GET_CHANNELS:
795 init_audio(priv);
796 if (!priv->audio_inited) return TVI_CONTROL_FALSE;
797 *(int *)arg = priv->audio_in.channels;
798 mp_msg(MSGT_TV, MSGL_V, "%s: get audio channels: %d\n",
799 info.short_name, *(int *)arg);
800 return TVI_CONTROL_TRUE;
801 case TVI_CONTROL_AUD_SET_SAMPLERATE:
802 init_audio(priv);
803 mp_msg(MSGT_TV, MSGL_V, "%s: set audio samplerate: %d\n",
804 info.short_name, *(int *)arg);
805 if (audio_in_set_samplerate(&priv->audio_in, *(int*)arg) < 0) return TVI_CONTROL_FALSE;
806 // setup_audio_buffer_sizes(priv);
807 return TVI_CONTROL_TRUE;
808 }
809 mp_msg(MSGT_TV, MSGL_V, "%s: unknown control: %d\n", info.short_name, cmd);
810 return(TVI_CONTROL_UNKNOWN);
811 }
812
813
814 #define PRIV ((priv_t *) (tvi_handle->priv))
815
816 /* handler creator - entry point ! */
817 tvi_handle_t *tvi_init_v4l2(char *video_dev, char *audio_dev)
818 {
819 tvi_handle_t *tvi_handle;
820
821 /* new_handle initializes priv with memset 0 */
822 tvi_handle = new_handle();
823 if (!tvi_handle) {
824 return NULL;
825 }
826 PRIV->video_fd = -1;
827
828 PRIV->video_dev = strdup(video_dev? video_dev: "/dev/video0");
829 if (!PRIV->video_dev) {
830 free_handle(tvi_handle);
831 return NULL;
832 }
833
834 if (audio_dev) {
835 PRIV->audio_dev = strdup(audio_dev);
836 if (!PRIV->audio_dev) {
837 free(PRIV->video_dev);
838 free_handle(tvi_handle);
839 return NULL;
840 }
841 }
842
843 return tvi_handle;
844 }
845
846 #undef PRIV
847
848
849 static int uninit(priv_t *priv)
850 {
851 int i, frames, dropped = 0;
852
853 priv->shutdown = 1;
854 if(priv->video_grabber_thread)
855 pthread_join(priv->video_grabber_thread, NULL);
856 pthread_mutex_destroy(&priv->video_buffer_mutex);
857
858 if (priv->streamon) {
859 struct v4l2_buffer buf;
860
861 /* get performance */
862 frames = 1 + (priv->curr_frame - priv->first_frame +
863 priv->standard.frameperiod.numerator * 500000 /
864 priv->standard.frameperiod.denominator) *
865 priv->standard.frameperiod.denominator /
866 priv->standard.frameperiod.numerator / 1000000;
867 dropped = frames - priv->frames;
868
869 /* turn off streaming */
870 if (ioctl(priv->video_fd, VIDIOC_STREAMOFF, &(priv->map[0].buf.type)) < 0) {
871 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamoff failed: %s\n",
872 info.short_name, strerror(errno));
873 }
874 priv->streamon = 0;
875
876 /* unqueue all remaining buffers */
877 memset(&buf,0,sizeof(buf));
878 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
879 while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
880 }
881
882 /* unmap all buffers */
883 for (i = 0; i < priv->mapcount; i++) {
884 if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {
885 mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",
886 info.short_name, strerror(errno));
887 }
888 }
889
890 /* stop audio thread */
891 if (!tv_param_noaudio && priv->audio_grabber_thread) {
892 pthread_join(priv->audio_grabber_thread, NULL);
893 pthread_mutex_destroy(&priv->skew_mutex);
894 pthread_mutex_destroy(&priv->audio_mutex);
895 }
896
897 set_mute(priv, 1);
898
899 /* free memory and close device */
900 free(priv->map); priv->map = NULL;
901 priv->mapcount = 0;
902 if(priv->video_fd!=-1)close(priv->video_fd); priv->video_fd = -1;
903 free(priv->video_dev); priv->video_dev = NULL;
904
905 if (priv->video_ringbuffer) {
906 int i;
907 for (i = 0; i < priv->video_buffer_size_current; i++) {
908 free(priv->video_ringbuffer[i]);
909 }
910 free(priv->video_ringbuffer);
911 }
912 if (priv->video_timebuffer)
913 free(priv->video_timebuffer);
914 if (!tv_param_noaudio) {
915 if (priv->audio_ringbuffer)
916 free(priv->audio_ringbuffer);
917 if (priv->audio_skew_buffer)
918 free(priv->audio_skew_buffer);
919 if (priv->audio_skew_delta_buffer)
920 free(priv->audio_skew_delta_buffer);
921 }
922
923 /* show some nice statistics ;-) */
924 mp_msg(MSGT_TV, MSGL_INFO,
925 "%s: %d frames successfully processed, %d frames dropped.\n",
926 info.short_name, priv->frames, dropped);
927 mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",
928 info.short_name, priv->video_buffer_size_current);
929 return 1;
930 }
931
932
933 /* initialisation */
934 static int init(priv_t *priv)
935 {
936 int i;
937
938 priv->audio_ringbuffer = NULL;
939 priv->audio_skew_buffer = NULL;
940 priv->audio_skew_delta_buffer = NULL;
941
942 priv->audio_inited = 0;
943
944 /* Open the video device. */
945 priv->video_fd = open(priv->video_dev, O_RDWR);
946 if (priv->video_fd < 0) {
947 mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",
948 info.short_name, priv->video_dev, strerror(errno));
949 uninit(priv);
950 return 0;
951 }
952 mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",
953 info.short_name, priv->video_dev, priv->video_fd);
954
955 /*
956 ** Query the video capabilities and current settings
957 ** for further control calls.
958 */
959 if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
960 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",
961 info.short_name, strerror(errno));
962 uninit(priv);
963 return 0;
964 }
965
966 if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))
967 {
968 mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",
969 priv->video_dev);
970 return 0;
971 }
972
973 if (getfmt(priv) < 0) {
974 uninit(priv);
975 return 0;
976 }
977 getstd(priv);
978 /*
979 ** if this device has got a tuner query it's settings
980 ** otherwise set some nice defaults
981 */
982 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
983 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
984 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
985 info.short_name, strerror(errno));
986 uninit(priv);
987 return 0;
988 }
989 }
990 mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);
991 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
992 mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",
993 (priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",
994 (priv->tuner.capability & V4L2_TUNER_CAP_LANG1) ? " LANG1" : "",
995 (priv->tuner.capability & V4L2_TUNER_CAP_LANG2) ? " LANG2" : "");
996 mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",
997 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO) ? " MONO" : "",
998 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",
999 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1) ? " LANG1" : "",
1000 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2) ? " LANG2" : "");
1001 }
1002 mp_msg(MSGT_TV, MSGL_INFO, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1003 priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
1004 " video capture": "",
1005 priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?
1006 " video output": "",
1007 priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?
1008 " video overlay": "",
1009 priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?
1010 " VBI capture device": "",
1011 priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?
1012 " VBI output": "",
1013 priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?
1014 " RDS data capture": "",
1015 priv->capability.capabilities & V4L2_CAP_TUNER?
1016 " tuner": "",
1017 priv->capability.capabilities & V4L2_CAP_AUDIO?
1018 " audio": "",
1019 priv->capability.capabilities & V4L2_CAP_READWRITE?
1020 " read/write": "",
1021 priv->capability.capabilities & V4L2_CAP_ASYNCIO?
1022 " async i/o": "",
1023 priv->capability.capabilities & V4L2_CAP_STREAMING?
1024 " streaming": "");
1025 mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");
1026 for (i = 0;; i++) {
1027 struct v4l2_standard standard;
1028 memset(&standard, 0, sizeof(standard));
1029 standard.index = i;
1030 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
1031 break;
1032 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);
1033 }
1034 mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");
1035 for (i = 0; 1; i++) {
1036 struct v4l2_input input;
1037
1038 input.index = i;
1039 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
1040 break;
1041 }
1042 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);
1043 }
1044 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
1045 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
1046 info.short_name, strerror(errno));
1047 }
1048 mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);
1049 for (i = 0; ; i++) {
1050 struct v4l2_fmtdesc fmtdesc;
1051
1052 fmtdesc.index = i;
1053 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1054 if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
1055 break;
1056 }
1057 mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",
1058 pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),
1059 fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));
1060 }
1061 mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",
1062 pixfmt2name(priv->format.fmt.pix.pixelformat));
1063
1064 /* set some nice defaults */
1065 if (getfmt(priv) < 0) return 0;
1066 priv->format.fmt.pix.width = 640;
1067 priv->format.fmt.pix.height = 480;
1068 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
1069 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
1070 info.short_name, strerror(errno));
1071 uninit(priv);
1072 return 0;
1073 }
1074
1075 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !tv_param_force_audio) tv_param_noaudio = 1;
1076
1077 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1078 struct v4l2_control control;
1079 if (tv_param_amode >= 0) {
1080 mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);
1081 priv->tuner.audmode = amode2v4l(tv_param_amode);
1082 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
1083 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
1084 info.short_name, strerror(errno));
1085 return TVI_CONTROL_FALSE;
1086 }
1087 }
1088 mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,
1089 (priv->tuner.audmode == V4L2_TUNER_MODE_MONO) ? " MONO" : "",
1090 (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",
1091 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG1) ? " LANG1" : "",
1092 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG2) ? " LANG2" : "");
1093
1094 if (tv_param_volume >= 0) {
1095 control.id = V4L2_CID_AUDIO_VOLUME;
1096 control.value = tv_param_volume;
1097 set_control(priv, &control, 0);
1098 }
1099 if (tv_param_bass >= 0) {
1100 control.id = V4L2_CID_AUDIO_BASS;
1101 control.value = tv_param_bass;
1102 set_control(priv, &control, 0);
1103 }
1104 if (tv_param_treble >= 0) {
1105 control.id = V4L2_CID_AUDIO_TREBLE;
1106 control.value = tv_param_treble;
1107 set_control(priv, &control, 0);
1108 }
1109 if (tv_param_balance >= 0) {
1110 control.id = V4L2_CID_AUDIO_BALANCE;
1111 control.value = tv_param_balance;
1112 set_control(priv, &control, 0);
1113 }
1114 }
1115
1116 return 1;
1117 }
1118
1119 static int get_capture_buffer_size(priv_t *priv)
1120 {
1121 int bufsize, cnt;
1122 int w = priv->format.fmt.pix.width;
1123 int h = priv->format.fmt.pix.height;
1124 int d = pixfmt2depth(priv->format.fmt.pix.pixelformat);
1125 int bytesperline = w*d/8;
1126
1127 if (tv_param_buffer_size >= 0) {
1128 bufsize = tv_param_buffer_size*1024*1024;
1129 } else {
1130 #ifdef HAVE_SYS_SYSINFO_H
1131 struct sysinfo si;
1132
1133 sysinfo(&si);
1134 if (si.totalram<2*1024*1024) {
1135 bufsize = 1024*1024;
1136 } else {
1137 bufsize = si.totalram/2;
1138 }
1139 #else
1140 bufsize = 16*1024*1024;
1141 #endif
1142 }
1143
1144 cnt = bufsize/(h*bytesperline);
1145 if (cnt < 2) cnt = 2;
1146
1147 return cnt;
1148 }
1149
1150 /* that's the real start, we'got the format parameters (checked with control) */
1151 static int start(priv_t *priv)
1152 {
1153 struct v4l2_requestbuffers request;
1154 int i;
1155
1156 /* setup audio parameters */
1157
1158 init_audio(priv);
1159 if (!tv_param_noaudio && !priv->audio_inited) return 0;
1160
1161 /* we need this to size the audio buffer properly */
1162 if (priv->immediate_mode) {
1163 priv->video_buffer_size_max = 2;
1164 } else {
1165 priv->video_buffer_size_max = get_capture_buffer_size(priv);
1166 }
1167
1168 if (!tv_param_noaudio) {
1169 setup_audio_buffer_sizes(priv);
1170 priv->audio_skew_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1171 if (!priv->audio_skew_buffer) {
1172 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1173 return 0;
1174 }
1175 priv->audio_skew_delta_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1176 if (!priv->audio_skew_delta_buffer) {
1177 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1178 return 0;
1179 }
1180
1181 priv->audio_ringbuffer = calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
1182 if (!priv->audio_ringbuffer) {
1183 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
1184 return 0;
1185 }
1186
1187 priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate
1188 *priv->audio_in.channels
1189 *priv->audio_in.bytes_per_sample);
1190 priv->audio_usecs_per_block = 1e6*priv->audio_secs_per_block;
1191 priv->audio_head = 0;
1192 priv->audio_tail = 0;
1193 priv->audio_cnt = 0;
1194 priv->audio_drop = 0;
1195 priv->audio_skew = 0;
1196 priv->audio_skew_total = 0;
1197 priv->audio_skew_delta_total = 0;
1198 priv->audio_recv_blocks_total = 0;
1199 priv->audio_sent_blocks_total = 0;
1200 priv->audio_null_blocks_inserted = 0;
1201 priv->audio_insert_null_samples = 0;
1202 priv->dropped_frames_timeshift = 0;
1203 priv->dropped_frames_compensated = 0;
1204
1205 pthread_mutex_init(&priv->skew_mutex, NULL);
1206 pthread_mutex_init(&priv->audio_mutex, NULL);
1207 }
1208
1209 /* setup video parameters */
1210 if (!tv_param_noaudio) {
1211 if (priv->video_buffer_size_max < (3*priv->standard.frameperiod.denominator) /
1212 priv->standard.frameperiod.numerator
1213 *priv->audio_secs_per_block) {
1214 mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"
1215 "You will probably experience heavy framedrops.\n");
1216 }
1217 }
1218
1219 {
1220 int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1221
1222 mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1223 priv->video_buffer_size_max,
1224 priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));
1225 }
1226
1227 priv->video_ringbuffer = calloc(priv->video_buffer_size_max, sizeof(unsigned char*));
1228 if (!priv->video_ringbuffer) {
1229 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
1230 return 0;
1231 }
1232 for (i = 0; i < priv->video_buffer_size_max; i++)
1233 priv->video_ringbuffer[i] = NULL;
1234 priv->video_timebuffer = calloc(priv->video_buffer_size_max, sizeof(long long));
1235 if (!priv->video_timebuffer) {
1236 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate time buffer: %s\n", strerror(errno));
1237 return 0;
1238 }
1239
1240 pthread_mutex_init(&priv->video_buffer_mutex, NULL);
1241
1242 priv->video_head = 0;
1243 priv->video_tail = 0;
1244 priv->video_cnt = 0;
1245
1246 /* request buffers */
1247 if (priv->immediate_mode) {
1248 request.count = 2;
1249 } else {
1250 request.count = BUFFER_COUNT;
1251 }
1252
1253 request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1254 request.memory = V4L2_MEMORY_MMAP;
1255 if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
1256 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",
1257 info.short_name, strerror(errno));
1258 return 0;
1259 }
1260
1261 /* query buffers */
1262 if (!(priv->map = calloc(request.count, sizeof(struct map)))) {
1263 mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",
1264 info.short_name, strerror(errno));
1265 return 0;
1266 }
1267
1268 /* map and queue buffers */
1269 for (i = 0; i < request.count; i++) {
1270 memset(&priv->map[i].buf,0,sizeof(priv->map[i].buf));
1271 priv->map[i].buf.index = i;
1272 priv->map[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1273 priv->map[i].buf.memory = V4L2_MEMORY_MMAP;
1274 if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
1275 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",
1276 info.short_name, strerror(errno));
1277 free(priv->map);
1278 priv->map = NULL;
1279 return 0;
1280 }
1281 priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |
1282 PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);
1283 if (priv->map[i].addr == MAP_FAILED) {
1284 mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",
1285 info.short_name, strerror(errno));
1286 priv->map[i].len = 0;
1287 return 0;
1288 }
1289 priv->map[i].len = priv->map[i].buf.length;
1290 /* count up to make sure this is correct everytime */
1291 priv->mapcount++;
1292
1293 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1294 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1295 info.short_name, strerror(errno));
1296 return 0;
1297 }
1298 }
1299
1300 /* start audio thread */
1301 priv->shutdown = 0;
1302 priv->audio_skew_measure_time = 0;
1303 priv->first_frame = 0;
1304 priv->audio_skew = 0;
1305 priv->first = 1;
1306
1307 set_mute(priv, 0);
1308
1309 return 1;
1310 }
1311
1312
1313 #ifdef HAVE_TV_BSDBT848
1314 static double grabimmediate_video_frame(priv_t *priv, char *buffer, int len)
1315 {
1316 memset(buffer, 0xCC, len);
1317 return(1);
1318 }
1319 #endif /* HAVE_TV_BSDBT848 */
1320
1321 // copies a video frame
1322 static inline void copy_frame(priv_t *priv, unsigned char *dest, unsigned char *source)
1323 {
1324 int w = priv->format.fmt.pix.width;
1325 int h = priv->format.fmt.pix.height;
1326 int d = pixfmt2depth(priv->format.fmt.pix.pixelformat);
1327 int bytesperline = w*d/8;
1328
1329 memcpy(dest, source, bytesperline * h);
1330 }
1331
1332 // maximum skew change, in frames
1333 #define MAX_SKEW_DELTA 0.6
1334 static void *video_grabber(void *data)
1335 {
1336 priv_t *priv = (priv_t*)data;
1337 long long skew, prev_skew, xskew, interval, prev_interval, delta;
1338 int i;
1339 int framesize = priv->format.fmt.pix.height*priv->format.fmt.pix.width*
1340 pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1341 fd_set rdset;
1342 struct timeval timeout;
1343 struct v4l2_buffer buf;
1344
1345 xskew = 0;
1346 skew = 0;
1347 interval = 0;
1348 prev_interval = 0;
1349 prev_skew = 0;
1350
1351 mp_msg(MSGT_TV, MSGL_V, "%s: going to capture\n", info.short_name);
1352 if (ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
1353 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamon failed: %s\n",
1354 info.short_name, strerror(errno));
1355 return 0;
1356 }
1357 priv->streamon = 1;
1358
1359 if (!tv_param_noaudio) {
1360 pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
1361 }
1362
1363 for (priv->frames = 0; !priv->shutdown;)
1364 {
1365 int ret;
1366
1367 if (priv->immediate_mode) {
1368 while (priv->video_cnt == priv->video_buffer_size_max) {
1369 usleep(10000);
1370 if (priv->shutdown) {
1371 return NULL;
1372 }
1373 }
1374 }
1375
1376 FD_ZERO (&rdset);
1377 FD_SET (priv->video_fd, &rdset);
1378
1379 timeout.tv_sec = 1;
1380 timeout.tv_usec = 0;
1381
1382 i = select(priv->video_fd + 1, &rdset, NULL, NULL, &timeout);
1383 if (i < 0) {
1384 mp_msg(MSGT_TV, MSGL_ERR, "%s: select failed: %s\n",
1385 info.short_name, strerror(errno));
1386 continue;
1387 }
1388 else if (i == 0) {
1389 mp_msg(MSGT_TV, MSGL_ERR, "%s: select timeout\n", info.short_name);
1390 continue;
1391 }
1392 else if (!FD_ISSET(priv->video_fd, &rdset)) {
1393 continue;
1394 }
1395
1396 memset(&buf,0,sizeof(buf));
1397 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1398 ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
1399
1400 if (ret < 0) {
1401 /*
1402 if there's no signal, the buffer might me dequeued
1403 so we query all the buffers to see which one we should
1404 put back to queue
1405
1406 observed with saa7134 0.2.8
1407 don't know if is it a bug or (mis)feature
1408 */
1409 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1410 info.short_name, strerror(errno), buf.index);
1411 for (i = 0; i < priv->mapcount; i++) {
1412 memset(&buf,0,sizeof(buf));
1413 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1414 buf.index = i;
1415 ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
1416 if (ret < 0) {
1417 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s, idx = %d\n",
1418 info.short_name, strerror(errno), buf.index);
1419 return 0;
1420 }
1421 if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
1422 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1423 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1424 info.short_name, strerror(errno));
1425 return 0;
1426 }
1427 }
1428 }
1429 continue;
1430 }
1431
1432 /* store the timestamp of the very first frame as reference */
1433 if (!priv->frames++) {
1434 if (!tv_param_noaudio) pthread_mutex_lock(&priv->skew_mutex);
1435 priv->first_frame = (long long)1e6*buf.timestamp.tv_sec + buf.timestamp.tv_usec;
1436 if (!tv_param_noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1437 }
1438 priv->curr_frame = (long long)buf.timestamp.tv_sec*1e6+buf.timestamp.tv_usec;
1439 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1440
1441 interval = priv->curr_frame - priv->first_frame;
1442 delta = interval - prev_interval;
1443
1444 if (!priv->immediate_mode) {
1445 // interpolate the skew in time
1446 if (!tv_param_noaudio) pthread_mutex_lock(&priv->skew_mutex);
1447 xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
1448 if (!tv_param_noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1449 // correct extreme skew changes to avoid (especially) moving backwards in time
1450 if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
1451 skew = prev_skew + delta*MAX_SKEW_DELTA;
1452 } else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) {
1453 skew = prev_skew - delta*MAX_SKEW_DELTA;
1454 } else {
1455 skew = xskew;
1456 }
1457 }
1458
1459 mp_msg(MSGT_TV, MSGL_DBG3, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1460 delta ? (double)1e6/delta : -1,
1461 (double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
1462 mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
1463
1464 prev_skew = skew;
1465 prev_interval = interval;
1466
1467 /* allocate a new buffer, if needed */
1468 pthread_mutex_lock(&priv->video_buffer_mutex);
1469 if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
1470 if (priv->video_cnt == priv->video_buffer_size_current) {
1471 unsigned char *newbuf = malloc(framesize);
1472 if (newbuf) {
1473 memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
1474 (priv->video_buffer_size_current-priv->video_tail)*sizeof(unsigned char *));
1475 memmove(priv->video_timebuffer+priv->video_tail+1, priv->video_timebuffer+priv->video_tail,
1476 (priv->video_buffer_size_current-priv->video_tail)*sizeof(long long));
1477 priv->video_ringbuffer[priv->video_tail] = newbuf;
1478 if ((priv->video_head >= priv->video_tail) && (priv->video_cnt > 0)) priv->video_head++;
1479 priv->video_buffer_size_current++;
1480 }
1481 }
1482 }
1483 pthread_mutex_unlock(&priv->video_buffer_mutex);
1484
1485 if (priv->video_cnt == priv->video_buffer_size_current) {
1486 if (!priv->immediate_mode) {
1487 mp_msg(MSGT_TV, MSGL_ERR, "\nvideo buffer full - dropping frame\n");
1488 if (priv->audio_insert_null_samples) {
1489 pthread_mutex_lock(&priv->audio_mutex);
1490 priv->dropped_frames_timeshift += delta;
1491 pthread_mutex_unlock(&priv->audio_mutex);
1492 }
1493 }
1494 } else {
1495 if (priv->immediate_mode) {
1496 priv->video_timebuffer[priv->video_tail] = 0;
1497 } else {
1498 // compensate for audio skew
1499 // negative skew => there are more audio samples, increase interval
1500 // positive skew => less samples, shorten the interval
1501 priv->video_timebuffer[priv->video_tail] = interval - skew;
1502 if (priv->audio_insert_null_samples && priv->video_timebuffer[priv->video_tail] > 0) {
1503 pthread_mutex_lock(&priv->audio_mutex);
1504 priv->video_timebuffer[priv->video_tail] +=
1505 (priv->audio_null_blocks_inserted
1506 - priv->dropped_frames_timeshift/priv->audio_usecs_per_block)
1507 *priv->audio_usecs_per_block;
1508 pthread_mutex_unlock(&priv->audio_mutex);
1509 }
1510 }
1511
1512 copy_frame(priv, priv->video_ringbuffer[priv->video_tail], priv->map[buf.index].addr);
1513 priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
1514 priv->video_cnt++;
1515 }
1516 if (ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
1517 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1518 info.short_name, strerror(errno));
1519 return 0;
1520 }
1521 }
1522 return NULL;
1523 }
1524
1525 #define MAX_LOOP 50
1526 static double grab_video_frame(priv_t *priv, char *buffer, int len)
1527 {
1528 double interval;
1529 int loop_cnt = 0;
1530
1531 if (priv->first) {
1532 pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1533 priv->first = 0;
1534 }
1535
1536 while (priv->video_cnt == 0) {
1537 usleep(10000);
1538 if (loop_cnt++ > MAX_LOOP) return 0;
1539 }
1540
1541 pthread_mutex_lock(&priv->video_buffer_mutex);
1542 interval = (double)priv->video_timebuffer[priv->video_head]*1e-6;
1543 memcpy(buffer, priv->video_ringbuffer[priv->video_head], len);
1544 priv->video_cnt--;
1545 priv->video_head = (priv->video_head+1)%priv->video_buffer_size_current;
1546 pthread_mutex_unlock(&priv->video_buffer_mutex);
1547
1548 return interval;
1549 }
1550
1551 static int get_video_framesize(priv_t *priv)
1552 {
1553 return priv->format.fmt.pix.sizeimage;
1554 }
1555
1556 //#define DOUBLESPEED
1557 #ifdef DOUBLESPEED
1558 // for testing purposes only
1559 static void read_doublespeed(priv_t *priv)
1560 {
1561 char *bufx = calloc(priv->audio_in.blocksize, 2);
1562 short *s;
1563 short *d;
1564 int i;
1565
1566 audio_in_read_chunk(&priv->audio_in, bufx);
1567 audio_in_read_chunk(&priv->audio_in, bufx+priv->audio_in.blocksize);
1568
1569 s = bufx;
1570 d = priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize;
1571 for (i = 0; i < priv->audio_in.blocksize/2; i++) {
1572 *d++ = *s++;
1573 *s++;
1574 }
1575
1576 }
1577 #endif
1578
1579 static void *audio_grabber(void *data)
1580 {
1581 priv_t *priv = (priv_t*)data;
1582 struct timeval tv;
1583 int i, audio_skew_ptr = 0;
1584 long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
1585 long long start_time_avg;
1586
1587 gettimeofday(&tv, NULL);
1588 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1589 audio_in_start_capture(&priv->audio_in);
1590 for (i = 0; i < priv->aud_skew_cnt; i++)
1591 priv->audio_skew_buffer[i] = 0;
1592 for (i = 0; i < priv->aud_skew_cnt; i++)
1593 priv->audio_skew_delta_buffer[i] = 0;
1594
1595 for (; !priv->shutdown;)
1596 {
1597 #ifdef DOUBLESPEED
1598 read_doublespeed(priv);
1599 #else
1600 if (audio_in_read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize) < 0)
1601 continue;
1602 #endif
1603 pthread_mutex_lock(&priv->skew_mutex);
1604 if (priv->first_frame == 0) {
1605 // there is no first frame yet (unlikely to happen)
1606 gettimeofday(&tv, NULL);
1607 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1608 // fprintf(stderr, "warning - first frame not yet available!\n");
1609 pthread_mutex_unlock(&priv->skew_mutex);
1610 continue;
1611 }
1612 pthread_mutex_unlock(&priv->skew_mutex);
1613
1614 gettimeofday(&tv, NULL);
1615
1616 priv->audio_recv_blocks_total++;
1617 current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
1618
1619 if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
1620 start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1621 priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
1622 }
1623
1624 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1625 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1626
1627 // put the current skew into the ring buffer
1628 priv->audio_skew_total -= priv->audio_skew_buffer[audio_skew_ptr];
1629 priv->audio_skew_buffer[audio_skew_ptr] = current_time
1630 - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1631 priv->audio_skew_total += priv->audio_skew_buffer[audio_skew_ptr];
1632
1633 pthread_mutex_lock(&priv->skew_mutex);
1634
1635 // skew calculation
1636
1637 // compute the sliding average of the skews
1638 if (priv->audio_recv_blocks_total > priv->aud_skew_cnt) {
1639 priv->audio_skew = priv->audio_skew_total/priv->aud_skew_cnt;
1640 } else {
1641 priv->audio_skew = priv->audio_skew_total/priv->audio_recv_blocks_total;
1642 }
1643
1644 // put the current skew change (skew-prev_skew) into the ring buffer
1645 priv->audio_skew_delta_total -= priv->audio_skew_delta_buffer[audio_skew_ptr];
1646 priv->audio_skew_delta_buffer[audio_skew_ptr] = priv->audio_skew - prev_skew_uncorr;
1647 priv->audio_skew_delta_total += priv->audio_skew_delta_buffer[audio_skew_ptr];
1648 prev_skew_uncorr = priv->audio_skew; // remember the _uncorrected_ average value
1649
1650 audio_skew_ptr = (audio_skew_ptr+1) % priv->aud_skew_cnt; // rotate the buffer pointer
1651
1652 // sliding average approximates the value in the middle of the interval
1653 // so interpolate the skew value further to the current time
1654 priv->audio_skew += priv->audio_skew_delta_total/2;
1655
1656 // now finally, priv->audio_skew contains fairly good approximation
1657 // of the current value
1658
1659 // current skew factor (assuming linearity)
1660 // used for further interpolation in video_grabber
1661 // probably overkill but seems to be necessary for
1662 // stress testing by dropping half of the audio frames ;)
1663 // especially when using ALSA with large block sizes
1664 // where audio_skew remains a long while behind
1665 if ((priv->audio_skew_measure_time != 0) && (current_time - priv->audio_skew_measure_time != 0)) {
1666 priv->audio_skew_factor = (double)(priv->audio_skew-prev_skew)/(current_time - priv->audio_skew_measure_time);
1667 } else {
1668 priv->audio_skew_factor = 0.0;
1669 }
1670
1671 priv->audio_skew_measure_time = current_time;
1672 prev_skew = priv->audio_skew;
1673 priv->audio_skew += priv->audio_start_time - priv->first_frame;
1674 pthread_mutex_unlock(&priv->skew_mutex);
1675
1676 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1677
1678 pthread_mutex_lock(&priv->audio_mutex);
1679 if ((priv->audio_tail+1) % priv->audio_buffer_size == priv->audio_head) {
1680 mp_msg(MSGT_TV, MSGL_ERR, "\ntoo bad - dropping audio frame !\n");
1681 priv->audio_drop++;
1682 } else {
1683 priv->audio_tail = (priv->audio_tail+1) % priv->audio_buffer_size;
1684 priv->audio_cnt++;
1685 }
1686 pthread_mutex_unlock(&priv->audio_mutex);
1687 }
1688 return NULL;
1689 }
1690
1691 static double grab_audio_frame(priv_t *priv, char *buffer, int len)
1692 {
1693 mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1694 priv, buffer, len);
1695
1696 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1697 // => switch to the mode which outputs audio immediately, even if
1698 // it should be silence
1699 if (priv->first) priv->audio_insert_null_samples = 1;
1700
1701 pthread_mutex_lock(&priv->audio_mutex);
1702 while (priv->audio_insert_null_samples
1703 && priv->dropped_frames_timeshift - priv->dropped_frames_compensated >= priv->audio_usecs_per_block) {
1704 // some frames were dropped - drop the corresponding number of audio blocks
1705 if (priv->audio_drop) {
1706 priv->audio_drop--;
1707 } else {
1708 if (priv->audio_head == priv->audio_tail) break;
1709 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1710 }
1711 priv->dropped_frames_compensated += priv->audio_usecs_per_block;
1712 }
1713
1714 // compensate for dropped audio frames
1715 if (priv->audio_drop && (priv->audio_head == priv->audio_tail)) {
1716 priv->audio_drop--;
1717 memset(buffer, 0, len);
1718 goto out;
1719 }
1720
1721 if (priv->audio_insert_null_samples && (priv->audio_head == priv->audio_tail)) {
1722 // return silence to avoid desync and stuttering
1723 memset(buffer, 0, len);
1724 priv->audio_null_blocks_inserted++;
1725 goto out;
1726 }
1727
1728 pthread_mutex_unlock(&priv->audio_mutex);
1729 while (priv->audio_head == priv->audio_tail) {
1730 // this is mencoder => just wait until some audio is available
1731 usleep(10000);
1732 }
1733 pthread_mutex_lock(&priv->audio_mutex);
1734 memcpy(buffer, priv->audio_ringbuffer+priv->audio_head*priv->audio_in.blocksize, len);
1735 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1736 priv->audio_cnt--;
1737 out:
1738 pthread_mutex_unlock(&priv->audio_mutex);
1739 priv->audio_sent_blocks_total++;
1740 return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
1741 }
1742
1743 static int get_audio_framesize(priv_t *priv)
1744 {
1745 return(priv->audio_in.blocksize);
1746 }