Make sure that -sid works even if the number of subtitles initially detected
[mplayer/glamo.git] / stream / tvi_v4l2.c
blobbf9ad46cfed614b6c56e3feef8eb0aa40f9f9340
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@gmail.com>
8 **
9 ** File licensed under the GPL, see http://www.fsf.org/ for more info.
11 ** Some ideas are based on works from
12 ** Alex Beregszaszi <alex@fsn.hu>
13 ** Gerd Knorr <kraxel@bytesex.org>
15 ** CODE IS UNDER DEVELOPMENT, NO FEATURE REQUESTS PLEASE!
20 known issues:
21 - norm setting isn't consistent with tvi_v4l
22 - the same for volume/bass/treble/balance
26 #include "config.h"
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 "libmpcodecs/img_format.h"
45 #include "libaf/af_format.h"
46 #include "tv.h"
47 #include "audio_in.h"
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 ;-)"
57 struct map {
58 struct v4l2_buffer buf;
59 void *addr;
60 size_t len;
63 #define BUFFER_COUNT 6
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;
86 /* 2nd level video buffers */
87 int first;
88 int immediate_mode;
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;
100 /* audio */
101 char *audio_dev;
102 audio_in_t audio_in;
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;
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;
133 #include "tvi_def.h"
135 static void *audio_grabber(void *data);
136 static void *video_grabber(void *data);
138 /**********************************************************************\
140 Only few of the fourccs are the same in v4l2 and mplayer:
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
150 This may be an useful translation table for some others:
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
164 \**********************************************************************/
167 ** Translate a mplayer fourcc to a video4linux2 pixel format.
169 static int fcc_mp2vl(int fcc)
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;
186 return fcc;
190 ** Translate a video4linux2 fourcc aka pixel format to mplayer.
192 static int fcc_vl2mp(int fcc)
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;
209 return fcc;
213 ** Translate a video4linux2 fourcc aka pixel format
214 ** to a human readable string.
216 static const char *pixfmt2name(int pixfmt)
218 static char unknown[24];
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";
248 sprintf(unknown, "unknown (0x%x)", pixfmt);
249 return unknown;
254 ** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
256 static int pixfmt2depth(int pixfmt)
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;
297 return 0;
300 static int amode2v4l(int amode)
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;
317 // sets and sanitizes audio buffer/block sizes
318 static void setup_audio_buffer_sizes(priv_t *priv)
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;
325 if (seconds < 5) seconds = 5;
326 if (seconds > 500) seconds = 500;
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;
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;
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);
344 static void init_audio(priv_t *priv)
346 if (priv->audio_inited) return;
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
358 if (priv->audio_dev) {
359 audio_in_set_device(&priv->audio_in, priv->audio_dev);
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);
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);
377 if (audio_in_setup(&priv->audio_in) < 0) return;
379 priv->audio_inited = 1;
383 #if 0
385 ** the number of milliseconds elapsed between time0 and time1
387 static size_t difftv(struct timeval time1, struct timeval time0)
389 return (time1.tv_sec - time0.tv_sec) * 1000 +
390 (time1.tv_usec - time0.tv_usec) / 1000;
392 #endif
395 ** Get current video capture format.
397 static int getfmt(priv_t *priv)
399 int i;
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));
406 return i;
411 ** Get current video capture standard.
413 static int getstd(priv_t *priv)
415 v4l2_std_id id;
416 int i=0;
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;
423 do {
424 priv->standard.index = i++;
425 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
426 return -1;
428 } while (priv->standard.id != id);
429 return 0;
432 /***********************************************************************\
435 * Interface to mplayer *
438 \***********************************************************************/
440 static int set_mute(priv_t *priv, int value)
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;
450 return 1;
454 ** MPlayer uses values from -100 up to 100 for controls.
455 ** Here they are scaled to what the tv card needs and applied.
457 static int set_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
458 struct v4l2_queryctrl qctrl;
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;
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;
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;
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;
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);
494 return TVI_CONTROL_TRUE;
499 ** Scale the control values back to what mplayer needs.
501 static int get_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
502 struct v4l2_queryctrl qctrl;
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;
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;
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);
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);
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;
537 return TVI_CONTROL_TRUE;
540 static int control(priv_t *priv, int cmd, void *arg)
542 struct v4l2_control control;
543 struct v4l2_frequency frequency;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
735 return TVI_CONTROL_TRUE;
736 case TVI_CONTROL_SPC_GET_NORMID:
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;
750 return TVI_CONTROL_FALSE;
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;
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;
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;
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;
809 mp_msg(MSGT_TV, MSGL_V, "%s: unknown control: %d\n", info.short_name, cmd);
810 return(TVI_CONTROL_UNKNOWN);
814 #define PRIV ((priv_t *) (tvi_handle->priv))
816 /* handler creator - entry point ! */
817 tvi_handle_t *tvi_init_v4l2(char *video_dev, char *audio_dev)
819 tvi_handle_t *tvi_handle;
821 /* new_handle initializes priv with memset 0 */
822 tvi_handle = new_handle();
823 if (!tvi_handle) {
824 return NULL;
826 PRIV->video_fd = -1;
828 PRIV->video_dev = strdup(video_dev? video_dev: "/dev/video0");
829 if (!PRIV->video_dev) {
830 free_handle(tvi_handle);
831 return NULL;
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;
843 return tvi_handle;
846 #undef PRIV
849 static int uninit(priv_t *priv)
851 int i, frames, dropped = 0;
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);
858 if (priv->streamon) {
859 struct v4l2_buffer buf;
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;
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));
874 priv->streamon = 0;
876 /* unqueue all remaining buffers */
877 memset(&buf,0,sizeof(buf));
878 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
879 buf.memory = V4L2_MEMORY_MMAP;
880 while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
883 /* unmap all buffers */
884 for (i = 0; i < priv->mapcount; i++) {
885 if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {
886 mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",
887 info.short_name, strerror(errno));
891 /* stop audio thread */
892 if (!tv_param_noaudio && priv->audio_grabber_thread) {
893 pthread_join(priv->audio_grabber_thread, NULL);
894 pthread_mutex_destroy(&priv->skew_mutex);
895 pthread_mutex_destroy(&priv->audio_mutex);
898 set_mute(priv, 1);
900 /* free memory and close device */
901 free(priv->map); priv->map = NULL;
902 priv->mapcount = 0;
903 if(priv->video_fd!=-1)close(priv->video_fd); priv->video_fd = -1;
904 free(priv->video_dev); priv->video_dev = NULL;
906 if (priv->video_ringbuffer) {
907 int i;
908 for (i = 0; i < priv->video_buffer_size_current; i++) {
909 free(priv->video_ringbuffer[i]);
911 free(priv->video_ringbuffer);
913 if (priv->video_timebuffer)
914 free(priv->video_timebuffer);
915 if (!tv_param_noaudio) {
916 if (priv->audio_ringbuffer)
917 free(priv->audio_ringbuffer);
918 if (priv->audio_skew_buffer)
919 free(priv->audio_skew_buffer);
920 if (priv->audio_skew_delta_buffer)
921 free(priv->audio_skew_delta_buffer);
924 /* show some nice statistics ;-) */
925 mp_msg(MSGT_TV, MSGL_INFO,
926 "%s: %d frames successfully processed, %d frames dropped.\n",
927 info.short_name, priv->frames, dropped);
928 mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",
929 info.short_name, priv->video_buffer_size_current);
930 return 1;
934 /* initialisation */
935 static int init(priv_t *priv)
937 int i;
939 priv->audio_ringbuffer = NULL;
940 priv->audio_skew_buffer = NULL;
941 priv->audio_skew_delta_buffer = NULL;
943 priv->audio_inited = 0;
945 /* Open the video device. */
946 priv->video_fd = open(priv->video_dev, O_RDWR);
947 if (priv->video_fd < 0) {
948 mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",
949 info.short_name, priv->video_dev, strerror(errno));
950 uninit(priv);
951 return 0;
953 mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",
954 info.short_name, priv->video_dev, priv->video_fd);
957 ** Query the video capabilities and current settings
958 ** for further control calls.
960 if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
961 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",
962 info.short_name, strerror(errno));
963 uninit(priv);
964 return 0;
967 if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))
969 mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",
970 priv->video_dev);
971 return 0;
974 if (getfmt(priv) < 0) {
975 uninit(priv);
976 return 0;
978 getstd(priv);
980 ** if this device has got a tuner query it's settings
981 ** otherwise set some nice defaults
983 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
984 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
985 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
986 info.short_name, strerror(errno));
987 uninit(priv);
988 return 0;
991 mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);
992 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
993 mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",
994 (priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",
995 (priv->tuner.capability & V4L2_TUNER_CAP_LANG1) ? " LANG1" : "",
996 (priv->tuner.capability & V4L2_TUNER_CAP_LANG2) ? " LANG2" : "");
997 mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",
998 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO) ? " MONO" : "",
999 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",
1000 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1) ? " LANG1" : "",
1001 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2) ? " LANG2" : "");
1003 mp_msg(MSGT_TV, MSGL_INFO, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1004 priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
1005 " video capture": "",
1006 priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?
1007 " video output": "",
1008 priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?
1009 " video overlay": "",
1010 priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?
1011 " VBI capture device": "",
1012 priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?
1013 " VBI output": "",
1014 priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?
1015 " RDS data capture": "",
1016 priv->capability.capabilities & V4L2_CAP_TUNER?
1017 " tuner": "",
1018 priv->capability.capabilities & V4L2_CAP_AUDIO?
1019 " audio": "",
1020 priv->capability.capabilities & V4L2_CAP_READWRITE?
1021 " read/write": "",
1022 priv->capability.capabilities & V4L2_CAP_ASYNCIO?
1023 " async i/o": "",
1024 priv->capability.capabilities & V4L2_CAP_STREAMING?
1025 " streaming": "");
1026 mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");
1027 for (i = 0;; i++) {
1028 struct v4l2_standard standard;
1029 memset(&standard, 0, sizeof(standard));
1030 standard.index = i;
1031 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
1032 break;
1033 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);
1035 mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");
1036 for (i = 0; 1; i++) {
1037 struct v4l2_input input;
1039 input.index = i;
1040 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
1041 break;
1043 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);
1045 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
1046 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
1047 info.short_name, strerror(errno));
1049 mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);
1050 for (i = 0; ; i++) {
1051 struct v4l2_fmtdesc fmtdesc;
1053 fmtdesc.index = i;
1054 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1055 if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
1056 break;
1058 mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",
1059 pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),
1060 fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));
1062 mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",
1063 pixfmt2name(priv->format.fmt.pix.pixelformat));
1065 /* set some nice defaults */
1066 if (getfmt(priv) < 0) return 0;
1067 priv->format.fmt.pix.width = 640;
1068 priv->format.fmt.pix.height = 480;
1069 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
1070 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
1071 info.short_name, strerror(errno));
1072 uninit(priv);
1073 return 0;
1076 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !tv_param_force_audio) tv_param_noaudio = 1;
1078 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1079 struct v4l2_control control;
1080 if (tv_param_amode >= 0) {
1081 mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);
1082 priv->tuner.audmode = amode2v4l(tv_param_amode);
1083 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
1084 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
1085 info.short_name, strerror(errno));
1086 return TVI_CONTROL_FALSE;
1089 mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,
1090 (priv->tuner.audmode == V4L2_TUNER_MODE_MONO) ? " MONO" : "",
1091 (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",
1092 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG1) ? " LANG1" : "",
1093 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG2) ? " LANG2" : "");
1095 if (tv_param_volume >= 0) {
1096 control.id = V4L2_CID_AUDIO_VOLUME;
1097 control.value = tv_param_volume;
1098 set_control(priv, &control, 0);
1100 if (tv_param_bass >= 0) {
1101 control.id = V4L2_CID_AUDIO_BASS;
1102 control.value = tv_param_bass;
1103 set_control(priv, &control, 0);
1105 if (tv_param_treble >= 0) {
1106 control.id = V4L2_CID_AUDIO_TREBLE;
1107 control.value = tv_param_treble;
1108 set_control(priv, &control, 0);
1110 if (tv_param_balance >= 0) {
1111 control.id = V4L2_CID_AUDIO_BALANCE;
1112 control.value = tv_param_balance;
1113 set_control(priv, &control, 0);
1117 return 1;
1120 static int get_capture_buffer_size(priv_t *priv)
1122 int bufsize, cnt;
1123 int w = priv->format.fmt.pix.width;
1124 int h = priv->format.fmt.pix.height;
1125 int d = pixfmt2depth(priv->format.fmt.pix.pixelformat);
1126 int bytesperline = w*d/8;
1128 if (tv_param_buffer_size >= 0) {
1129 bufsize = tv_param_buffer_size*1024*1024;
1130 } else {
1131 #ifdef HAVE_SYS_SYSINFO_H
1132 struct sysinfo si;
1134 sysinfo(&si);
1135 if (si.totalram<2*1024*1024) {
1136 bufsize = 1024*1024;
1137 } else {
1138 bufsize = si.totalram/2;
1140 #else
1141 bufsize = 16*1024*1024;
1142 #endif
1145 cnt = bufsize/(h*bytesperline);
1146 if (cnt < 2) cnt = 2;
1148 return cnt;
1151 /* that's the real start, we'got the format parameters (checked with control) */
1152 static int start(priv_t *priv)
1154 struct v4l2_requestbuffers request;
1155 int i;
1157 /* setup audio parameters */
1159 init_audio(priv);
1160 if (!tv_param_noaudio && !priv->audio_inited) return 0;
1162 /* we need this to size the audio buffer properly */
1163 if (priv->immediate_mode) {
1164 priv->video_buffer_size_max = 2;
1165 } else {
1166 priv->video_buffer_size_max = get_capture_buffer_size(priv);
1169 if (!tv_param_noaudio) {
1170 setup_audio_buffer_sizes(priv);
1171 priv->audio_skew_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1172 if (!priv->audio_skew_buffer) {
1173 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1174 return 0;
1176 priv->audio_skew_delta_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1177 if (!priv->audio_skew_delta_buffer) {
1178 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1179 return 0;
1182 priv->audio_ringbuffer = calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
1183 if (!priv->audio_ringbuffer) {
1184 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
1185 return 0;
1188 priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate
1189 *priv->audio_in.channels
1190 *priv->audio_in.bytes_per_sample);
1191 priv->audio_usecs_per_block = 1e6*priv->audio_secs_per_block;
1192 priv->audio_head = 0;
1193 priv->audio_tail = 0;
1194 priv->audio_cnt = 0;
1195 priv->audio_drop = 0;
1196 priv->audio_skew = 0;
1197 priv->audio_skew_total = 0;
1198 priv->audio_skew_delta_total = 0;
1199 priv->audio_recv_blocks_total = 0;
1200 priv->audio_sent_blocks_total = 0;
1201 priv->audio_null_blocks_inserted = 0;
1202 priv->audio_insert_null_samples = 0;
1203 priv->dropped_frames_timeshift = 0;
1204 priv->dropped_frames_compensated = 0;
1206 pthread_mutex_init(&priv->skew_mutex, NULL);
1207 pthread_mutex_init(&priv->audio_mutex, NULL);
1210 /* setup video parameters */
1211 if (!tv_param_noaudio) {
1212 if (priv->video_buffer_size_max < (3*priv->standard.frameperiod.denominator) /
1213 priv->standard.frameperiod.numerator
1214 *priv->audio_secs_per_block) {
1215 mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"
1216 "You will probably experience heavy framedrops.\n");
1221 int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1223 mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1224 priv->video_buffer_size_max,
1225 priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));
1228 priv->video_ringbuffer = calloc(priv->video_buffer_size_max, sizeof(unsigned char*));
1229 if (!priv->video_ringbuffer) {
1230 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
1231 return 0;
1233 for (i = 0; i < priv->video_buffer_size_max; i++)
1234 priv->video_ringbuffer[i] = NULL;
1235 priv->video_timebuffer = calloc(priv->video_buffer_size_max, sizeof(long long));
1236 if (!priv->video_timebuffer) {
1237 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate time buffer: %s\n", strerror(errno));
1238 return 0;
1241 pthread_mutex_init(&priv->video_buffer_mutex, NULL);
1243 priv->video_head = 0;
1244 priv->video_tail = 0;
1245 priv->video_cnt = 0;
1247 /* request buffers */
1248 if (priv->immediate_mode) {
1249 request.count = 2;
1250 } else {
1251 request.count = BUFFER_COUNT;
1254 request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1255 request.memory = V4L2_MEMORY_MMAP;
1256 if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
1257 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",
1258 info.short_name, strerror(errno));
1259 return 0;
1262 /* query buffers */
1263 if (!(priv->map = calloc(request.count, sizeof(struct map)))) {
1264 mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",
1265 info.short_name, strerror(errno));
1266 return 0;
1269 /* map and queue buffers */
1270 for (i = 0; i < request.count; i++) {
1271 memset(&priv->map[i].buf,0,sizeof(priv->map[i].buf));
1272 priv->map[i].buf.index = i;
1273 priv->map[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1274 priv->map[i].buf.memory = V4L2_MEMORY_MMAP;
1275 if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
1276 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",
1277 info.short_name, strerror(errno));
1278 free(priv->map);
1279 priv->map = NULL;
1280 return 0;
1282 priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |
1283 PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);
1284 if (priv->map[i].addr == MAP_FAILED) {
1285 mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",
1286 info.short_name, strerror(errno));
1287 priv->map[i].len = 0;
1288 return 0;
1290 priv->map[i].len = priv->map[i].buf.length;
1291 /* count up to make sure this is correct everytime */
1292 priv->mapcount++;
1294 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1295 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1296 info.short_name, strerror(errno));
1297 return 0;
1301 /* start audio thread */
1302 priv->shutdown = 0;
1303 priv->audio_skew_measure_time = 0;
1304 priv->first_frame = 0;
1305 priv->audio_skew = 0;
1306 priv->first = 1;
1308 set_mute(priv, 0);
1310 return 1;
1314 #ifdef HAVE_TV_BSDBT848
1315 static double grabimmediate_video_frame(priv_t *priv, char *buffer, int len)
1317 memset(buffer, 0xCC, len);
1318 return(1);
1320 #endif /* HAVE_TV_BSDBT848 */
1322 // copies a video frame
1323 static inline void copy_frame(priv_t *priv, unsigned char *dest, unsigned char *source)
1325 int w = priv->format.fmt.pix.width;
1326 int h = priv->format.fmt.pix.height;
1327 int d = pixfmt2depth(priv->format.fmt.pix.pixelformat);
1328 int bytesperline = w*d/8;
1330 memcpy(dest, source, bytesperline * h);
1333 // maximum skew change, in frames
1334 #define MAX_SKEW_DELTA 0.6
1335 static void *video_grabber(void *data)
1337 priv_t *priv = (priv_t*)data;
1338 long long skew, prev_skew, xskew, interval, prev_interval, delta;
1339 int i;
1340 int framesize = priv->format.fmt.pix.height*priv->format.fmt.pix.width*
1341 pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1342 fd_set rdset;
1343 struct timeval timeout;
1344 struct v4l2_buffer buf;
1346 xskew = 0;
1347 skew = 0;
1348 interval = 0;
1349 prev_interval = 0;
1350 prev_skew = 0;
1352 mp_msg(MSGT_TV, MSGL_V, "%s: going to capture\n", info.short_name);
1353 if (ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
1354 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamon failed: %s\n",
1355 info.short_name, strerror(errno));
1356 return 0;
1358 priv->streamon = 1;
1360 if (!tv_param_noaudio) {
1361 pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
1364 for (priv->frames = 0; !priv->shutdown;)
1366 int ret;
1368 if (priv->immediate_mode) {
1369 while (priv->video_cnt == priv->video_buffer_size_max) {
1370 usleep(10000);
1371 if (priv->shutdown) {
1372 return NULL;
1377 FD_ZERO (&rdset);
1378 FD_SET (priv->video_fd, &rdset);
1380 timeout.tv_sec = 1;
1381 timeout.tv_usec = 0;
1383 i = select(priv->video_fd + 1, &rdset, NULL, NULL, &timeout);
1384 if (i < 0) {
1385 mp_msg(MSGT_TV, MSGL_ERR, "%s: select failed: %s\n",
1386 info.short_name, strerror(errno));
1387 continue;
1389 else if (i == 0) {
1390 mp_msg(MSGT_TV, MSGL_ERR, "%s: select timeout\n", info.short_name);
1391 continue;
1393 else if (!FD_ISSET(priv->video_fd, &rdset)) {
1394 continue;
1397 memset(&buf,0,sizeof(buf));
1398 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1399 buf.memory = V4L2_MEMORY_MMAP;
1400 ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
1402 if (ret < 0) {
1404 if there's no signal, the buffer might me dequeued
1405 so we query all the buffers to see which one we should
1406 put back to queue
1408 observed with saa7134 0.2.8
1409 don't know if is it a bug or (mis)feature
1411 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1412 info.short_name, strerror(errno), buf.index);
1413 for (i = 0; i < priv->mapcount; i++) {
1414 memset(&buf,0,sizeof(buf));
1415 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1416 buf.memory = V4L2_MEMORY_MMAP;
1417 buf.index = i;
1418 ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
1419 if (ret < 0) {
1420 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s, idx = %d\n",
1421 info.short_name, strerror(errno), buf.index);
1422 return 0;
1424 if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
1425 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1426 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1427 info.short_name, strerror(errno));
1428 return 0;
1432 continue;
1435 /* store the timestamp of the very first frame as reference */
1436 if (!priv->frames++) {
1437 if (!tv_param_noaudio) pthread_mutex_lock(&priv->skew_mutex);
1438 priv->first_frame = (long long)1e6*buf.timestamp.tv_sec + buf.timestamp.tv_usec;
1439 if (!tv_param_noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1441 priv->curr_frame = (long long)buf.timestamp.tv_sec*1e6+buf.timestamp.tv_usec;
1442 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1444 interval = priv->curr_frame - priv->first_frame;
1445 delta = interval - prev_interval;
1447 if (!priv->immediate_mode) {
1448 // interpolate the skew in time
1449 if (!tv_param_noaudio) pthread_mutex_lock(&priv->skew_mutex);
1450 xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
1451 if (!tv_param_noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1452 // correct extreme skew changes to avoid (especially) moving backwards in time
1453 if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
1454 skew = prev_skew + delta*MAX_SKEW_DELTA;
1455 } else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) {
1456 skew = prev_skew - delta*MAX_SKEW_DELTA;
1457 } else {
1458 skew = xskew;
1462 mp_msg(MSGT_TV, MSGL_DBG3, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1463 delta ? (double)1e6/delta : -1,
1464 (double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
1465 mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
1467 prev_skew = skew;
1468 prev_interval = interval;
1470 /* allocate a new buffer, if needed */
1471 pthread_mutex_lock(&priv->video_buffer_mutex);
1472 if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
1473 if (priv->video_cnt == priv->video_buffer_size_current) {
1474 unsigned char *newbuf = malloc(framesize);
1475 if (newbuf) {
1476 memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
1477 (priv->video_buffer_size_current-priv->video_tail)*sizeof(unsigned char *));
1478 memmove(priv->video_timebuffer+priv->video_tail+1, priv->video_timebuffer+priv->video_tail,
1479 (priv->video_buffer_size_current-priv->video_tail)*sizeof(long long));
1480 priv->video_ringbuffer[priv->video_tail] = newbuf;
1481 if ((priv->video_head >= priv->video_tail) && (priv->video_cnt > 0)) priv->video_head++;
1482 priv->video_buffer_size_current++;
1486 pthread_mutex_unlock(&priv->video_buffer_mutex);
1488 if (priv->video_cnt == priv->video_buffer_size_current) {
1489 if (!priv->immediate_mode) {
1490 mp_msg(MSGT_TV, MSGL_ERR, "\nvideo buffer full - dropping frame\n");
1491 if (priv->audio_insert_null_samples) {
1492 pthread_mutex_lock(&priv->audio_mutex);
1493 priv->dropped_frames_timeshift += delta;
1494 pthread_mutex_unlock(&priv->audio_mutex);
1497 } else {
1498 if (priv->immediate_mode) {
1499 priv->video_timebuffer[priv->video_tail] = 0;
1500 } else {
1501 // compensate for audio skew
1502 // negative skew => there are more audio samples, increase interval
1503 // positive skew => less samples, shorten the interval
1504 priv->video_timebuffer[priv->video_tail] = interval - skew;
1505 if (priv->audio_insert_null_samples && priv->video_timebuffer[priv->video_tail] > 0) {
1506 pthread_mutex_lock(&priv->audio_mutex);
1507 priv->video_timebuffer[priv->video_tail] +=
1508 (priv->audio_null_blocks_inserted
1509 - priv->dropped_frames_timeshift/priv->audio_usecs_per_block)
1510 *priv->audio_usecs_per_block;
1511 pthread_mutex_unlock(&priv->audio_mutex);
1515 copy_frame(priv, priv->video_ringbuffer[priv->video_tail], priv->map[buf.index].addr);
1516 priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
1517 priv->video_cnt++;
1519 if (ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
1520 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1521 info.short_name, strerror(errno));
1522 return 0;
1525 return NULL;
1528 #define MAX_LOOP 50
1529 static double grab_video_frame(priv_t *priv, char *buffer, int len)
1531 double interval;
1532 int loop_cnt = 0;
1534 if (priv->first) {
1535 pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1536 priv->first = 0;
1539 while (priv->video_cnt == 0) {
1540 usleep(10000);
1541 if (loop_cnt++ > MAX_LOOP) return 0;
1544 pthread_mutex_lock(&priv->video_buffer_mutex);
1545 interval = (double)priv->video_timebuffer[priv->video_head]*1e-6;
1546 memcpy(buffer, priv->video_ringbuffer[priv->video_head], len);
1547 priv->video_cnt--;
1548 priv->video_head = (priv->video_head+1)%priv->video_buffer_size_current;
1549 pthread_mutex_unlock(&priv->video_buffer_mutex);
1551 return interval;
1554 static int get_video_framesize(priv_t *priv)
1556 return priv->format.fmt.pix.sizeimage;
1559 //#define DOUBLESPEED
1560 #ifdef DOUBLESPEED
1561 // for testing purposes only
1562 static void read_doublespeed(priv_t *priv)
1564 char *bufx = calloc(priv->audio_in.blocksize, 2);
1565 short *s;
1566 short *d;
1567 int i;
1569 audio_in_read_chunk(&priv->audio_in, bufx);
1570 audio_in_read_chunk(&priv->audio_in, bufx+priv->audio_in.blocksize);
1572 s = bufx;
1573 d = priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize;
1574 for (i = 0; i < priv->audio_in.blocksize/2; i++) {
1575 *d++ = *s++;
1576 *s++;
1580 #endif
1582 static void *audio_grabber(void *data)
1584 priv_t *priv = (priv_t*)data;
1585 struct timeval tv;
1586 int i, audio_skew_ptr = 0;
1587 long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
1588 long long start_time_avg;
1590 gettimeofday(&tv, NULL);
1591 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1592 audio_in_start_capture(&priv->audio_in);
1593 for (i = 0; i < priv->aud_skew_cnt; i++)
1594 priv->audio_skew_buffer[i] = 0;
1595 for (i = 0; i < priv->aud_skew_cnt; i++)
1596 priv->audio_skew_delta_buffer[i] = 0;
1598 for (; !priv->shutdown;)
1600 #ifdef DOUBLESPEED
1601 read_doublespeed(priv);
1602 #else
1603 if (audio_in_read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize) < 0)
1604 continue;
1605 #endif
1606 pthread_mutex_lock(&priv->skew_mutex);
1607 if (priv->first_frame == 0) {
1608 // there is no first frame yet (unlikely to happen)
1609 gettimeofday(&tv, NULL);
1610 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1611 // fprintf(stderr, "warning - first frame not yet available!\n");
1612 pthread_mutex_unlock(&priv->skew_mutex);
1613 continue;
1615 pthread_mutex_unlock(&priv->skew_mutex);
1617 gettimeofday(&tv, NULL);
1619 priv->audio_recv_blocks_total++;
1620 current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
1622 if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
1623 start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1624 priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
1627 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1628 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1630 // put the current skew into the ring buffer
1631 priv->audio_skew_total -= priv->audio_skew_buffer[audio_skew_ptr];
1632 priv->audio_skew_buffer[audio_skew_ptr] = current_time
1633 - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1634 priv->audio_skew_total += priv->audio_skew_buffer[audio_skew_ptr];
1636 pthread_mutex_lock(&priv->skew_mutex);
1638 // skew calculation
1640 // compute the sliding average of the skews
1641 if (priv->audio_recv_blocks_total > priv->aud_skew_cnt) {
1642 priv->audio_skew = priv->audio_skew_total/priv->aud_skew_cnt;
1643 } else {
1644 priv->audio_skew = priv->audio_skew_total/priv->audio_recv_blocks_total;
1647 // put the current skew change (skew-prev_skew) into the ring buffer
1648 priv->audio_skew_delta_total -= priv->audio_skew_delta_buffer[audio_skew_ptr];
1649 priv->audio_skew_delta_buffer[audio_skew_ptr] = priv->audio_skew - prev_skew_uncorr;
1650 priv->audio_skew_delta_total += priv->audio_skew_delta_buffer[audio_skew_ptr];
1651 prev_skew_uncorr = priv->audio_skew; // remember the _uncorrected_ average value
1653 audio_skew_ptr = (audio_skew_ptr+1) % priv->aud_skew_cnt; // rotate the buffer pointer
1655 // sliding average approximates the value in the middle of the interval
1656 // so interpolate the skew value further to the current time
1657 priv->audio_skew += priv->audio_skew_delta_total/2;
1659 // now finally, priv->audio_skew contains fairly good approximation
1660 // of the current value
1662 // current skew factor (assuming linearity)
1663 // used for further interpolation in video_grabber
1664 // probably overkill but seems to be necessary for
1665 // stress testing by dropping half of the audio frames ;)
1666 // especially when using ALSA with large block sizes
1667 // where audio_skew remains a long while behind
1668 if ((priv->audio_skew_measure_time != 0) && (current_time - priv->audio_skew_measure_time != 0)) {
1669 priv->audio_skew_factor = (double)(priv->audio_skew-prev_skew)/(current_time - priv->audio_skew_measure_time);
1670 } else {
1671 priv->audio_skew_factor = 0.0;
1674 priv->audio_skew_measure_time = current_time;
1675 prev_skew = priv->audio_skew;
1676 priv->audio_skew += priv->audio_start_time - priv->first_frame;
1677 pthread_mutex_unlock(&priv->skew_mutex);
1679 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1681 pthread_mutex_lock(&priv->audio_mutex);
1682 if ((priv->audio_tail+1) % priv->audio_buffer_size == priv->audio_head) {
1683 mp_msg(MSGT_TV, MSGL_ERR, "\ntoo bad - dropping audio frame !\n");
1684 priv->audio_drop++;
1685 } else {
1686 priv->audio_tail = (priv->audio_tail+1) % priv->audio_buffer_size;
1687 priv->audio_cnt++;
1689 pthread_mutex_unlock(&priv->audio_mutex);
1691 return NULL;
1694 static double grab_audio_frame(priv_t *priv, char *buffer, int len)
1696 mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1697 priv, buffer, len);
1699 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1700 // => switch to the mode which outputs audio immediately, even if
1701 // it should be silence
1702 if (priv->first) priv->audio_insert_null_samples = 1;
1704 pthread_mutex_lock(&priv->audio_mutex);
1705 while (priv->audio_insert_null_samples
1706 && priv->dropped_frames_timeshift - priv->dropped_frames_compensated >= priv->audio_usecs_per_block) {
1707 // some frames were dropped - drop the corresponding number of audio blocks
1708 if (priv->audio_drop) {
1709 priv->audio_drop--;
1710 } else {
1711 if (priv->audio_head == priv->audio_tail) break;
1712 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1714 priv->dropped_frames_compensated += priv->audio_usecs_per_block;
1717 // compensate for dropped audio frames
1718 if (priv->audio_drop && (priv->audio_head == priv->audio_tail)) {
1719 priv->audio_drop--;
1720 memset(buffer, 0, len);
1721 goto out;
1724 if (priv->audio_insert_null_samples && (priv->audio_head == priv->audio_tail)) {
1725 // return silence to avoid desync and stuttering
1726 memset(buffer, 0, len);
1727 priv->audio_null_blocks_inserted++;
1728 goto out;
1731 pthread_mutex_unlock(&priv->audio_mutex);
1732 while (priv->audio_head == priv->audio_tail) {
1733 // this is mencoder => just wait until some audio is available
1734 usleep(10000);
1736 pthread_mutex_lock(&priv->audio_mutex);
1737 memcpy(buffer, priv->audio_ringbuffer+priv->audio_head*priv->audio_in.blocksize, len);
1738 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1739 priv->audio_cnt--;
1740 out:
1741 pthread_mutex_unlock(&priv->audio_mutex);
1742 priv->audio_sent_blocks_total++;
1743 return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
1746 static int get_audio_framesize(priv_t *priv)
1748 return(priv->audio_in.blocksize);