Simplify: use &= instead of a = b & a;
[mplayer/greg.git] / stream / tvi_v4l2.c
bloba47ea11400df9c2e77a84690101443b9074732de
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 "libmpcodecs/dec_teletext.h"
57 #include "libaf/af_format.h"
58 #include "tv.h"
59 #include "audio_in.h"
61 #define info tvi_info_v4l2
62 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param);
63 /* information about this file */
64 const tvi_info_t tvi_info_v4l2 = {
65 tvi_init_v4l2,
66 "Video 4 Linux 2 input",
67 "v4l2",
68 "Martin Olschewski <olschewski@zpr.uni-koeln.de>",
69 "first try, more to come ;-)"
72 struct map {
73 struct v4l2_buffer buf;
74 void *addr;
75 size_t len;
78 #define BUFFER_COUNT 6
80 /** video ringbuffer entry */
81 typedef struct {
82 unsigned char *data; ///< frame contents
83 long long timestamp; ///< frame timestamp
84 int framesize; ///< actual frame size
85 } video_buffer_entry;
87 /* private data */
88 typedef struct {
89 /* video */
90 char *video_dev;
91 int video_fd;
92 #ifdef CONFIG_TV_TELETEXT
93 char *vbi_dev;
94 int vbi_fd;
95 int vbi_bufsize;
96 int vbi_shutdown;
97 pthread_t vbi_grabber_thread;
98 void *priv_vbi;
99 #endif
100 int mp_format;
101 struct v4l2_capability capability;
102 struct v4l2_input input;
103 struct v4l2_format format;
104 struct v4l2_standard standard;
105 struct v4l2_tuner tuner;
106 struct map *map;
107 int mapcount;
108 int frames;
109 volatile long long first_frame;
110 long long curr_frame;
111 /* audio video interleaving ;-) */
112 volatile int streamon;
113 pthread_t audio_grabber_thread;
114 pthread_mutex_t skew_mutex;
116 /* 2nd level video buffers */
117 int first;
118 int immediate_mode;
120 int video_buffer_size_max;
121 volatile int video_buffer_size_current;
122 video_buffer_entry *video_ringbuffer;
123 volatile int video_head;
124 volatile int video_tail;
125 volatile int video_cnt;
126 pthread_t video_grabber_thread;
127 pthread_mutex_t video_buffer_mutex;
129 /* audio */
130 char *audio_dev;
131 audio_in_t audio_in;
133 long long audio_start_time;
134 int audio_buffer_size;
135 int aud_skew_cnt;
136 unsigned char *audio_ringbuffer;
137 long long *audio_skew_buffer;
138 long long *audio_skew_delta_buffer;
139 volatile int audio_head;
140 volatile int audio_tail;
141 volatile int audio_cnt;
142 volatile long long audio_skew;
143 volatile double audio_skew_factor;
144 volatile long long audio_skew_measure_time;
145 volatile int audio_drop;
146 volatile int shutdown;
148 int audio_initialized;
149 double audio_secs_per_block;
150 long long audio_usecs_per_block;
151 long long audio_skew_total;
152 long long audio_skew_delta_total;
153 long audio_recv_blocks_total;
154 long audio_sent_blocks_total;
155 pthread_mutex_t audio_mutex;
156 int audio_insert_null_samples;
157 volatile long audio_null_blocks_inserted;
158 volatile long long dropped_frames_timeshift;
159 long long dropped_frames_compensated;
161 tv_param_t *tv_param;
162 } priv_t;
164 #include "tvi_def.h"
166 static void *audio_grabber(void *data);
167 static void *video_grabber(void *data);
169 /**********************************************************************\
171 Only few of the fourccs are the same in v4l2 and mplayer:
173 IMGFMT_YVU9 == V4L2_PIX_FMT_YVU410
174 IMGFMT_YV12 == V4L2_PIX_FMT_YVU420
175 IMGFMT_NV12 == V4L2_PIX_FMT_NV12
176 IMGFMT_422P == V4L2_PIX_FMT_YUV422P
177 IMGFMT_411P == V4L2_PIX_FMT_YUV411P
178 IMGFMT_UYVY == V4L2_PIX_FMT_UYVY
179 IMGFMT_Y41P == V4L2_PIX_FMT_Y41P
181 This may be an useful translation table for some others:
183 IMGFMT_RGB8 == V4L2_PIX_FMT_RGB332
184 IMGFMT_BGR15 == V4L2_PIX_FMT_RGB555
185 IMGFMT_BGR16 == V4L2_PIX_FMT_RGB565
186 IMGFMT_RGB24 == V4L2_PIX_FMT_RGB24
187 IMGFMT_RGB32 == V4L2_PIX_FMT_RGB32
188 IMGFMT_BGR24 == V4L2_PIX_FMT_BGR24
189 IMGFMT_BGR32 == V4L2_PIX_FMT_BGR32
190 IMGFMT_Y800 == V4L2_PIX_FMT_GREY
191 IMGFMT_IF09 == V4L2_PIX_FMT_YUV410
192 IMGFMT_I420 == V4L2_PIX_FMT_YUV420
193 IMGFMT_YUY2 == V4L2_PIX_FMT_YUYV
195 \**********************************************************************/
198 ** Translate a mplayer fourcc to a video4linux2 pixel format.
200 static int fcc_mp2vl(int fcc)
202 switch (fcc) {
203 case IMGFMT_RGB8: return V4L2_PIX_FMT_RGB332;
204 case IMGFMT_BGR15: return V4L2_PIX_FMT_RGB555;
205 case IMGFMT_BGR16: return V4L2_PIX_FMT_RGB565;
206 case IMGFMT_RGB24: return V4L2_PIX_FMT_RGB24;
207 case IMGFMT_RGB32: return V4L2_PIX_FMT_RGB32;
208 case IMGFMT_BGR24: return V4L2_PIX_FMT_BGR24;
209 case IMGFMT_BGR32: return V4L2_PIX_FMT_BGR32;
210 case IMGFMT_Y800: return V4L2_PIX_FMT_GREY;
211 case IMGFMT_IF09: return V4L2_PIX_FMT_YUV410;
212 case IMGFMT_I420: return V4L2_PIX_FMT_YUV420;
213 case IMGFMT_YUY2: return V4L2_PIX_FMT_YUYV;
214 case IMGFMT_YV12: return V4L2_PIX_FMT_YVU420;
215 case IMGFMT_UYVY: return V4L2_PIX_FMT_UYVY;
216 case IMGFMT_MJPEG: return V4L2_PIX_FMT_MJPEG;
218 return fcc;
222 ** Translate a video4linux2 fourcc aka pixel format to mplayer.
224 static int fcc_vl2mp(int fcc)
226 switch (fcc) {
227 case V4L2_PIX_FMT_RGB332: return IMGFMT_RGB8;
228 case V4L2_PIX_FMT_RGB555: return IMGFMT_BGR15;
229 case V4L2_PIX_FMT_RGB565: return IMGFMT_BGR16;
230 case V4L2_PIX_FMT_RGB24: return IMGFMT_RGB24;
231 case V4L2_PIX_FMT_RGB32: return IMGFMT_RGB32;
232 case V4L2_PIX_FMT_BGR24: return IMGFMT_BGR24;
233 case V4L2_PIX_FMT_BGR32: return IMGFMT_BGR32;
234 case V4L2_PIX_FMT_GREY: return IMGFMT_Y800;
235 case V4L2_PIX_FMT_YUV410: return IMGFMT_IF09;
236 case V4L2_PIX_FMT_YUV420: return IMGFMT_I420;
237 case V4L2_PIX_FMT_YVU420: return IMGFMT_YV12;
238 case V4L2_PIX_FMT_YUYV: return IMGFMT_YUY2;
239 case V4L2_PIX_FMT_UYVY: return IMGFMT_UYVY;
240 case V4L2_PIX_FMT_MJPEG: return IMGFMT_MJPEG;
242 return fcc;
246 ** Translate a video4linux2 fourcc aka pixel format
247 ** to a human readable string.
249 static const char *pixfmt2name(int pixfmt)
251 static char unknown[24];
253 switch (pixfmt) {
254 case V4L2_PIX_FMT_RGB332: return "RGB332";
255 case V4L2_PIX_FMT_RGB555: return "RGB555";
256 case V4L2_PIX_FMT_RGB565: return "RGB565";
257 case V4L2_PIX_FMT_RGB555X: return "RGB555X";
258 case V4L2_PIX_FMT_RGB565X: return "RGB565X";
259 case V4L2_PIX_FMT_BGR24: return "BGR24";
260 case V4L2_PIX_FMT_RGB24: return "RGB24";
261 case V4L2_PIX_FMT_BGR32: return "BGR32";
262 case V4L2_PIX_FMT_RGB32: return "RGB32";
263 case V4L2_PIX_FMT_GREY: return "GREY";
264 case V4L2_PIX_FMT_YVU410: return "YVU410";
265 case V4L2_PIX_FMT_YVU420: return "YVU420";
266 case V4L2_PIX_FMT_YUYV: return "YUYV";
267 case V4L2_PIX_FMT_UYVY: return "UYVY";
268 /* case V4L2_PIX_FMT_YVU422P: return "YVU422P"; */
269 /* case V4L2_PIX_FMT_YVU411P: return "YVU411P"; */
270 case V4L2_PIX_FMT_YUV422P: return "YUV422P";
271 case V4L2_PIX_FMT_YUV411P: return "YUV411P";
272 case V4L2_PIX_FMT_Y41P: return "Y41P";
273 case V4L2_PIX_FMT_NV12: return "NV12";
274 case V4L2_PIX_FMT_NV21: return "NV21";
275 case V4L2_PIX_FMT_YUV410: return "YUV410";
276 case V4L2_PIX_FMT_YUV420: return "YUV420";
277 case V4L2_PIX_FMT_YYUV: return "YYUV";
278 case V4L2_PIX_FMT_HI240: return "HI240";
279 case V4L2_PIX_FMT_WNVA: return "WNVA";
280 case V4L2_PIX_FMT_MJPEG: return "MJPEG";
282 sprintf(unknown, "unknown (0x%x)", pixfmt);
283 return unknown;
288 ** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
290 static int pixfmt2depth(int pixfmt)
292 switch (pixfmt) {
293 case V4L2_PIX_FMT_RGB332:
294 return 8;
295 case V4L2_PIX_FMT_RGB555:
296 case V4L2_PIX_FMT_RGB565:
297 case V4L2_PIX_FMT_RGB555X:
298 case V4L2_PIX_FMT_RGB565X:
299 return 16;
300 case V4L2_PIX_FMT_BGR24:
301 case V4L2_PIX_FMT_RGB24:
302 return 24;
303 case V4L2_PIX_FMT_BGR32:
304 case V4L2_PIX_FMT_RGB32:
305 return 32;
306 case V4L2_PIX_FMT_GREY:
307 return 8;
308 case V4L2_PIX_FMT_YVU410:
309 return 9;
310 case V4L2_PIX_FMT_YVU420:
311 return 12;
312 case V4L2_PIX_FMT_YUYV:
313 case V4L2_PIX_FMT_UYVY:
314 case V4L2_PIX_FMT_YUV422P:
315 case V4L2_PIX_FMT_YUV411P:
316 return 16;
317 case V4L2_PIX_FMT_Y41P:
318 case V4L2_PIX_FMT_NV12:
319 case V4L2_PIX_FMT_NV21:
320 return 12;
321 case V4L2_PIX_FMT_YUV410:
322 return 9;
323 case V4L2_PIX_FMT_YUV420:
324 return 12;
325 case V4L2_PIX_FMT_YYUV:
326 return 16;
327 case V4L2_PIX_FMT_HI240:
328 return 8;
331 return 0;
334 static int amode2v4l(int amode)
336 switch (amode) {
337 case 0:
338 return V4L2_TUNER_MODE_MONO;
339 case 1:
340 return V4L2_TUNER_MODE_STEREO;
341 case 2:
342 return V4L2_TUNER_MODE_LANG1;
343 case 3:
344 return V4L2_TUNER_MODE_LANG2;
345 default:
346 return -1;
352 ** Get current FPS.
354 static double getfps(priv_t *priv)
356 if (priv->tv_param->fps > 0)
357 return priv->tv_param->fps;
358 if (priv->standard.frameperiod.denominator && priv->standard.frameperiod.numerator)
359 return (double)priv->standard.frameperiod.denominator / priv->standard.frameperiod.numerator;
360 return 25.0;
363 // sets and sanitizes audio buffer/block sizes
364 static void setup_audio_buffer_sizes(priv_t *priv)
366 int bytes_per_sample = priv->audio_in.bytes_per_sample;
367 int seconds = priv->video_buffer_size_max/getfps(priv);
369 if (seconds < 5) seconds = 5;
370 if (seconds > 500) seconds = 500;
372 // make the audio buffer at least as the video buffer capacity (or 5 seconds) long
373 priv->audio_buffer_size = 1 + seconds*priv->audio_in.samplerate
374 *priv->audio_in.channels
375 *bytes_per_sample/priv->audio_in.blocksize;
376 if (priv->audio_buffer_size < 256) priv->audio_buffer_size = 256;
378 // make the skew buffer at least 1 second long
379 priv->aud_skew_cnt = 1 + 1*priv->audio_in.samplerate
380 *priv->audio_in.channels
381 *bytes_per_sample/priv->audio_in.blocksize;
382 if (priv->aud_skew_cnt < 16) priv->aud_skew_cnt = 16;
384 mp_msg(MSGT_TV, MSGL_V, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
385 priv->audio_buffer_size, priv->audio_in.blocksize, priv->aud_skew_cnt);
388 static void init_audio(priv_t *priv)
390 if (priv->audio_initialized) return;
392 if (!priv->tv_param->noaudio) {
393 #ifdef CONFIG_ALSA
394 if (priv->tv_param->alsa)
395 audio_in_init(&priv->audio_in, AUDIO_IN_ALSA);
396 else
397 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
398 #else
399 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
400 #endif
402 if (priv->audio_dev) {
403 audio_in_set_device(&priv->audio_in, priv->audio_dev);
406 audio_in_set_samplerate(&priv->audio_in, 44100);
407 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
408 if (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) {
409 audio_in_set_channels(&priv->audio_in, 2);
410 } else {
411 audio_in_set_channels(&priv->audio_in, 1);
413 } else {
414 if (priv->tv_param->forcechan >= 0) {
415 audio_in_set_channels(&priv->audio_in, priv->tv_param->forcechan);
416 } else {
417 audio_in_set_channels(&priv->audio_in, 2);
421 if (audio_in_setup(&priv->audio_in) < 0) return;
423 priv->audio_initialized = 1;
427 #if 0
429 ** the number of milliseconds elapsed between time0 and time1
431 static size_t difftv(struct timeval time1, struct timeval time0)
433 return (time1.tv_sec - time0.tv_sec) * 1000 +
434 (time1.tv_usec - time0.tv_usec) / 1000;
436 #endif
439 ** Get current video capture format.
441 static int getfmt(priv_t *priv)
443 int i;
445 priv->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
446 if ((i = ioctl(priv->video_fd, VIDIOC_G_FMT, &priv->format)) < 0) {
447 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get format failed: %s\n",
448 info.short_name, strerror(errno));
450 return i;
455 ** Get current video capture standard.
457 static int getstd(priv_t *priv)
459 v4l2_std_id id;
460 int i=0;
462 if (ioctl(priv->video_fd, VIDIOC_G_STD, &id) < 0) {
463 struct v4l2_streamparm parm;
465 parm.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
466 if(ioctl(priv->video_fd, VIDIOC_G_PARM, &parm) >= 0) {
467 mp_msg(MSGT_TV, MSGL_WARN, "%s: your device driver does not support VIDIOC_G_STD ioctl,"
468 " VIDIOC_G_PARM was used instead.\n", info.short_name);
469 priv->standard.index=0;
470 priv->standard.id=0;
471 priv->standard.frameperiod=parm.parm.capture.timeperframe;
472 return 0;
475 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get standard failed: %s\n",
476 info.short_name, strerror(errno));
477 return -1;
479 do {
480 priv->standard.index = i++;
481 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
482 return -1;
484 } while (priv->standard.id != id);
485 return 0;
488 /***********************************************************************\
491 * Interface to mplayer *
494 \***********************************************************************/
496 static int set_mute(priv_t *priv, int value)
498 struct v4l2_control control;
499 control.id = V4L2_CID_AUDIO_MUTE;
500 control.value = value;
501 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, &control) < 0) {
502 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set mute failed: %s\n",
503 info.short_name, strerror(errno));
504 return 0;
506 return 1;
510 ** MPlayer uses values from -100 up to 100 for controls.
511 ** Here they are scaled to what the tv card needs and applied.
513 static int set_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
514 struct v4l2_queryctrl qctrl;
515 qctrl.id = control->id;
516 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
517 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
518 info.short_name, strerror(errno));
519 return TVI_CONTROL_FALSE;
522 if (val_signed) {
523 if (control->value < 0) {
524 control->value = qctrl.default_value + control->value *
525 (qctrl.default_value - qctrl.minimum) / 100;
526 } else {
527 control->value = qctrl.default_value + control->value *
528 (qctrl.maximum - qctrl.default_value) / 100;
530 } else {
531 if (control->value < 50) {
532 control->value = qctrl.default_value + (control->value-50) *
533 (qctrl.default_value - qctrl.minimum) / 50;
534 } else {
535 control->value = qctrl.default_value + (control->value-50) *
536 (qctrl.maximum - qctrl.default_value) / 50;
541 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, control) < 0) {
542 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl set %s %d failed: %s\n",
543 info.short_name, qctrl.name, control->value, strerror(errno));
544 return TVI_CONTROL_FALSE;
546 mp_msg(MSGT_TV, MSGL_V, "%s: set %s: %d [%d, %d]\n", info.short_name,
547 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
549 return TVI_CONTROL_TRUE;
554 ** Scale the control values back to what mplayer needs.
556 static int get_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
557 struct v4l2_queryctrl qctrl;
559 qctrl.id = control->id;
560 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
561 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
562 info.short_name, strerror(errno));
563 return TVI_CONTROL_FALSE;
566 if (ioctl(priv->video_fd, VIDIOC_G_CTRL, control) < 0) {
567 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl get %s failed: %s\n",
568 info.short_name, qctrl.name, strerror(errno));
569 return TVI_CONTROL_FALSE;
571 mp_msg(MSGT_TV, MSGL_V, "%s: get %s: %d [%d, %d]\n", info.short_name,
572 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
574 if (val_signed) {
575 if (control->value < qctrl.default_value) {
576 control->value = (control->value - qctrl.default_value) * 100 /
577 (qctrl.default_value - qctrl.minimum);
578 } else {
579 control->value = (control->value - qctrl.default_value) * 100 /
580 (qctrl.maximum - qctrl.default_value);
582 } else {
583 if (control->value < qctrl.default_value) {
584 control->value = (control->value - qctrl.default_value) * 50 /
585 (qctrl.default_value - qctrl.minimum) + 50;
586 } else {
587 control->value = (control->value - qctrl.default_value) * 50 /
588 (qctrl.maximum - qctrl.default_value) + 50;
592 return TVI_CONTROL_TRUE;
595 #ifdef CONFIG_TV_TELETEXT
596 static int vbi_init(priv_t* priv,char* device)
598 int vbi_fd=0;
599 struct v4l2_capability cap;
600 struct v4l2_format fmt;
601 int res;
603 if(!device)
604 return TVI_CONTROL_FALSE;
606 priv->vbi_dev=strdup(device);
608 vbi_fd=open(priv->vbi_dev,O_RDWR);
609 if(vbi_fd<0){
610 mp_msg(MSGT_TV,MSGL_ERR,"vbi: could not open device %s\n",priv->vbi_dev);
611 return TVI_CONTROL_FALSE;
614 if(ioctl(vbi_fd,VIDIOC_QUERYCAP,&cap)<0){
615 mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query capatibilities failed for %s\n",priv->vbi_dev);
616 close(vbi_fd);
617 return TVI_CONTROL_FALSE;
619 if(!cap.capabilities & V4L2_CAP_VBI_CAPTURE){
620 mp_msg(MSGT_TV,MSGL_ERR,"vbi: %s does not support VBI capture\n",priv->vbi_dev);
621 close(vbi_fd);
622 return TVI_CONTROL_FALSE;
625 memset(&fmt,0,sizeof(struct v4l2_format));
626 fmt.type=V4L2_BUF_TYPE_VBI_CAPTURE;
627 if((res=ioctl(vbi_fd,VIDIOC_G_FMT,&fmt))<0){
628 mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query format failed: %x\n",res);
629 close(vbi_fd);
630 return TVI_CONTROL_FALSE;
632 if(fmt.fmt.vbi.sample_format!=V4L2_PIX_FMT_GREY){
633 mp_msg(MSGT_TV,MSGL_ERR,"vbi: format 0x%x is not supported\n",fmt.fmt.vbi.sample_format);
634 close(vbi_fd);
635 return TVI_CONTROL_FALSE;
637 priv->vbi_fd=vbi_fd;
638 mp_msg(MSGT_TV,MSGL_DBG3,"vbi: init ok\n");
639 return TVI_CONTROL_TRUE;
642 static int vbi_get_props(priv_t* priv,tt_stream_props* ptsp)
644 struct v4l2_format fmt;
645 int res;
646 if(!priv || !ptsp)
647 return TVI_CONTROL_FALSE;
649 memset(&fmt,0,sizeof(struct v4l2_format));
650 fmt.type=V4L2_BUF_TYPE_VBI_CAPTURE;
651 if((res=ioctl(priv->vbi_fd,VIDIOC_G_FMT,&fmt))<0){
652 mp_msg(MSGT_TV,MSGL_ERR,"vbi_get_props: Query format failed: %x\n",res);
653 return TVI_CONTROL_FALSE;
656 ptsp->interlaced=(fmt.fmt.vbi.flags& V4L2_VBI_INTERLACED?1:0);
658 ptsp->offset=fmt.fmt.vbi.offset;
659 ptsp->sampling_rate=fmt.fmt.vbi.sampling_rate;
660 ptsp->samples_per_line=fmt.fmt.vbi.samples_per_line,
662 ptsp->count[0]=fmt.fmt.vbi.count[0];
663 ptsp->count[1]=fmt.fmt.vbi.count[1];
664 ptsp->bufsize = ptsp->samples_per_line * (ptsp->count[0] + ptsp->count[1]);
666 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",
667 ptsp->sampling_rate,
668 ptsp->offset,
669 ptsp->samples_per_line,
670 ptsp->interlaced?"Yes":"No",
671 ptsp->count[0],
672 ptsp->count[1]);
674 return TVI_CONTROL_TRUE;
677 static void *vbi_grabber(void *data)
679 priv_t *priv = (priv_t *) data;
680 int bytes,seq,prev_seq;
681 unsigned char* buf;
682 tt_stream_props tsp;
684 if(!priv->priv_vbi){
685 mp_msg(MSGT_TV,MSGL_WARN,"vbi: vbi not initialized. stopping thread.\n");
686 return NULL;
689 if(vbi_get_props(priv,&tsp)!=TVI_CONTROL_TRUE)
690 return NULL;
692 buf=malloc(tsp.bufsize);
693 seq=0;
694 prev_seq=0;
695 mp_msg(MSGT_TV,MSGL_V,"vbi: vbi capture thread started.\n");
697 while (!priv->vbi_shutdown){
698 bytes=read(priv->vbi_fd,buf,tsp.bufsize);
699 if(bytes<0 && errno==EINTR)
700 continue;
701 if (bytes!=tsp.bufsize){
702 mp_msg(MSGT_TV,MSGL_WARN,"vbi: expecting bytes: %d, got: %d\n",tsp.bufsize,bytes);
703 break;
705 seq=*(int*)(buf+bytes-4);
706 if(seq<=1) continue;
707 if (prev_seq && seq!=prev_seq+1){
708 prev_seq=0;
709 seq=0;
711 prev_seq=seq;
712 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_DECODE_PAGE,&buf);
713 mp_msg(MSGT_TV,MSGL_DBG3,"grabber: seq:%d\n",seq);
715 free(buf);
716 return NULL;
718 #endif /* CONFIG_TV_TELETEXT */
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 if (!priv->standard.frameperiod.denominator || !priv->standard.frameperiod.numerator) {
739 mp_msg(MSGT_TV, MSGL_ERR, "%s: Cannot get fps\n", info.short_name);
740 return TVI_CONTROL_FALSE;
742 *(float *)arg = (float)priv->standard.frameperiod.denominator /
743 priv->standard.frameperiod.numerator;
744 mp_msg(MSGT_TV, MSGL_V, "%s: get fps: %f\n", info.short_name,
745 *(float *)arg);
746 return TVI_CONTROL_TRUE;
747 case TVI_CONTROL_VID_GET_BITS:
748 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
749 *(int *)arg = pixfmt2depth(priv->format.fmt.pix.pixelformat);
750 mp_msg(MSGT_TV, MSGL_V, "%s: get depth: %d\n", info.short_name,
751 *(int *)arg);
752 return TVI_CONTROL_TRUE;
753 case TVI_CONTROL_VID_GET_FORMAT:
754 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
755 *(int *)arg = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
756 mp_msg(MSGT_TV, MSGL_V, "%s: get format: %s\n", info.short_name,
757 pixfmt2name(priv->format.fmt.pix.pixelformat));
758 return TVI_CONTROL_TRUE;
759 case TVI_CONTROL_VID_SET_FORMAT:
760 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
761 priv->format.fmt.pix.pixelformat = fcc_mp2vl(*(int *)arg);
762 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
764 priv->mp_format = *(int *)arg;
765 mp_msg(MSGT_TV, MSGL_V, "%s: set format: %s\n", info.short_name,
766 pixfmt2name(priv->format.fmt.pix.pixelformat));
767 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
768 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
769 info.short_name, strerror(errno));
770 return TVI_CONTROL_FALSE;
772 /* according to the v4l2 specs VIDIOC_S_FMT should not fail, inflexible drivers
773 might even always return the default parameters -> update the format here*/
774 priv->mp_format = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
775 return TVI_CONTROL_TRUE;
776 case TVI_CONTROL_VID_GET_WIDTH:
777 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
778 *(int *)arg = priv->format.fmt.pix.width;
779 mp_msg(MSGT_TV, MSGL_V, "%s: get width: %d\n", info.short_name,
780 *(int *)arg);
781 return TVI_CONTROL_TRUE;
782 case TVI_CONTROL_VID_CHK_WIDTH:
783 return TVI_CONTROL_TRUE;
784 case TVI_CONTROL_VID_SET_WIDTH_HEIGHT:
785 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
786 priv->format.fmt.pix.width = ((int *)arg)[0];
787 priv->format.fmt.pix.height = ((int *)arg)[1];
788 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
789 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0)
790 return TVI_CONTROL_FALSE;
791 return TVI_CONTROL_TRUE;
792 case TVI_CONTROL_VID_SET_WIDTH:
793 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
794 priv->format.fmt.pix.width = *(int *)arg;
795 mp_msg(MSGT_TV, MSGL_V, "%s: set width: %d\n", info.short_name,
796 *(int *)arg);
797 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
798 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set width failed: %s\n",
799 info.short_name, strerror(errno));
800 return TVI_CONTROL_FALSE;
802 return TVI_CONTROL_TRUE;
803 case TVI_CONTROL_VID_GET_HEIGHT:
804 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
805 *(int *)arg = priv->format.fmt.pix.height;
806 mp_msg(MSGT_TV, MSGL_V, "%s: get height: %d\n", info.short_name,
807 *(int *)arg);
808 return TVI_CONTROL_TRUE;
809 case TVI_CONTROL_VID_CHK_HEIGHT:
810 return TVI_CONTROL_TRUE;
811 case TVI_CONTROL_VID_SET_HEIGHT:
812 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
813 priv->format.fmt.pix.height = *(int *)arg;
814 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
815 mp_msg(MSGT_TV, MSGL_V, "%s: set height: %d\n", info.short_name,
816 *(int *)arg);
817 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
818 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set height failed: %s\n",
819 info.short_name, strerror(errno));
820 return TVI_CONTROL_FALSE;
822 return TVI_CONTROL_TRUE;
823 case TVI_CONTROL_VID_GET_BRIGHTNESS:
824 control.id = V4L2_CID_BRIGHTNESS;
825 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
826 *(int *)arg = control.value;
827 return TVI_CONTROL_TRUE;
829 return TVI_CONTROL_FALSE;
830 case TVI_CONTROL_VID_SET_BRIGHTNESS:
831 control.id = V4L2_CID_BRIGHTNESS;
832 control.value = *(int *)arg;
833 return set_control(priv, &control, 1);
834 case TVI_CONTROL_VID_GET_HUE:
835 control.id = V4L2_CID_HUE;
836 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
837 *(int *)arg = control.value;
838 return TVI_CONTROL_TRUE;
840 return TVI_CONTROL_FALSE;
841 case TVI_CONTROL_VID_SET_HUE:
842 control.id = V4L2_CID_HUE;
843 control.value = *(int *)arg;
844 return set_control(priv, &control, 1);
845 case TVI_CONTROL_VID_GET_SATURATION:
846 control.id = V4L2_CID_SATURATION;
847 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
848 *(int *)arg = control.value;
849 return TVI_CONTROL_TRUE;
851 return TVI_CONTROL_FALSE;
852 case TVI_CONTROL_VID_SET_SATURATION:
853 control.id = V4L2_CID_SATURATION;
854 control.value = *(int *)arg;
855 return set_control(priv, &control, 1);
856 case TVI_CONTROL_VID_GET_GAIN:
859 control.id = V4L2_CID_AUTOGAIN;
860 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
861 return TVI_CONTROL_FALSE;
863 if(control.value){ //Auto Gain control is enabled
864 *(int*)arg=0;
865 return TVI_CONTROL_TRUE;
868 //Manual Gain control
869 control.id = V4L2_CID_GAIN;
870 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
871 return TVI_CONTROL_FALSE;
873 *(int*)arg=control.value?control.value:1;
875 return TVI_CONTROL_TRUE;
877 case TVI_CONTROL_VID_SET_GAIN:
879 //value==0 means automatic gain control
880 int value=*(int*)arg;
882 if (value < 0 || value>100)
883 return TVI_CONTROL_FALSE;
885 control.id=value?V4L2_CID_GAIN:V4L2_CID_AUTOGAIN;
886 control.value=value?value:1;
888 return set_control(priv,&control,0);
890 case TVI_CONTROL_VID_GET_CONTRAST:
891 control.id = V4L2_CID_CONTRAST;
892 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
893 *(int *)arg = control.value;
894 return TVI_CONTROL_TRUE;
896 return TVI_CONTROL_FALSE;
897 case TVI_CONTROL_VID_SET_CONTRAST:
898 control.id = V4L2_CID_CONTRAST;
899 control.value = *(int *)arg;
900 return set_control(priv, &control, 1);
901 case TVI_CONTROL_TUN_GET_FREQ:
902 frequency.tuner = 0;
903 frequency.type = V4L2_TUNER_ANALOG_TV;
904 if (ioctl(priv->video_fd, VIDIOC_G_FREQUENCY, &frequency) < 0) {
905 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl get frequency failed: %s\n",
906 info.short_name, strerror(errno));
907 return TVI_CONTROL_FALSE;
909 *(int *)arg = frequency.frequency;
910 return TVI_CONTROL_TRUE;
911 case TVI_CONTROL_TUN_SET_FREQ:
912 #if 0
913 set_mute(priv, 1);
914 usleep(100000); // wait to suppress noise during switching
915 #endif
916 frequency.tuner = 0;
917 frequency.type = V4L2_TUNER_ANALOG_TV;
918 frequency.frequency = *(int *)arg;
919 if (ioctl(priv->video_fd, VIDIOC_S_FREQUENCY, &frequency) < 0) {
920 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set frequency failed: %s\n",
921 info.short_name, strerror(errno));
922 return TVI_CONTROL_FALSE;
924 #if 0
925 usleep(100000); // wait to suppress noise during switching
926 set_mute(priv, 0);
927 #endif
928 return TVI_CONTROL_TRUE;
929 case TVI_CONTROL_TUN_GET_TUNER:
930 mp_msg(MSGT_TV, MSGL_V, "%s: get tuner\n",info.short_name);
931 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
932 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
933 info.short_name, strerror(errno));
934 return TVI_CONTROL_FALSE;
936 return TVI_CONTROL_TRUE;
937 case TVI_CONTROL_TUN_SET_TUNER:
938 mp_msg(MSGT_TV, MSGL_V, "%s: set tuner\n",info.short_name);
939 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
940 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
941 info.short_name, strerror(errno));
942 return TVI_CONTROL_FALSE;
944 return TVI_CONTROL_TRUE;
945 case TVI_CONTROL_TUN_GET_NORM:
946 *(int *)arg = priv->standard.index;
947 return TVI_CONTROL_TRUE;
948 case TVI_CONTROL_TUN_GET_SIGNAL:
949 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
950 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
951 info.short_name, strerror(errno));
952 return TVI_CONTROL_FALSE;
954 *(int*)arg=100*(priv->tuner.signal>>8)/255;
955 return TVI_CONTROL_TRUE;
956 case TVI_CONTROL_TUN_SET_NORM:
957 priv->standard.index = *(int *)arg;
958 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
959 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum norm failed: %s\n",
960 info.short_name, strerror(errno));
961 return TVI_CONTROL_FALSE;
963 mp_msg(MSGT_TV, MSGL_V, "%s: set norm: %s\n", info.short_name, priv->standard.name);
964 if (ioctl(priv->video_fd, VIDIOC_S_STD, &priv->standard.id) < 0) {
965 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set norm failed: %s\n",
966 info.short_name, strerror(errno));
967 return TVI_CONTROL_FALSE;
969 return TVI_CONTROL_TRUE;
970 case TVI_CONTROL_SPC_GET_NORMID:
972 int i;
973 for (i = 0;; i++) {
974 struct v4l2_standard standard;
975 memset(&standard, 0, sizeof(standard));
976 standard.index = i;
977 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
978 return TVI_CONTROL_FALSE;
979 if (!strcasecmp(standard.name, (char *)arg)) {
980 *(int *)arg = i;
981 return TVI_CONTROL_TRUE;
984 return TVI_CONTROL_FALSE;
986 case TVI_CONTROL_SPC_GET_INPUT:
987 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, (int *)arg) < 0) {
988 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
989 info.short_name, strerror(errno));
990 return TVI_CONTROL_FALSE;
992 return TVI_CONTROL_TRUE;
993 case TVI_CONTROL_SPC_SET_INPUT:
994 mp_msg(MSGT_TV, MSGL_V, "%s: set input: %d\n", info.short_name, *(int *)arg);
995 priv->input.index = *(int *)arg;
996 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &priv->input) < 0) {
997 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum input failed: %s\n",
998 info.short_name, strerror(errno));
999 return TVI_CONTROL_FALSE;
1001 if (ioctl(priv->video_fd, VIDIOC_S_INPUT, (int *)arg) < 0) {
1002 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set input failed: %s\n",
1003 info.short_name, strerror(errno));
1004 return TVI_CONTROL_FALSE;
1006 return TVI_CONTROL_TRUE;
1007 case TVI_CONTROL_AUD_GET_FORMAT:
1008 init_audio(priv);
1009 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1010 *(int *)arg = AF_FORMAT_S16_LE;
1011 mp_msg(MSGT_TV, MSGL_V, "%s: get audio format: %d\n",
1012 info.short_name, *(int *)arg);
1013 return TVI_CONTROL_TRUE;
1014 case TVI_CONTROL_AUD_GET_SAMPLERATE:
1015 init_audio(priv);
1016 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1017 *(int *)arg = priv->audio_in.samplerate;
1018 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplerate: %d\n",
1019 info.short_name, *(int *)arg);
1020 return TVI_CONTROL_TRUE;
1021 case TVI_CONTROL_AUD_GET_SAMPLESIZE:
1022 init_audio(priv);
1023 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1024 *(int *)arg = priv->audio_in.bytes_per_sample;
1025 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplesize: %d\n",
1026 info.short_name, *(int *)arg);
1027 return TVI_CONTROL_TRUE;
1028 case TVI_CONTROL_AUD_GET_CHANNELS:
1029 init_audio(priv);
1030 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1031 *(int *)arg = priv->audio_in.channels;
1032 mp_msg(MSGT_TV, MSGL_V, "%s: get audio channels: %d\n",
1033 info.short_name, *(int *)arg);
1034 return TVI_CONTROL_TRUE;
1035 case TVI_CONTROL_AUD_SET_SAMPLERATE:
1036 init_audio(priv);
1037 mp_msg(MSGT_TV, MSGL_V, "%s: set audio samplerate: %d\n",
1038 info.short_name, *(int *)arg);
1039 if (audio_in_set_samplerate(&priv->audio_in, *(int*)arg) < 0) return TVI_CONTROL_FALSE;
1040 // setup_audio_buffer_sizes(priv);
1041 return TVI_CONTROL_TRUE;
1042 #ifdef CONFIG_TV_TELETEXT
1043 case TVI_CONTROL_VBI_INIT:
1045 void* ptr;
1046 tt_stream_props tsp;
1048 if (vbi_init(priv,*(char**)arg)!=TVI_CONTROL_TRUE)
1049 return TVI_CONTROL_FALSE;
1050 if(vbi_get_props(priv,&tsp)==TVI_CONTROL_TRUE)
1052 ptr=&tsp;
1053 if(teletext_control(NULL,TV_VBI_CONTROL_START,&ptr)==VBI_CONTROL_TRUE)
1054 priv->priv_vbi=ptr;
1055 else
1056 priv->priv_vbi=NULL;
1058 return TVI_CONTROL_TRUE;
1060 default:
1061 return teletext_control(priv->priv_vbi,cmd,arg);
1062 #endif
1064 mp_msg(MSGT_TV, MSGL_V, "%s: unknown control: %d\n", info.short_name, cmd);
1065 return TVI_CONTROL_UNKNOWN;
1069 #define PRIV ((priv_t *) (tvi_handle->priv))
1071 /* handler creator - entry point ! */
1072 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param)
1074 tvi_handle_t *tvi_handle;
1076 /* new_handle initializes priv with memset 0 */
1077 tvi_handle = new_handle();
1078 if (!tvi_handle) {
1079 return NULL;
1081 PRIV->video_fd = -1;
1083 PRIV->video_dev = strdup(tv_param->device? tv_param->device: "/dev/video0");
1084 if (!PRIV->video_dev) {
1085 free_handle(tvi_handle);
1086 return NULL;
1089 if (tv_param->adevice) {
1090 PRIV->audio_dev = strdup(tv_param->adevice);
1091 if (!PRIV->audio_dev) {
1092 free(PRIV->video_dev);
1093 free_handle(tvi_handle);
1094 return NULL;
1098 PRIV->tv_param=tv_param;
1099 return tvi_handle;
1102 #undef PRIV
1105 static int uninit(priv_t *priv)
1107 int i, frames, dropped = 0;
1109 #ifdef CONFIG_TV_TELETEXT
1110 priv->vbi_shutdown=1;
1111 if(priv->vbi_grabber_thread)
1112 pthread_join(priv->vbi_grabber_thread, NULL);
1114 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_STOP,(void*)1);
1115 priv->priv_vbi=NULL;
1117 if(priv->vbi_fd){
1118 close(priv->vbi_fd);
1119 priv->vbi_fd=0;
1122 if(priv->vbi_dev){
1123 free(priv->vbi_dev);
1124 priv->vbi_dev=0;
1127 #endif
1129 priv->shutdown = 1;
1130 if(priv->video_grabber_thread)
1131 pthread_join(priv->video_grabber_thread, NULL);
1132 pthread_mutex_destroy(&priv->video_buffer_mutex);
1134 if (priv->streamon) {
1135 struct v4l2_buffer buf;
1137 /* get performance */
1138 frames = 1 + lrintf((double)(priv->curr_frame - priv->first_frame) / 1e6 * getfps(priv));
1139 dropped = frames - priv->frames;
1141 /* turn off streaming */
1142 if (ioctl(priv->video_fd, VIDIOC_STREAMOFF, &(priv->map[0].buf.type)) < 0) {
1143 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamoff failed: %s\n",
1144 info.short_name, strerror(errno));
1146 priv->streamon = 0;
1148 /* unqueue all remaining buffers */
1149 memset(&buf,0,sizeof(buf));
1150 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1151 buf.memory = V4L2_MEMORY_MMAP;
1152 while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
1155 /* unmap all buffers */
1156 for (i = 0; i < priv->mapcount; i++) {
1157 if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {
1158 mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",
1159 info.short_name, strerror(errno));
1163 /* stop audio thread */
1164 if (!priv->tv_param->noaudio && priv->audio_grabber_thread) {
1165 pthread_join(priv->audio_grabber_thread, NULL);
1166 pthread_mutex_destroy(&priv->skew_mutex);
1167 pthread_mutex_destroy(&priv->audio_mutex);
1170 set_mute(priv, 1);
1172 /* free memory and close device */
1173 free(priv->map); priv->map = NULL;
1174 priv->mapcount = 0;
1175 if(priv->video_fd!=-1)close(priv->video_fd); priv->video_fd = -1;
1176 free(priv->video_dev); priv->video_dev = NULL;
1178 if (priv->video_ringbuffer) {
1179 int i;
1180 for (i = 0; i < priv->video_buffer_size_current; i++) {
1181 free(priv->video_ringbuffer[i].data);
1183 free(priv->video_ringbuffer);
1185 if (!priv->tv_param->noaudio) {
1186 if (priv->audio_ringbuffer)
1187 free(priv->audio_ringbuffer);
1188 if (priv->audio_skew_buffer)
1189 free(priv->audio_skew_buffer);
1190 if (priv->audio_skew_delta_buffer)
1191 free(priv->audio_skew_delta_buffer);
1193 audio_in_uninit(&priv->audio_in);
1196 /* show some nice statistics ;-) */
1197 mp_msg(MSGT_TV, MSGL_INFO,
1198 "%s: %d frames successfully processed, %d frames dropped.\n",
1199 info.short_name, priv->frames, dropped);
1200 mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",
1201 info.short_name, priv->video_buffer_size_current);
1202 return 1;
1206 /* initialisation */
1207 static int init(priv_t *priv)
1209 int i;
1211 priv->audio_ringbuffer = NULL;
1212 priv->audio_skew_buffer = NULL;
1213 priv->audio_skew_delta_buffer = NULL;
1215 priv->audio_initialized = 0;
1217 /* Open the video device. */
1218 priv->video_fd = open(priv->video_dev, O_RDWR);
1219 if (priv->video_fd < 0) {
1220 mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",
1221 info.short_name, priv->video_dev, strerror(errno));
1222 uninit(priv);
1223 return 0;
1225 mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",
1226 info.short_name, priv->video_dev, priv->video_fd);
1229 ** Query the video capabilities and current settings
1230 ** for further control calls.
1232 if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
1233 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",
1234 info.short_name, strerror(errno));
1235 uninit(priv);
1236 return 0;
1239 if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))
1241 mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",
1242 priv->video_dev);
1243 return 0;
1246 if (getfmt(priv) < 0) {
1247 uninit(priv);
1248 return 0;
1250 getstd(priv);
1252 ** if this device has got a tuner query it's settings
1253 ** otherwise set some nice defaults
1255 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1256 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
1257 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
1258 info.short_name, strerror(errno));
1259 uninit(priv);
1260 return 0;
1263 mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);
1264 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1265 mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",
1266 (priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",
1267 (priv->tuner.capability & V4L2_TUNER_CAP_LANG1) ? " LANG1" : "",
1268 (priv->tuner.capability & V4L2_TUNER_CAP_LANG2) ? " LANG2" : "");
1269 mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",
1270 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO) ? " MONO" : "",
1271 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",
1272 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1) ? " LANG1" : "",
1273 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2) ? " LANG2" : "");
1275 mp_msg(MSGT_TV, MSGL_INFO, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1276 priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
1277 " video capture": "",
1278 priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?
1279 " video output": "",
1280 priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?
1281 " video overlay": "",
1282 priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?
1283 " VBI capture device": "",
1284 priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?
1285 " VBI output": "",
1286 priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?
1287 " RDS data capture": "",
1288 priv->capability.capabilities & V4L2_CAP_TUNER?
1289 " tuner": "",
1290 priv->capability.capabilities & V4L2_CAP_AUDIO?
1291 " audio": "",
1292 priv->capability.capabilities & V4L2_CAP_READWRITE?
1293 " read/write": "",
1294 priv->capability.capabilities & V4L2_CAP_ASYNCIO?
1295 " async i/o": "",
1296 priv->capability.capabilities & V4L2_CAP_STREAMING?
1297 " streaming": "");
1298 mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");
1299 for (i = 0;; i++) {
1300 struct v4l2_standard standard;
1301 memset(&standard, 0, sizeof(standard));
1302 standard.index = i;
1303 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
1304 break;
1305 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);
1307 mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");
1308 for (i = 0; 1; i++) {
1309 struct v4l2_input input;
1311 input.index = i;
1312 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
1313 break;
1315 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);
1317 i = -1;
1318 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
1319 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
1320 info.short_name, strerror(errno));
1322 mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);
1323 for (i = 0; ; i++) {
1324 struct v4l2_fmtdesc fmtdesc;
1326 fmtdesc.index = i;
1327 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1328 if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
1329 break;
1331 mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",
1332 pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),
1333 fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));
1335 mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",
1336 pixfmt2name(priv->format.fmt.pix.pixelformat));
1338 /* set some nice defaults */
1339 if (getfmt(priv) < 0) return 0;
1340 priv->format.fmt.pix.width = 640;
1341 priv->format.fmt.pix.height = 480;
1342 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
1343 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
1344 info.short_name, strerror(errno));
1345 uninit(priv);
1346 return 0;
1349 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;
1351 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1352 struct v4l2_control control;
1353 if (priv->tv_param->amode >= 0) {
1354 mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);
1355 priv->tuner.audmode = amode2v4l(priv->tv_param->amode);
1356 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
1357 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
1358 info.short_name, strerror(errno));
1359 return TVI_CONTROL_FALSE;
1362 mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,
1363 (priv->tuner.audmode == V4L2_TUNER_MODE_MONO) ? " MONO" : "",
1364 (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",
1365 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG1) ? " LANG1" : "",
1366 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG2) ? " LANG2" : "");
1368 if (priv->tv_param->volume >= 0) {
1369 control.id = V4L2_CID_AUDIO_VOLUME;
1370 control.value = priv->tv_param->volume;
1371 set_control(priv, &control, 0);
1373 if (priv->tv_param->bass >= 0) {
1374 control.id = V4L2_CID_AUDIO_BASS;
1375 control.value = priv->tv_param->bass;
1376 set_control(priv, &control, 0);
1378 if (priv->tv_param->treble >= 0) {
1379 control.id = V4L2_CID_AUDIO_TREBLE;
1380 control.value = priv->tv_param->treble;
1381 set_control(priv, &control, 0);
1383 if (priv->tv_param->balance >= 0) {
1384 control.id = V4L2_CID_AUDIO_BALANCE;
1385 control.value = priv->tv_param->balance;
1386 set_control(priv, &control, 0);
1390 return 1;
1393 static int get_capture_buffer_size(priv_t *priv)
1395 int bufsize, cnt;
1397 if (priv->tv_param->buffer_size >= 0) {
1398 bufsize = priv->tv_param->buffer_size*1024*1024;
1399 } else {
1400 #ifdef HAVE_SYS_SYSINFO_H
1401 struct sysinfo si;
1403 sysinfo(&si);
1404 if (si.totalram<2*1024*1024) {
1405 bufsize = 1024*1024;
1406 } else {
1407 bufsize = si.totalram/2;
1409 #else
1410 bufsize = 16*1024*1024;
1411 #endif
1414 cnt = bufsize/priv->format.fmt.pix.sizeimage;
1415 if (cnt < 2) cnt = 2;
1417 return cnt;
1420 /* that's the real start, we'got the format parameters (checked with control) */
1421 static int start(priv_t *priv)
1423 struct v4l2_requestbuffers request;
1424 unsigned int i;
1426 /* setup audio parameters */
1428 init_audio(priv);
1429 if (!priv->tv_param->noaudio && !priv->audio_initialized) return 0;
1431 /* we need this to size the audio buffer properly */
1432 if (priv->immediate_mode) {
1433 priv->video_buffer_size_max = 2;
1434 } else {
1435 priv->video_buffer_size_max = get_capture_buffer_size(priv);
1438 if (!priv->tv_param->noaudio) {
1439 setup_audio_buffer_sizes(priv);
1440 priv->audio_skew_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1441 if (!priv->audio_skew_buffer) {
1442 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1443 return 0;
1445 priv->audio_skew_delta_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1446 if (!priv->audio_skew_delta_buffer) {
1447 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1448 return 0;
1451 priv->audio_ringbuffer = calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
1452 if (!priv->audio_ringbuffer) {
1453 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
1454 return 0;
1457 priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate
1458 *priv->audio_in.channels
1459 *priv->audio_in.bytes_per_sample);
1460 priv->audio_usecs_per_block = 1e6*priv->audio_secs_per_block;
1461 priv->audio_head = 0;
1462 priv->audio_tail = 0;
1463 priv->audio_cnt = 0;
1464 priv->audio_drop = 0;
1465 priv->audio_skew = 0;
1466 priv->audio_skew_total = 0;
1467 priv->audio_skew_delta_total = 0;
1468 priv->audio_recv_blocks_total = 0;
1469 priv->audio_sent_blocks_total = 0;
1470 priv->audio_null_blocks_inserted = 0;
1471 priv->audio_insert_null_samples = 0;
1472 priv->dropped_frames_timeshift = 0;
1473 priv->dropped_frames_compensated = 0;
1475 pthread_mutex_init(&priv->skew_mutex, NULL);
1476 pthread_mutex_init(&priv->audio_mutex, NULL);
1479 /* setup video parameters */
1480 if (!priv->tv_param->noaudio) {
1481 if (priv->video_buffer_size_max < (3*priv->standard.frameperiod.denominator) /
1482 priv->standard.frameperiod.numerator
1483 *priv->audio_secs_per_block) {
1484 mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"
1485 "You will probably experience heavy framedrops.\n");
1490 int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1492 mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1493 priv->video_buffer_size_max,
1494 priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));
1497 priv->video_ringbuffer = calloc(priv->video_buffer_size_max, sizeof(video_buffer_entry));
1498 if (!priv->video_ringbuffer) {
1499 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
1500 return 0;
1502 memset(priv->video_ringbuffer,0,priv->video_buffer_size_max * sizeof(video_buffer_entry));
1504 pthread_mutex_init(&priv->video_buffer_mutex, NULL);
1506 priv->video_head = 0;
1507 priv->video_tail = 0;
1508 priv->video_cnt = 0;
1510 /* request buffers */
1511 if (priv->immediate_mode) {
1512 request.count = 2;
1513 } else {
1514 request.count = BUFFER_COUNT;
1517 request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1518 request.memory = V4L2_MEMORY_MMAP;
1519 if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
1520 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",
1521 info.short_name, strerror(errno));
1522 return 0;
1525 /* query buffers */
1526 if (!(priv->map = calloc(request.count, sizeof(struct map)))) {
1527 mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",
1528 info.short_name, strerror(errno));
1529 return 0;
1532 /* map and queue buffers */
1533 for (i = 0; i < request.count; i++) {
1534 memset(&priv->map[i].buf,0,sizeof(priv->map[i].buf));
1535 priv->map[i].buf.index = i;
1536 priv->map[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1537 priv->map[i].buf.memory = V4L2_MEMORY_MMAP;
1538 if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
1539 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",
1540 info.short_name, strerror(errno));
1541 free(priv->map);
1542 priv->map = NULL;
1543 return 0;
1545 priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |
1546 PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);
1547 if (priv->map[i].addr == MAP_FAILED) {
1548 mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",
1549 info.short_name, strerror(errno));
1550 priv->map[i].len = 0;
1551 return 0;
1553 priv->map[i].len = priv->map[i].buf.length;
1554 /* count up to make sure this is correct everytime */
1555 priv->mapcount++;
1557 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1558 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1559 info.short_name, strerror(errno));
1560 return 0;
1564 #ifdef CONFIG_TV_TELETEXT
1565 /* start vbi thread */
1566 if(priv->priv_vbi){
1567 priv->vbi_shutdown = 0;
1568 pthread_create(&priv->vbi_grabber_thread, NULL, vbi_grabber, priv);
1570 #endif
1571 /* start audio thread */
1572 priv->shutdown = 0;
1573 priv->audio_skew_measure_time = 0;
1574 priv->first_frame = 0;
1575 priv->audio_skew = 0;
1576 priv->first = 1;
1578 set_mute(priv, 0);
1580 return 1;
1583 // copies a video frame
1584 static inline void copy_frame(priv_t *priv, video_buffer_entry *dest, unsigned char *source,int len)
1586 dest->framesize=len;
1587 if(priv->tv_param->automute>0){
1588 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) >= 0) {
1589 if(priv->tv_param->automute<<8>priv->tuner.signal){
1590 fill_blank_frame(dest->data,dest->framesize,fcc_vl2mp(priv->format.fmt.pix.pixelformat));
1591 set_mute(priv,1);
1592 return;
1595 set_mute(priv,0);
1597 memcpy(dest->data, source, len);
1600 // maximum skew change, in frames
1601 #define MAX_SKEW_DELTA 0.6
1602 static void *video_grabber(void *data)
1604 priv_t *priv = (priv_t*)data;
1605 long long skew, prev_skew, xskew, interval, prev_interval, delta;
1606 int i;
1607 int framesize = priv->format.fmt.pix.sizeimage;
1608 fd_set rdset;
1609 struct timeval timeout;
1610 struct v4l2_buffer buf;
1612 xskew = 0;
1613 skew = 0;
1614 interval = 0;
1615 prev_interval = 0;
1616 prev_skew = 0;
1618 mp_msg(MSGT_TV, MSGL_V, "%s: going to capture\n", info.short_name);
1619 if (ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
1620 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamon failed: %s\n",
1621 info.short_name, strerror(errno));
1622 return 0;
1624 priv->streamon = 1;
1626 if (!priv->tv_param->noaudio) {
1627 pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
1630 for (priv->frames = 0; !priv->shutdown;)
1632 int ret;
1634 if (priv->immediate_mode) {
1635 while (priv->video_cnt == priv->video_buffer_size_max) {
1636 usleep(10000);
1637 if (priv->shutdown) {
1638 return NULL;
1643 FD_ZERO (&rdset);
1644 FD_SET (priv->video_fd, &rdset);
1646 timeout.tv_sec = 1;
1647 timeout.tv_usec = 0;
1649 i = select(priv->video_fd + 1, &rdset, NULL, NULL, &timeout);
1650 if (i < 0) {
1651 mp_msg(MSGT_TV, MSGL_ERR, "%s: select failed: %s\n",
1652 info.short_name, strerror(errno));
1653 continue;
1655 else if (i == 0) {
1656 mp_msg(MSGT_TV, MSGL_ERR, "%s: select timeout\n", info.short_name);
1657 continue;
1659 else if (!FD_ISSET(priv->video_fd, &rdset)) {
1660 continue;
1663 memset(&buf,0,sizeof(buf));
1664 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1665 buf.memory = V4L2_MEMORY_MMAP;
1666 ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
1668 if (ret < 0) {
1670 if there's no signal, the buffer might me dequeued
1671 so we query all the buffers to see which one we should
1672 put back to queue
1674 observed with saa7134 0.2.8
1675 don't know if is it a bug or (mis)feature
1677 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1678 info.short_name, strerror(errno), buf.index);
1679 for (i = 0; i < priv->mapcount; i++) {
1680 memset(&buf,0,sizeof(buf));
1681 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1682 buf.memory = V4L2_MEMORY_MMAP;
1683 buf.index = i;
1684 ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
1685 if (ret < 0) {
1686 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s, idx = %d\n",
1687 info.short_name, strerror(errno), buf.index);
1688 return 0;
1690 if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
1691 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1692 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1693 info.short_name, strerror(errno));
1694 return 0;
1698 continue;
1701 /* store the timestamp of the very first frame as reference */
1702 if (!priv->frames++) {
1703 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1704 priv->first_frame = (long long)1e6*buf.timestamp.tv_sec + buf.timestamp.tv_usec;
1705 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1707 priv->curr_frame = (long long)buf.timestamp.tv_sec*1e6+buf.timestamp.tv_usec;
1708 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1710 interval = priv->curr_frame - priv->first_frame;
1711 delta = interval - prev_interval;
1713 if (!priv->immediate_mode) {
1714 // interpolate the skew in time
1715 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1716 xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
1717 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1718 // correct extreme skew changes to avoid (especially) moving backwards in time
1719 if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
1720 skew = prev_skew + delta*MAX_SKEW_DELTA;
1721 } else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) {
1722 skew = prev_skew - delta*MAX_SKEW_DELTA;
1723 } else {
1724 skew = xskew;
1728 mp_msg(MSGT_TV, MSGL_DBG3, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1729 delta ? (double)1e6/delta : -1,
1730 (double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
1731 mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
1733 prev_skew = skew;
1734 prev_interval = interval;
1736 /* allocate a new buffer, if needed */
1737 pthread_mutex_lock(&priv->video_buffer_mutex);
1738 if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
1739 if (priv->video_cnt == priv->video_buffer_size_current) {
1740 unsigned char *newbuf = malloc(framesize);
1741 if (newbuf) {
1742 memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
1743 (priv->video_buffer_size_current-priv->video_tail)*sizeof(video_buffer_entry));
1744 priv->video_ringbuffer[priv->video_tail].data = newbuf;
1745 if ((priv->video_head >= priv->video_tail) && (priv->video_cnt > 0)) priv->video_head++;
1746 priv->video_buffer_size_current++;
1750 pthread_mutex_unlock(&priv->video_buffer_mutex);
1752 if (priv->video_cnt == priv->video_buffer_size_current) {
1753 if (!priv->immediate_mode) {
1754 mp_msg(MSGT_TV, MSGL_ERR, "\nvideo buffer full - dropping frame\n");
1755 if (priv->audio_insert_null_samples) {
1756 pthread_mutex_lock(&priv->audio_mutex);
1757 priv->dropped_frames_timeshift += delta;
1758 pthread_mutex_unlock(&priv->audio_mutex);
1761 } else {
1762 if (priv->immediate_mode) {
1763 priv->video_ringbuffer[priv->video_tail].timestamp = 0;
1764 } else {
1765 // compensate for audio skew
1766 // negative skew => there are more audio samples, increase interval
1767 // positive skew => less samples, shorten the interval
1768 priv->video_ringbuffer[priv->video_tail].timestamp = interval - skew;
1769 if (priv->audio_insert_null_samples && priv->video_ringbuffer[priv->video_tail].timestamp > 0) {
1770 pthread_mutex_lock(&priv->audio_mutex);
1771 priv->video_ringbuffer[priv->video_tail].timestamp +=
1772 (priv->audio_null_blocks_inserted
1773 - priv->dropped_frames_timeshift/priv->audio_usecs_per_block)
1774 *priv->audio_usecs_per_block;
1775 pthread_mutex_unlock(&priv->audio_mutex);
1778 copy_frame(priv, priv->video_ringbuffer+priv->video_tail, priv->map[buf.index].addr,buf.bytesused);
1779 priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
1780 priv->video_cnt++;
1782 if (ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
1783 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1784 info.short_name, strerror(errno));
1785 return 0;
1788 return NULL;
1791 #define MAX_LOOP 50
1792 static double grab_video_frame(priv_t *priv, char *buffer, int len)
1794 double interval;
1795 int loop_cnt = 0;
1797 if (priv->first) {
1798 pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1799 priv->first = 0;
1802 while (priv->video_cnt == 0) {
1803 usleep(10000);
1804 if (loop_cnt++ > MAX_LOOP) return 0;
1807 pthread_mutex_lock(&priv->video_buffer_mutex);
1808 interval = (double)priv->video_ringbuffer[priv->video_head].timestamp*1e-6;
1809 memcpy(buffer, priv->video_ringbuffer[priv->video_head].data, len);
1810 priv->video_cnt--;
1811 priv->video_head = (priv->video_head+1)%priv->video_buffer_size_current;
1812 pthread_mutex_unlock(&priv->video_buffer_mutex);
1814 return interval;
1817 static int get_video_framesize(priv_t *priv)
1820 this routine will be called before grab_video_frame
1821 thus let's return topmost frame's size
1823 if (priv->video_cnt)
1824 return priv->video_ringbuffer[priv->video_head].framesize;
1826 no video frames yet available. i don't know what to do in this case,
1827 thus let's return some fallback result (for compressed format this will be
1828 maximum allowed frame size.
1830 return priv->format.fmt.pix.sizeimage;
1833 //#define DOUBLESPEED
1834 #ifdef DOUBLESPEED
1835 // for testing purposes only
1836 static void read_doublespeed(priv_t *priv)
1838 char *bufx = calloc(priv->audio_in.blocksize, 2);
1839 short *s;
1840 short *d;
1841 int i;
1843 audio_in_read_chunk(&priv->audio_in, bufx);
1844 audio_in_read_chunk(&priv->audio_in, bufx+priv->audio_in.blocksize);
1846 s = bufx;
1847 d = priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize;
1848 for (i = 0; i < priv->audio_in.blocksize/2; i++) {
1849 *d++ = *s++;
1850 *s++;
1854 #endif
1856 static void *audio_grabber(void *data)
1858 priv_t *priv = (priv_t*)data;
1859 struct timeval tv;
1860 int i, audio_skew_ptr = 0;
1861 long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
1862 long long start_time_avg;
1864 gettimeofday(&tv, NULL);
1865 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1866 audio_in_start_capture(&priv->audio_in);
1867 for (i = 0; i < priv->aud_skew_cnt; i++)
1868 priv->audio_skew_buffer[i] = 0;
1869 for (i = 0; i < priv->aud_skew_cnt; i++)
1870 priv->audio_skew_delta_buffer[i] = 0;
1872 for (; !priv->shutdown;)
1874 #ifdef DOUBLESPEED
1875 read_doublespeed(priv);
1876 #else
1877 if (audio_in_read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize) < 0)
1878 continue;
1879 #endif
1880 pthread_mutex_lock(&priv->skew_mutex);
1881 if (priv->first_frame == 0) {
1882 // there is no first frame yet (unlikely to happen)
1883 gettimeofday(&tv, NULL);
1884 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1885 // fprintf(stderr, "warning - first frame not yet available!\n");
1886 pthread_mutex_unlock(&priv->skew_mutex);
1887 continue;
1889 pthread_mutex_unlock(&priv->skew_mutex);
1891 gettimeofday(&tv, NULL);
1893 priv->audio_recv_blocks_total++;
1894 current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
1896 if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
1897 start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1898 priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
1901 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1902 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1904 // put the current skew into the ring buffer
1905 priv->audio_skew_total -= priv->audio_skew_buffer[audio_skew_ptr];
1906 priv->audio_skew_buffer[audio_skew_ptr] = current_time
1907 - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1908 priv->audio_skew_total += priv->audio_skew_buffer[audio_skew_ptr];
1910 pthread_mutex_lock(&priv->skew_mutex);
1912 // skew calculation
1914 // compute the sliding average of the skews
1915 if (priv->audio_recv_blocks_total > priv->aud_skew_cnt) {
1916 priv->audio_skew = priv->audio_skew_total/priv->aud_skew_cnt;
1917 } else {
1918 priv->audio_skew = priv->audio_skew_total/priv->audio_recv_blocks_total;
1921 // put the current skew change (skew-prev_skew) into the ring buffer
1922 priv->audio_skew_delta_total -= priv->audio_skew_delta_buffer[audio_skew_ptr];
1923 priv->audio_skew_delta_buffer[audio_skew_ptr] = priv->audio_skew - prev_skew_uncorr;
1924 priv->audio_skew_delta_total += priv->audio_skew_delta_buffer[audio_skew_ptr];
1925 prev_skew_uncorr = priv->audio_skew; // remember the _uncorrected_ average value
1927 audio_skew_ptr = (audio_skew_ptr+1) % priv->aud_skew_cnt; // rotate the buffer pointer
1929 // sliding average approximates the value in the middle of the interval
1930 // so interpolate the skew value further to the current time
1931 priv->audio_skew += priv->audio_skew_delta_total/2;
1933 // now finally, priv->audio_skew contains fairly good approximation
1934 // of the current value
1936 // current skew factor (assuming linearity)
1937 // used for further interpolation in video_grabber
1938 // probably overkill but seems to be necessary for
1939 // stress testing by dropping half of the audio frames ;)
1940 // especially when using ALSA with large block sizes
1941 // where audio_skew remains a long while behind
1942 if ((priv->audio_skew_measure_time != 0) && (current_time - priv->audio_skew_measure_time != 0)) {
1943 priv->audio_skew_factor = (double)(priv->audio_skew-prev_skew)/(current_time - priv->audio_skew_measure_time);
1944 } else {
1945 priv->audio_skew_factor = 0.0;
1948 priv->audio_skew_measure_time = current_time;
1949 prev_skew = priv->audio_skew;
1950 priv->audio_skew += priv->audio_start_time - priv->first_frame;
1951 pthread_mutex_unlock(&priv->skew_mutex);
1953 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1955 pthread_mutex_lock(&priv->audio_mutex);
1956 if ((priv->audio_tail+1) % priv->audio_buffer_size == priv->audio_head) {
1957 mp_msg(MSGT_TV, MSGL_ERR, "\ntoo bad - dropping audio frame !\n");
1958 priv->audio_drop++;
1959 } else {
1960 priv->audio_tail = (priv->audio_tail+1) % priv->audio_buffer_size;
1961 priv->audio_cnt++;
1963 pthread_mutex_unlock(&priv->audio_mutex);
1965 return NULL;
1968 static double grab_audio_frame(priv_t *priv, char *buffer, int len)
1970 mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1971 priv, buffer, len);
1973 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1974 // => switch to the mode which outputs audio immediately, even if
1975 // it should be silence
1976 if (priv->first) priv->audio_insert_null_samples = 1;
1978 pthread_mutex_lock(&priv->audio_mutex);
1979 while (priv->audio_insert_null_samples
1980 && priv->dropped_frames_timeshift - priv->dropped_frames_compensated >= priv->audio_usecs_per_block) {
1981 // some frames were dropped - drop the corresponding number of audio blocks
1982 if (priv->audio_drop) {
1983 priv->audio_drop--;
1984 } else {
1985 if (priv->audio_head == priv->audio_tail) break;
1986 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1988 priv->dropped_frames_compensated += priv->audio_usecs_per_block;
1991 // compensate for dropped audio frames
1992 if (priv->audio_drop && (priv->audio_head == priv->audio_tail)) {
1993 priv->audio_drop--;
1994 memset(buffer, 0, len);
1995 goto out;
1998 if (priv->audio_insert_null_samples && (priv->audio_head == priv->audio_tail)) {
1999 // return silence to avoid desync and stuttering
2000 memset(buffer, 0, len);
2001 priv->audio_null_blocks_inserted++;
2002 goto out;
2005 pthread_mutex_unlock(&priv->audio_mutex);
2006 while (priv->audio_head == priv->audio_tail) {
2007 // this is mencoder => just wait until some audio is available
2008 usleep(10000);
2010 pthread_mutex_lock(&priv->audio_mutex);
2011 memcpy(buffer, priv->audio_ringbuffer+priv->audio_head*priv->audio_in.blocksize, len);
2012 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
2013 priv->audio_cnt--;
2014 out:
2015 pthread_mutex_unlock(&priv->audio_mutex);
2016 priv->audio_sent_blocks_total++;
2017 return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
2020 static int get_audio_framesize(priv_t *priv)
2022 return priv->audio_in.blocksize;