gl_common: minor cleanup/refactor
[mplayer.git] / stream / tvi_v4l2.c
bloba3be9e799a7d5696887ba97a1a0f4ac7f6ad69d5
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 #ifdef HAVE_SYS_VIDEOIO_H
53 #include <sys/videoio.h>
54 #else
55 #include <linux/types.h>
56 #include <linux/videodev2.h>
57 #endif
58 #include "mp_msg.h"
59 #include "libmpcodecs/img_format.h"
60 #include "libmpcodecs/dec_teletext.h"
61 #include "libaf/af_format.h"
62 #include "tv.h"
63 #include "audio_in.h"
65 #define info tvi_info_v4l2
66 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param);
67 /* information about this file */
68 const tvi_info_t tvi_info_v4l2 = {
69 tvi_init_v4l2,
70 "Video 4 Linux 2 input",
71 "v4l2",
72 "Martin Olschewski <olschewski@zpr.uni-koeln.de>",
73 "first try, more to come ;-)"
76 struct map {
77 struct v4l2_buffer buf;
78 void *addr;
79 size_t len;
82 #define BUFFER_COUNT 6
84 /** video ringbuffer entry */
85 typedef struct {
86 unsigned char *data; ///< frame contents
87 long long timestamp; ///< frame timestamp
88 int framesize; ///< actual frame size
89 } video_buffer_entry;
91 /* private data */
92 typedef struct priv {
93 /* video */
94 char *video_dev;
95 int video_fd;
96 char *vbi_dev;
97 int vbi_fd;
98 int vbi_bufsize;
99 int vbi_shutdown;
100 pthread_t vbi_grabber_thread;
101 void *priv_vbi;
102 int mp_format;
103 struct v4l2_capability capability;
104 struct v4l2_input input;
105 struct v4l2_format format;
106 struct v4l2_standard standard;
107 struct v4l2_tuner tuner;
108 struct map *map;
109 int mapcount;
110 int frames;
111 volatile long long first_frame;
112 long long curr_frame;
113 /* audio video interleaving ;-) */
114 volatile int streamon;
115 pthread_t audio_grabber_thread;
116 pthread_mutex_t skew_mutex;
118 /* 2nd level video buffers */
119 int first;
120 int immediate_mode;
122 int video_buffer_size_max;
123 volatile int video_buffer_size_current;
124 video_buffer_entry *video_ringbuffer;
125 volatile int video_head;
126 volatile int video_tail;
127 volatile int video_cnt;
128 pthread_t video_grabber_thread;
129 pthread_mutex_t video_buffer_mutex;
131 /* audio */
132 char *audio_dev;
133 audio_in_t audio_in;
135 long long audio_start_time;
136 int audio_buffer_size;
137 int aud_skew_cnt;
138 unsigned char *audio_ringbuffer;
139 long long *audio_skew_buffer;
140 long long *audio_skew_delta_buffer;
141 volatile int audio_head;
142 volatile int audio_tail;
143 volatile int audio_cnt;
144 volatile long long audio_skew;
145 volatile double audio_skew_factor;
146 volatile long long audio_skew_measure_time;
147 volatile int audio_drop;
148 volatile int shutdown;
150 int audio_initialized;
151 double audio_secs_per_block;
152 long long audio_usecs_per_block;
153 long long audio_skew_total;
154 long long audio_skew_delta_total;
155 long audio_recv_blocks_total;
156 long audio_sent_blocks_total;
157 pthread_mutex_t audio_mutex;
158 int audio_insert_null_samples;
159 volatile long audio_null_blocks_inserted;
160 volatile long long dropped_frames_timeshift;
161 long long dropped_frames_compensated;
163 tv_param_t *tv_param;
164 } priv_t;
166 #include "tvi_def.h"
168 static void *audio_grabber(void *data);
169 static void *video_grabber(void *data);
171 /**********************************************************************\
173 Only few of the fourccs are the same in v4l2 and mplayer:
175 IMGFMT_YVU9 == V4L2_PIX_FMT_YVU410
176 IMGFMT_YV12 == V4L2_PIX_FMT_YVU420
177 IMGFMT_NV12 == V4L2_PIX_FMT_NV12
178 IMGFMT_422P == V4L2_PIX_FMT_YUV422P
179 IMGFMT_411P == V4L2_PIX_FMT_YUV411P
180 IMGFMT_UYVY == V4L2_PIX_FMT_UYVY
181 IMGFMT_Y41P == V4L2_PIX_FMT_Y41P
183 This may be an useful translation table for some others:
185 IMGFMT_RGB8 == V4L2_PIX_FMT_RGB332
186 IMGFMT_BGR15 == V4L2_PIX_FMT_RGB555
187 IMGFMT_BGR16 == V4L2_PIX_FMT_RGB565
188 IMGFMT_RGB24 == V4L2_PIX_FMT_RGB24
189 IMGFMT_RGB32 == V4L2_PIX_FMT_RGB32
190 IMGFMT_BGR24 == V4L2_PIX_FMT_BGR24
191 IMGFMT_BGR32 == V4L2_PIX_FMT_BGR32
192 IMGFMT_Y800 == V4L2_PIX_FMT_GREY
193 IMGFMT_IF09 == V4L2_PIX_FMT_YUV410
194 IMGFMT_I420 == V4L2_PIX_FMT_YUV420
195 IMGFMT_YUY2 == V4L2_PIX_FMT_YUYV
197 \**********************************************************************/
200 ** Translate a mplayer fourcc to a video4linux2 pixel format.
202 static int fcc_mp2vl(int fcc)
204 switch (fcc) {
205 case IMGFMT_RGB8: return V4L2_PIX_FMT_RGB332;
206 case IMGFMT_BGR15: return V4L2_PIX_FMT_RGB555;
207 case IMGFMT_BGR16: return V4L2_PIX_FMT_RGB565;
208 case IMGFMT_RGB24: return V4L2_PIX_FMT_RGB24;
209 case IMGFMT_RGB32: return V4L2_PIX_FMT_RGB32;
210 case IMGFMT_BGR24: return V4L2_PIX_FMT_BGR24;
211 case IMGFMT_BGR32: return V4L2_PIX_FMT_BGR32;
212 case IMGFMT_Y800: return V4L2_PIX_FMT_GREY;
213 case IMGFMT_IF09: return V4L2_PIX_FMT_YUV410;
214 case IMGFMT_I420: return V4L2_PIX_FMT_YUV420;
215 case IMGFMT_YUY2: return V4L2_PIX_FMT_YUYV;
216 case IMGFMT_YV12: return V4L2_PIX_FMT_YVU420;
217 case IMGFMT_UYVY: return V4L2_PIX_FMT_UYVY;
218 case IMGFMT_MJPEG: return V4L2_PIX_FMT_MJPEG;
220 return fcc;
224 ** Translate a video4linux2 fourcc aka pixel format to mplayer.
226 static int fcc_vl2mp(int fcc)
228 switch (fcc) {
229 case V4L2_PIX_FMT_RGB332: return IMGFMT_RGB8;
230 case V4L2_PIX_FMT_RGB555: return IMGFMT_BGR15;
231 case V4L2_PIX_FMT_RGB565: return IMGFMT_BGR16;
232 case V4L2_PIX_FMT_RGB24: return IMGFMT_RGB24;
233 case V4L2_PIX_FMT_RGB32: return IMGFMT_RGB32;
234 case V4L2_PIX_FMT_BGR24: return IMGFMT_BGR24;
235 case V4L2_PIX_FMT_BGR32: return IMGFMT_BGR32;
236 case V4L2_PIX_FMT_GREY: return IMGFMT_Y800;
237 case V4L2_PIX_FMT_YUV410: return IMGFMT_IF09;
238 case V4L2_PIX_FMT_YUV420: return IMGFMT_I420;
239 case V4L2_PIX_FMT_YVU420: return IMGFMT_YV12;
240 case V4L2_PIX_FMT_YUYV: return IMGFMT_YUY2;
241 case V4L2_PIX_FMT_UYVY: return IMGFMT_UYVY;
242 case V4L2_PIX_FMT_MJPEG: return IMGFMT_MJPEG;
244 return fcc;
248 ** Translate a video4linux2 fourcc aka pixel format
249 ** to a human readable string.
251 static const char *pixfmt2name(int pixfmt)
253 static char unknown[24];
255 switch (pixfmt) {
256 case V4L2_PIX_FMT_RGB332: return "RGB332";
257 case V4L2_PIX_FMT_RGB555: return "RGB555";
258 case V4L2_PIX_FMT_RGB565: return "RGB565";
259 case V4L2_PIX_FMT_RGB555X: return "RGB555X";
260 case V4L2_PIX_FMT_RGB565X: return "RGB565X";
261 case V4L2_PIX_FMT_BGR24: return "BGR24";
262 case V4L2_PIX_FMT_RGB24: return "RGB24";
263 case V4L2_PIX_FMT_BGR32: return "BGR32";
264 case V4L2_PIX_FMT_RGB32: return "RGB32";
265 case V4L2_PIX_FMT_GREY: return "GREY";
266 case V4L2_PIX_FMT_YVU410: return "YVU410";
267 case V4L2_PIX_FMT_YVU420: return "YVU420";
268 case V4L2_PIX_FMT_YUYV: return "YUYV";
269 case V4L2_PIX_FMT_UYVY: return "UYVY";
270 /* case V4L2_PIX_FMT_YVU422P: return "YVU422P"; */
271 /* case V4L2_PIX_FMT_YVU411P: return "YVU411P"; */
272 case V4L2_PIX_FMT_YUV422P: return "YUV422P";
273 case V4L2_PIX_FMT_YUV411P: return "YUV411P";
274 case V4L2_PIX_FMT_Y41P: return "Y41P";
275 case V4L2_PIX_FMT_NV12: return "NV12";
276 case V4L2_PIX_FMT_NV21: return "NV21";
277 case V4L2_PIX_FMT_YUV410: return "YUV410";
278 case V4L2_PIX_FMT_YUV420: return "YUV420";
279 case V4L2_PIX_FMT_YYUV: return "YYUV";
280 case V4L2_PIX_FMT_HI240: return "HI240";
281 case V4L2_PIX_FMT_WNVA: return "WNVA";
282 case V4L2_PIX_FMT_MJPEG: return "MJPEG";
284 sprintf(unknown, "unknown (0x%x)", pixfmt);
285 return unknown;
290 ** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
292 static int pixfmt2depth(int pixfmt)
294 switch (pixfmt) {
295 case V4L2_PIX_FMT_RGB332:
296 return 8;
297 case V4L2_PIX_FMT_RGB555:
298 case V4L2_PIX_FMT_RGB565:
299 case V4L2_PIX_FMT_RGB555X:
300 case V4L2_PIX_FMT_RGB565X:
301 return 16;
302 case V4L2_PIX_FMT_BGR24:
303 case V4L2_PIX_FMT_RGB24:
304 return 24;
305 case V4L2_PIX_FMT_BGR32:
306 case V4L2_PIX_FMT_RGB32:
307 return 32;
308 case V4L2_PIX_FMT_GREY:
309 return 8;
310 case V4L2_PIX_FMT_YVU410:
311 return 9;
312 case V4L2_PIX_FMT_YVU420:
313 return 12;
314 case V4L2_PIX_FMT_YUYV:
315 case V4L2_PIX_FMT_UYVY:
316 case V4L2_PIX_FMT_YUV422P:
317 case V4L2_PIX_FMT_YUV411P:
318 return 16;
319 case V4L2_PIX_FMT_Y41P:
320 case V4L2_PIX_FMT_NV12:
321 case V4L2_PIX_FMT_NV21:
322 return 12;
323 case V4L2_PIX_FMT_YUV410:
324 return 9;
325 case V4L2_PIX_FMT_YUV420:
326 return 12;
327 case V4L2_PIX_FMT_YYUV:
328 return 16;
329 case V4L2_PIX_FMT_HI240:
330 return 8;
333 return 0;
336 static int amode2v4l(int amode)
338 switch (amode) {
339 case 0:
340 return V4L2_TUNER_MODE_MONO;
341 case 1:
342 return V4L2_TUNER_MODE_STEREO;
343 case 2:
344 return V4L2_TUNER_MODE_LANG1;
345 case 3:
346 return V4L2_TUNER_MODE_LANG2;
347 default:
348 return -1;
354 ** Get current FPS.
356 static double getfps(priv_t *priv)
358 if (priv->tv_param->fps > 0)
359 return priv->tv_param->fps;
360 if (priv->standard.frameperiod.denominator && priv->standard.frameperiod.numerator)
361 return (double)priv->standard.frameperiod.denominator / priv->standard.frameperiod.numerator;
362 return 25.0;
365 // sets and sanitizes audio buffer/block sizes
366 static void setup_audio_buffer_sizes(priv_t *priv)
368 int bytes_per_sample = priv->audio_in.bytes_per_sample;
369 int seconds = priv->video_buffer_size_max/getfps(priv);
371 if (seconds < 5) seconds = 5;
372 if (seconds > 500) seconds = 500;
374 // make the audio buffer at least as the video buffer capacity (or 5 seconds) long
375 priv->audio_buffer_size = 1 + seconds*priv->audio_in.samplerate
376 *priv->audio_in.channels
377 *bytes_per_sample/priv->audio_in.blocksize;
378 if (priv->audio_buffer_size < 256) priv->audio_buffer_size = 256;
380 // make the skew buffer at least 1 second long
381 priv->aud_skew_cnt = 1 + 1*priv->audio_in.samplerate
382 *priv->audio_in.channels
383 *bytes_per_sample/priv->audio_in.blocksize;
384 if (priv->aud_skew_cnt < 16) priv->aud_skew_cnt = 16;
386 mp_msg(MSGT_TV, MSGL_V, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
387 priv->audio_buffer_size, priv->audio_in.blocksize, priv->aud_skew_cnt);
390 static void init_audio(priv_t *priv)
392 if (priv->audio_initialized) return;
394 if (!priv->tv_param->noaudio) {
395 #ifdef CONFIG_ALSA
396 if (priv->tv_param->alsa)
397 audio_in_init(&priv->audio_in, AUDIO_IN_ALSA);
398 else
399 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
400 #else
401 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
402 #endif
404 if (priv->audio_dev) {
405 audio_in_set_device(&priv->audio_in, priv->audio_dev);
408 audio_in_set_samplerate(&priv->audio_in, 44100);
409 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
410 if (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) {
411 audio_in_set_channels(&priv->audio_in, 2);
412 } else {
413 audio_in_set_channels(&priv->audio_in, 1);
415 } else {
416 if (priv->tv_param->forcechan >= 0) {
417 audio_in_set_channels(&priv->audio_in, priv->tv_param->forcechan);
418 } else {
419 audio_in_set_channels(&priv->audio_in, 2);
423 if (audio_in_setup(&priv->audio_in) < 0) return;
425 priv->audio_initialized = 1;
429 #if 0
431 ** the number of milliseconds elapsed between time0 and time1
433 static size_t difftv(struct timeval time1, struct timeval time0)
435 return (time1.tv_sec - time0.tv_sec) * 1000 +
436 (time1.tv_usec - time0.tv_usec) / 1000;
438 #endif
441 ** Get current video capture format.
443 static int getfmt(priv_t *priv)
445 int i;
447 priv->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
448 if ((i = ioctl(priv->video_fd, VIDIOC_G_FMT, &priv->format)) < 0) {
449 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get format failed: %s\n",
450 info.short_name, strerror(errno));
452 return i;
457 ** Get current video capture standard.
459 static int getstd(priv_t *priv)
461 v4l2_std_id id;
462 int i=0;
464 if (ioctl(priv->video_fd, VIDIOC_G_STD, &id) < 0) {
465 struct v4l2_streamparm parm;
467 parm.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
468 if(ioctl(priv->video_fd, VIDIOC_G_PARM, &parm) >= 0) {
469 mp_msg(MSGT_TV, MSGL_WARN, "%s: your device driver does not support VIDIOC_G_STD ioctl,"
470 " VIDIOC_G_PARM was used instead.\n", info.short_name);
471 priv->standard.index=0;
472 priv->standard.id=0;
473 priv->standard.frameperiod=parm.parm.capture.timeperframe;
474 return 0;
477 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get standard failed: %s\n",
478 info.short_name, strerror(errno));
479 return -1;
481 do {
482 priv->standard.index = i++;
483 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
484 return -1;
486 } while (priv->standard.id != id);
487 return 0;
490 /***********************************************************************\
493 * Interface to mplayer *
496 \***********************************************************************/
498 static int set_mute(priv_t *priv, int value)
500 struct v4l2_control control;
501 control.id = V4L2_CID_AUDIO_MUTE;
502 control.value = value;
503 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, &control) < 0) {
504 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set mute failed: %s\n",
505 info.short_name, strerror(errno));
506 return 0;
508 return 1;
512 ** MPlayer uses values from -100 up to 100 for controls.
513 ** Here they are scaled to what the tv card needs and applied.
515 static int set_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
516 struct v4l2_queryctrl qctrl;
517 qctrl.id = control->id;
518 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
519 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
520 info.short_name, strerror(errno));
521 return TVI_CONTROL_FALSE;
524 if (val_signed) {
525 if (control->value < 0) {
526 control->value = qctrl.default_value + control->value *
527 (qctrl.default_value - qctrl.minimum) / 100;
528 } else {
529 control->value = qctrl.default_value + control->value *
530 (qctrl.maximum - qctrl.default_value) / 100;
532 } else {
533 if (control->value < 50) {
534 control->value = qctrl.default_value + (control->value-50) *
535 (qctrl.default_value - qctrl.minimum) / 50;
536 } else {
537 control->value = qctrl.default_value + (control->value-50) *
538 (qctrl.maximum - qctrl.default_value) / 50;
543 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, control) < 0) {
544 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl set %s %d failed: %s\n",
545 info.short_name, qctrl.name, control->value, strerror(errno));
546 return TVI_CONTROL_FALSE;
548 mp_msg(MSGT_TV, MSGL_V, "%s: set %s: %d [%d, %d]\n", info.short_name,
549 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
551 return TVI_CONTROL_TRUE;
556 ** Scale the control values back to what mplayer needs.
558 static int get_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
559 struct v4l2_queryctrl qctrl;
561 qctrl.id = control->id;
562 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
563 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
564 info.short_name, strerror(errno));
565 return TVI_CONTROL_FALSE;
568 if (ioctl(priv->video_fd, VIDIOC_G_CTRL, control) < 0) {
569 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl get %s failed: %s\n",
570 info.short_name, qctrl.name, strerror(errno));
571 return TVI_CONTROL_FALSE;
573 mp_msg(MSGT_TV, MSGL_V, "%s: get %s: %d [%d, %d]\n", info.short_name,
574 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
576 if (val_signed) {
577 if (control->value < qctrl.default_value) {
578 control->value = (control->value - qctrl.default_value) * 100 /
579 (qctrl.default_value - qctrl.minimum);
580 } else {
581 control->value = (control->value - qctrl.default_value) * 100 /
582 (qctrl.maximum - qctrl.default_value);
584 } else {
585 if (control->value < qctrl.default_value) {
586 control->value = (control->value - qctrl.default_value) * 50 /
587 (qctrl.default_value - qctrl.minimum) + 50;
588 } else {
589 control->value = (control->value - qctrl.default_value) * 50 /
590 (qctrl.maximum - qctrl.default_value) + 50;
594 return TVI_CONTROL_TRUE;
597 static int vbi_init(priv_t* priv,char* device)
599 int vbi_fd=0;
600 struct v4l2_capability cap;
601 struct v4l2_format fmt;
602 int res;
604 if(!device)
605 return TVI_CONTROL_FALSE;
607 priv->vbi_dev=strdup(device);
609 vbi_fd=open(priv->vbi_dev,O_RDWR);
610 if(vbi_fd<0){
611 mp_msg(MSGT_TV,MSGL_ERR,"vbi: could not open device %s\n",priv->vbi_dev);
612 return TVI_CONTROL_FALSE;
615 if(ioctl(vbi_fd,VIDIOC_QUERYCAP,&cap)<0){
616 mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query capabilities failed for %s\n",priv->vbi_dev);
617 close(vbi_fd);
618 return TVI_CONTROL_FALSE;
620 if(!(cap.capabilities & V4L2_CAP_VBI_CAPTURE)){
621 mp_msg(MSGT_TV,MSGL_ERR,"vbi: %s does not support VBI capture\n",priv->vbi_dev);
622 close(vbi_fd);
623 return TVI_CONTROL_FALSE;
626 memset(&fmt,0,sizeof(struct v4l2_format));
627 fmt.type=V4L2_BUF_TYPE_VBI_CAPTURE;
628 if((res=ioctl(vbi_fd,VIDIOC_G_FMT,&fmt))<0){
629 mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query format failed: %x\n",res);
630 close(vbi_fd);
631 return TVI_CONTROL_FALSE;
633 if(fmt.fmt.vbi.sample_format!=V4L2_PIX_FMT_GREY){
634 mp_msg(MSGT_TV,MSGL_ERR,"vbi: format 0x%x is not supported\n",fmt.fmt.vbi.sample_format);
635 close(vbi_fd);
636 return TVI_CONTROL_FALSE;
638 priv->vbi_fd=vbi_fd;
639 mp_msg(MSGT_TV,MSGL_DBG3,"vbi: init ok\n");
640 return TVI_CONTROL_TRUE;
643 static int vbi_get_props(priv_t* priv,tt_stream_props* ptsp)
645 struct v4l2_format fmt;
646 int res;
647 if(!priv || !ptsp)
648 return TVI_CONTROL_FALSE;
650 memset(&fmt,0,sizeof(struct v4l2_format));
651 fmt.type=V4L2_BUF_TYPE_VBI_CAPTURE;
652 if((res=ioctl(priv->vbi_fd,VIDIOC_G_FMT,&fmt))<0){
653 mp_msg(MSGT_TV,MSGL_ERR,"vbi_get_props: Query format failed: %x\n",res);
654 return TVI_CONTROL_FALSE;
657 ptsp->interlaced=(fmt.fmt.vbi.flags& V4L2_VBI_INTERLACED?1:0);
659 ptsp->offset=fmt.fmt.vbi.offset;
660 ptsp->sampling_rate=fmt.fmt.vbi.sampling_rate;
661 ptsp->samples_per_line=fmt.fmt.vbi.samples_per_line,
663 ptsp->count[0]=fmt.fmt.vbi.count[0];
664 ptsp->count[1]=fmt.fmt.vbi.count[1];
665 ptsp->bufsize = ptsp->samples_per_line * (ptsp->count[0] + ptsp->count[1]);
667 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",
668 ptsp->sampling_rate,
669 ptsp->offset,
670 ptsp->samples_per_line,
671 ptsp->interlaced?"Yes":"No",
672 ptsp->count[0],
673 ptsp->count[1]);
675 return TVI_CONTROL_TRUE;
678 static void *vbi_grabber(void *data)
680 priv_t *priv = (priv_t *) data;
681 int bytes,seq,prev_seq;
682 unsigned char* buf;
683 tt_stream_props tsp;
685 if(!priv->priv_vbi){
686 mp_msg(MSGT_TV,MSGL_WARN,"vbi: vbi not initialized. stopping thread.\n");
687 return NULL;
690 if(vbi_get_props(priv,&tsp)!=TVI_CONTROL_TRUE)
691 return NULL;
693 buf=malloc(tsp.bufsize);
694 seq=0;
695 prev_seq=0;
696 mp_msg(MSGT_TV,MSGL_V,"vbi: vbi capture thread started.\n");
698 while (!priv->vbi_shutdown){
699 bytes=read(priv->vbi_fd,buf,tsp.bufsize);
700 if(bytes<0 && errno==EINTR)
701 continue;
702 if (bytes!=tsp.bufsize){
703 mp_msg(MSGT_TV,MSGL_WARN,"vbi: expecting bytes: %d, got: %d\n",tsp.bufsize,bytes);
704 break;
706 seq=*(int*)(buf+bytes-4);
707 if(seq<=1) continue;
708 if (prev_seq && seq!=prev_seq+1){
709 prev_seq=0;
710 seq=0;
712 prev_seq=seq;
713 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_DECODE_PAGE,&buf);
714 mp_msg(MSGT_TV,MSGL_DBG3,"grabber: seq:%d\n",seq);
716 free(buf);
717 return NULL;
720 static int control(priv_t *priv, int cmd, void *arg)
722 struct v4l2_control control;
723 struct v4l2_frequency frequency;
725 switch(cmd) {
726 case TVI_CONTROL_IS_VIDEO:
727 return priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
728 TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
729 case TVI_CONTROL_IS_AUDIO:
730 if (priv->tv_param->force_audio) return TVI_CONTROL_TRUE;
731 case TVI_CONTROL_IS_TUNER:
732 return priv->capability.capabilities & V4L2_CAP_TUNER?
733 TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
734 case TVI_CONTROL_IMMEDIATE:
735 priv->immediate_mode = 1;
736 return TVI_CONTROL_TRUE;
737 case TVI_CONTROL_VID_GET_FPS:
738 *(float *)arg = getfps(priv);
739 mp_msg(MSGT_TV, MSGL_V, "%s: get fps: %f\n", info.short_name,
740 *(float *)arg);
741 return TVI_CONTROL_TRUE;
742 case TVI_CONTROL_VID_GET_BITS:
743 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
744 *(int *)arg = pixfmt2depth(priv->format.fmt.pix.pixelformat);
745 mp_msg(MSGT_TV, MSGL_V, "%s: get depth: %d\n", info.short_name,
746 *(int *)arg);
747 return TVI_CONTROL_TRUE;
748 case TVI_CONTROL_VID_GET_FORMAT:
749 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
750 *(int *)arg = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
751 mp_msg(MSGT_TV, MSGL_V, "%s: get format: %s\n", info.short_name,
752 pixfmt2name(priv->format.fmt.pix.pixelformat));
753 return TVI_CONTROL_TRUE;
754 case TVI_CONTROL_VID_SET_FORMAT:
755 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
756 priv->format.fmt.pix.pixelformat = fcc_mp2vl(*(int *)arg);
757 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
759 priv->mp_format = *(int *)arg;
760 mp_msg(MSGT_TV, MSGL_V, "%s: set format: %s\n", info.short_name,
761 pixfmt2name(priv->format.fmt.pix.pixelformat));
762 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
763 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
764 info.short_name, strerror(errno));
765 return TVI_CONTROL_FALSE;
767 /* according to the v4l2 specs VIDIOC_S_FMT should not fail, inflexible drivers
768 might even always return the default parameters -> update the format here*/
769 priv->mp_format = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
770 return TVI_CONTROL_TRUE;
771 case TVI_CONTROL_VID_GET_WIDTH:
772 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
773 *(int *)arg = priv->format.fmt.pix.width;
774 mp_msg(MSGT_TV, MSGL_V, "%s: get width: %d\n", info.short_name,
775 *(int *)arg);
776 return TVI_CONTROL_TRUE;
777 case TVI_CONTROL_VID_CHK_WIDTH:
778 return TVI_CONTROL_TRUE;
779 case TVI_CONTROL_VID_SET_WIDTH_HEIGHT:
780 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
781 priv->format.fmt.pix.width = ((int *)arg)[0];
782 priv->format.fmt.pix.height = ((int *)arg)[1];
783 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
784 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0)
785 return TVI_CONTROL_FALSE;
786 return TVI_CONTROL_TRUE;
787 case TVI_CONTROL_VID_SET_WIDTH:
788 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
789 priv->format.fmt.pix.width = *(int *)arg;
790 mp_msg(MSGT_TV, MSGL_V, "%s: set width: %d\n", info.short_name,
791 *(int *)arg);
792 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
793 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set width failed: %s\n",
794 info.short_name, strerror(errno));
795 return TVI_CONTROL_FALSE;
797 return TVI_CONTROL_TRUE;
798 case TVI_CONTROL_VID_GET_HEIGHT:
799 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
800 *(int *)arg = priv->format.fmt.pix.height;
801 mp_msg(MSGT_TV, MSGL_V, "%s: get height: %d\n", info.short_name,
802 *(int *)arg);
803 return TVI_CONTROL_TRUE;
804 case TVI_CONTROL_VID_CHK_HEIGHT:
805 return TVI_CONTROL_TRUE;
806 case TVI_CONTROL_VID_SET_HEIGHT:
807 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
808 priv->format.fmt.pix.height = *(int *)arg;
809 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
810 mp_msg(MSGT_TV, MSGL_V, "%s: set height: %d\n", info.short_name,
811 *(int *)arg);
812 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
813 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set height failed: %s\n",
814 info.short_name, strerror(errno));
815 return TVI_CONTROL_FALSE;
817 return TVI_CONTROL_TRUE;
818 case TVI_CONTROL_VID_GET_BRIGHTNESS:
819 control.id = V4L2_CID_BRIGHTNESS;
820 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
821 *(int *)arg = control.value;
822 return TVI_CONTROL_TRUE;
824 return TVI_CONTROL_FALSE;
825 case TVI_CONTROL_VID_SET_BRIGHTNESS:
826 control.id = V4L2_CID_BRIGHTNESS;
827 control.value = *(int *)arg;
828 return set_control(priv, &control, 1);
829 case TVI_CONTROL_VID_GET_HUE:
830 control.id = V4L2_CID_HUE;
831 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
832 *(int *)arg = control.value;
833 return TVI_CONTROL_TRUE;
835 return TVI_CONTROL_FALSE;
836 case TVI_CONTROL_VID_SET_HUE:
837 control.id = V4L2_CID_HUE;
838 control.value = *(int *)arg;
839 return set_control(priv, &control, 1);
840 case TVI_CONTROL_VID_GET_SATURATION:
841 control.id = V4L2_CID_SATURATION;
842 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
843 *(int *)arg = control.value;
844 return TVI_CONTROL_TRUE;
846 return TVI_CONTROL_FALSE;
847 case TVI_CONTROL_VID_SET_SATURATION:
848 control.id = V4L2_CID_SATURATION;
849 control.value = *(int *)arg;
850 return set_control(priv, &control, 1);
851 case TVI_CONTROL_VID_GET_GAIN:
854 control.id = V4L2_CID_AUTOGAIN;
855 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
856 return TVI_CONTROL_FALSE;
858 if(control.value){ //Auto Gain control is enabled
859 *(int*)arg=0;
860 return TVI_CONTROL_TRUE;
863 //Manual Gain control
864 control.id = V4L2_CID_GAIN;
865 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
866 return TVI_CONTROL_FALSE;
868 *(int*)arg=control.value?control.value:1;
870 return TVI_CONTROL_TRUE;
872 case TVI_CONTROL_VID_SET_GAIN:
874 //value==0 means automatic gain control
875 int value=*(int*)arg;
877 if (value < 0 || value>100)
878 return TVI_CONTROL_FALSE;
880 control.id=value?V4L2_CID_GAIN:V4L2_CID_AUTOGAIN;
881 control.value=value?value:1;
883 return set_control(priv,&control,0);
885 case TVI_CONTROL_VID_GET_CONTRAST:
886 control.id = V4L2_CID_CONTRAST;
887 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
888 *(int *)arg = control.value;
889 return TVI_CONTROL_TRUE;
891 return TVI_CONTROL_FALSE;
892 case TVI_CONTROL_VID_SET_CONTRAST:
893 control.id = V4L2_CID_CONTRAST;
894 control.value = *(int *)arg;
895 return set_control(priv, &control, 1);
896 case TVI_CONTROL_TUN_GET_FREQ:
897 frequency.tuner = 0;
898 frequency.type = V4L2_TUNER_ANALOG_TV;
899 if (ioctl(priv->video_fd, VIDIOC_G_FREQUENCY, &frequency) < 0) {
900 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl get frequency failed: %s\n",
901 info.short_name, strerror(errno));
902 return TVI_CONTROL_FALSE;
904 *(int *)arg = frequency.frequency;
905 return TVI_CONTROL_TRUE;
906 case TVI_CONTROL_TUN_SET_FREQ:
907 #if 0
908 set_mute(priv, 1);
909 usleep(100000); // wait to suppress noise during switching
910 #endif
911 frequency.tuner = 0;
912 frequency.type = V4L2_TUNER_ANALOG_TV;
913 frequency.frequency = *(int *)arg;
914 if (ioctl(priv->video_fd, VIDIOC_S_FREQUENCY, &frequency) < 0) {
915 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set frequency failed: %s\n",
916 info.short_name, strerror(errno));
917 return TVI_CONTROL_FALSE;
919 #if 0
920 usleep(100000); // wait to suppress noise during switching
921 set_mute(priv, 0);
922 #endif
923 return TVI_CONTROL_TRUE;
924 case TVI_CONTROL_TUN_GET_TUNER:
925 mp_msg(MSGT_TV, MSGL_V, "%s: get tuner\n",info.short_name);
926 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
927 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
928 info.short_name, strerror(errno));
929 return TVI_CONTROL_FALSE;
931 return TVI_CONTROL_TRUE;
932 case TVI_CONTROL_TUN_SET_TUNER:
933 mp_msg(MSGT_TV, MSGL_V, "%s: set tuner\n",info.short_name);
934 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
935 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
936 info.short_name, strerror(errno));
937 return TVI_CONTROL_FALSE;
939 return TVI_CONTROL_TRUE;
940 case TVI_CONTROL_TUN_GET_NORM:
941 *(int *)arg = priv->standard.index;
942 return TVI_CONTROL_TRUE;
943 case TVI_CONTROL_TUN_GET_SIGNAL:
944 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
945 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
946 info.short_name, strerror(errno));
947 return TVI_CONTROL_FALSE;
949 *(int*)arg=100*(priv->tuner.signal>>8)/255;
950 return TVI_CONTROL_TRUE;
951 case TVI_CONTROL_TUN_SET_NORM:
952 priv->standard.index = *(int *)arg;
953 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
954 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum norm failed: %s\n",
955 info.short_name, strerror(errno));
956 return TVI_CONTROL_FALSE;
958 mp_msg(MSGT_TV, MSGL_V, "%s: set norm: %s\n", info.short_name, priv->standard.name);
959 if (ioctl(priv->video_fd, VIDIOC_S_STD, &priv->standard.id) < 0) {
960 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set norm failed: %s\n",
961 info.short_name, strerror(errno));
962 return TVI_CONTROL_FALSE;
964 return TVI_CONTROL_TRUE;
965 case TVI_CONTROL_SPC_GET_NORMID:
967 int i;
968 for (i = 0;; i++) {
969 struct v4l2_standard standard;
970 memset(&standard, 0, sizeof(standard));
971 standard.index = i;
972 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
973 return TVI_CONTROL_FALSE;
974 if (!strcasecmp(standard.name, (char *)arg)) {
975 *(int *)arg = i;
976 return TVI_CONTROL_TRUE;
979 return TVI_CONTROL_FALSE;
981 case TVI_CONTROL_SPC_GET_INPUT:
982 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, (int *)arg) < 0) {
983 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
984 info.short_name, strerror(errno));
985 return TVI_CONTROL_FALSE;
987 return TVI_CONTROL_TRUE;
988 case TVI_CONTROL_SPC_SET_INPUT:
989 mp_msg(MSGT_TV, MSGL_V, "%s: set input: %d\n", info.short_name, *(int *)arg);
990 priv->input.index = *(int *)arg;
991 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &priv->input) < 0) {
992 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum input failed: %s\n",
993 info.short_name, strerror(errno));
994 return TVI_CONTROL_FALSE;
996 if (ioctl(priv->video_fd, VIDIOC_S_INPUT, (int *)arg) < 0) {
997 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set input failed: %s\n",
998 info.short_name, strerror(errno));
999 return TVI_CONTROL_FALSE;
1001 return TVI_CONTROL_TRUE;
1002 case TVI_CONTROL_AUD_GET_FORMAT:
1003 init_audio(priv);
1004 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1005 *(int *)arg = AF_FORMAT_S16_LE;
1006 mp_msg(MSGT_TV, MSGL_V, "%s: get audio format: %d\n",
1007 info.short_name, *(int *)arg);
1008 return TVI_CONTROL_TRUE;
1009 case TVI_CONTROL_AUD_GET_SAMPLERATE:
1010 init_audio(priv);
1011 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1012 *(int *)arg = priv->audio_in.samplerate;
1013 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplerate: %d\n",
1014 info.short_name, *(int *)arg);
1015 return TVI_CONTROL_TRUE;
1016 case TVI_CONTROL_AUD_GET_SAMPLESIZE:
1017 init_audio(priv);
1018 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1019 *(int *)arg = priv->audio_in.bytes_per_sample;
1020 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplesize: %d\n",
1021 info.short_name, *(int *)arg);
1022 return TVI_CONTROL_TRUE;
1023 case TVI_CONTROL_AUD_GET_CHANNELS:
1024 init_audio(priv);
1025 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1026 *(int *)arg = priv->audio_in.channels;
1027 mp_msg(MSGT_TV, MSGL_V, "%s: get audio channels: %d\n",
1028 info.short_name, *(int *)arg);
1029 return TVI_CONTROL_TRUE;
1030 case TVI_CONTROL_AUD_SET_SAMPLERATE:
1031 init_audio(priv);
1032 mp_msg(MSGT_TV, MSGL_V, "%s: set audio samplerate: %d\n",
1033 info.short_name, *(int *)arg);
1034 if (audio_in_set_samplerate(&priv->audio_in, *(int*)arg) < 0) return TVI_CONTROL_FALSE;
1035 // setup_audio_buffer_sizes(priv);
1036 return TVI_CONTROL_TRUE;
1037 case TVI_CONTROL_VBI_INIT:
1039 void* ptr;
1040 tt_stream_props tsp;
1042 if (vbi_init(priv,*(char**)arg)!=TVI_CONTROL_TRUE)
1043 return TVI_CONTROL_FALSE;
1044 if(vbi_get_props(priv,&tsp)==TVI_CONTROL_TRUE)
1046 ptr=&tsp;
1047 if(teletext_control(NULL,TV_VBI_CONTROL_START,&ptr)==VBI_CONTROL_TRUE)
1048 priv->priv_vbi=ptr;
1049 else
1050 priv->priv_vbi=NULL;
1052 return TVI_CONTROL_TRUE;
1054 case TVI_CONTROL_GET_VBI_PTR:
1055 *(void **)arg=priv->priv_vbi;
1056 return TVI_CONTROL_TRUE;
1058 mp_msg(MSGT_TV, MSGL_V, "%s: unknown control: %d\n", info.short_name, cmd);
1059 return TVI_CONTROL_UNKNOWN;
1063 #define PRIV ((priv_t *) (tvi_handle->priv))
1065 /* handler creator - entry point ! */
1066 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param)
1068 tvi_handle_t *tvi_handle;
1070 tvi_handle = tv_new_handle(sizeof(priv_t), &functions);
1071 if (!tvi_handle) {
1072 return NULL;
1074 PRIV->video_fd = -1;
1076 PRIV->video_dev = strdup(tv_param->device? tv_param->device: "/dev/video0");
1077 if (!PRIV->video_dev) {
1078 tv_free_handle(tvi_handle);
1079 return NULL;
1082 if (tv_param->adevice) {
1083 PRIV->audio_dev = strdup(tv_param->adevice);
1084 if (!PRIV->audio_dev) {
1085 free(PRIV->video_dev);
1086 tv_free_handle(tvi_handle);
1087 return NULL;
1091 PRIV->tv_param=tv_param;
1092 return tvi_handle;
1095 #undef PRIV
1098 static int uninit(priv_t *priv)
1100 int i, frames, dropped = 0;
1102 priv->vbi_shutdown=1;
1103 if(priv->vbi_grabber_thread)
1104 pthread_join(priv->vbi_grabber_thread, NULL);
1106 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_STOP,(void*)1);
1107 priv->priv_vbi=NULL;
1109 if(priv->vbi_fd){
1110 close(priv->vbi_fd);
1111 priv->vbi_fd=0;
1114 free(priv->vbi_dev);
1115 priv->vbi_dev = NULL;
1116 priv->shutdown = 1;
1117 if(priv->video_grabber_thread)
1118 pthread_join(priv->video_grabber_thread, NULL);
1119 pthread_mutex_destroy(&priv->video_buffer_mutex);
1121 if (priv->streamon) {
1122 struct v4l2_buffer buf;
1124 /* get performance */
1125 frames = 1 + lrintf((double)(priv->curr_frame - priv->first_frame) / 1e6 * getfps(priv));
1126 dropped = frames - priv->frames;
1128 /* turn off streaming */
1129 if (ioctl(priv->video_fd, VIDIOC_STREAMOFF, &(priv->map[0].buf.type)) < 0) {
1130 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamoff failed: %s\n",
1131 info.short_name, strerror(errno));
1133 priv->streamon = 0;
1135 /* unqueue all remaining buffers */
1136 memset(&buf,0,sizeof(buf));
1137 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1138 buf.memory = V4L2_MEMORY_MMAP;
1139 while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
1142 /* unmap all buffers */
1143 for (i = 0; i < priv->mapcount; i++) {
1144 if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {
1145 mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",
1146 info.short_name, strerror(errno));
1150 /* stop audio thread */
1151 if (!priv->tv_param->noaudio && priv->audio_grabber_thread) {
1152 pthread_join(priv->audio_grabber_thread, NULL);
1153 pthread_mutex_destroy(&priv->skew_mutex);
1154 pthread_mutex_destroy(&priv->audio_mutex);
1157 set_mute(priv, 1);
1159 /* free memory and close device */
1160 free(priv->map); priv->map = NULL;
1161 priv->mapcount = 0;
1162 if(priv->video_fd!=-1)close(priv->video_fd); priv->video_fd = -1;
1163 free(priv->video_dev); priv->video_dev = NULL;
1165 if (priv->video_ringbuffer) {
1166 int i;
1167 for (i = 0; i < priv->video_buffer_size_current; i++) {
1168 free(priv->video_ringbuffer[i].data);
1170 free(priv->video_ringbuffer);
1172 if (!priv->tv_param->noaudio) {
1173 free(priv->audio_ringbuffer);
1174 free(priv->audio_skew_buffer);
1175 free(priv->audio_skew_delta_buffer);
1177 audio_in_uninit(&priv->audio_in);
1180 /* show some nice statistics ;-) */
1181 mp_msg(MSGT_TV, MSGL_INFO,
1182 "%s: %d frames successfully processed, %d frames dropped.\n",
1183 info.short_name, priv->frames, dropped);
1184 mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",
1185 info.short_name, priv->video_buffer_size_current);
1186 return 1;
1190 /* initialisation */
1191 static int init(priv_t *priv)
1193 int i;
1195 priv->audio_ringbuffer = NULL;
1196 priv->audio_skew_buffer = NULL;
1197 priv->audio_skew_delta_buffer = NULL;
1199 priv->audio_initialized = 0;
1201 /* Open the video device. */
1202 priv->video_fd = open(priv->video_dev, O_RDWR);
1203 if (priv->video_fd < 0) {
1204 mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",
1205 info.short_name, priv->video_dev, strerror(errno));
1206 uninit(priv);
1207 return 0;
1209 mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",
1210 info.short_name, priv->video_dev, priv->video_fd);
1213 ** Query the video capabilities and current settings
1214 ** for further control calls.
1216 if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
1217 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",
1218 info.short_name, strerror(errno));
1219 uninit(priv);
1220 return 0;
1223 if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))
1225 mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",
1226 priv->video_dev);
1227 return 0;
1230 if (getfmt(priv) < 0) {
1231 uninit(priv);
1232 return 0;
1234 getstd(priv);
1236 ** if this device has got a tuner query it's settings
1237 ** otherwise set some nice defaults
1239 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1240 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
1241 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
1242 info.short_name, strerror(errno));
1243 uninit(priv);
1244 return 0;
1247 mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);
1248 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1249 mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",
1250 (priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",
1251 (priv->tuner.capability & V4L2_TUNER_CAP_LANG1) ? " LANG1" : "",
1252 (priv->tuner.capability & V4L2_TUNER_CAP_LANG2) ? " LANG2" : "");
1253 mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",
1254 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO) ? " MONO" : "",
1255 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",
1256 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1) ? " LANG1" : "",
1257 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2) ? " LANG2" : "");
1259 mp_msg(MSGT_TV, MSGL_INFO, " Capabilities:%s%s%s%s%s%s%s%s%s%s%s\n",
1260 priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
1261 " video capture": "",
1262 priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?
1263 " video output": "",
1264 priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?
1265 " video overlay": "",
1266 priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?
1267 " VBI capture device": "",
1268 priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?
1269 " VBI output": "",
1270 priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?
1271 " RDS data capture": "",
1272 priv->capability.capabilities & V4L2_CAP_TUNER?
1273 " tuner": "",
1274 priv->capability.capabilities & V4L2_CAP_AUDIO?
1275 " audio": "",
1276 priv->capability.capabilities & V4L2_CAP_READWRITE?
1277 " read/write": "",
1278 priv->capability.capabilities & V4L2_CAP_ASYNCIO?
1279 " async i/o": "",
1280 priv->capability.capabilities & V4L2_CAP_STREAMING?
1281 " streaming": "");
1282 mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");
1283 for (i = 0;; i++) {
1284 struct v4l2_standard standard;
1285 memset(&standard, 0, sizeof(standard));
1286 standard.index = i;
1287 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
1288 break;
1289 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);
1291 mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");
1292 for (i = 0; 1; i++) {
1293 struct v4l2_input input;
1295 input.index = i;
1296 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
1297 break;
1299 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);
1301 i = -1;
1302 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
1303 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
1304 info.short_name, strerror(errno));
1306 mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);
1307 for (i = 0; ; i++) {
1308 struct v4l2_fmtdesc fmtdesc;
1310 fmtdesc.index = i;
1311 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1312 if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
1313 break;
1315 mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",
1316 pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),
1317 fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));
1319 mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",
1320 pixfmt2name(priv->format.fmt.pix.pixelformat));
1322 /* set some nice defaults */
1323 if (getfmt(priv) < 0) return 0;
1324 priv->format.fmt.pix.width = 640;
1325 priv->format.fmt.pix.height = 480;
1326 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
1327 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
1328 info.short_name, strerror(errno));
1329 uninit(priv);
1330 return 0;
1333 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;
1335 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1336 struct v4l2_control control;
1337 if (priv->tv_param->amode >= 0) {
1338 mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);
1339 priv->tuner.audmode = amode2v4l(priv->tv_param->amode);
1340 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
1341 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
1342 info.short_name, strerror(errno));
1343 return TVI_CONTROL_FALSE;
1346 mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,
1347 (priv->tuner.audmode == V4L2_TUNER_MODE_MONO) ? " MONO" : "",
1348 (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",
1349 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG1) ? " LANG1" : "",
1350 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG2) ? " LANG2" : "");
1352 if (priv->tv_param->volume >= 0) {
1353 control.id = V4L2_CID_AUDIO_VOLUME;
1354 control.value = priv->tv_param->volume;
1355 set_control(priv, &control, 0);
1357 if (priv->tv_param->bass >= 0) {
1358 control.id = V4L2_CID_AUDIO_BASS;
1359 control.value = priv->tv_param->bass;
1360 set_control(priv, &control, 0);
1362 if (priv->tv_param->treble >= 0) {
1363 control.id = V4L2_CID_AUDIO_TREBLE;
1364 control.value = priv->tv_param->treble;
1365 set_control(priv, &control, 0);
1367 if (priv->tv_param->balance >= 0) {
1368 control.id = V4L2_CID_AUDIO_BALANCE;
1369 control.value = priv->tv_param->balance;
1370 set_control(priv, &control, 0);
1374 return 1;
1377 static int get_capture_buffer_size(priv_t *priv)
1379 uint64_t bufsize;
1380 int cnt;
1382 if (priv->tv_param->buffer_size >= 0) {
1383 bufsize = priv->tv_param->buffer_size*1024*1024;
1384 } else {
1385 #ifdef HAVE_SYS_SYSINFO_H
1386 struct sysinfo si;
1388 sysinfo(&si);
1389 bufsize = (si.freeram/2)*si.mem_unit;
1390 if ( bufsize < 16*1024*1024)
1391 #endif
1392 bufsize = 16*1024*1024;
1395 cnt = bufsize/priv->format.fmt.pix.sizeimage;
1396 if (cnt < 2) cnt = 2;
1398 return cnt;
1401 /* that's the real start, we'got the format parameters (checked with control) */
1402 static int start(priv_t *priv)
1404 struct v4l2_requestbuffers request;
1405 unsigned int i;
1407 /* setup audio parameters */
1409 init_audio(priv);
1410 if (!priv->tv_param->noaudio && !priv->audio_initialized) return 0;
1412 /* we need this to size the audio buffer properly */
1413 if (priv->immediate_mode) {
1414 priv->video_buffer_size_max = 2;
1415 } else {
1416 priv->video_buffer_size_max = get_capture_buffer_size(priv);
1419 if (!priv->tv_param->noaudio) {
1420 setup_audio_buffer_sizes(priv);
1421 priv->audio_skew_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1422 if (!priv->audio_skew_buffer) {
1423 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1424 return 0;
1426 priv->audio_skew_delta_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1427 if (!priv->audio_skew_delta_buffer) {
1428 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1429 return 0;
1432 priv->audio_ringbuffer = calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
1433 if (!priv->audio_ringbuffer) {
1434 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
1435 return 0;
1438 priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate
1439 *priv->audio_in.channels
1440 *priv->audio_in.bytes_per_sample);
1441 priv->audio_usecs_per_block = 1e6*priv->audio_secs_per_block;
1442 priv->audio_head = 0;
1443 priv->audio_tail = 0;
1444 priv->audio_cnt = 0;
1445 priv->audio_drop = 0;
1446 priv->audio_skew = 0;
1447 priv->audio_skew_total = 0;
1448 priv->audio_skew_delta_total = 0;
1449 priv->audio_recv_blocks_total = 0;
1450 priv->audio_sent_blocks_total = 0;
1451 priv->audio_null_blocks_inserted = 0;
1452 priv->audio_insert_null_samples = 0;
1453 priv->dropped_frames_timeshift = 0;
1454 priv->dropped_frames_compensated = 0;
1456 pthread_mutex_init(&priv->skew_mutex, NULL);
1457 pthread_mutex_init(&priv->audio_mutex, NULL);
1460 /* setup video parameters */
1461 if (!priv->tv_param->noaudio) {
1462 if (priv->video_buffer_size_max < 3*getfps(priv)*priv->audio_secs_per_block) {
1463 mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"
1464 "You will probably experience heavy framedrops.\n");
1469 int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1471 mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1472 priv->video_buffer_size_max,
1473 priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));
1476 priv->video_ringbuffer = calloc(priv->video_buffer_size_max, sizeof(video_buffer_entry));
1477 if (!priv->video_ringbuffer) {
1478 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
1479 return 0;
1481 memset(priv->video_ringbuffer,0,priv->video_buffer_size_max * sizeof(video_buffer_entry));
1483 pthread_mutex_init(&priv->video_buffer_mutex, NULL);
1485 priv->video_head = 0;
1486 priv->video_tail = 0;
1487 priv->video_cnt = 0;
1489 /* request buffers */
1490 if (priv->immediate_mode) {
1491 request.count = 2;
1492 } else {
1493 request.count = BUFFER_COUNT;
1496 request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1497 request.memory = V4L2_MEMORY_MMAP;
1498 if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
1499 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",
1500 info.short_name, strerror(errno));
1501 return 0;
1504 /* query buffers */
1505 if (!(priv->map = calloc(request.count, sizeof(struct map)))) {
1506 mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",
1507 info.short_name, strerror(errno));
1508 return 0;
1511 /* map and queue buffers */
1512 for (i = 0; i < request.count; i++) {
1513 memset(&priv->map[i].buf,0,sizeof(priv->map[i].buf));
1514 priv->map[i].buf.index = i;
1515 priv->map[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1516 priv->map[i].buf.memory = V4L2_MEMORY_MMAP;
1517 if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
1518 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",
1519 info.short_name, strerror(errno));
1520 free(priv->map);
1521 priv->map = NULL;
1522 return 0;
1524 priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |
1525 PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);
1526 if (priv->map[i].addr == MAP_FAILED) {
1527 mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",
1528 info.short_name, strerror(errno));
1529 priv->map[i].len = 0;
1530 return 0;
1532 priv->map[i].len = priv->map[i].buf.length;
1533 /* count up to make sure this is correct everytime */
1534 priv->mapcount++;
1536 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1537 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1538 info.short_name, strerror(errno));
1539 return 0;
1543 /* start vbi thread */
1544 if(priv->priv_vbi){
1545 priv->vbi_shutdown = 0;
1546 pthread_create(&priv->vbi_grabber_thread, NULL, vbi_grabber, priv);
1548 /* start audio thread */
1549 priv->shutdown = 0;
1550 priv->audio_skew_measure_time = 0;
1551 priv->first_frame = 0;
1552 priv->audio_skew = 0;
1553 priv->first = 1;
1555 set_mute(priv, 0);
1557 return 1;
1560 // copies a video frame
1561 static inline void copy_frame(priv_t *priv, video_buffer_entry *dest, unsigned char *source,int len)
1563 dest->framesize=len;
1564 if(priv->tv_param->automute>0){
1565 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) >= 0) {
1566 if(priv->tv_param->automute<<8>priv->tuner.signal){
1567 fill_blank_frame(dest->data,dest->framesize,fcc_vl2mp(priv->format.fmt.pix.pixelformat));
1568 set_mute(priv,1);
1569 return;
1572 set_mute(priv,0);
1574 memcpy(dest->data, source, len);
1577 // maximum skew change, in frames
1578 #define MAX_SKEW_DELTA 0.6
1579 static void *video_grabber(void *data)
1581 priv_t *priv = (priv_t*)data;
1582 long long skew, prev_skew, xskew, interval, prev_interval, delta;
1583 int i;
1584 int framesize = priv->format.fmt.pix.sizeimage;
1585 fd_set rdset;
1586 struct timeval timeout;
1587 struct v4l2_buffer buf;
1589 xskew = 0;
1590 skew = 0;
1591 interval = 0;
1592 prev_interval = 0;
1593 prev_skew = 0;
1595 mp_msg(MSGT_TV, MSGL_V, "%s: going to capture\n", info.short_name);
1596 if (ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
1597 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamon failed: %s\n",
1598 info.short_name, strerror(errno));
1599 return 0;
1601 priv->streamon = 1;
1603 if (!priv->tv_param->noaudio) {
1604 pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
1607 for (priv->frames = 0; !priv->shutdown;)
1609 int ret;
1611 if (priv->immediate_mode) {
1612 while (priv->video_cnt == priv->video_buffer_size_max) {
1613 usleep(10000);
1614 if (priv->shutdown) {
1615 return NULL;
1620 FD_ZERO (&rdset);
1621 FD_SET (priv->video_fd, &rdset);
1623 timeout.tv_sec = 1;
1624 timeout.tv_usec = 0;
1626 i = select(priv->video_fd + 1, &rdset, NULL, NULL, &timeout);
1627 if (i < 0) {
1628 mp_msg(MSGT_TV, MSGL_ERR, "%s: select failed: %s\n",
1629 info.short_name, strerror(errno));
1630 continue;
1632 else if (i == 0) {
1633 mp_msg(MSGT_TV, MSGL_ERR, "%s: select timeout\n", info.short_name);
1634 continue;
1636 else if (!FD_ISSET(priv->video_fd, &rdset)) {
1637 continue;
1640 memset(&buf,0,sizeof(buf));
1641 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1642 buf.memory = V4L2_MEMORY_MMAP;
1643 ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
1645 if (ret < 0) {
1647 if there's no signal, the buffer might me dequeued
1648 so we query all the buffers to see which one we should
1649 put back to queue
1651 observed with saa7134 0.2.8
1652 don't know if is it a bug or (mis)feature
1654 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1655 info.short_name, strerror(errno), buf.index);
1656 for (i = 0; i < priv->mapcount; i++) {
1657 memset(&buf,0,sizeof(buf));
1658 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1659 buf.memory = V4L2_MEMORY_MMAP;
1660 buf.index = i;
1661 ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
1662 if (ret < 0) {
1663 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s, idx = %d\n",
1664 info.short_name, strerror(errno), buf.index);
1665 return 0;
1667 if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
1668 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1669 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1670 info.short_name, strerror(errno));
1671 return 0;
1675 continue;
1678 /* store the timestamp of the very first frame as reference */
1679 if (!priv->frames++) {
1680 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1681 priv->first_frame = (long long)1e6*buf.timestamp.tv_sec + buf.timestamp.tv_usec;
1682 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1684 priv->curr_frame = (long long)buf.timestamp.tv_sec*1e6+buf.timestamp.tv_usec;
1685 // fprintf(stderr, "idx = %d, ts = %f\n", buf.index, (double)(priv->curr_frame) / 1e6);
1687 interval = priv->curr_frame - priv->first_frame;
1688 delta = interval - prev_interval;
1690 if (!priv->immediate_mode) {
1691 // interpolate the skew in time
1692 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1693 xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
1694 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1695 // correct extreme skew changes to avoid (especially) moving backwards in time
1696 if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
1697 skew = prev_skew + delta*MAX_SKEW_DELTA;
1698 } else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) {
1699 skew = prev_skew - delta*MAX_SKEW_DELTA;
1700 } else {
1701 skew = xskew;
1705 mp_msg(MSGT_TV, MSGL_DBG3, "\nfps = %f, interval = %f, a_skew = %f, corr_skew = %f\n",
1706 delta ? (double)1e6/delta : -1,
1707 (double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
1708 mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
1710 prev_skew = skew;
1711 prev_interval = interval;
1713 /* allocate a new buffer, if needed */
1714 pthread_mutex_lock(&priv->video_buffer_mutex);
1715 if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
1716 if (priv->video_cnt == priv->video_buffer_size_current) {
1717 unsigned char *newbuf = malloc(framesize);
1718 if (newbuf) {
1719 memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
1720 (priv->video_buffer_size_current-priv->video_tail)*sizeof(video_buffer_entry));
1721 priv->video_ringbuffer[priv->video_tail].data = newbuf;
1722 if ((priv->video_head >= priv->video_tail) && (priv->video_cnt > 0)) priv->video_head++;
1723 priv->video_buffer_size_current++;
1727 pthread_mutex_unlock(&priv->video_buffer_mutex);
1729 if (priv->video_cnt == priv->video_buffer_size_current) {
1730 if (!priv->immediate_mode) {
1731 mp_msg(MSGT_TV, MSGL_ERR, "\nvideo buffer full - dropping frame\n");
1732 if (priv->audio_insert_null_samples) {
1733 pthread_mutex_lock(&priv->audio_mutex);
1734 priv->dropped_frames_timeshift += delta;
1735 pthread_mutex_unlock(&priv->audio_mutex);
1738 } else {
1739 if (priv->immediate_mode) {
1740 priv->video_ringbuffer[priv->video_tail].timestamp = 0;
1741 } else {
1742 // compensate for audio skew
1743 // negative skew => there are more audio samples, increase interval
1744 // positive skew => less samples, shorten the interval
1745 priv->video_ringbuffer[priv->video_tail].timestamp = interval - skew;
1746 if (priv->audio_insert_null_samples && priv->video_ringbuffer[priv->video_tail].timestamp > 0) {
1747 pthread_mutex_lock(&priv->audio_mutex);
1748 priv->video_ringbuffer[priv->video_tail].timestamp +=
1749 (priv->audio_null_blocks_inserted
1750 - priv->dropped_frames_timeshift/priv->audio_usecs_per_block)
1751 *priv->audio_usecs_per_block;
1752 pthread_mutex_unlock(&priv->audio_mutex);
1755 copy_frame(priv, priv->video_ringbuffer+priv->video_tail, priv->map[buf.index].addr,buf.bytesused);
1756 priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
1757 priv->video_cnt++;
1759 if (ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
1760 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1761 info.short_name, strerror(errno));
1762 return 0;
1765 return NULL;
1768 #define MAX_LOOP 50
1769 static double grab_video_frame(priv_t *priv, char *buffer, int len)
1771 double interval;
1772 int loop_cnt = 0;
1774 if (priv->first) {
1775 pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1776 priv->first = 0;
1779 while (priv->video_cnt == 0) {
1780 usleep(10000);
1781 if (loop_cnt++ > MAX_LOOP) return 0;
1784 pthread_mutex_lock(&priv->video_buffer_mutex);
1785 interval = (double)priv->video_ringbuffer[priv->video_head].timestamp*1e-6;
1786 memcpy(buffer, priv->video_ringbuffer[priv->video_head].data, len);
1787 priv->video_cnt--;
1788 priv->video_head = (priv->video_head+1)%priv->video_buffer_size_current;
1789 pthread_mutex_unlock(&priv->video_buffer_mutex);
1791 return interval;
1794 static int get_video_framesize(priv_t *priv)
1797 this routine will be called before grab_video_frame
1798 thus let's return topmost frame's size
1800 if (priv->video_cnt)
1801 return priv->video_ringbuffer[priv->video_head].framesize;
1803 no video frames yet available. i don't know what to do in this case,
1804 thus let's return some fallback result (for compressed format this will be
1805 maximum allowed frame size.
1807 return priv->format.fmt.pix.sizeimage;
1810 //#define DOUBLESPEED
1811 #ifdef DOUBLESPEED
1812 // for testing purposes only
1813 static void read_doublespeed(priv_t *priv)
1815 char *bufx = calloc(priv->audio_in.blocksize, 2);
1816 short *s;
1817 short *d;
1818 int i;
1820 audio_in_read_chunk(&priv->audio_in, bufx);
1821 audio_in_read_chunk(&priv->audio_in, bufx+priv->audio_in.blocksize);
1823 s = bufx;
1824 d = priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize;
1825 for (i = 0; i < priv->audio_in.blocksize/2; i++) {
1826 *d++ = *s++;
1827 *s++;
1831 #endif
1833 static void *audio_grabber(void *data)
1835 priv_t *priv = (priv_t*)data;
1836 struct timeval tv;
1837 int i, audio_skew_ptr = 0;
1838 long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
1839 long long start_time_avg;
1841 gettimeofday(&tv, NULL);
1842 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1843 audio_in_start_capture(&priv->audio_in);
1844 for (i = 0; i < priv->aud_skew_cnt; i++)
1845 priv->audio_skew_buffer[i] = 0;
1846 for (i = 0; i < priv->aud_skew_cnt; i++)
1847 priv->audio_skew_delta_buffer[i] = 0;
1849 for (; !priv->shutdown;)
1851 #ifdef DOUBLESPEED
1852 read_doublespeed(priv);
1853 #else
1854 if (audio_in_read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize) < 0)
1855 continue;
1856 #endif
1857 pthread_mutex_lock(&priv->skew_mutex);
1858 if (priv->first_frame == 0) {
1859 // there is no first frame yet (unlikely to happen)
1860 gettimeofday(&tv, NULL);
1861 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1862 // fprintf(stderr, "warning - first frame not yet available!\n");
1863 pthread_mutex_unlock(&priv->skew_mutex);
1864 continue;
1866 pthread_mutex_unlock(&priv->skew_mutex);
1868 gettimeofday(&tv, NULL);
1870 priv->audio_recv_blocks_total++;
1871 current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
1873 if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
1874 start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1875 priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
1878 // fprintf(stderr, "spb = %f, bs = %d, skew = %f\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1879 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1881 // put the current skew into the ring buffer
1882 priv->audio_skew_total -= priv->audio_skew_buffer[audio_skew_ptr];
1883 priv->audio_skew_buffer[audio_skew_ptr] = current_time
1884 - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1885 priv->audio_skew_total += priv->audio_skew_buffer[audio_skew_ptr];
1887 pthread_mutex_lock(&priv->skew_mutex);
1889 // skew calculation
1891 // compute the sliding average of the skews
1892 if (priv->audio_recv_blocks_total > priv->aud_skew_cnt) {
1893 priv->audio_skew = priv->audio_skew_total/priv->aud_skew_cnt;
1894 } else {
1895 priv->audio_skew = priv->audio_skew_total/priv->audio_recv_blocks_total;
1898 // put the current skew change (skew-prev_skew) into the ring buffer
1899 priv->audio_skew_delta_total -= priv->audio_skew_delta_buffer[audio_skew_ptr];
1900 priv->audio_skew_delta_buffer[audio_skew_ptr] = priv->audio_skew - prev_skew_uncorr;
1901 priv->audio_skew_delta_total += priv->audio_skew_delta_buffer[audio_skew_ptr];
1902 prev_skew_uncorr = priv->audio_skew; // remember the _uncorrected_ average value
1904 audio_skew_ptr = (audio_skew_ptr+1) % priv->aud_skew_cnt; // rotate the buffer pointer
1906 // sliding average approximates the value in the middle of the interval
1907 // so interpolate the skew value further to the current time
1908 priv->audio_skew += priv->audio_skew_delta_total/2;
1910 // now finally, priv->audio_skew contains fairly good approximation
1911 // of the current value
1913 // current skew factor (assuming linearity)
1914 // used for further interpolation in video_grabber
1915 // probably overkill but seems to be necessary for
1916 // stress testing by dropping half of the audio frames ;)
1917 // especially when using ALSA with large block sizes
1918 // where audio_skew remains a long while behind
1919 if ((priv->audio_skew_measure_time != 0) && (current_time - priv->audio_skew_measure_time != 0)) {
1920 priv->audio_skew_factor = (double)(priv->audio_skew-prev_skew)/(current_time - priv->audio_skew_measure_time);
1921 } else {
1922 priv->audio_skew_factor = 0.0;
1925 priv->audio_skew_measure_time = current_time;
1926 prev_skew = priv->audio_skew;
1927 priv->audio_skew += priv->audio_start_time - priv->first_frame;
1928 pthread_mutex_unlock(&priv->skew_mutex);
1930 // fprintf(stderr, "audio_skew = %f, delta = %f\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1932 pthread_mutex_lock(&priv->audio_mutex);
1933 if ((priv->audio_tail+1) % priv->audio_buffer_size == priv->audio_head) {
1934 mp_msg(MSGT_TV, MSGL_ERR, "\ntoo bad - dropping audio frame !\n");
1935 priv->audio_drop++;
1936 } else {
1937 priv->audio_tail = (priv->audio_tail+1) % priv->audio_buffer_size;
1938 priv->audio_cnt++;
1940 pthread_mutex_unlock(&priv->audio_mutex);
1942 return NULL;
1945 static double grab_audio_frame(priv_t *priv, char *buffer, int len)
1947 mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1948 priv, buffer, len);
1950 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1951 // => switch to the mode which outputs audio immediately, even if
1952 // it should be silence
1953 if (priv->first) priv->audio_insert_null_samples = 1;
1955 pthread_mutex_lock(&priv->audio_mutex);
1956 while (priv->audio_insert_null_samples
1957 && priv->dropped_frames_timeshift - priv->dropped_frames_compensated >= priv->audio_usecs_per_block) {
1958 // some frames were dropped - drop the corresponding number of audio blocks
1959 if (priv->audio_drop) {
1960 priv->audio_drop--;
1961 } else {
1962 if (priv->audio_head == priv->audio_tail) break;
1963 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1965 priv->dropped_frames_compensated += priv->audio_usecs_per_block;
1968 // compensate for dropped audio frames
1969 if (priv->audio_drop && (priv->audio_head == priv->audio_tail)) {
1970 priv->audio_drop--;
1971 memset(buffer, 0, len);
1972 goto out;
1975 if (priv->audio_insert_null_samples && (priv->audio_head == priv->audio_tail)) {
1976 // return silence to avoid desync and stuttering
1977 memset(buffer, 0, len);
1978 priv->audio_null_blocks_inserted++;
1979 goto out;
1982 pthread_mutex_unlock(&priv->audio_mutex);
1983 while (priv->audio_head == priv->audio_tail) {
1984 // this is mencoder => just wait until some audio is available
1985 usleep(10000);
1987 pthread_mutex_lock(&priv->audio_mutex);
1988 memcpy(buffer, priv->audio_ringbuffer+priv->audio_head*priv->audio_in.blocksize, len);
1989 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1990 priv->audio_cnt--;
1991 out:
1992 pthread_mutex_unlock(&priv->audio_mutex);
1993 priv->audio_sent_blocks_total++;
1994 return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
1997 static int get_audio_framesize(priv_t *priv)
1999 return priv->audio_in.blocksize;