Get rid of nonsensical limits on -geometry x, y,w and h values, they only
[mplayer/glamo.git] / stream / tvi_v4l2.c
blobc890d7a51e5d09a48f995fb9262230f2e7e0618f
1 /*
2 * Video 4 Linux 2 input
4 * copyright (c) 2003 Martin Olschewski <olschewski@zpr.uni-koeln.de>
5 * copyright (c) 2003 Jindrich Makovicka <makovick@gmail.com>
7 * Some ideas are based on works from
8 * Alex Beregszaszi <alex@fsn.hu>
9 * Gerd Knorr <kraxel@bytesex.org>
11 * This file is part of MPlayer.
13 * MPlayer is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * MPlayer is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 known issues:
31 - norm setting isn't consistent with tvi_v4l
32 - the same for volume/bass/treble/balance
36 #include "config.h"
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <pthread.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <sys/ioctl.h>
44 #include <sys/mman.h>
45 #include <sys/time.h>
46 #include <sys/types.h>
47 #include <unistd.h>
48 #include <math.h>
49 #ifdef HAVE_SYS_SYSINFO_H
50 #include <sys/sysinfo.h>
51 #endif
52 #include <linux/types.h>
53 #include <linux/videodev2.h>
54 #include "mp_msg.h"
55 #include "libmpcodecs/img_format.h"
56 #include "libaf/af_format.h"
57 #include "tv.h"
58 #include "audio_in.h"
60 #define info tvi_info_v4l2
61 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param);
62 /* information about this file */
63 const tvi_info_t tvi_info_v4l2 = {
64 tvi_init_v4l2,
65 "Video 4 Linux 2 input",
66 "v4l2",
67 "Martin Olschewski <olschewski@zpr.uni-koeln.de>",
68 "first try, more to come ;-)"
71 struct map {
72 struct v4l2_buffer buf;
73 void *addr;
74 size_t len;
77 #define BUFFER_COUNT 6
79 /** video ringbuffer entry */
80 typedef struct {
81 unsigned char *data; ///< frame contents
82 long long timestamp; ///< frame timestamp
83 int framesize; ///< actual frame size
84 } video_buffer_entry;
86 /* private data */
87 typedef struct {
88 /* video */
89 char *video_dev;
90 int video_fd;
91 #ifdef CONFIG_TV_TELETEXT
92 char *vbi_dev;
93 int vbi_fd;
94 int vbi_bufsize;
95 int vbi_shutdown;
96 pthread_t vbi_grabber_thread;
97 void *priv_vbi;
98 #endif
99 int mp_format;
100 struct v4l2_capability capability;
101 struct v4l2_input input;
102 struct v4l2_format format;
103 struct v4l2_standard standard;
104 struct v4l2_tuner tuner;
105 struct map *map;
106 int mapcount;
107 int frames;
108 volatile long long first_frame;
109 long long curr_frame;
110 /* audio video interleaving ;-) */
111 volatile int streamon;
112 pthread_t audio_grabber_thread;
113 pthread_mutex_t skew_mutex;
115 /* 2nd level video buffers */
116 int first;
117 int immediate_mode;
119 int video_buffer_size_max;
120 volatile int video_buffer_size_current;
121 video_buffer_entry *video_ringbuffer;
122 volatile int video_head;
123 volatile int video_tail;
124 volatile int video_cnt;
125 pthread_t video_grabber_thread;
126 pthread_mutex_t video_buffer_mutex;
128 /* audio */
129 char *audio_dev;
130 audio_in_t audio_in;
132 long long audio_start_time;
133 int audio_buffer_size;
134 int aud_skew_cnt;
135 unsigned char *audio_ringbuffer;
136 long long *audio_skew_buffer;
137 long long *audio_skew_delta_buffer;
138 volatile int audio_head;
139 volatile int audio_tail;
140 volatile int audio_cnt;
141 volatile long long audio_skew;
142 volatile double audio_skew_factor;
143 volatile long long audio_skew_measure_time;
144 volatile int audio_drop;
145 volatile int shutdown;
147 int audio_initialized;
148 double audio_secs_per_block;
149 long long audio_usecs_per_block;
150 long long audio_skew_total;
151 long long audio_skew_delta_total;
152 long audio_recv_blocks_total;
153 long audio_sent_blocks_total;
154 pthread_mutex_t audio_mutex;
155 int audio_insert_null_samples;
156 volatile long audio_null_blocks_inserted;
157 volatile long long dropped_frames_timeshift;
158 long long dropped_frames_compensated;
160 tv_param_t *tv_param;
161 } priv_t;
163 #include "tvi_def.h"
165 static void *audio_grabber(void *data);
166 static void *video_grabber(void *data);
168 /**********************************************************************\
170 Only few of the fourccs are the same in v4l2 and mplayer:
172 IMGFMT_YVU9 == V4L2_PIX_FMT_YVU410
173 IMGFMT_YV12 == V4L2_PIX_FMT_YVU420
174 IMGFMT_NV12 == V4L2_PIX_FMT_NV12
175 IMGFMT_422P == V4L2_PIX_FMT_YUV422P
176 IMGFMT_411P == V4L2_PIX_FMT_YUV411P
177 IMGFMT_UYVY == V4L2_PIX_FMT_UYVY
178 IMGFMT_Y41P == V4L2_PIX_FMT_Y41P
180 This may be an useful translation table for some others:
182 IMGFMT_RGB8 == V4L2_PIX_FMT_RGB332
183 IMGFMT_BGR15 == V4L2_PIX_FMT_RGB555
184 IMGFMT_BGR16 == V4L2_PIX_FMT_RGB565
185 IMGFMT_RGB24 == V4L2_PIX_FMT_RGB24
186 IMGFMT_RGB32 == V4L2_PIX_FMT_RGB32
187 IMGFMT_BGR24 == V4L2_PIX_FMT_BGR24
188 IMGFMT_BGR32 == V4L2_PIX_FMT_BGR32
189 IMGFMT_Y800 == V4L2_PIX_FMT_GREY
190 IMGFMT_IF09 == V4L2_PIX_FMT_YUV410
191 IMGFMT_I420 == V4L2_PIX_FMT_YUV420
192 IMGFMT_YUY2 == V4L2_PIX_FMT_YUYV
194 \**********************************************************************/
197 ** Translate a mplayer fourcc to a video4linux2 pixel format.
199 static int fcc_mp2vl(int fcc)
201 switch (fcc) {
202 case IMGFMT_RGB8: return V4L2_PIX_FMT_RGB332;
203 case IMGFMT_BGR15: return V4L2_PIX_FMT_RGB555;
204 case IMGFMT_BGR16: return V4L2_PIX_FMT_RGB565;
205 case IMGFMT_RGB24: return V4L2_PIX_FMT_RGB24;
206 case IMGFMT_RGB32: return V4L2_PIX_FMT_RGB32;
207 case IMGFMT_BGR24: return V4L2_PIX_FMT_BGR24;
208 case IMGFMT_BGR32: return V4L2_PIX_FMT_BGR32;
209 case IMGFMT_Y800: return V4L2_PIX_FMT_GREY;
210 case IMGFMT_IF09: return V4L2_PIX_FMT_YUV410;
211 case IMGFMT_I420: return V4L2_PIX_FMT_YUV420;
212 case IMGFMT_YUY2: return V4L2_PIX_FMT_YUYV;
213 case IMGFMT_YV12: return V4L2_PIX_FMT_YVU420;
214 case IMGFMT_UYVY: return V4L2_PIX_FMT_UYVY;
215 case IMGFMT_MJPEG: return V4L2_PIX_FMT_MJPEG;
217 return fcc;
221 ** Translate a video4linux2 fourcc aka pixel format to mplayer.
223 static int fcc_vl2mp(int fcc)
225 switch (fcc) {
226 case V4L2_PIX_FMT_RGB332: return IMGFMT_RGB8;
227 case V4L2_PIX_FMT_RGB555: return IMGFMT_BGR15;
228 case V4L2_PIX_FMT_RGB565: return IMGFMT_BGR16;
229 case V4L2_PIX_FMT_RGB24: return IMGFMT_RGB24;
230 case V4L2_PIX_FMT_RGB32: return IMGFMT_RGB32;
231 case V4L2_PIX_FMT_BGR24: return IMGFMT_BGR24;
232 case V4L2_PIX_FMT_BGR32: return IMGFMT_BGR32;
233 case V4L2_PIX_FMT_GREY: return IMGFMT_Y800;
234 case V4L2_PIX_FMT_YUV410: return IMGFMT_IF09;
235 case V4L2_PIX_FMT_YUV420: return IMGFMT_I420;
236 case V4L2_PIX_FMT_YVU420: return IMGFMT_YV12;
237 case V4L2_PIX_FMT_YUYV: return IMGFMT_YUY2;
238 case V4L2_PIX_FMT_UYVY: return IMGFMT_UYVY;
239 case V4L2_PIX_FMT_MJPEG: return IMGFMT_MJPEG;
241 return fcc;
245 ** Translate a video4linux2 fourcc aka pixel format
246 ** to a human readable string.
248 static const char *pixfmt2name(int pixfmt)
250 static char unknown[24];
252 switch (pixfmt) {
253 case V4L2_PIX_FMT_RGB332: return "RGB332";
254 case V4L2_PIX_FMT_RGB555: return "RGB555";
255 case V4L2_PIX_FMT_RGB565: return "RGB565";
256 case V4L2_PIX_FMT_RGB555X: return "RGB555X";
257 case V4L2_PIX_FMT_RGB565X: return "RGB565X";
258 case V4L2_PIX_FMT_BGR24: return "BGR24";
259 case V4L2_PIX_FMT_RGB24: return "RGB24";
260 case V4L2_PIX_FMT_BGR32: return "BGR32";
261 case V4L2_PIX_FMT_RGB32: return "RGB32";
262 case V4L2_PIX_FMT_GREY: return "GREY";
263 case V4L2_PIX_FMT_YVU410: return "YVU410";
264 case V4L2_PIX_FMT_YVU420: return "YVU420";
265 case V4L2_PIX_FMT_YUYV: return "YUYV";
266 case V4L2_PIX_FMT_UYVY: return "UYVY";
267 /* case V4L2_PIX_FMT_YVU422P: return "YVU422P"; */
268 /* case V4L2_PIX_FMT_YVU411P: return "YVU411P"; */
269 case V4L2_PIX_FMT_YUV422P: return "YUV422P";
270 case V4L2_PIX_FMT_YUV411P: return "YUV411P";
271 case V4L2_PIX_FMT_Y41P: return "Y41P";
272 case V4L2_PIX_FMT_NV12: return "NV12";
273 case V4L2_PIX_FMT_NV21: return "NV21";
274 case V4L2_PIX_FMT_YUV410: return "YUV410";
275 case V4L2_PIX_FMT_YUV420: return "YUV420";
276 case V4L2_PIX_FMT_YYUV: return "YYUV";
277 case V4L2_PIX_FMT_HI240: return "HI240";
278 case V4L2_PIX_FMT_WNVA: return "WNVA";
279 case V4L2_PIX_FMT_MJPEG: return "MJPEG";
281 sprintf(unknown, "unknown (0x%x)", pixfmt);
282 return unknown;
287 ** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
289 static int pixfmt2depth(int pixfmt)
291 switch (pixfmt) {
292 case V4L2_PIX_FMT_RGB332:
293 return 8;
294 case V4L2_PIX_FMT_RGB555:
295 case V4L2_PIX_FMT_RGB565:
296 case V4L2_PIX_FMT_RGB555X:
297 case V4L2_PIX_FMT_RGB565X:
298 return 16;
299 case V4L2_PIX_FMT_BGR24:
300 case V4L2_PIX_FMT_RGB24:
301 return 24;
302 case V4L2_PIX_FMT_BGR32:
303 case V4L2_PIX_FMT_RGB32:
304 return 32;
305 case V4L2_PIX_FMT_GREY:
306 return 8;
307 case V4L2_PIX_FMT_YVU410:
308 return 9;
309 case V4L2_PIX_FMT_YVU420:
310 return 12;
311 case V4L2_PIX_FMT_YUYV:
312 case V4L2_PIX_FMT_UYVY:
313 case V4L2_PIX_FMT_YUV422P:
314 case V4L2_PIX_FMT_YUV411P:
315 return 16;
316 case V4L2_PIX_FMT_Y41P:
317 case V4L2_PIX_FMT_NV12:
318 case V4L2_PIX_FMT_NV21:
319 return 12;
320 case V4L2_PIX_FMT_YUV410:
321 return 9;
322 case V4L2_PIX_FMT_YUV420:
323 return 12;
324 case V4L2_PIX_FMT_YYUV:
325 return 16;
326 case V4L2_PIX_FMT_HI240:
327 return 8;
330 return 0;
333 static int amode2v4l(int amode)
335 switch (amode) {
336 case 0:
337 return V4L2_TUNER_MODE_MONO;
338 case 1:
339 return V4L2_TUNER_MODE_STEREO;
340 case 2:
341 return V4L2_TUNER_MODE_LANG1;
342 case 3:
343 return V4L2_TUNER_MODE_LANG2;
344 default:
345 return -1;
351 ** Get current FPS.
353 static double getfps(priv_t *priv)
355 if (priv->tv_param->fps > 0)
356 return priv->tv_param->fps;
357 if (priv->standard.frameperiod.denominator && priv->standard.frameperiod.numerator)
358 return (double)priv->standard.frameperiod.denominator / priv->standard.frameperiod.numerator;
359 return 25.0;
362 // sets and sanitizes audio buffer/block sizes
363 static void setup_audio_buffer_sizes(priv_t *priv)
365 int bytes_per_sample = priv->audio_in.bytes_per_sample;
366 int seconds = priv->video_buffer_size_max/getfps(priv);
368 if (seconds < 5) seconds = 5;
369 if (seconds > 500) seconds = 500;
371 // make the audio buffer at least as the video buffer capacity (or 5 seconds) long
372 priv->audio_buffer_size = 1 + seconds*priv->audio_in.samplerate
373 *priv->audio_in.channels
374 *bytes_per_sample/priv->audio_in.blocksize;
375 if (priv->audio_buffer_size < 256) priv->audio_buffer_size = 256;
377 // make the skew buffer at least 1 second long
378 priv->aud_skew_cnt = 1 + 1*priv->audio_in.samplerate
379 *priv->audio_in.channels
380 *bytes_per_sample/priv->audio_in.blocksize;
381 if (priv->aud_skew_cnt < 16) priv->aud_skew_cnt = 16;
383 mp_msg(MSGT_TV, MSGL_V, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
384 priv->audio_buffer_size, priv->audio_in.blocksize, priv->aud_skew_cnt);
387 static void init_audio(priv_t *priv)
389 if (priv->audio_initialized) return;
391 if (!priv->tv_param->noaudio) {
392 #ifdef CONFIG_ALSA
393 if (priv->tv_param->alsa)
394 audio_in_init(&priv->audio_in, AUDIO_IN_ALSA);
395 else
396 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
397 #else
398 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
399 #endif
401 if (priv->audio_dev) {
402 audio_in_set_device(&priv->audio_in, priv->audio_dev);
405 audio_in_set_samplerate(&priv->audio_in, 44100);
406 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
407 if (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) {
408 audio_in_set_channels(&priv->audio_in, 2);
409 } else {
410 audio_in_set_channels(&priv->audio_in, 1);
412 } else {
413 if (priv->tv_param->forcechan >= 0) {
414 audio_in_set_channels(&priv->audio_in, priv->tv_param->forcechan);
415 } else {
416 audio_in_set_channels(&priv->audio_in, 2);
420 if (audio_in_setup(&priv->audio_in) < 0) return;
422 priv->audio_initialized = 1;
426 #if 0
428 ** the number of milliseconds elapsed between time0 and time1
430 static size_t difftv(struct timeval time1, struct timeval time0)
432 return (time1.tv_sec - time0.tv_sec) * 1000 +
433 (time1.tv_usec - time0.tv_usec) / 1000;
435 #endif
438 ** Get current video capture format.
440 static int getfmt(priv_t *priv)
442 int i;
444 priv->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
445 if ((i = ioctl(priv->video_fd, VIDIOC_G_FMT, &priv->format)) < 0) {
446 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get format failed: %s\n",
447 info.short_name, strerror(errno));
449 return i;
454 ** Get current video capture standard.
456 static int getstd(priv_t *priv)
458 v4l2_std_id id;
459 int i=0;
461 if (ioctl(priv->video_fd, VIDIOC_G_STD, &id) < 0) {
462 struct v4l2_streamparm parm;
464 parm.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
465 if(ioctl(priv->video_fd, VIDIOC_G_PARM, &parm) >= 0) {
466 mp_msg(MSGT_TV, MSGL_WARN, "%s: your device driver does not support VIDIOC_G_STD ioctl,"
467 " VIDIOC_G_PARM was used instead.\n", info.short_name);
468 priv->standard.index=0;
469 priv->standard.id=0;
470 priv->standard.frameperiod=parm.parm.capture.timeperframe;
471 return 0;
474 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get standard failed: %s\n",
475 info.short_name, strerror(errno));
476 return -1;
478 do {
479 priv->standard.index = i++;
480 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
481 return -1;
483 } while (priv->standard.id != id);
484 return 0;
487 /***********************************************************************\
490 * Interface to mplayer *
493 \***********************************************************************/
495 static int set_mute(priv_t *priv, int value)
497 struct v4l2_control control;
498 control.id = V4L2_CID_AUDIO_MUTE;
499 control.value = value;
500 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, &control) < 0) {
501 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set mute failed: %s\n",
502 info.short_name, strerror(errno));
503 return 0;
505 return 1;
509 ** MPlayer uses values from -100 up to 100 for controls.
510 ** Here they are scaled to what the tv card needs and applied.
512 static int set_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
513 struct v4l2_queryctrl qctrl;
514 qctrl.id = control->id;
515 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
516 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
517 info.short_name, strerror(errno));
518 return TVI_CONTROL_FALSE;
521 if (val_signed) {
522 if (control->value < 0) {
523 control->value = qctrl.default_value + control->value *
524 (qctrl.default_value - qctrl.minimum) / 100;
525 } else {
526 control->value = qctrl.default_value + control->value *
527 (qctrl.maximum - qctrl.default_value) / 100;
529 } else {
530 if (control->value < 50) {
531 control->value = qctrl.default_value + (control->value-50) *
532 (qctrl.default_value - qctrl.minimum) / 50;
533 } else {
534 control->value = qctrl.default_value + (control->value-50) *
535 (qctrl.maximum - qctrl.default_value) / 50;
540 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, control) < 0) {
541 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl set %s %d failed: %s\n",
542 info.short_name, qctrl.name, control->value, strerror(errno));
543 return TVI_CONTROL_FALSE;
545 mp_msg(MSGT_TV, MSGL_V, "%s: set %s: %d [%d, %d]\n", info.short_name,
546 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
548 return TVI_CONTROL_TRUE;
553 ** Scale the control values back to what mplayer needs.
555 static int get_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
556 struct v4l2_queryctrl qctrl;
558 qctrl.id = control->id;
559 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
560 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
561 info.short_name, strerror(errno));
562 return TVI_CONTROL_FALSE;
565 if (ioctl(priv->video_fd, VIDIOC_G_CTRL, control) < 0) {
566 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl get %s failed: %s\n",
567 info.short_name, qctrl.name, strerror(errno));
568 return TVI_CONTROL_FALSE;
570 mp_msg(MSGT_TV, MSGL_V, "%s: get %s: %d [%d, %d]\n", info.short_name,
571 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
573 if (val_signed) {
574 if (control->value < qctrl.default_value) {
575 control->value = (control->value - qctrl.default_value) * 100 /
576 (qctrl.default_value - qctrl.minimum);
577 } else {
578 control->value = (control->value - qctrl.default_value) * 100 /
579 (qctrl.maximum - qctrl.default_value);
581 } else {
582 if (control->value < qctrl.default_value) {
583 control->value = (control->value - qctrl.default_value) * 50 /
584 (qctrl.default_value - qctrl.minimum) + 50;
585 } else {
586 control->value = (control->value - qctrl.default_value) * 50 /
587 (qctrl.maximum - qctrl.default_value) + 50;
591 return TVI_CONTROL_TRUE;
594 #ifdef CONFIG_TV_TELETEXT
595 static int vbi_init(priv_t* priv,char* device)
597 int vbi_fd=0;
598 struct v4l2_capability cap;
599 struct v4l2_format fmt;
600 int res;
602 if(!device)
603 return TVI_CONTROL_FALSE;
605 priv->vbi_dev=strdup(device);
607 vbi_fd=open(priv->vbi_dev,O_RDWR);
608 if(vbi_fd<0){
609 mp_msg(MSGT_TV,MSGL_ERR,"vbi: could not open device %s\n",priv->vbi_dev);
610 return TVI_CONTROL_FALSE;
613 if(ioctl(vbi_fd,VIDIOC_QUERYCAP,&cap)<0){
614 mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query capatibilities failed for %s\n",priv->vbi_dev);
615 close(vbi_fd);
616 return TVI_CONTROL_FALSE;
618 if(!cap.capabilities & V4L2_CAP_VBI_CAPTURE){
619 mp_msg(MSGT_TV,MSGL_ERR,"vbi: %s does not support VBI capture\n",priv->vbi_dev);
620 close(vbi_fd);
621 return TVI_CONTROL_FALSE;
624 memset(&fmt,0,sizeof(struct v4l2_format));
625 fmt.type=V4L2_BUF_TYPE_VBI_CAPTURE;
626 if((res=ioctl(vbi_fd,VIDIOC_G_FMT,&fmt))<0){
627 mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query format failed: %x\n",res);
628 close(vbi_fd);
629 return TVI_CONTROL_FALSE;
631 if(fmt.fmt.vbi.sample_format!=V4L2_PIX_FMT_GREY){
632 mp_msg(MSGT_TV,MSGL_ERR,"vbi: format 0x%x is not supported\n",fmt.fmt.vbi.sample_format);
633 close(vbi_fd);
634 return TVI_CONTROL_FALSE;
636 priv->vbi_fd=vbi_fd;
637 mp_msg(MSGT_TV,MSGL_DBG3,"vbi: init ok\n");
638 return TVI_CONTROL_TRUE;
641 static int vbi_get_props(priv_t* priv,tt_stream_props* ptsp)
643 struct v4l2_format fmt;
644 int res;
645 if(!priv || !ptsp)
646 return TVI_CONTROL_FALSE;
648 memset(&fmt,0,sizeof(struct v4l2_format));
649 fmt.type=V4L2_BUF_TYPE_VBI_CAPTURE;
650 if((res=ioctl(priv->vbi_fd,VIDIOC_G_FMT,&fmt))<0){
651 mp_msg(MSGT_TV,MSGL_ERR,"vbi_get_props: Query format failed: %x\n",res);
652 return TVI_CONTROL_FALSE;
655 ptsp->interlaced=(fmt.fmt.vbi.flags& V4L2_VBI_INTERLACED?1:0);
657 ptsp->offset=fmt.fmt.vbi.offset;
658 ptsp->sampling_rate=fmt.fmt.vbi.sampling_rate;
659 ptsp->samples_per_line=fmt.fmt.vbi.samples_per_line,
661 ptsp->count[0]=fmt.fmt.vbi.count[0];
662 ptsp->count[1]=fmt.fmt.vbi.count[1];
663 ptsp->bufsize = ptsp->samples_per_line * (ptsp->count[0] + ptsp->count[1]);
665 mp_msg(MSGT_TV,MSGL_V,"vbi_get_props: sampling_rate=%d,offset:%d,samples_per_line: %d\n interlaced:%s, count=[%d,%d]\n",
666 ptsp->sampling_rate,
667 ptsp->offset,
668 ptsp->samples_per_line,
669 ptsp->interlaced?"Yes":"No",
670 ptsp->count[0],
671 ptsp->count[1]);
673 return TVI_CONTROL_TRUE;
676 static void *vbi_grabber(void *data)
678 priv_t *priv = (priv_t *) data;
679 int bytes,seq,prev_seq;
680 unsigned char* buf;
681 tt_stream_props tsp;
683 if(!priv->priv_vbi){
684 mp_msg(MSGT_TV,MSGL_WARN,"vbi: vbi not initialized. stopping thread.\n");
685 return NULL;
688 if(vbi_get_props(priv,&tsp)!=TVI_CONTROL_TRUE)
689 return NULL;
691 buf=malloc(tsp.bufsize);
692 seq=0;
693 prev_seq=0;
694 mp_msg(MSGT_TV,MSGL_V,"vbi: vbi capture thread started.\n");
696 while (!priv->vbi_shutdown){
697 bytes=read(priv->vbi_fd,buf,tsp.bufsize);
698 if(bytes<0 && errno==EINTR)
699 continue;
700 if (bytes!=tsp.bufsize){
701 mp_msg(MSGT_TV,MSGL_WARN,"vbi: expecting bytes: %d, got: %d\n",tsp.bufsize,bytes);
702 break;
704 seq=*(int*)(buf+bytes-4);
705 if(seq<=1) continue;
706 if (prev_seq && seq!=prev_seq+1){
707 prev_seq=0;
708 seq=0;
710 prev_seq=seq;
711 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_DECODE_PAGE,&buf);
712 mp_msg(MSGT_TV,MSGL_DBG3,"grabber: seq:%d\n",seq);
714 free(buf);
715 return NULL;
717 #endif /* CONFIG_TV_TELETEXT */
719 static int control(priv_t *priv, int cmd, void *arg)
721 struct v4l2_control control;
722 struct v4l2_frequency frequency;
724 switch(cmd) {
725 case TVI_CONTROL_IS_VIDEO:
726 return priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
727 TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
728 case TVI_CONTROL_IS_AUDIO:
729 if (priv->tv_param->force_audio) return TVI_CONTROL_TRUE;
730 case TVI_CONTROL_IS_TUNER:
731 return priv->capability.capabilities & V4L2_CAP_TUNER?
732 TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
733 case TVI_CONTROL_IMMEDIATE:
734 priv->immediate_mode = 1;
735 return TVI_CONTROL_TRUE;
736 case TVI_CONTROL_VID_GET_FPS:
737 if (!priv->standard.frameperiod.denominator || !priv->standard.frameperiod.numerator) {
738 mp_msg(MSGT_TV, MSGL_ERR, "%s: Cannot get fps\n", info.short_name);
739 return TVI_CONTROL_FALSE;
741 *(float *)arg = (float)priv->standard.frameperiod.denominator /
742 priv->standard.frameperiod.numerator;
743 mp_msg(MSGT_TV, MSGL_V, "%s: get fps: %f\n", info.short_name,
744 *(float *)arg);
745 return TVI_CONTROL_TRUE;
746 case TVI_CONTROL_VID_GET_BITS:
747 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
748 *(int *)arg = pixfmt2depth(priv->format.fmt.pix.pixelformat);
749 mp_msg(MSGT_TV, MSGL_V, "%s: get depth: %d\n", info.short_name,
750 *(int *)arg);
751 return TVI_CONTROL_TRUE;
752 case TVI_CONTROL_VID_GET_FORMAT:
753 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
754 *(int *)arg = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
755 mp_msg(MSGT_TV, MSGL_V, "%s: get format: %s\n", info.short_name,
756 pixfmt2name(priv->format.fmt.pix.pixelformat));
757 return TVI_CONTROL_TRUE;
758 case TVI_CONTROL_VID_SET_FORMAT:
759 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
760 priv->format.fmt.pix.pixelformat = fcc_mp2vl(*(int *)arg);
761 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
763 priv->mp_format = *(int *)arg;
764 mp_msg(MSGT_TV, MSGL_V, "%s: set format: %s\n", info.short_name,
765 pixfmt2name(priv->format.fmt.pix.pixelformat));
766 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
767 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
768 info.short_name, strerror(errno));
769 return TVI_CONTROL_FALSE;
771 /* according to the v4l2 specs VIDIOC_S_FMT should not fail, inflexible drivers
772 might even always return the default parameters -> update the format here*/
773 priv->mp_format = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
774 return TVI_CONTROL_TRUE;
775 case TVI_CONTROL_VID_GET_WIDTH:
776 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
777 *(int *)arg = priv->format.fmt.pix.width;
778 mp_msg(MSGT_TV, MSGL_V, "%s: get width: %d\n", info.short_name,
779 *(int *)arg);
780 return TVI_CONTROL_TRUE;
781 case TVI_CONTROL_VID_CHK_WIDTH:
782 return TVI_CONTROL_TRUE;
783 case TVI_CONTROL_VID_SET_WIDTH_HEIGHT:
784 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
785 priv->format.fmt.pix.width = ((int *)arg)[0];
786 priv->format.fmt.pix.height = ((int *)arg)[1];
787 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
788 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0)
789 return TVI_CONTROL_FALSE;
790 return TVI_CONTROL_TRUE;
791 case TVI_CONTROL_VID_SET_WIDTH:
792 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
793 priv->format.fmt.pix.width = *(int *)arg;
794 mp_msg(MSGT_TV, MSGL_V, "%s: set width: %d\n", info.short_name,
795 *(int *)arg);
796 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
797 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set width failed: %s\n",
798 info.short_name, strerror(errno));
799 return TVI_CONTROL_FALSE;
801 return TVI_CONTROL_TRUE;
802 case TVI_CONTROL_VID_GET_HEIGHT:
803 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
804 *(int *)arg = priv->format.fmt.pix.height;
805 mp_msg(MSGT_TV, MSGL_V, "%s: get height: %d\n", info.short_name,
806 *(int *)arg);
807 return TVI_CONTROL_TRUE;
808 case TVI_CONTROL_VID_CHK_HEIGHT:
809 return TVI_CONTROL_TRUE;
810 case TVI_CONTROL_VID_SET_HEIGHT:
811 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
812 priv->format.fmt.pix.height = *(int *)arg;
813 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
814 mp_msg(MSGT_TV, MSGL_V, "%s: set height: %d\n", info.short_name,
815 *(int *)arg);
816 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
817 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set height failed: %s\n",
818 info.short_name, strerror(errno));
819 return TVI_CONTROL_FALSE;
821 return TVI_CONTROL_TRUE;
822 case TVI_CONTROL_VID_GET_BRIGHTNESS:
823 control.id = V4L2_CID_BRIGHTNESS;
824 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
825 *(int *)arg = control.value;
826 return TVI_CONTROL_TRUE;
828 return TVI_CONTROL_FALSE;
829 case TVI_CONTROL_VID_SET_BRIGHTNESS:
830 control.id = V4L2_CID_BRIGHTNESS;
831 control.value = *(int *)arg;
832 return set_control(priv, &control, 1);
833 case TVI_CONTROL_VID_GET_HUE:
834 control.id = V4L2_CID_HUE;
835 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
836 *(int *)arg = control.value;
837 return TVI_CONTROL_TRUE;
839 return TVI_CONTROL_FALSE;
840 case TVI_CONTROL_VID_SET_HUE:
841 control.id = V4L2_CID_HUE;
842 control.value = *(int *)arg;
843 return set_control(priv, &control, 1);
844 case TVI_CONTROL_VID_GET_SATURATION:
845 control.id = V4L2_CID_SATURATION;
846 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
847 *(int *)arg = control.value;
848 return TVI_CONTROL_TRUE;
850 return TVI_CONTROL_FALSE;
851 case TVI_CONTROL_VID_SET_SATURATION:
852 control.id = V4L2_CID_SATURATION;
853 control.value = *(int *)arg;
854 return set_control(priv, &control, 1);
855 case TVI_CONTROL_VID_GET_GAIN:
858 control.id = V4L2_CID_AUTOGAIN;
859 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
860 return TVI_CONTROL_FALSE;
862 if(control.value){ //Auto Gain control is enabled
863 *(int*)arg=0;
864 return TVI_CONTROL_TRUE;
867 //Manual Gain control
868 control.id = V4L2_CID_GAIN;
869 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
870 return TVI_CONTROL_FALSE;
872 *(int*)arg=control.value?control.value:1;
874 return TVI_CONTROL_TRUE;
876 case TVI_CONTROL_VID_SET_GAIN:
878 //value==0 means automatic gain control
879 int value=*(int*)arg;
881 if (value < 0 || value>100)
882 return TVI_CONTROL_FALSE;
884 control.id=value?V4L2_CID_GAIN:V4L2_CID_AUTOGAIN;
885 control.value=value?value:1;
887 return set_control(priv,&control,0);
889 case TVI_CONTROL_VID_GET_CONTRAST:
890 control.id = V4L2_CID_CONTRAST;
891 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
892 *(int *)arg = control.value;
893 return TVI_CONTROL_TRUE;
895 return TVI_CONTROL_FALSE;
896 case TVI_CONTROL_VID_SET_CONTRAST:
897 control.id = V4L2_CID_CONTRAST;
898 control.value = *(int *)arg;
899 return set_control(priv, &control, 1);
900 case TVI_CONTROL_TUN_GET_FREQ:
901 frequency.tuner = 0;
902 frequency.type = V4L2_TUNER_ANALOG_TV;
903 if (ioctl(priv->video_fd, VIDIOC_G_FREQUENCY, &frequency) < 0) {
904 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl get frequency failed: %s\n",
905 info.short_name, strerror(errno));
906 return TVI_CONTROL_FALSE;
908 *(int *)arg = frequency.frequency;
909 return TVI_CONTROL_TRUE;
910 case TVI_CONTROL_TUN_SET_FREQ:
911 #if 0
912 set_mute(priv, 1);
913 usleep(100000); // wait to suppress noise during switching
914 #endif
915 frequency.tuner = 0;
916 frequency.type = V4L2_TUNER_ANALOG_TV;
917 frequency.frequency = *(int *)arg;
918 if (ioctl(priv->video_fd, VIDIOC_S_FREQUENCY, &frequency) < 0) {
919 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set frequency failed: %s\n",
920 info.short_name, strerror(errno));
921 return TVI_CONTROL_FALSE;
923 #if 0
924 usleep(100000); // wait to suppress noise during switching
925 set_mute(priv, 0);
926 #endif
927 return TVI_CONTROL_TRUE;
928 case TVI_CONTROL_TUN_GET_TUNER:
929 mp_msg(MSGT_TV, MSGL_V, "%s: get tuner\n",info.short_name);
930 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
931 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
932 info.short_name, strerror(errno));
933 return TVI_CONTROL_FALSE;
935 return TVI_CONTROL_TRUE;
936 case TVI_CONTROL_TUN_SET_TUNER:
937 mp_msg(MSGT_TV, MSGL_V, "%s: set tuner\n",info.short_name);
938 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
939 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
940 info.short_name, strerror(errno));
941 return TVI_CONTROL_FALSE;
943 return TVI_CONTROL_TRUE;
944 case TVI_CONTROL_TUN_GET_NORM:
945 *(int *)arg = priv->standard.index;
946 return TVI_CONTROL_TRUE;
947 case TVI_CONTROL_TUN_GET_SIGNAL:
948 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
949 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
950 info.short_name, strerror(errno));
951 return TVI_CONTROL_FALSE;
953 *(int*)arg=100*(priv->tuner.signal>>8)/255;
954 return TVI_CONTROL_TRUE;
955 case TVI_CONTROL_TUN_SET_NORM:
956 priv->standard.index = *(int *)arg;
957 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
958 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum norm failed: %s\n",
959 info.short_name, strerror(errno));
960 return TVI_CONTROL_FALSE;
962 mp_msg(MSGT_TV, MSGL_V, "%s: set norm: %s\n", info.short_name, priv->standard.name);
963 if (ioctl(priv->video_fd, VIDIOC_S_STD, &priv->standard.id) < 0) {
964 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set norm failed: %s\n",
965 info.short_name, strerror(errno));
966 return TVI_CONTROL_FALSE;
968 return TVI_CONTROL_TRUE;
969 case TVI_CONTROL_SPC_GET_NORMID:
971 int i;
972 for (i = 0;; i++) {
973 struct v4l2_standard standard;
974 memset(&standard, 0, sizeof(standard));
975 standard.index = i;
976 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
977 return TVI_CONTROL_FALSE;
978 if (!strcasecmp(standard.name, (char *)arg)) {
979 *(int *)arg = i;
980 return TVI_CONTROL_TRUE;
983 return TVI_CONTROL_FALSE;
985 case TVI_CONTROL_SPC_GET_INPUT:
986 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, (int *)arg) < 0) {
987 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
988 info.short_name, strerror(errno));
989 return TVI_CONTROL_FALSE;
991 return TVI_CONTROL_TRUE;
992 case TVI_CONTROL_SPC_SET_INPUT:
993 mp_msg(MSGT_TV, MSGL_V, "%s: set input: %d\n", info.short_name, *(int *)arg);
994 priv->input.index = *(int *)arg;
995 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &priv->input) < 0) {
996 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum input failed: %s\n",
997 info.short_name, strerror(errno));
998 return TVI_CONTROL_FALSE;
1000 if (ioctl(priv->video_fd, VIDIOC_S_INPUT, (int *)arg) < 0) {
1001 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set input failed: %s\n",
1002 info.short_name, strerror(errno));
1003 return TVI_CONTROL_FALSE;
1005 return TVI_CONTROL_TRUE;
1006 case TVI_CONTROL_AUD_GET_FORMAT:
1007 init_audio(priv);
1008 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1009 *(int *)arg = AF_FORMAT_S16_LE;
1010 mp_msg(MSGT_TV, MSGL_V, "%s: get audio format: %d\n",
1011 info.short_name, *(int *)arg);
1012 return TVI_CONTROL_TRUE;
1013 case TVI_CONTROL_AUD_GET_SAMPLERATE:
1014 init_audio(priv);
1015 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1016 *(int *)arg = priv->audio_in.samplerate;
1017 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplerate: %d\n",
1018 info.short_name, *(int *)arg);
1019 return TVI_CONTROL_TRUE;
1020 case TVI_CONTROL_AUD_GET_SAMPLESIZE:
1021 init_audio(priv);
1022 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1023 *(int *)arg = priv->audio_in.bytes_per_sample;
1024 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplesize: %d\n",
1025 info.short_name, *(int *)arg);
1026 return TVI_CONTROL_TRUE;
1027 case TVI_CONTROL_AUD_GET_CHANNELS:
1028 init_audio(priv);
1029 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1030 *(int *)arg = priv->audio_in.channels;
1031 mp_msg(MSGT_TV, MSGL_V, "%s: get audio channels: %d\n",
1032 info.short_name, *(int *)arg);
1033 return TVI_CONTROL_TRUE;
1034 case TVI_CONTROL_AUD_SET_SAMPLERATE:
1035 init_audio(priv);
1036 mp_msg(MSGT_TV, MSGL_V, "%s: set audio samplerate: %d\n",
1037 info.short_name, *(int *)arg);
1038 if (audio_in_set_samplerate(&priv->audio_in, *(int*)arg) < 0) return TVI_CONTROL_FALSE;
1039 // setup_audio_buffer_sizes(priv);
1040 return TVI_CONTROL_TRUE;
1041 #ifdef CONFIG_TV_TELETEXT
1042 case TVI_CONTROL_VBI_INIT:
1044 void* ptr;
1045 tt_stream_props tsp;
1047 if (vbi_init(priv,*(char**)arg)!=TVI_CONTROL_TRUE)
1048 return TVI_CONTROL_FALSE;
1049 if(vbi_get_props(priv,&tsp)==TVI_CONTROL_TRUE)
1051 ptr=&tsp;
1052 if(teletext_control(NULL,TV_VBI_CONTROL_START,&ptr)==TVI_CONTROL_TRUE)
1053 priv->priv_vbi=ptr;
1054 else
1055 priv->priv_vbi=NULL;
1057 return TVI_CONTROL_TRUE;
1059 default:
1060 return teletext_control(priv->priv_vbi,cmd,arg);
1061 #endif
1063 mp_msg(MSGT_TV, MSGL_V, "%s: unknown control: %d\n", info.short_name, cmd);
1064 return TVI_CONTROL_UNKNOWN;
1068 #define PRIV ((priv_t *) (tvi_handle->priv))
1070 /* handler creator - entry point ! */
1071 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param)
1073 tvi_handle_t *tvi_handle;
1075 /* new_handle initializes priv with memset 0 */
1076 tvi_handle = new_handle();
1077 if (!tvi_handle) {
1078 return NULL;
1080 PRIV->video_fd = -1;
1082 PRIV->video_dev = strdup(tv_param->device? tv_param->device: "/dev/video0");
1083 if (!PRIV->video_dev) {
1084 free_handle(tvi_handle);
1085 return NULL;
1088 if (tv_param->adevice) {
1089 PRIV->audio_dev = strdup(tv_param->adevice);
1090 if (!PRIV->audio_dev) {
1091 free(PRIV->video_dev);
1092 free_handle(tvi_handle);
1093 return NULL;
1097 PRIV->tv_param=tv_param;
1098 return tvi_handle;
1101 #undef PRIV
1104 static int uninit(priv_t *priv)
1106 int i, frames, dropped = 0;
1108 #ifdef CONFIG_TV_TELETEXT
1109 priv->vbi_shutdown=1;
1110 if(priv->vbi_grabber_thread)
1111 pthread_join(priv->vbi_grabber_thread, NULL);
1113 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_STOP,(void*)1);
1114 priv->priv_vbi=NULL;
1116 if(priv->vbi_fd){
1117 close(priv->vbi_fd);
1118 priv->vbi_fd=0;
1121 if(priv->vbi_dev){
1122 free(priv->vbi_dev);
1123 priv->vbi_dev=0;
1126 #endif
1128 priv->shutdown = 1;
1129 if(priv->video_grabber_thread)
1130 pthread_join(priv->video_grabber_thread, NULL);
1131 pthread_mutex_destroy(&priv->video_buffer_mutex);
1133 if (priv->streamon) {
1134 struct v4l2_buffer buf;
1136 /* get performance */
1137 frames = 1 + lrintf((double)(priv->curr_frame - priv->first_frame) / 1e6 * getfps(priv));
1138 dropped = frames - priv->frames;
1140 /* turn off streaming */
1141 if (ioctl(priv->video_fd, VIDIOC_STREAMOFF, &(priv->map[0].buf.type)) < 0) {
1142 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamoff failed: %s\n",
1143 info.short_name, strerror(errno));
1145 priv->streamon = 0;
1147 /* unqueue all remaining buffers */
1148 memset(&buf,0,sizeof(buf));
1149 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1150 buf.memory = V4L2_MEMORY_MMAP;
1151 while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
1154 /* unmap all buffers */
1155 for (i = 0; i < priv->mapcount; i++) {
1156 if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {
1157 mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",
1158 info.short_name, strerror(errno));
1162 /* stop audio thread */
1163 if (!priv->tv_param->noaudio && priv->audio_grabber_thread) {
1164 pthread_join(priv->audio_grabber_thread, NULL);
1165 pthread_mutex_destroy(&priv->skew_mutex);
1166 pthread_mutex_destroy(&priv->audio_mutex);
1169 set_mute(priv, 1);
1171 /* free memory and close device */
1172 free(priv->map); priv->map = NULL;
1173 priv->mapcount = 0;
1174 if(priv->video_fd!=-1)close(priv->video_fd); priv->video_fd = -1;
1175 free(priv->video_dev); priv->video_dev = NULL;
1177 if (priv->video_ringbuffer) {
1178 int i;
1179 for (i = 0; i < priv->video_buffer_size_current; i++) {
1180 free(priv->video_ringbuffer[i].data);
1182 free(priv->video_ringbuffer);
1184 if (!priv->tv_param->noaudio) {
1185 if (priv->audio_ringbuffer)
1186 free(priv->audio_ringbuffer);
1187 if (priv->audio_skew_buffer)
1188 free(priv->audio_skew_buffer);
1189 if (priv->audio_skew_delta_buffer)
1190 free(priv->audio_skew_delta_buffer);
1192 audio_in_uninit(&priv->audio_in);
1195 /* show some nice statistics ;-) */
1196 mp_msg(MSGT_TV, MSGL_INFO,
1197 "%s: %d frames successfully processed, %d frames dropped.\n",
1198 info.short_name, priv->frames, dropped);
1199 mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",
1200 info.short_name, priv->video_buffer_size_current);
1201 return 1;
1205 /* initialisation */
1206 static int init(priv_t *priv)
1208 int i;
1210 priv->audio_ringbuffer = NULL;
1211 priv->audio_skew_buffer = NULL;
1212 priv->audio_skew_delta_buffer = NULL;
1214 priv->audio_initialized = 0;
1216 /* Open the video device. */
1217 priv->video_fd = open(priv->video_dev, O_RDWR);
1218 if (priv->video_fd < 0) {
1219 mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",
1220 info.short_name, priv->video_dev, strerror(errno));
1221 uninit(priv);
1222 return 0;
1224 mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",
1225 info.short_name, priv->video_dev, priv->video_fd);
1228 ** Query the video capabilities and current settings
1229 ** for further control calls.
1231 if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
1232 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",
1233 info.short_name, strerror(errno));
1234 uninit(priv);
1235 return 0;
1238 if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))
1240 mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",
1241 priv->video_dev);
1242 return 0;
1245 if (getfmt(priv) < 0) {
1246 uninit(priv);
1247 return 0;
1249 getstd(priv);
1251 ** if this device has got a tuner query it's settings
1252 ** otherwise set some nice defaults
1254 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1255 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
1256 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
1257 info.short_name, strerror(errno));
1258 uninit(priv);
1259 return 0;
1262 mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);
1263 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1264 mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",
1265 (priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",
1266 (priv->tuner.capability & V4L2_TUNER_CAP_LANG1) ? " LANG1" : "",
1267 (priv->tuner.capability & V4L2_TUNER_CAP_LANG2) ? " LANG2" : "");
1268 mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",
1269 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO) ? " MONO" : "",
1270 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",
1271 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1) ? " LANG1" : "",
1272 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2) ? " LANG2" : "");
1274 mp_msg(MSGT_TV, MSGL_INFO, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1275 priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
1276 " video capture": "",
1277 priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?
1278 " video output": "",
1279 priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?
1280 " video overlay": "",
1281 priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?
1282 " VBI capture device": "",
1283 priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?
1284 " VBI output": "",
1285 priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?
1286 " RDS data capture": "",
1287 priv->capability.capabilities & V4L2_CAP_TUNER?
1288 " tuner": "",
1289 priv->capability.capabilities & V4L2_CAP_AUDIO?
1290 " audio": "",
1291 priv->capability.capabilities & V4L2_CAP_READWRITE?
1292 " read/write": "",
1293 priv->capability.capabilities & V4L2_CAP_ASYNCIO?
1294 " async i/o": "",
1295 priv->capability.capabilities & V4L2_CAP_STREAMING?
1296 " streaming": "");
1297 mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");
1298 for (i = 0;; i++) {
1299 struct v4l2_standard standard;
1300 memset(&standard, 0, sizeof(standard));
1301 standard.index = i;
1302 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
1303 break;
1304 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);
1306 mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");
1307 for (i = 0; 1; i++) {
1308 struct v4l2_input input;
1310 input.index = i;
1311 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
1312 break;
1314 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);
1316 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
1317 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
1318 info.short_name, strerror(errno));
1320 mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);
1321 for (i = 0; ; i++) {
1322 struct v4l2_fmtdesc fmtdesc;
1324 fmtdesc.index = i;
1325 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1326 if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
1327 break;
1329 mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",
1330 pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),
1331 fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));
1333 mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",
1334 pixfmt2name(priv->format.fmt.pix.pixelformat));
1336 /* set some nice defaults */
1337 if (getfmt(priv) < 0) return 0;
1338 priv->format.fmt.pix.width = 640;
1339 priv->format.fmt.pix.height = 480;
1340 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
1341 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
1342 info.short_name, strerror(errno));
1343 uninit(priv);
1344 return 0;
1347 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;
1349 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1350 struct v4l2_control control;
1351 if (priv->tv_param->amode >= 0) {
1352 mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);
1353 priv->tuner.audmode = amode2v4l(priv->tv_param->amode);
1354 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
1355 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
1356 info.short_name, strerror(errno));
1357 return TVI_CONTROL_FALSE;
1360 mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,
1361 (priv->tuner.audmode == V4L2_TUNER_MODE_MONO) ? " MONO" : "",
1362 (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",
1363 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG1) ? " LANG1" : "",
1364 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG2) ? " LANG2" : "");
1366 if (priv->tv_param->volume >= 0) {
1367 control.id = V4L2_CID_AUDIO_VOLUME;
1368 control.value = priv->tv_param->volume;
1369 set_control(priv, &control, 0);
1371 if (priv->tv_param->bass >= 0) {
1372 control.id = V4L2_CID_AUDIO_BASS;
1373 control.value = priv->tv_param->bass;
1374 set_control(priv, &control, 0);
1376 if (priv->tv_param->treble >= 0) {
1377 control.id = V4L2_CID_AUDIO_TREBLE;
1378 control.value = priv->tv_param->treble;
1379 set_control(priv, &control, 0);
1381 if (priv->tv_param->balance >= 0) {
1382 control.id = V4L2_CID_AUDIO_BALANCE;
1383 control.value = priv->tv_param->balance;
1384 set_control(priv, &control, 0);
1388 return 1;
1391 static int get_capture_buffer_size(priv_t *priv)
1393 int bufsize, cnt;
1395 if (priv->tv_param->buffer_size >= 0) {
1396 bufsize = priv->tv_param->buffer_size*1024*1024;
1397 } else {
1398 #ifdef HAVE_SYS_SYSINFO_H
1399 struct sysinfo si;
1401 sysinfo(&si);
1402 if (si.totalram<2*1024*1024) {
1403 bufsize = 1024*1024;
1404 } else {
1405 bufsize = si.totalram/2;
1407 #else
1408 bufsize = 16*1024*1024;
1409 #endif
1412 cnt = bufsize/priv->format.fmt.pix.sizeimage;
1413 if (cnt < 2) cnt = 2;
1415 return cnt;
1418 /* that's the real start, we'got the format parameters (checked with control) */
1419 static int start(priv_t *priv)
1421 struct v4l2_requestbuffers request;
1422 unsigned int i;
1424 /* setup audio parameters */
1426 init_audio(priv);
1427 if (!priv->tv_param->noaudio && !priv->audio_initialized) return 0;
1429 /* we need this to size the audio buffer properly */
1430 if (priv->immediate_mode) {
1431 priv->video_buffer_size_max = 2;
1432 } else {
1433 priv->video_buffer_size_max = get_capture_buffer_size(priv);
1436 if (!priv->tv_param->noaudio) {
1437 setup_audio_buffer_sizes(priv);
1438 priv->audio_skew_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1439 if (!priv->audio_skew_buffer) {
1440 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1441 return 0;
1443 priv->audio_skew_delta_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1444 if (!priv->audio_skew_delta_buffer) {
1445 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1446 return 0;
1449 priv->audio_ringbuffer = calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
1450 if (!priv->audio_ringbuffer) {
1451 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
1452 return 0;
1455 priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate
1456 *priv->audio_in.channels
1457 *priv->audio_in.bytes_per_sample);
1458 priv->audio_usecs_per_block = 1e6*priv->audio_secs_per_block;
1459 priv->audio_head = 0;
1460 priv->audio_tail = 0;
1461 priv->audio_cnt = 0;
1462 priv->audio_drop = 0;
1463 priv->audio_skew = 0;
1464 priv->audio_skew_total = 0;
1465 priv->audio_skew_delta_total = 0;
1466 priv->audio_recv_blocks_total = 0;
1467 priv->audio_sent_blocks_total = 0;
1468 priv->audio_null_blocks_inserted = 0;
1469 priv->audio_insert_null_samples = 0;
1470 priv->dropped_frames_timeshift = 0;
1471 priv->dropped_frames_compensated = 0;
1473 pthread_mutex_init(&priv->skew_mutex, NULL);
1474 pthread_mutex_init(&priv->audio_mutex, NULL);
1477 /* setup video parameters */
1478 if (!priv->tv_param->noaudio) {
1479 if (priv->video_buffer_size_max < (3*priv->standard.frameperiod.denominator) /
1480 priv->standard.frameperiod.numerator
1481 *priv->audio_secs_per_block) {
1482 mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"
1483 "You will probably experience heavy framedrops.\n");
1488 int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1490 mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1491 priv->video_buffer_size_max,
1492 priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));
1495 priv->video_ringbuffer = calloc(priv->video_buffer_size_max, sizeof(video_buffer_entry));
1496 if (!priv->video_ringbuffer) {
1497 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
1498 return 0;
1500 memset(priv->video_ringbuffer,0,priv->video_buffer_size_max * sizeof(video_buffer_entry));
1502 pthread_mutex_init(&priv->video_buffer_mutex, NULL);
1504 priv->video_head = 0;
1505 priv->video_tail = 0;
1506 priv->video_cnt = 0;
1508 /* request buffers */
1509 if (priv->immediate_mode) {
1510 request.count = 2;
1511 } else {
1512 request.count = BUFFER_COUNT;
1515 request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1516 request.memory = V4L2_MEMORY_MMAP;
1517 if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
1518 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",
1519 info.short_name, strerror(errno));
1520 return 0;
1523 /* query buffers */
1524 if (!(priv->map = calloc(request.count, sizeof(struct map)))) {
1525 mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",
1526 info.short_name, strerror(errno));
1527 return 0;
1530 /* map and queue buffers */
1531 for (i = 0; i < request.count; i++) {
1532 memset(&priv->map[i].buf,0,sizeof(priv->map[i].buf));
1533 priv->map[i].buf.index = i;
1534 priv->map[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1535 priv->map[i].buf.memory = V4L2_MEMORY_MMAP;
1536 if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
1537 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",
1538 info.short_name, strerror(errno));
1539 free(priv->map);
1540 priv->map = NULL;
1541 return 0;
1543 priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |
1544 PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);
1545 if (priv->map[i].addr == MAP_FAILED) {
1546 mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",
1547 info.short_name, strerror(errno));
1548 priv->map[i].len = 0;
1549 return 0;
1551 priv->map[i].len = priv->map[i].buf.length;
1552 /* count up to make sure this is correct everytime */
1553 priv->mapcount++;
1555 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1556 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1557 info.short_name, strerror(errno));
1558 return 0;
1562 #ifdef CONFIG_TV_TELETEXT
1563 /* start vbi thread */
1564 if(priv->priv_vbi){
1565 priv->vbi_shutdown = 0;
1566 pthread_create(&priv->vbi_grabber_thread, NULL, vbi_grabber, priv);
1568 #endif
1569 /* start audio thread */
1570 priv->shutdown = 0;
1571 priv->audio_skew_measure_time = 0;
1572 priv->first_frame = 0;
1573 priv->audio_skew = 0;
1574 priv->first = 1;
1576 set_mute(priv, 0);
1578 return 1;
1581 // copies a video frame
1582 static inline void copy_frame(priv_t *priv, video_buffer_entry *dest, unsigned char *source,int len)
1584 dest->framesize=len;
1585 if(priv->tv_param->automute>0){
1586 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) >= 0) {
1587 if(priv->tv_param->automute<<8>priv->tuner.signal){
1588 fill_blank_frame(dest->data,dest->framesize,fcc_vl2mp(priv->format.fmt.pix.pixelformat));
1589 set_mute(priv,1);
1590 return;
1593 set_mute(priv,0);
1595 memcpy(dest->data, source, len);
1598 // maximum skew change, in frames
1599 #define MAX_SKEW_DELTA 0.6
1600 static void *video_grabber(void *data)
1602 priv_t *priv = (priv_t*)data;
1603 long long skew, prev_skew, xskew, interval, prev_interval, delta;
1604 int i;
1605 int framesize = priv->format.fmt.pix.sizeimage;
1606 fd_set rdset;
1607 struct timeval timeout;
1608 struct v4l2_buffer buf;
1610 xskew = 0;
1611 skew = 0;
1612 interval = 0;
1613 prev_interval = 0;
1614 prev_skew = 0;
1616 mp_msg(MSGT_TV, MSGL_V, "%s: going to capture\n", info.short_name);
1617 if (ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
1618 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamon failed: %s\n",
1619 info.short_name, strerror(errno));
1620 return 0;
1622 priv->streamon = 1;
1624 if (!priv->tv_param->noaudio) {
1625 pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
1628 for (priv->frames = 0; !priv->shutdown;)
1630 int ret;
1632 if (priv->immediate_mode) {
1633 while (priv->video_cnt == priv->video_buffer_size_max) {
1634 usleep(10000);
1635 if (priv->shutdown) {
1636 return NULL;
1641 FD_ZERO (&rdset);
1642 FD_SET (priv->video_fd, &rdset);
1644 timeout.tv_sec = 1;
1645 timeout.tv_usec = 0;
1647 i = select(priv->video_fd + 1, &rdset, NULL, NULL, &timeout);
1648 if (i < 0) {
1649 mp_msg(MSGT_TV, MSGL_ERR, "%s: select failed: %s\n",
1650 info.short_name, strerror(errno));
1651 continue;
1653 else if (i == 0) {
1654 mp_msg(MSGT_TV, MSGL_ERR, "%s: select timeout\n", info.short_name);
1655 continue;
1657 else if (!FD_ISSET(priv->video_fd, &rdset)) {
1658 continue;
1661 memset(&buf,0,sizeof(buf));
1662 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1663 buf.memory = V4L2_MEMORY_MMAP;
1664 ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
1666 if (ret < 0) {
1668 if there's no signal, the buffer might me dequeued
1669 so we query all the buffers to see which one we should
1670 put back to queue
1672 observed with saa7134 0.2.8
1673 don't know if is it a bug or (mis)feature
1675 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1676 info.short_name, strerror(errno), buf.index);
1677 for (i = 0; i < priv->mapcount; i++) {
1678 memset(&buf,0,sizeof(buf));
1679 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1680 buf.memory = V4L2_MEMORY_MMAP;
1681 buf.index = i;
1682 ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
1683 if (ret < 0) {
1684 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s, idx = %d\n",
1685 info.short_name, strerror(errno), buf.index);
1686 return 0;
1688 if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
1689 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1690 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1691 info.short_name, strerror(errno));
1692 return 0;
1696 continue;
1699 /* store the timestamp of the very first frame as reference */
1700 if (!priv->frames++) {
1701 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1702 priv->first_frame = (long long)1e6*buf.timestamp.tv_sec + buf.timestamp.tv_usec;
1703 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1705 priv->curr_frame = (long long)buf.timestamp.tv_sec*1e6+buf.timestamp.tv_usec;
1706 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1708 interval = priv->curr_frame - priv->first_frame;
1709 delta = interval - prev_interval;
1711 if (!priv->immediate_mode) {
1712 // interpolate the skew in time
1713 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1714 xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
1715 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1716 // correct extreme skew changes to avoid (especially) moving backwards in time
1717 if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
1718 skew = prev_skew + delta*MAX_SKEW_DELTA;
1719 } else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) {
1720 skew = prev_skew - delta*MAX_SKEW_DELTA;
1721 } else {
1722 skew = xskew;
1726 mp_msg(MSGT_TV, MSGL_DBG3, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1727 delta ? (double)1e6/delta : -1,
1728 (double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
1729 mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
1731 prev_skew = skew;
1732 prev_interval = interval;
1734 /* allocate a new buffer, if needed */
1735 pthread_mutex_lock(&priv->video_buffer_mutex);
1736 if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
1737 if (priv->video_cnt == priv->video_buffer_size_current) {
1738 unsigned char *newbuf = malloc(framesize);
1739 if (newbuf) {
1740 memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
1741 (priv->video_buffer_size_current-priv->video_tail)*sizeof(video_buffer_entry));
1742 priv->video_ringbuffer[priv->video_tail].data = newbuf;
1743 if ((priv->video_head >= priv->video_tail) && (priv->video_cnt > 0)) priv->video_head++;
1744 priv->video_buffer_size_current++;
1748 pthread_mutex_unlock(&priv->video_buffer_mutex);
1750 if (priv->video_cnt == priv->video_buffer_size_current) {
1751 if (!priv->immediate_mode) {
1752 mp_msg(MSGT_TV, MSGL_ERR, "\nvideo buffer full - dropping frame\n");
1753 if (priv->audio_insert_null_samples) {
1754 pthread_mutex_lock(&priv->audio_mutex);
1755 priv->dropped_frames_timeshift += delta;
1756 pthread_mutex_unlock(&priv->audio_mutex);
1759 } else {
1760 if (priv->immediate_mode) {
1761 priv->video_ringbuffer[priv->video_tail].timestamp = 0;
1762 } else {
1763 // compensate for audio skew
1764 // negative skew => there are more audio samples, increase interval
1765 // positive skew => less samples, shorten the interval
1766 priv->video_ringbuffer[priv->video_tail].timestamp = interval - skew;
1767 if (priv->audio_insert_null_samples && priv->video_ringbuffer[priv->video_tail].timestamp > 0) {
1768 pthread_mutex_lock(&priv->audio_mutex);
1769 priv->video_ringbuffer[priv->video_tail].timestamp +=
1770 (priv->audio_null_blocks_inserted
1771 - priv->dropped_frames_timeshift/priv->audio_usecs_per_block)
1772 *priv->audio_usecs_per_block;
1773 pthread_mutex_unlock(&priv->audio_mutex);
1776 copy_frame(priv, priv->video_ringbuffer+priv->video_tail, priv->map[buf.index].addr,buf.bytesused);
1777 priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
1778 priv->video_cnt++;
1780 if (ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
1781 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1782 info.short_name, strerror(errno));
1783 return 0;
1786 return NULL;
1789 #define MAX_LOOP 50
1790 static double grab_video_frame(priv_t *priv, char *buffer, int len)
1792 double interval;
1793 int loop_cnt = 0;
1795 if (priv->first) {
1796 pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1797 priv->first = 0;
1800 while (priv->video_cnt == 0) {
1801 usleep(10000);
1802 if (loop_cnt++ > MAX_LOOP) return 0;
1805 pthread_mutex_lock(&priv->video_buffer_mutex);
1806 interval = (double)priv->video_ringbuffer[priv->video_head].timestamp*1e-6;
1807 memcpy(buffer, priv->video_ringbuffer[priv->video_head].data, len);
1808 priv->video_cnt--;
1809 priv->video_head = (priv->video_head+1)%priv->video_buffer_size_current;
1810 pthread_mutex_unlock(&priv->video_buffer_mutex);
1812 return interval;
1815 static int get_video_framesize(priv_t *priv)
1818 this routine will be called before grab_video_frame
1819 thus let's return topmost frame's size
1821 if (priv->video_cnt)
1822 return priv->video_ringbuffer[priv->video_head].framesize;
1824 no video frames yet available. i don't know what to do in this case,
1825 thus let's return some fallback result (for compressed format this will be
1826 maximum allowed frame size.
1828 return priv->format.fmt.pix.sizeimage;
1831 //#define DOUBLESPEED
1832 #ifdef DOUBLESPEED
1833 // for testing purposes only
1834 static void read_doublespeed(priv_t *priv)
1836 char *bufx = calloc(priv->audio_in.blocksize, 2);
1837 short *s;
1838 short *d;
1839 int i;
1841 audio_in_read_chunk(&priv->audio_in, bufx);
1842 audio_in_read_chunk(&priv->audio_in, bufx+priv->audio_in.blocksize);
1844 s = bufx;
1845 d = priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize;
1846 for (i = 0; i < priv->audio_in.blocksize/2; i++) {
1847 *d++ = *s++;
1848 *s++;
1852 #endif
1854 static void *audio_grabber(void *data)
1856 priv_t *priv = (priv_t*)data;
1857 struct timeval tv;
1858 int i, audio_skew_ptr = 0;
1859 long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
1860 long long start_time_avg;
1862 gettimeofday(&tv, NULL);
1863 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1864 audio_in_start_capture(&priv->audio_in);
1865 for (i = 0; i < priv->aud_skew_cnt; i++)
1866 priv->audio_skew_buffer[i] = 0;
1867 for (i = 0; i < priv->aud_skew_cnt; i++)
1868 priv->audio_skew_delta_buffer[i] = 0;
1870 for (; !priv->shutdown;)
1872 #ifdef DOUBLESPEED
1873 read_doublespeed(priv);
1874 #else
1875 if (audio_in_read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize) < 0)
1876 continue;
1877 #endif
1878 pthread_mutex_lock(&priv->skew_mutex);
1879 if (priv->first_frame == 0) {
1880 // there is no first frame yet (unlikely to happen)
1881 gettimeofday(&tv, NULL);
1882 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1883 // fprintf(stderr, "warning - first frame not yet available!\n");
1884 pthread_mutex_unlock(&priv->skew_mutex);
1885 continue;
1887 pthread_mutex_unlock(&priv->skew_mutex);
1889 gettimeofday(&tv, NULL);
1891 priv->audio_recv_blocks_total++;
1892 current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
1894 if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
1895 start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1896 priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
1899 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1900 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1902 // put the current skew into the ring buffer
1903 priv->audio_skew_total -= priv->audio_skew_buffer[audio_skew_ptr];
1904 priv->audio_skew_buffer[audio_skew_ptr] = current_time
1905 - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1906 priv->audio_skew_total += priv->audio_skew_buffer[audio_skew_ptr];
1908 pthread_mutex_lock(&priv->skew_mutex);
1910 // skew calculation
1912 // compute the sliding average of the skews
1913 if (priv->audio_recv_blocks_total > priv->aud_skew_cnt) {
1914 priv->audio_skew = priv->audio_skew_total/priv->aud_skew_cnt;
1915 } else {
1916 priv->audio_skew = priv->audio_skew_total/priv->audio_recv_blocks_total;
1919 // put the current skew change (skew-prev_skew) into the ring buffer
1920 priv->audio_skew_delta_total -= priv->audio_skew_delta_buffer[audio_skew_ptr];
1921 priv->audio_skew_delta_buffer[audio_skew_ptr] = priv->audio_skew - prev_skew_uncorr;
1922 priv->audio_skew_delta_total += priv->audio_skew_delta_buffer[audio_skew_ptr];
1923 prev_skew_uncorr = priv->audio_skew; // remember the _uncorrected_ average value
1925 audio_skew_ptr = (audio_skew_ptr+1) % priv->aud_skew_cnt; // rotate the buffer pointer
1927 // sliding average approximates the value in the middle of the interval
1928 // so interpolate the skew value further to the current time
1929 priv->audio_skew += priv->audio_skew_delta_total/2;
1931 // now finally, priv->audio_skew contains fairly good approximation
1932 // of the current value
1934 // current skew factor (assuming linearity)
1935 // used for further interpolation in video_grabber
1936 // probably overkill but seems to be necessary for
1937 // stress testing by dropping half of the audio frames ;)
1938 // especially when using ALSA with large block sizes
1939 // where audio_skew remains a long while behind
1940 if ((priv->audio_skew_measure_time != 0) && (current_time - priv->audio_skew_measure_time != 0)) {
1941 priv->audio_skew_factor = (double)(priv->audio_skew-prev_skew)/(current_time - priv->audio_skew_measure_time);
1942 } else {
1943 priv->audio_skew_factor = 0.0;
1946 priv->audio_skew_measure_time = current_time;
1947 prev_skew = priv->audio_skew;
1948 priv->audio_skew += priv->audio_start_time - priv->first_frame;
1949 pthread_mutex_unlock(&priv->skew_mutex);
1951 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1953 pthread_mutex_lock(&priv->audio_mutex);
1954 if ((priv->audio_tail+1) % priv->audio_buffer_size == priv->audio_head) {
1955 mp_msg(MSGT_TV, MSGL_ERR, "\ntoo bad - dropping audio frame !\n");
1956 priv->audio_drop++;
1957 } else {
1958 priv->audio_tail = (priv->audio_tail+1) % priv->audio_buffer_size;
1959 priv->audio_cnt++;
1961 pthread_mutex_unlock(&priv->audio_mutex);
1963 return NULL;
1966 static double grab_audio_frame(priv_t *priv, char *buffer, int len)
1968 mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1969 priv, buffer, len);
1971 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1972 // => switch to the mode which outputs audio immediately, even if
1973 // it should be silence
1974 if (priv->first) priv->audio_insert_null_samples = 1;
1976 pthread_mutex_lock(&priv->audio_mutex);
1977 while (priv->audio_insert_null_samples
1978 && priv->dropped_frames_timeshift - priv->dropped_frames_compensated >= priv->audio_usecs_per_block) {
1979 // some frames were dropped - drop the corresponding number of audio blocks
1980 if (priv->audio_drop) {
1981 priv->audio_drop--;
1982 } else {
1983 if (priv->audio_head == priv->audio_tail) break;
1984 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1986 priv->dropped_frames_compensated += priv->audio_usecs_per_block;
1989 // compensate for dropped audio frames
1990 if (priv->audio_drop && (priv->audio_head == priv->audio_tail)) {
1991 priv->audio_drop--;
1992 memset(buffer, 0, len);
1993 goto out;
1996 if (priv->audio_insert_null_samples && (priv->audio_head == priv->audio_tail)) {
1997 // return silence to avoid desync and stuttering
1998 memset(buffer, 0, len);
1999 priv->audio_null_blocks_inserted++;
2000 goto out;
2003 pthread_mutex_unlock(&priv->audio_mutex);
2004 while (priv->audio_head == priv->audio_tail) {
2005 // this is mencoder => just wait until some audio is available
2006 usleep(10000);
2008 pthread_mutex_lock(&priv->audio_mutex);
2009 memcpy(buffer, priv->audio_ringbuffer+priv->audio_head*priv->audio_in.blocksize, len);
2010 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
2011 priv->audio_cnt--;
2012 out:
2013 pthread_mutex_unlock(&priv->audio_mutex);
2014 priv->audio_sent_blocks_total++;
2015 return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
2018 static int get_audio_framesize(priv_t *priv)
2020 return priv->audio_in.blocksize;