Add statistics audio filter that prints information about the audio stream.
[mplayer/glamo.git] / stream / tvi_v4l2.c
blob0742135740839f51d92dc3b265edd9001de92ab0
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:
784 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
785 priv->format.fmt.pix.width = *(int *)arg;
786 mp_msg(MSGT_TV, MSGL_V, "%s: set width: %d\n", info.short_name,
787 *(int *)arg);
788 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
789 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set width failed: %s\n",
790 info.short_name, strerror(errno));
791 return TVI_CONTROL_FALSE;
793 return TVI_CONTROL_TRUE;
794 case TVI_CONTROL_VID_GET_HEIGHT:
795 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
796 *(int *)arg = priv->format.fmt.pix.height;
797 mp_msg(MSGT_TV, MSGL_V, "%s: get height: %d\n", info.short_name,
798 *(int *)arg);
799 return TVI_CONTROL_TRUE;
800 case TVI_CONTROL_VID_CHK_HEIGHT:
801 return TVI_CONTROL_TRUE;
802 case TVI_CONTROL_VID_SET_HEIGHT:
803 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
804 priv->format.fmt.pix.height = *(int *)arg;
805 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
806 mp_msg(MSGT_TV, MSGL_V, "%s: set height: %d\n", info.short_name,
807 *(int *)arg);
808 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
809 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set height failed: %s\n",
810 info.short_name, strerror(errno));
811 return TVI_CONTROL_FALSE;
813 return TVI_CONTROL_TRUE;
814 case TVI_CONTROL_VID_GET_BRIGHTNESS:
815 control.id = V4L2_CID_BRIGHTNESS;
816 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
817 *(int *)arg = control.value;
818 return TVI_CONTROL_TRUE;
820 return TVI_CONTROL_FALSE;
821 case TVI_CONTROL_VID_SET_BRIGHTNESS:
822 control.id = V4L2_CID_BRIGHTNESS;
823 control.value = *(int *)arg;
824 return set_control(priv, &control, 1);
825 case TVI_CONTROL_VID_GET_HUE:
826 control.id = V4L2_CID_HUE;
827 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
828 *(int *)arg = control.value;
829 return TVI_CONTROL_TRUE;
831 return TVI_CONTROL_FALSE;
832 case TVI_CONTROL_VID_SET_HUE:
833 control.id = V4L2_CID_HUE;
834 control.value = *(int *)arg;
835 return set_control(priv, &control, 1);
836 case TVI_CONTROL_VID_GET_SATURATION:
837 control.id = V4L2_CID_SATURATION;
838 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
839 *(int *)arg = control.value;
840 return TVI_CONTROL_TRUE;
842 return TVI_CONTROL_FALSE;
843 case TVI_CONTROL_VID_SET_SATURATION:
844 control.id = V4L2_CID_SATURATION;
845 control.value = *(int *)arg;
846 return set_control(priv, &control, 1);
847 case TVI_CONTROL_VID_GET_GAIN:
850 control.id = V4L2_CID_AUTOGAIN;
851 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
852 return TVI_CONTROL_FALSE;
854 if(control.value){ //Auto Gain control is enabled
855 *(int*)arg=0;
856 return TVI_CONTROL_TRUE;
859 //Manual Gain control
860 control.id = V4L2_CID_GAIN;
861 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
862 return TVI_CONTROL_FALSE;
864 *(int*)arg=control.value?control.value:1;
866 return TVI_CONTROL_TRUE;
868 case TVI_CONTROL_VID_SET_GAIN:
870 //value==0 means automatic gain control
871 int value=*(int*)arg;
873 if (value < 0 || value>100)
874 return TVI_CONTROL_FALSE;
876 control.id=value?V4L2_CID_GAIN:V4L2_CID_AUTOGAIN;
877 control.value=value?value:1;
879 return set_control(priv,&control,0);
881 case TVI_CONTROL_VID_GET_CONTRAST:
882 control.id = V4L2_CID_CONTRAST;
883 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
884 *(int *)arg = control.value;
885 return TVI_CONTROL_TRUE;
887 return TVI_CONTROL_FALSE;
888 case TVI_CONTROL_VID_SET_CONTRAST:
889 control.id = V4L2_CID_CONTRAST;
890 control.value = *(int *)arg;
891 return set_control(priv, &control, 1);
892 case TVI_CONTROL_TUN_GET_FREQ:
893 frequency.tuner = 0;
894 frequency.type = V4L2_TUNER_ANALOG_TV;
895 if (ioctl(priv->video_fd, VIDIOC_G_FREQUENCY, &frequency) < 0) {
896 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl get frequency failed: %s\n",
897 info.short_name, strerror(errno));
898 return TVI_CONTROL_FALSE;
900 *(int *)arg = frequency.frequency;
901 return TVI_CONTROL_TRUE;
902 case TVI_CONTROL_TUN_SET_FREQ:
903 #if 0
904 set_mute(priv, 1);
905 usleep(100000); // wait to suppress noise during switching
906 #endif
907 frequency.tuner = 0;
908 frequency.type = V4L2_TUNER_ANALOG_TV;
909 frequency.frequency = *(int *)arg;
910 if (ioctl(priv->video_fd, VIDIOC_S_FREQUENCY, &frequency) < 0) {
911 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set frequency failed: %s\n",
912 info.short_name, strerror(errno));
913 return TVI_CONTROL_FALSE;
915 #if 0
916 usleep(100000); // wait to suppress noise during switching
917 set_mute(priv, 0);
918 #endif
919 return TVI_CONTROL_TRUE;
920 case TVI_CONTROL_TUN_GET_TUNER:
921 mp_msg(MSGT_TV, MSGL_V, "%s: get tuner\n",info.short_name);
922 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
923 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
924 info.short_name, strerror(errno));
925 return TVI_CONTROL_FALSE;
927 return TVI_CONTROL_TRUE;
928 case TVI_CONTROL_TUN_SET_TUNER:
929 mp_msg(MSGT_TV, MSGL_V, "%s: set tuner\n",info.short_name);
930 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
931 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set 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_GET_NORM:
937 *(int *)arg = priv->standard.index;
938 return TVI_CONTROL_TRUE;
939 case TVI_CONTROL_TUN_GET_SIGNAL:
940 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
941 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
942 info.short_name, strerror(errno));
943 return TVI_CONTROL_FALSE;
945 *(int*)arg=100*(priv->tuner.signal>>8)/255;
946 return TVI_CONTROL_TRUE;
947 case TVI_CONTROL_TUN_SET_NORM:
948 priv->standard.index = *(int *)arg;
949 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
950 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum norm failed: %s\n",
951 info.short_name, strerror(errno));
952 return TVI_CONTROL_FALSE;
954 mp_msg(MSGT_TV, MSGL_V, "%s: set norm: %s\n", info.short_name, priv->standard.name);
955 if (ioctl(priv->video_fd, VIDIOC_S_STD, &priv->standard.id) < 0) {
956 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set norm failed: %s\n",
957 info.short_name, strerror(errno));
958 return TVI_CONTROL_FALSE;
960 return TVI_CONTROL_TRUE;
961 case TVI_CONTROL_SPC_GET_NORMID:
963 int i;
964 for (i = 0;; i++) {
965 struct v4l2_standard standard;
966 memset(&standard, 0, sizeof(standard));
967 standard.index = i;
968 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
969 return TVI_CONTROL_FALSE;
970 if (!strcasecmp(standard.name, (char *)arg)) {
971 *(int *)arg = i;
972 return TVI_CONTROL_TRUE;
975 return TVI_CONTROL_FALSE;
977 case TVI_CONTROL_SPC_GET_INPUT:
978 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, (int *)arg) < 0) {
979 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
980 info.short_name, strerror(errno));
981 return TVI_CONTROL_FALSE;
983 return TVI_CONTROL_TRUE;
984 case TVI_CONTROL_SPC_SET_INPUT:
985 mp_msg(MSGT_TV, MSGL_V, "%s: set input: %d\n", info.short_name, *(int *)arg);
986 priv->input.index = *(int *)arg;
987 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &priv->input) < 0) {
988 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum input failed: %s\n",
989 info.short_name, strerror(errno));
990 return TVI_CONTROL_FALSE;
992 if (ioctl(priv->video_fd, VIDIOC_S_INPUT, (int *)arg) < 0) {
993 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set input failed: %s\n",
994 info.short_name, strerror(errno));
995 return TVI_CONTROL_FALSE;
997 return TVI_CONTROL_TRUE;
998 case TVI_CONTROL_AUD_GET_FORMAT:
999 init_audio(priv);
1000 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1001 *(int *)arg = AF_FORMAT_S16_LE;
1002 mp_msg(MSGT_TV, MSGL_V, "%s: get audio format: %d\n",
1003 info.short_name, *(int *)arg);
1004 return TVI_CONTROL_TRUE;
1005 case TVI_CONTROL_AUD_GET_SAMPLERATE:
1006 init_audio(priv);
1007 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1008 *(int *)arg = priv->audio_in.samplerate;
1009 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplerate: %d\n",
1010 info.short_name, *(int *)arg);
1011 return TVI_CONTROL_TRUE;
1012 case TVI_CONTROL_AUD_GET_SAMPLESIZE:
1013 init_audio(priv);
1014 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1015 *(int *)arg = priv->audio_in.bytes_per_sample;
1016 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplesize: %d\n",
1017 info.short_name, *(int *)arg);
1018 return TVI_CONTROL_TRUE;
1019 case TVI_CONTROL_AUD_GET_CHANNELS:
1020 init_audio(priv);
1021 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1022 *(int *)arg = priv->audio_in.channels;
1023 mp_msg(MSGT_TV, MSGL_V, "%s: get audio channels: %d\n",
1024 info.short_name, *(int *)arg);
1025 return TVI_CONTROL_TRUE;
1026 case TVI_CONTROL_AUD_SET_SAMPLERATE:
1027 init_audio(priv);
1028 mp_msg(MSGT_TV, MSGL_V, "%s: set audio samplerate: %d\n",
1029 info.short_name, *(int *)arg);
1030 if (audio_in_set_samplerate(&priv->audio_in, *(int*)arg) < 0) return TVI_CONTROL_FALSE;
1031 // setup_audio_buffer_sizes(priv);
1032 return TVI_CONTROL_TRUE;
1033 #ifdef CONFIG_TV_TELETEXT
1034 case TVI_CONTROL_VBI_INIT:
1036 void* ptr;
1037 tt_stream_props tsp;
1039 if (vbi_init(priv,*(char**)arg)!=TVI_CONTROL_TRUE)
1040 return TVI_CONTROL_FALSE;
1041 if(vbi_get_props(priv,&tsp)==TVI_CONTROL_TRUE)
1043 ptr=&tsp;
1044 if(teletext_control(NULL,TV_VBI_CONTROL_START,&ptr)==TVI_CONTROL_TRUE)
1045 priv->priv_vbi=ptr;
1046 else
1047 priv->priv_vbi=NULL;
1049 return TVI_CONTROL_TRUE;
1051 default:
1052 return teletext_control(priv->priv_vbi,cmd,arg);
1053 #endif
1055 mp_msg(MSGT_TV, MSGL_V, "%s: unknown control: %d\n", info.short_name, cmd);
1056 return TVI_CONTROL_UNKNOWN;
1060 #define PRIV ((priv_t *) (tvi_handle->priv))
1062 /* handler creator - entry point ! */
1063 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param)
1065 tvi_handle_t *tvi_handle;
1067 /* new_handle initializes priv with memset 0 */
1068 tvi_handle = new_handle();
1069 if (!tvi_handle) {
1070 return NULL;
1072 PRIV->video_fd = -1;
1074 PRIV->video_dev = strdup(tv_param->device? tv_param->device: "/dev/video0");
1075 if (!PRIV->video_dev) {
1076 free_handle(tvi_handle);
1077 return NULL;
1080 if (tv_param->adevice) {
1081 PRIV->audio_dev = strdup(tv_param->adevice);
1082 if (!PRIV->audio_dev) {
1083 free(PRIV->video_dev);
1084 free_handle(tvi_handle);
1085 return NULL;
1089 PRIV->tv_param=tv_param;
1090 return tvi_handle;
1093 #undef PRIV
1096 static int uninit(priv_t *priv)
1098 int i, frames, dropped = 0;
1100 #ifdef CONFIG_TV_TELETEXT
1101 priv->vbi_shutdown=1;
1102 if(priv->vbi_grabber_thread)
1103 pthread_join(priv->vbi_grabber_thread, NULL);
1105 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_STOP,(void*)1);
1106 priv->priv_vbi=NULL;
1108 if(priv->vbi_fd){
1109 close(priv->vbi_fd);
1110 priv->vbi_fd=0;
1113 if(priv->vbi_dev){
1114 free(priv->vbi_dev);
1115 priv->vbi_dev=0;
1118 #endif
1120 priv->shutdown = 1;
1121 if(priv->video_grabber_thread)
1122 pthread_join(priv->video_grabber_thread, NULL);
1123 pthread_mutex_destroy(&priv->video_buffer_mutex);
1125 if (priv->streamon) {
1126 struct v4l2_buffer buf;
1128 /* get performance */
1129 frames = 1 + lrintf((double)(priv->curr_frame - priv->first_frame) / (1e6 * getfps(priv)));
1130 dropped = frames - priv->frames;
1132 /* turn off streaming */
1133 if (ioctl(priv->video_fd, VIDIOC_STREAMOFF, &(priv->map[0].buf.type)) < 0) {
1134 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamoff failed: %s\n",
1135 info.short_name, strerror(errno));
1137 priv->streamon = 0;
1139 /* unqueue all remaining buffers */
1140 memset(&buf,0,sizeof(buf));
1141 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1142 buf.memory = V4L2_MEMORY_MMAP;
1143 while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
1146 /* unmap all buffers */
1147 for (i = 0; i < priv->mapcount; i++) {
1148 if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {
1149 mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",
1150 info.short_name, strerror(errno));
1154 /* stop audio thread */
1155 if (!priv->tv_param->noaudio && priv->audio_grabber_thread) {
1156 pthread_join(priv->audio_grabber_thread, NULL);
1157 pthread_mutex_destroy(&priv->skew_mutex);
1158 pthread_mutex_destroy(&priv->audio_mutex);
1161 set_mute(priv, 1);
1163 /* free memory and close device */
1164 free(priv->map); priv->map = NULL;
1165 priv->mapcount = 0;
1166 if(priv->video_fd!=-1)close(priv->video_fd); priv->video_fd = -1;
1167 free(priv->video_dev); priv->video_dev = NULL;
1169 if (priv->video_ringbuffer) {
1170 int i;
1171 for (i = 0; i < priv->video_buffer_size_current; i++) {
1172 free(priv->video_ringbuffer[i].data);
1174 free(priv->video_ringbuffer);
1176 if (!priv->tv_param->noaudio) {
1177 if (priv->audio_ringbuffer)
1178 free(priv->audio_ringbuffer);
1179 if (priv->audio_skew_buffer)
1180 free(priv->audio_skew_buffer);
1181 if (priv->audio_skew_delta_buffer)
1182 free(priv->audio_skew_delta_buffer);
1184 audio_in_uninit(&priv->audio_in);
1187 /* show some nice statistics ;-) */
1188 mp_msg(MSGT_TV, MSGL_INFO,
1189 "%s: %d frames successfully processed, %d frames dropped.\n",
1190 info.short_name, priv->frames, dropped);
1191 mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",
1192 info.short_name, priv->video_buffer_size_current);
1193 return 1;
1197 /* initialisation */
1198 static int init(priv_t *priv)
1200 int i;
1202 priv->audio_ringbuffer = NULL;
1203 priv->audio_skew_buffer = NULL;
1204 priv->audio_skew_delta_buffer = NULL;
1206 priv->audio_initialized = 0;
1208 /* Open the video device. */
1209 priv->video_fd = open(priv->video_dev, O_RDWR);
1210 if (priv->video_fd < 0) {
1211 mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",
1212 info.short_name, priv->video_dev, strerror(errno));
1213 uninit(priv);
1214 return 0;
1216 mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",
1217 info.short_name, priv->video_dev, priv->video_fd);
1220 ** Query the video capabilities and current settings
1221 ** for further control calls.
1223 if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
1224 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",
1225 info.short_name, strerror(errno));
1226 uninit(priv);
1227 return 0;
1230 if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))
1232 mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",
1233 priv->video_dev);
1234 return 0;
1237 if (getfmt(priv) < 0) {
1238 uninit(priv);
1239 return 0;
1241 getstd(priv);
1243 ** if this device has got a tuner query it's settings
1244 ** otherwise set some nice defaults
1246 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1247 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
1248 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
1249 info.short_name, strerror(errno));
1250 uninit(priv);
1251 return 0;
1254 mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);
1255 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1256 mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",
1257 (priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",
1258 (priv->tuner.capability & V4L2_TUNER_CAP_LANG1) ? " LANG1" : "",
1259 (priv->tuner.capability & V4L2_TUNER_CAP_LANG2) ? " LANG2" : "");
1260 mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",
1261 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO) ? " MONO" : "",
1262 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",
1263 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1) ? " LANG1" : "",
1264 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2) ? " LANG2" : "");
1266 mp_msg(MSGT_TV, MSGL_INFO, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1267 priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
1268 " video capture": "",
1269 priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?
1270 " video output": "",
1271 priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?
1272 " video overlay": "",
1273 priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?
1274 " VBI capture device": "",
1275 priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?
1276 " VBI output": "",
1277 priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?
1278 " RDS data capture": "",
1279 priv->capability.capabilities & V4L2_CAP_TUNER?
1280 " tuner": "",
1281 priv->capability.capabilities & V4L2_CAP_AUDIO?
1282 " audio": "",
1283 priv->capability.capabilities & V4L2_CAP_READWRITE?
1284 " read/write": "",
1285 priv->capability.capabilities & V4L2_CAP_ASYNCIO?
1286 " async i/o": "",
1287 priv->capability.capabilities & V4L2_CAP_STREAMING?
1288 " streaming": "");
1289 mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");
1290 for (i = 0;; i++) {
1291 struct v4l2_standard standard;
1292 memset(&standard, 0, sizeof(standard));
1293 standard.index = i;
1294 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
1295 break;
1296 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);
1298 mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");
1299 for (i = 0; 1; i++) {
1300 struct v4l2_input input;
1302 input.index = i;
1303 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
1304 break;
1306 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);
1308 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
1309 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
1310 info.short_name, strerror(errno));
1312 mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);
1313 for (i = 0; ; i++) {
1314 struct v4l2_fmtdesc fmtdesc;
1316 fmtdesc.index = i;
1317 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1318 if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
1319 break;
1321 mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",
1322 pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),
1323 fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));
1325 mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",
1326 pixfmt2name(priv->format.fmt.pix.pixelformat));
1328 /* set some nice defaults */
1329 if (getfmt(priv) < 0) return 0;
1330 priv->format.fmt.pix.width = 640;
1331 priv->format.fmt.pix.height = 480;
1332 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
1333 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
1334 info.short_name, strerror(errno));
1335 uninit(priv);
1336 return 0;
1339 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;
1341 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1342 struct v4l2_control control;
1343 if (priv->tv_param->amode >= 0) {
1344 mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);
1345 priv->tuner.audmode = amode2v4l(priv->tv_param->amode);
1346 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
1347 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
1348 info.short_name, strerror(errno));
1349 return TVI_CONTROL_FALSE;
1352 mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,
1353 (priv->tuner.audmode == V4L2_TUNER_MODE_MONO) ? " MONO" : "",
1354 (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",
1355 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG1) ? " LANG1" : "",
1356 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG2) ? " LANG2" : "");
1358 if (priv->tv_param->volume >= 0) {
1359 control.id = V4L2_CID_AUDIO_VOLUME;
1360 control.value = priv->tv_param->volume;
1361 set_control(priv, &control, 0);
1363 if (priv->tv_param->bass >= 0) {
1364 control.id = V4L2_CID_AUDIO_BASS;
1365 control.value = priv->tv_param->bass;
1366 set_control(priv, &control, 0);
1368 if (priv->tv_param->treble >= 0) {
1369 control.id = V4L2_CID_AUDIO_TREBLE;
1370 control.value = priv->tv_param->treble;
1371 set_control(priv, &control, 0);
1373 if (priv->tv_param->balance >= 0) {
1374 control.id = V4L2_CID_AUDIO_BALANCE;
1375 control.value = priv->tv_param->balance;
1376 set_control(priv, &control, 0);
1380 return 1;
1383 static int get_capture_buffer_size(priv_t *priv)
1385 int bufsize, cnt;
1387 if (priv->tv_param->buffer_size >= 0) {
1388 bufsize = priv->tv_param->buffer_size*1024*1024;
1389 } else {
1390 #ifdef HAVE_SYS_SYSINFO_H
1391 struct sysinfo si;
1393 sysinfo(&si);
1394 if (si.totalram<2*1024*1024) {
1395 bufsize = 1024*1024;
1396 } else {
1397 bufsize = si.totalram/2;
1399 #else
1400 bufsize = 16*1024*1024;
1401 #endif
1404 cnt = bufsize/priv->format.fmt.pix.sizeimage;
1405 if (cnt < 2) cnt = 2;
1407 return cnt;
1410 /* that's the real start, we'got the format parameters (checked with control) */
1411 static int start(priv_t *priv)
1413 struct v4l2_requestbuffers request;
1414 unsigned int i;
1416 /* setup audio parameters */
1418 init_audio(priv);
1419 if (!priv->tv_param->noaudio && !priv->audio_initialized) return 0;
1421 /* we need this to size the audio buffer properly */
1422 if (priv->immediate_mode) {
1423 priv->video_buffer_size_max = 2;
1424 } else {
1425 priv->video_buffer_size_max = get_capture_buffer_size(priv);
1428 if (!priv->tv_param->noaudio) {
1429 setup_audio_buffer_sizes(priv);
1430 priv->audio_skew_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1431 if (!priv->audio_skew_buffer) {
1432 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1433 return 0;
1435 priv->audio_skew_delta_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1436 if (!priv->audio_skew_delta_buffer) {
1437 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1438 return 0;
1441 priv->audio_ringbuffer = calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
1442 if (!priv->audio_ringbuffer) {
1443 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
1444 return 0;
1447 priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate
1448 *priv->audio_in.channels
1449 *priv->audio_in.bytes_per_sample);
1450 priv->audio_usecs_per_block = 1e6*priv->audio_secs_per_block;
1451 priv->audio_head = 0;
1452 priv->audio_tail = 0;
1453 priv->audio_cnt = 0;
1454 priv->audio_drop = 0;
1455 priv->audio_skew = 0;
1456 priv->audio_skew_total = 0;
1457 priv->audio_skew_delta_total = 0;
1458 priv->audio_recv_blocks_total = 0;
1459 priv->audio_sent_blocks_total = 0;
1460 priv->audio_null_blocks_inserted = 0;
1461 priv->audio_insert_null_samples = 0;
1462 priv->dropped_frames_timeshift = 0;
1463 priv->dropped_frames_compensated = 0;
1465 pthread_mutex_init(&priv->skew_mutex, NULL);
1466 pthread_mutex_init(&priv->audio_mutex, NULL);
1469 /* setup video parameters */
1470 if (!priv->tv_param->noaudio) {
1471 if (priv->video_buffer_size_max < (3*priv->standard.frameperiod.denominator) /
1472 priv->standard.frameperiod.numerator
1473 *priv->audio_secs_per_block) {
1474 mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"
1475 "You will probably experience heavy framedrops.\n");
1480 int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1482 mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1483 priv->video_buffer_size_max,
1484 priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));
1487 priv->video_ringbuffer = calloc(priv->video_buffer_size_max, sizeof(video_buffer_entry));
1488 if (!priv->video_ringbuffer) {
1489 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
1490 return 0;
1492 memset(priv->video_ringbuffer,0,priv->video_buffer_size_max * sizeof(video_buffer_entry));
1494 pthread_mutex_init(&priv->video_buffer_mutex, NULL);
1496 priv->video_head = 0;
1497 priv->video_tail = 0;
1498 priv->video_cnt = 0;
1500 /* request buffers */
1501 if (priv->immediate_mode) {
1502 request.count = 2;
1503 } else {
1504 request.count = BUFFER_COUNT;
1507 request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1508 request.memory = V4L2_MEMORY_MMAP;
1509 if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
1510 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",
1511 info.short_name, strerror(errno));
1512 return 0;
1515 /* query buffers */
1516 if (!(priv->map = calloc(request.count, sizeof(struct map)))) {
1517 mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",
1518 info.short_name, strerror(errno));
1519 return 0;
1522 /* map and queue buffers */
1523 for (i = 0; i < request.count; i++) {
1524 memset(&priv->map[i].buf,0,sizeof(priv->map[i].buf));
1525 priv->map[i].buf.index = i;
1526 priv->map[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1527 priv->map[i].buf.memory = V4L2_MEMORY_MMAP;
1528 if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
1529 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",
1530 info.short_name, strerror(errno));
1531 free(priv->map);
1532 priv->map = NULL;
1533 return 0;
1535 priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |
1536 PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);
1537 if (priv->map[i].addr == MAP_FAILED) {
1538 mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",
1539 info.short_name, strerror(errno));
1540 priv->map[i].len = 0;
1541 return 0;
1543 priv->map[i].len = priv->map[i].buf.length;
1544 /* count up to make sure this is correct everytime */
1545 priv->mapcount++;
1547 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1548 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1549 info.short_name, strerror(errno));
1550 return 0;
1554 #ifdef CONFIG_TV_TELETEXT
1555 /* start vbi thread */
1556 if(priv->priv_vbi){
1557 priv->vbi_shutdown = 0;
1558 pthread_create(&priv->vbi_grabber_thread, NULL, vbi_grabber, priv);
1560 #endif
1561 /* start audio thread */
1562 priv->shutdown = 0;
1563 priv->audio_skew_measure_time = 0;
1564 priv->first_frame = 0;
1565 priv->audio_skew = 0;
1566 priv->first = 1;
1568 set_mute(priv, 0);
1570 return 1;
1573 // copies a video frame
1574 static inline void copy_frame(priv_t *priv, video_buffer_entry *dest, unsigned char *source,int len)
1576 dest->framesize=len;
1577 if(priv->tv_param->automute>0){
1578 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) >= 0) {
1579 if(priv->tv_param->automute<<8>priv->tuner.signal){
1580 fill_blank_frame(dest->data,dest->framesize,fcc_vl2mp(priv->format.fmt.pix.pixelformat));
1581 set_mute(priv,1);
1582 return;
1585 set_mute(priv,0);
1587 memcpy(dest->data, source, len);
1590 // maximum skew change, in frames
1591 #define MAX_SKEW_DELTA 0.6
1592 static void *video_grabber(void *data)
1594 priv_t *priv = (priv_t*)data;
1595 long long skew, prev_skew, xskew, interval, prev_interval, delta;
1596 int i;
1597 int framesize = priv->format.fmt.pix.sizeimage;
1598 fd_set rdset;
1599 struct timeval timeout;
1600 struct v4l2_buffer buf;
1602 xskew = 0;
1603 skew = 0;
1604 interval = 0;
1605 prev_interval = 0;
1606 prev_skew = 0;
1608 mp_msg(MSGT_TV, MSGL_V, "%s: going to capture\n", info.short_name);
1609 if (ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
1610 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamon failed: %s\n",
1611 info.short_name, strerror(errno));
1612 return 0;
1614 priv->streamon = 1;
1616 if (!priv->tv_param->noaudio) {
1617 pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
1620 for (priv->frames = 0; !priv->shutdown;)
1622 int ret;
1624 if (priv->immediate_mode) {
1625 while (priv->video_cnt == priv->video_buffer_size_max) {
1626 usleep(10000);
1627 if (priv->shutdown) {
1628 return NULL;
1633 FD_ZERO (&rdset);
1634 FD_SET (priv->video_fd, &rdset);
1636 timeout.tv_sec = 1;
1637 timeout.tv_usec = 0;
1639 i = select(priv->video_fd + 1, &rdset, NULL, NULL, &timeout);
1640 if (i < 0) {
1641 mp_msg(MSGT_TV, MSGL_ERR, "%s: select failed: %s\n",
1642 info.short_name, strerror(errno));
1643 continue;
1645 else if (i == 0) {
1646 mp_msg(MSGT_TV, MSGL_ERR, "%s: select timeout\n", info.short_name);
1647 continue;
1649 else if (!FD_ISSET(priv->video_fd, &rdset)) {
1650 continue;
1653 memset(&buf,0,sizeof(buf));
1654 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1655 buf.memory = V4L2_MEMORY_MMAP;
1656 ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
1658 if (ret < 0) {
1660 if there's no signal, the buffer might me dequeued
1661 so we query all the buffers to see which one we should
1662 put back to queue
1664 observed with saa7134 0.2.8
1665 don't know if is it a bug or (mis)feature
1667 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1668 info.short_name, strerror(errno), buf.index);
1669 for (i = 0; i < priv->mapcount; i++) {
1670 memset(&buf,0,sizeof(buf));
1671 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1672 buf.memory = V4L2_MEMORY_MMAP;
1673 buf.index = i;
1674 ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
1675 if (ret < 0) {
1676 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s, idx = %d\n",
1677 info.short_name, strerror(errno), buf.index);
1678 return 0;
1680 if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
1681 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1682 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1683 info.short_name, strerror(errno));
1684 return 0;
1688 continue;
1691 /* store the timestamp of the very first frame as reference */
1692 if (!priv->frames++) {
1693 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1694 priv->first_frame = (long long)1e6*buf.timestamp.tv_sec + buf.timestamp.tv_usec;
1695 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1697 priv->curr_frame = (long long)buf.timestamp.tv_sec*1e6+buf.timestamp.tv_usec;
1698 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1700 interval = priv->curr_frame - priv->first_frame;
1701 delta = interval - prev_interval;
1703 if (!priv->immediate_mode) {
1704 // interpolate the skew in time
1705 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1706 xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
1707 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1708 // correct extreme skew changes to avoid (especially) moving backwards in time
1709 if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
1710 skew = prev_skew + delta*MAX_SKEW_DELTA;
1711 } else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) {
1712 skew = prev_skew - delta*MAX_SKEW_DELTA;
1713 } else {
1714 skew = xskew;
1718 mp_msg(MSGT_TV, MSGL_DBG3, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1719 delta ? (double)1e6/delta : -1,
1720 (double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
1721 mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
1723 prev_skew = skew;
1724 prev_interval = interval;
1726 /* allocate a new buffer, if needed */
1727 pthread_mutex_lock(&priv->video_buffer_mutex);
1728 if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
1729 if (priv->video_cnt == priv->video_buffer_size_current) {
1730 unsigned char *newbuf = malloc(framesize);
1731 if (newbuf) {
1732 memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
1733 (priv->video_buffer_size_current-priv->video_tail)*sizeof(video_buffer_entry));
1734 priv->video_ringbuffer[priv->video_tail].data = newbuf;
1735 if ((priv->video_head >= priv->video_tail) && (priv->video_cnt > 0)) priv->video_head++;
1736 priv->video_buffer_size_current++;
1740 pthread_mutex_unlock(&priv->video_buffer_mutex);
1742 if (priv->video_cnt == priv->video_buffer_size_current) {
1743 if (!priv->immediate_mode) {
1744 mp_msg(MSGT_TV, MSGL_ERR, "\nvideo buffer full - dropping frame\n");
1745 if (priv->audio_insert_null_samples) {
1746 pthread_mutex_lock(&priv->audio_mutex);
1747 priv->dropped_frames_timeshift += delta;
1748 pthread_mutex_unlock(&priv->audio_mutex);
1751 } else {
1752 if (priv->immediate_mode) {
1753 priv->video_ringbuffer[priv->video_tail].timestamp = 0;
1754 } else {
1755 // compensate for audio skew
1756 // negative skew => there are more audio samples, increase interval
1757 // positive skew => less samples, shorten the interval
1758 priv->video_ringbuffer[priv->video_tail].timestamp = interval - skew;
1759 if (priv->audio_insert_null_samples && priv->video_ringbuffer[priv->video_tail].timestamp > 0) {
1760 pthread_mutex_lock(&priv->audio_mutex);
1761 priv->video_ringbuffer[priv->video_tail].timestamp +=
1762 (priv->audio_null_blocks_inserted
1763 - priv->dropped_frames_timeshift/priv->audio_usecs_per_block)
1764 *priv->audio_usecs_per_block;
1765 pthread_mutex_unlock(&priv->audio_mutex);
1768 copy_frame(priv, priv->video_ringbuffer+priv->video_tail, priv->map[buf.index].addr,buf.bytesused);
1769 priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
1770 priv->video_cnt++;
1772 if (ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
1773 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1774 info.short_name, strerror(errno));
1775 return 0;
1778 return NULL;
1781 #define MAX_LOOP 50
1782 static double grab_video_frame(priv_t *priv, char *buffer, int len)
1784 double interval;
1785 int loop_cnt = 0;
1787 if (priv->first) {
1788 pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1789 priv->first = 0;
1792 while (priv->video_cnt == 0) {
1793 usleep(10000);
1794 if (loop_cnt++ > MAX_LOOP) return 0;
1797 pthread_mutex_lock(&priv->video_buffer_mutex);
1798 interval = (double)priv->video_ringbuffer[priv->video_head].timestamp*1e-6;
1799 memcpy(buffer, priv->video_ringbuffer[priv->video_head].data, len);
1800 priv->video_cnt--;
1801 priv->video_head = (priv->video_head+1)%priv->video_buffer_size_current;
1802 pthread_mutex_unlock(&priv->video_buffer_mutex);
1804 return interval;
1807 static int get_video_framesize(priv_t *priv)
1810 this routine will be called before grab_video_frame
1811 thus let's return topmost frame's size
1813 if (priv->video_cnt)
1814 return priv->video_ringbuffer[priv->video_head].framesize;
1816 no video frames yet available. i don't know what to do in this case,
1817 thus let's return some fallback result (for compressed format this will be
1818 maximum allowed frame size.
1820 return priv->format.fmt.pix.sizeimage;
1823 //#define DOUBLESPEED
1824 #ifdef DOUBLESPEED
1825 // for testing purposes only
1826 static void read_doublespeed(priv_t *priv)
1828 char *bufx = calloc(priv->audio_in.blocksize, 2);
1829 short *s;
1830 short *d;
1831 int i;
1833 audio_in_read_chunk(&priv->audio_in, bufx);
1834 audio_in_read_chunk(&priv->audio_in, bufx+priv->audio_in.blocksize);
1836 s = bufx;
1837 d = priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize;
1838 for (i = 0; i < priv->audio_in.blocksize/2; i++) {
1839 *d++ = *s++;
1840 *s++;
1844 #endif
1846 static void *audio_grabber(void *data)
1848 priv_t *priv = (priv_t*)data;
1849 struct timeval tv;
1850 int i, audio_skew_ptr = 0;
1851 long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
1852 long long start_time_avg;
1854 gettimeofday(&tv, NULL);
1855 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1856 audio_in_start_capture(&priv->audio_in);
1857 for (i = 0; i < priv->aud_skew_cnt; i++)
1858 priv->audio_skew_buffer[i] = 0;
1859 for (i = 0; i < priv->aud_skew_cnt; i++)
1860 priv->audio_skew_delta_buffer[i] = 0;
1862 for (; !priv->shutdown;)
1864 #ifdef DOUBLESPEED
1865 read_doublespeed(priv);
1866 #else
1867 if (audio_in_read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize) < 0)
1868 continue;
1869 #endif
1870 pthread_mutex_lock(&priv->skew_mutex);
1871 if (priv->first_frame == 0) {
1872 // there is no first frame yet (unlikely to happen)
1873 gettimeofday(&tv, NULL);
1874 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1875 // fprintf(stderr, "warning - first frame not yet available!\n");
1876 pthread_mutex_unlock(&priv->skew_mutex);
1877 continue;
1879 pthread_mutex_unlock(&priv->skew_mutex);
1881 gettimeofday(&tv, NULL);
1883 priv->audio_recv_blocks_total++;
1884 current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
1886 if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
1887 start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1888 priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
1891 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1892 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1894 // put the current skew into the ring buffer
1895 priv->audio_skew_total -= priv->audio_skew_buffer[audio_skew_ptr];
1896 priv->audio_skew_buffer[audio_skew_ptr] = current_time
1897 - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1898 priv->audio_skew_total += priv->audio_skew_buffer[audio_skew_ptr];
1900 pthread_mutex_lock(&priv->skew_mutex);
1902 // skew calculation
1904 // compute the sliding average of the skews
1905 if (priv->audio_recv_blocks_total > priv->aud_skew_cnt) {
1906 priv->audio_skew = priv->audio_skew_total/priv->aud_skew_cnt;
1907 } else {
1908 priv->audio_skew = priv->audio_skew_total/priv->audio_recv_blocks_total;
1911 // put the current skew change (skew-prev_skew) into the ring buffer
1912 priv->audio_skew_delta_total -= priv->audio_skew_delta_buffer[audio_skew_ptr];
1913 priv->audio_skew_delta_buffer[audio_skew_ptr] = priv->audio_skew - prev_skew_uncorr;
1914 priv->audio_skew_delta_total += priv->audio_skew_delta_buffer[audio_skew_ptr];
1915 prev_skew_uncorr = priv->audio_skew; // remember the _uncorrected_ average value
1917 audio_skew_ptr = (audio_skew_ptr+1) % priv->aud_skew_cnt; // rotate the buffer pointer
1919 // sliding average approximates the value in the middle of the interval
1920 // so interpolate the skew value further to the current time
1921 priv->audio_skew += priv->audio_skew_delta_total/2;
1923 // now finally, priv->audio_skew contains fairly good approximation
1924 // of the current value
1926 // current skew factor (assuming linearity)
1927 // used for further interpolation in video_grabber
1928 // probably overkill but seems to be necessary for
1929 // stress testing by dropping half of the audio frames ;)
1930 // especially when using ALSA with large block sizes
1931 // where audio_skew remains a long while behind
1932 if ((priv->audio_skew_measure_time != 0) && (current_time - priv->audio_skew_measure_time != 0)) {
1933 priv->audio_skew_factor = (double)(priv->audio_skew-prev_skew)/(current_time - priv->audio_skew_measure_time);
1934 } else {
1935 priv->audio_skew_factor = 0.0;
1938 priv->audio_skew_measure_time = current_time;
1939 prev_skew = priv->audio_skew;
1940 priv->audio_skew += priv->audio_start_time - priv->first_frame;
1941 pthread_mutex_unlock(&priv->skew_mutex);
1943 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1945 pthread_mutex_lock(&priv->audio_mutex);
1946 if ((priv->audio_tail+1) % priv->audio_buffer_size == priv->audio_head) {
1947 mp_msg(MSGT_TV, MSGL_ERR, "\ntoo bad - dropping audio frame !\n");
1948 priv->audio_drop++;
1949 } else {
1950 priv->audio_tail = (priv->audio_tail+1) % priv->audio_buffer_size;
1951 priv->audio_cnt++;
1953 pthread_mutex_unlock(&priv->audio_mutex);
1955 return NULL;
1958 static double grab_audio_frame(priv_t *priv, char *buffer, int len)
1960 mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1961 priv, buffer, len);
1963 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1964 // => switch to the mode which outputs audio immediately, even if
1965 // it should be silence
1966 if (priv->first) priv->audio_insert_null_samples = 1;
1968 pthread_mutex_lock(&priv->audio_mutex);
1969 while (priv->audio_insert_null_samples
1970 && priv->dropped_frames_timeshift - priv->dropped_frames_compensated >= priv->audio_usecs_per_block) {
1971 // some frames were dropped - drop the corresponding number of audio blocks
1972 if (priv->audio_drop) {
1973 priv->audio_drop--;
1974 } else {
1975 if (priv->audio_head == priv->audio_tail) break;
1976 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1978 priv->dropped_frames_compensated += priv->audio_usecs_per_block;
1981 // compensate for dropped audio frames
1982 if (priv->audio_drop && (priv->audio_head == priv->audio_tail)) {
1983 priv->audio_drop--;
1984 memset(buffer, 0, len);
1985 goto out;
1988 if (priv->audio_insert_null_samples && (priv->audio_head == priv->audio_tail)) {
1989 // return silence to avoid desync and stuttering
1990 memset(buffer, 0, len);
1991 priv->audio_null_blocks_inserted++;
1992 goto out;
1995 pthread_mutex_unlock(&priv->audio_mutex);
1996 while (priv->audio_head == priv->audio_tail) {
1997 // this is mencoder => just wait until some audio is available
1998 usleep(10000);
2000 pthread_mutex_lock(&priv->audio_mutex);
2001 memcpy(buffer, priv->audio_ringbuffer+priv->audio_head*priv->audio_in.blocksize, len);
2002 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
2003 priv->audio_cnt--;
2004 out:
2005 pthread_mutex_unlock(&priv->audio_mutex);
2006 priv->audio_sent_blocks_total++;
2007 return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
2010 static int get_audio_framesize(priv_t *priv)
2012 return priv->audio_in.blocksize;