configure: Update required x264 version
[mplayer.git] / stream / tvi_v4l2.c
blob7a15a9b0be068131a7c1cce0910f601d078c037f
1 /*
2 ** Video 4 Linux 2 input
3 **
4 ** This file is part of MPlayer, see http://mplayerhq.hu/ for info.
5 **
6 ** (c) 2003 Martin Olschewski <olschewski@zpr.uni-koeln.de>
7 ** (c) 2003 Jindrich Makovicka <makovick@gmail.com>
8 **
9 ** File licensed under the GPL, see http://www.fsf.org/ for more info.
11 ** Some ideas are based on works from
12 ** Alex Beregszaszi <alex@fsn.hu>
13 ** Gerd Knorr <kraxel@bytesex.org>
15 ** CODE IS UNDER DEVELOPMENT, NO FEATURE REQUESTS PLEASE!
20 known issues:
21 - norm setting isn't consistent with tvi_v4l
22 - the same for volume/bass/treble/balance
26 #include "config.h"
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <pthread.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <sys/ioctl.h>
34 #include <sys/mman.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #include <unistd.h>
38 #include <math.h>
39 #ifdef HAVE_SYS_SYSINFO_H
40 #include <sys/sysinfo.h>
41 #endif
42 #include <linux/types.h>
43 #include <linux/videodev2.h>
44 #include "mp_msg.h"
45 #include "libmpcodecs/img_format.h"
46 #include "libaf/af_format.h"
47 #include "tv.h"
48 #include "audio_in.h"
50 #define info tvi_info_v4l2
51 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param);
52 /* information about this file */
53 const tvi_info_t tvi_info_v4l2 = {
54 tvi_init_v4l2,
55 "Video 4 Linux 2 input",
56 "v4l2",
57 "Martin Olschewski <olschewski@zpr.uni-koeln.de>",
58 "first try, more to come ;-)"
61 struct map {
62 struct v4l2_buffer buf;
63 void *addr;
64 size_t len;
67 #define BUFFER_COUNT 6
69 /** video ringbuffer entry */
70 typedef struct {
71 unsigned char *data; ///< frame contents
72 long long timestamp; ///< frame timestamp
73 int framesize; ///< actual frame size
74 } video_buffer_entry;
76 /* private data */
77 typedef struct {
78 /* video */
79 char *video_dev;
80 int video_fd;
81 #ifdef CONFIG_TV_TELETEXT
82 char *vbi_dev;
83 int vbi_fd;
84 int vbi_bufsize;
85 int vbi_shutdown;
86 pthread_t vbi_grabber_thread;
87 void *priv_vbi;
88 #endif
89 int mp_format;
90 struct v4l2_capability capability;
91 struct v4l2_input input;
92 struct v4l2_format format;
93 struct v4l2_standard standard;
94 struct v4l2_tuner tuner;
95 struct map *map;
96 int mapcount;
97 int frames;
98 volatile long long first_frame;
99 long long curr_frame;
100 /* audio video interleaving ;-) */
101 volatile int streamon;
102 pthread_t audio_grabber_thread;
103 pthread_mutex_t skew_mutex;
105 /* 2nd level video buffers */
106 int first;
107 int immediate_mode;
109 int video_buffer_size_max;
110 volatile int video_buffer_size_current;
111 video_buffer_entry *video_ringbuffer;
112 volatile int video_head;
113 volatile int video_tail;
114 volatile int video_cnt;
115 pthread_t video_grabber_thread;
116 pthread_mutex_t video_buffer_mutex;
118 /* audio */
119 char *audio_dev;
120 audio_in_t audio_in;
122 long long audio_start_time;
123 int audio_buffer_size;
124 int aud_skew_cnt;
125 unsigned char *audio_ringbuffer;
126 long long *audio_skew_buffer;
127 long long *audio_skew_delta_buffer;
128 volatile int audio_head;
129 volatile int audio_tail;
130 volatile int audio_cnt;
131 volatile long long audio_skew;
132 volatile double audio_skew_factor;
133 volatile long long audio_skew_measure_time;
134 volatile int audio_drop;
135 volatile int shutdown;
137 int audio_initialized;
138 double audio_secs_per_block;
139 long long audio_usecs_per_block;
140 long long audio_skew_total;
141 long long audio_skew_delta_total;
142 long audio_recv_blocks_total;
143 long audio_sent_blocks_total;
144 pthread_mutex_t audio_mutex;
145 int audio_insert_null_samples;
146 volatile long audio_null_blocks_inserted;
147 volatile long long dropped_frames_timeshift;
148 long long dropped_frames_compensated;
150 tv_param_t *tv_param;
151 } priv_t;
153 #include "tvi_def.h"
155 static void *audio_grabber(void *data);
156 static void *video_grabber(void *data);
158 /**********************************************************************\
160 Only few of the fourccs are the same in v4l2 and mplayer:
162 IMGFMT_YVU9 == V4L2_PIX_FMT_YVU410
163 IMGFMT_YV12 == V4L2_PIX_FMT_YVU420
164 IMGFMT_NV12 == V4L2_PIX_FMT_NV12
165 IMGFMT_422P == V4L2_PIX_FMT_YUV422P
166 IMGFMT_411P == V4L2_PIX_FMT_YUV411P
167 IMGFMT_UYVY == V4L2_PIX_FMT_UYVY
168 IMGFMT_Y41P == V4L2_PIX_FMT_Y41P
170 This may be an useful translation table for some others:
172 IMGFMT_RGB8 == V4L2_PIX_FMT_RGB332
173 IMGFMT_BGR15 == V4L2_PIX_FMT_RGB555
174 IMGFMT_BGR16 == V4L2_PIX_FMT_RGB565
175 IMGFMT_RGB24 == V4L2_PIX_FMT_RGB24
176 IMGFMT_RGB32 == V4L2_PIX_FMT_RGB32
177 IMGFMT_BGR24 == V4L2_PIX_FMT_BGR24
178 IMGFMT_BGR32 == V4L2_PIX_FMT_BGR32
179 IMGFMT_Y800 == V4L2_PIX_FMT_GREY
180 IMGFMT_IF09 == V4L2_PIX_FMT_YUV410
181 IMGFMT_I420 == V4L2_PIX_FMT_YUV420
182 IMGFMT_YUY2 == V4L2_PIX_FMT_YUYV
184 \**********************************************************************/
187 ** Translate a mplayer fourcc to a video4linux2 pixel format.
189 static int fcc_mp2vl(int fcc)
191 switch (fcc) {
192 case IMGFMT_RGB8: return V4L2_PIX_FMT_RGB332;
193 case IMGFMT_BGR15: return V4L2_PIX_FMT_RGB555;
194 case IMGFMT_BGR16: return V4L2_PIX_FMT_RGB565;
195 case IMGFMT_RGB24: return V4L2_PIX_FMT_RGB24;
196 case IMGFMT_RGB32: return V4L2_PIX_FMT_RGB32;
197 case IMGFMT_BGR24: return V4L2_PIX_FMT_BGR24;
198 case IMGFMT_BGR32: return V4L2_PIX_FMT_BGR32;
199 case IMGFMT_Y800: return V4L2_PIX_FMT_GREY;
200 case IMGFMT_IF09: return V4L2_PIX_FMT_YUV410;
201 case IMGFMT_I420: return V4L2_PIX_FMT_YUV420;
202 case IMGFMT_YUY2: return V4L2_PIX_FMT_YUYV;
203 case IMGFMT_YV12: return V4L2_PIX_FMT_YVU420;
204 case IMGFMT_UYVY: return V4L2_PIX_FMT_UYVY;
205 case IMGFMT_MJPEG: return V4L2_PIX_FMT_MJPEG;
207 return fcc;
211 ** Translate a video4linux2 fourcc aka pixel format to mplayer.
213 static int fcc_vl2mp(int fcc)
215 switch (fcc) {
216 case V4L2_PIX_FMT_RGB332: return IMGFMT_RGB8;
217 case V4L2_PIX_FMT_RGB555: return IMGFMT_BGR15;
218 case V4L2_PIX_FMT_RGB565: return IMGFMT_BGR16;
219 case V4L2_PIX_FMT_RGB24: return IMGFMT_RGB24;
220 case V4L2_PIX_FMT_RGB32: return IMGFMT_RGB32;
221 case V4L2_PIX_FMT_BGR24: return IMGFMT_BGR24;
222 case V4L2_PIX_FMT_BGR32: return IMGFMT_BGR32;
223 case V4L2_PIX_FMT_GREY: return IMGFMT_Y800;
224 case V4L2_PIX_FMT_YUV410: return IMGFMT_IF09;
225 case V4L2_PIX_FMT_YUV420: return IMGFMT_I420;
226 case V4L2_PIX_FMT_YVU420: return IMGFMT_YV12;
227 case V4L2_PIX_FMT_YUYV: return IMGFMT_YUY2;
228 case V4L2_PIX_FMT_UYVY: return IMGFMT_UYVY;
229 case V4L2_PIX_FMT_MJPEG: return IMGFMT_MJPEG;
231 return fcc;
235 ** Translate a video4linux2 fourcc aka pixel format
236 ** to a human readable string.
238 static const char *pixfmt2name(int pixfmt)
240 static char unknown[24];
242 switch (pixfmt) {
243 case V4L2_PIX_FMT_RGB332: return "RGB332";
244 case V4L2_PIX_FMT_RGB555: return "RGB555";
245 case V4L2_PIX_FMT_RGB565: return "RGB565";
246 case V4L2_PIX_FMT_RGB555X: return "RGB555X";
247 case V4L2_PIX_FMT_RGB565X: return "RGB565X";
248 case V4L2_PIX_FMT_BGR24: return "BGR24";
249 case V4L2_PIX_FMT_RGB24: return "RGB24";
250 case V4L2_PIX_FMT_BGR32: return "BGR32";
251 case V4L2_PIX_FMT_RGB32: return "RGB32";
252 case V4L2_PIX_FMT_GREY: return "GREY";
253 case V4L2_PIX_FMT_YVU410: return "YVU410";
254 case V4L2_PIX_FMT_YVU420: return "YVU420";
255 case V4L2_PIX_FMT_YUYV: return "YUYV";
256 case V4L2_PIX_FMT_UYVY: return "UYVY";
257 /* case V4L2_PIX_FMT_YVU422P: return "YVU422P"; */
258 /* case V4L2_PIX_FMT_YVU411P: return "YVU411P"; */
259 case V4L2_PIX_FMT_YUV422P: return "YUV422P";
260 case V4L2_PIX_FMT_YUV411P: return "YUV411P";
261 case V4L2_PIX_FMT_Y41P: return "Y41P";
262 case V4L2_PIX_FMT_NV12: return "NV12";
263 case V4L2_PIX_FMT_NV21: return "NV21";
264 case V4L2_PIX_FMT_YUV410: return "YUV410";
265 case V4L2_PIX_FMT_YUV420: return "YUV420";
266 case V4L2_PIX_FMT_YYUV: return "YYUV";
267 case V4L2_PIX_FMT_HI240: return "HI240";
268 case V4L2_PIX_FMT_WNVA: return "WNVA";
269 case V4L2_PIX_FMT_MJPEG: return "MJPEG";
271 sprintf(unknown, "unknown (0x%x)", pixfmt);
272 return unknown;
277 ** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
279 static int pixfmt2depth(int pixfmt)
281 switch (pixfmt) {
282 case V4L2_PIX_FMT_RGB332:
283 return 8;
284 case V4L2_PIX_FMT_RGB555:
285 case V4L2_PIX_FMT_RGB565:
286 case V4L2_PIX_FMT_RGB555X:
287 case V4L2_PIX_FMT_RGB565X:
288 return 16;
289 case V4L2_PIX_FMT_BGR24:
290 case V4L2_PIX_FMT_RGB24:
291 return 24;
292 case V4L2_PIX_FMT_BGR32:
293 case V4L2_PIX_FMT_RGB32:
294 return 32;
295 case V4L2_PIX_FMT_GREY:
296 return 8;
297 case V4L2_PIX_FMT_YVU410:
298 return 9;
299 case V4L2_PIX_FMT_YVU420:
300 return 12;
301 case V4L2_PIX_FMT_YUYV:
302 case V4L2_PIX_FMT_UYVY:
303 case V4L2_PIX_FMT_YUV422P:
304 case V4L2_PIX_FMT_YUV411P:
305 return 16;
306 case V4L2_PIX_FMT_Y41P:
307 case V4L2_PIX_FMT_NV12:
308 case V4L2_PIX_FMT_NV21:
309 return 12;
310 case V4L2_PIX_FMT_YUV410:
311 return 9;
312 case V4L2_PIX_FMT_YUV420:
313 return 12;
314 case V4L2_PIX_FMT_YYUV:
315 return 16;
316 case V4L2_PIX_FMT_HI240:
317 return 8;
320 return 0;
323 static int amode2v4l(int amode)
325 switch (amode) {
326 case 0:
327 return V4L2_TUNER_MODE_MONO;
328 case 1:
329 return V4L2_TUNER_MODE_STEREO;
330 case 2:
331 return V4L2_TUNER_MODE_LANG1;
332 case 3:
333 return V4L2_TUNER_MODE_LANG2;
334 default:
335 return -1;
341 ** Get current FPS.
343 static double getfps(priv_t *priv)
345 if (priv->tv_param->fps > 0)
346 return priv->tv_param->fps;
347 if (priv->standard.frameperiod.denominator && priv->standard.frameperiod.numerator)
348 return (double)priv->standard.frameperiod.denominator / priv->standard.frameperiod.numerator;
349 return 25.0;
352 // sets and sanitizes audio buffer/block sizes
353 static void setup_audio_buffer_sizes(priv_t *priv)
355 int bytes_per_sample = priv->audio_in.bytes_per_sample;
356 int seconds = priv->video_buffer_size_max/getfps(priv);
358 if (seconds < 5) seconds = 5;
359 if (seconds > 500) seconds = 500;
361 // make the audio buffer at least as the video buffer capacity (or 5 seconds) long
362 priv->audio_buffer_size = 1 + seconds*priv->audio_in.samplerate
363 *priv->audio_in.channels
364 *bytes_per_sample/priv->audio_in.blocksize;
365 if (priv->audio_buffer_size < 256) priv->audio_buffer_size = 256;
367 // make the skew buffer at least 1 second long
368 priv->aud_skew_cnt = 1 + 1*priv->audio_in.samplerate
369 *priv->audio_in.channels
370 *bytes_per_sample/priv->audio_in.blocksize;
371 if (priv->aud_skew_cnt < 16) priv->aud_skew_cnt = 16;
373 mp_msg(MSGT_TV, MSGL_V, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
374 priv->audio_buffer_size, priv->audio_in.blocksize, priv->aud_skew_cnt);
377 static void init_audio(priv_t *priv)
379 if (priv->audio_initialized) return;
381 if (!priv->tv_param->noaudio) {
382 #ifdef CONFIG_ALSA
383 if (priv->tv_param->alsa)
384 audio_in_init(&priv->audio_in, AUDIO_IN_ALSA);
385 else
386 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
387 #else
388 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
389 #endif
391 if (priv->audio_dev) {
392 audio_in_set_device(&priv->audio_in, priv->audio_dev);
395 audio_in_set_samplerate(&priv->audio_in, 44100);
396 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
397 if (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) {
398 audio_in_set_channels(&priv->audio_in, 2);
399 } else {
400 audio_in_set_channels(&priv->audio_in, 1);
402 } else {
403 if (priv->tv_param->forcechan >= 0) {
404 audio_in_set_channels(&priv->audio_in, priv->tv_param->forcechan);
405 } else {
406 audio_in_set_channels(&priv->audio_in, 2);
410 if (audio_in_setup(&priv->audio_in) < 0) return;
412 priv->audio_initialized = 1;
416 #if 0
418 ** the number of milliseconds elapsed between time0 and time1
420 static size_t difftv(struct timeval time1, struct timeval time0)
422 return (time1.tv_sec - time0.tv_sec) * 1000 +
423 (time1.tv_usec - time0.tv_usec) / 1000;
425 #endif
428 ** Get current video capture format.
430 static int getfmt(priv_t *priv)
432 int i;
434 priv->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
435 if ((i = ioctl(priv->video_fd, VIDIOC_G_FMT, &priv->format)) < 0) {
436 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get format failed: %s\n",
437 info.short_name, strerror(errno));
439 return i;
444 ** Get current video capture standard.
446 static int getstd(priv_t *priv)
448 v4l2_std_id id;
449 int i=0;
451 if (ioctl(priv->video_fd, VIDIOC_G_STD, &id) < 0) {
452 struct v4l2_streamparm parm;
454 parm.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
455 if(ioctl(priv->video_fd, VIDIOC_G_PARM, &parm) >= 0) {
456 mp_msg(MSGT_TV, MSGL_WARN, "%s: your device driver does not support VIDIOC_G_STD ioctl,"
457 " VIDIOC_G_PARM was used instead.\n", info.short_name);
458 priv->standard.index=0;
459 priv->standard.id=0;
460 priv->standard.frameperiod=parm.parm.capture.timeperframe;
461 return 0;
464 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get standard failed: %s\n",
465 info.short_name, strerror(errno));
466 return -1;
468 do {
469 priv->standard.index = i++;
470 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
471 return -1;
473 } while (priv->standard.id != id);
474 return 0;
477 /***********************************************************************\
480 * Interface to mplayer *
483 \***********************************************************************/
485 static int set_mute(priv_t *priv, int value)
487 struct v4l2_control control;
488 control.id = V4L2_CID_AUDIO_MUTE;
489 control.value = value;
490 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, &control) < 0) {
491 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set mute failed: %s\n",
492 info.short_name, strerror(errno));
493 return 0;
495 return 1;
499 ** MPlayer uses values from -100 up to 100 for controls.
500 ** Here they are scaled to what the tv card needs and applied.
502 static int set_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
503 struct v4l2_queryctrl qctrl;
504 qctrl.id = control->id;
505 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
506 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
507 info.short_name, strerror(errno));
508 return TVI_CONTROL_FALSE;
511 if (val_signed) {
512 if (control->value < 0) {
513 control->value = qctrl.default_value + control->value *
514 (qctrl.default_value - qctrl.minimum) / 100;
515 } else {
516 control->value = qctrl.default_value + control->value *
517 (qctrl.maximum - qctrl.default_value) / 100;
519 } else {
520 if (control->value < 50) {
521 control->value = qctrl.default_value + (control->value-50) *
522 (qctrl.default_value - qctrl.minimum) / 50;
523 } else {
524 control->value = qctrl.default_value + (control->value-50) *
525 (qctrl.maximum - qctrl.default_value) / 50;
530 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, control) < 0) {
531 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl set %s %d failed: %s\n",
532 info.short_name, qctrl.name, control->value, strerror(errno));
533 return TVI_CONTROL_FALSE;
535 mp_msg(MSGT_TV, MSGL_V, "%s: set %s: %d [%d, %d]\n", info.short_name,
536 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
538 return TVI_CONTROL_TRUE;
543 ** Scale the control values back to what mplayer needs.
545 static int get_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
546 struct v4l2_queryctrl qctrl;
548 qctrl.id = control->id;
549 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
550 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
551 info.short_name, strerror(errno));
552 return TVI_CONTROL_FALSE;
555 if (ioctl(priv->video_fd, VIDIOC_G_CTRL, control) < 0) {
556 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl get %s failed: %s\n",
557 info.short_name, qctrl.name, strerror(errno));
558 return TVI_CONTROL_FALSE;
560 mp_msg(MSGT_TV, MSGL_V, "%s: get %s: %d [%d, %d]\n", info.short_name,
561 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
563 if (val_signed) {
564 if (control->value < qctrl.default_value) {
565 control->value = (control->value - qctrl.default_value) * 100 /
566 (qctrl.default_value - qctrl.minimum);
567 } else {
568 control->value = (control->value - qctrl.default_value) * 100 /
569 (qctrl.maximum - qctrl.default_value);
571 } else {
572 if (control->value < qctrl.default_value) {
573 control->value = (control->value - qctrl.default_value) * 50 /
574 (qctrl.default_value - qctrl.minimum) + 50;
575 } else {
576 control->value = (control->value - qctrl.default_value) * 50 /
577 (qctrl.maximum - qctrl.default_value) + 50;
581 return TVI_CONTROL_TRUE;
584 #ifdef CONFIG_TV_TELETEXT
585 static int vbi_init(priv_t* priv,char* device)
587 int vbi_fd=0;
588 struct v4l2_capability cap;
589 struct v4l2_format fmt;
590 int res;
592 if(!device)
593 return TVI_CONTROL_FALSE;
595 priv->vbi_dev=strdup(device);
597 vbi_fd=open(priv->vbi_dev,O_RDWR);
598 if(vbi_fd<0){
599 mp_msg(MSGT_TV,MSGL_ERR,"vbi: could not open device %s\n",priv->vbi_dev);
600 return TVI_CONTROL_FALSE;
603 if(ioctl(vbi_fd,VIDIOC_QUERYCAP,&cap)<0){
604 mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query capatibilities failed for %s\n",priv->vbi_dev);
605 close(vbi_fd);
606 return TVI_CONTROL_FALSE;
608 if(!cap.capabilities & V4L2_CAP_VBI_CAPTURE){
609 mp_msg(MSGT_TV,MSGL_ERR,"vbi: %s does not support VBI capture\n",priv->vbi_dev);
610 close(vbi_fd);
611 return TVI_CONTROL_FALSE;
614 memset(&fmt,0,sizeof(struct v4l2_format));
615 fmt.type=V4L2_BUF_TYPE_VBI_CAPTURE;
616 if((res=ioctl(vbi_fd,VIDIOC_G_FMT,&fmt))<0){
617 mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query format failed: %x\n",res);
618 close(vbi_fd);
619 return TVI_CONTROL_FALSE;
621 if(fmt.fmt.vbi.sample_format!=V4L2_PIX_FMT_GREY){
622 mp_msg(MSGT_TV,MSGL_ERR,"vbi: format 0x%x is not supported\n",fmt.fmt.vbi.sample_format);
623 close(vbi_fd);
624 return TVI_CONTROL_FALSE;
626 priv->vbi_fd=vbi_fd;
627 mp_msg(MSGT_TV,MSGL_DBG3,"vbi: init ok\n");
628 return TVI_CONTROL_TRUE;
631 static int vbi_get_props(priv_t* priv,tt_stream_props* ptsp)
633 struct v4l2_format fmt;
634 int res;
635 if(!priv || !ptsp)
636 return TVI_CONTROL_FALSE;
638 memset(&fmt,0,sizeof(struct v4l2_format));
639 fmt.type=V4L2_BUF_TYPE_VBI_CAPTURE;
640 if((res=ioctl(priv->vbi_fd,VIDIOC_G_FMT,&fmt))<0){
641 mp_msg(MSGT_TV,MSGL_ERR,"vbi_get_props: Query format failed: %x\n",res);
642 return TVI_CONTROL_FALSE;
645 ptsp->interlaced=(fmt.fmt.vbi.flags& V4L2_VBI_INTERLACED?1:0);
647 ptsp->offset=fmt.fmt.vbi.offset;
648 ptsp->sampling_rate=fmt.fmt.vbi.sampling_rate;
649 ptsp->samples_per_line=fmt.fmt.vbi.samples_per_line,
651 ptsp->count[0]=fmt.fmt.vbi.count[0];
652 ptsp->count[1]=fmt.fmt.vbi.count[1];
653 ptsp->bufsize = ptsp->samples_per_line * (ptsp->count[0] + ptsp->count[1]);
655 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",
656 ptsp->sampling_rate,
657 ptsp->offset,
658 ptsp->samples_per_line,
659 ptsp->interlaced?"Yes":"No",
660 ptsp->count[0],
661 ptsp->count[1]);
663 return TVI_CONTROL_TRUE;
666 static void *vbi_grabber(void *data)
668 priv_t *priv = (priv_t *) data;
669 int bytes,seq,prev_seq;
670 unsigned char* buf;
671 tt_stream_props tsp;
673 if(!priv->priv_vbi){
674 mp_msg(MSGT_TV,MSGL_WARN,"vbi: vbi not initialized. stopping thread.\n");
675 return NULL;
678 if(vbi_get_props(priv,&tsp)!=TVI_CONTROL_TRUE)
679 return NULL;
681 buf=malloc(tsp.bufsize);
682 seq=0;
683 prev_seq=0;
684 mp_msg(MSGT_TV,MSGL_V,"vbi: vbi capture thread started.\n");
686 while (!priv->vbi_shutdown){
687 bytes=read(priv->vbi_fd,buf,tsp.bufsize);
688 if(bytes<0 && errno==EINTR)
689 continue;
690 if (bytes!=tsp.bufsize){
691 mp_msg(MSGT_TV,MSGL_WARN,"vbi: expecting bytes: %d, got: %d\n",tsp.bufsize,bytes);
692 break;
694 seq=*(int*)(buf+bytes-4);
695 if(seq<=1) continue;
696 if (prev_seq && seq!=prev_seq+1){
697 prev_seq=0;
698 seq=0;
700 prev_seq=seq;
701 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_DECODE_PAGE,&buf);
702 mp_msg(MSGT_TV,MSGL_DBG3,"grabber: seq:%d\n",seq);
704 free(buf);
705 return NULL;
707 #endif /* CONFIG_TV_TELETEXT */
709 static int control(priv_t *priv, int cmd, void *arg)
711 struct v4l2_control control;
712 struct v4l2_frequency frequency;
714 switch(cmd) {
715 case TVI_CONTROL_IS_VIDEO:
716 return priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
717 TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
718 case TVI_CONTROL_IS_AUDIO:
719 if (priv->tv_param->force_audio) return TVI_CONTROL_TRUE;
720 case TVI_CONTROL_IS_TUNER:
721 return priv->capability.capabilities & V4L2_CAP_TUNER?
722 TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
723 case TVI_CONTROL_IMMEDIATE:
724 priv->immediate_mode = 1;
725 return TVI_CONTROL_TRUE;
726 case TVI_CONTROL_VID_GET_FPS:
727 if (!priv->standard.frameperiod.denominator || !priv->standard.frameperiod.numerator) {
728 mp_msg(MSGT_TV, MSGL_ERR, "%s: Cannot get fps\n", info.short_name);
729 return TVI_CONTROL_FALSE;
731 *(float *)arg = (float)priv->standard.frameperiod.denominator /
732 priv->standard.frameperiod.numerator;
733 mp_msg(MSGT_TV, MSGL_V, "%s: get fps: %f\n", info.short_name,
734 *(float *)arg);
735 return TVI_CONTROL_TRUE;
736 case TVI_CONTROL_VID_GET_BITS:
737 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
738 *(int *)arg = pixfmt2depth(priv->format.fmt.pix.pixelformat);
739 mp_msg(MSGT_TV, MSGL_V, "%s: get depth: %d\n", info.short_name,
740 *(int *)arg);
741 return TVI_CONTROL_TRUE;
742 case TVI_CONTROL_VID_GET_FORMAT:
743 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
744 *(int *)arg = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
745 mp_msg(MSGT_TV, MSGL_V, "%s: get format: %s\n", info.short_name,
746 pixfmt2name(priv->format.fmt.pix.pixelformat));
747 return TVI_CONTROL_TRUE;
748 case TVI_CONTROL_VID_SET_FORMAT:
749 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
750 priv->format.fmt.pix.pixelformat = fcc_mp2vl(*(int *)arg);
751 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
753 priv->mp_format = *(int *)arg;
754 mp_msg(MSGT_TV, MSGL_V, "%s: set format: %s\n", info.short_name,
755 pixfmt2name(priv->format.fmt.pix.pixelformat));
756 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
757 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
758 info.short_name, strerror(errno));
759 return TVI_CONTROL_FALSE;
761 /* according to the v4l2 specs VIDIOC_S_FMT should not fail, inflexible drivers
762 might even always return the default parameters -> update the format here*/
763 priv->mp_format = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
764 return TVI_CONTROL_TRUE;
765 case TVI_CONTROL_VID_GET_WIDTH:
766 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
767 *(int *)arg = priv->format.fmt.pix.width;
768 mp_msg(MSGT_TV, MSGL_V, "%s: get width: %d\n", info.short_name,
769 *(int *)arg);
770 return TVI_CONTROL_TRUE;
771 case TVI_CONTROL_VID_CHK_WIDTH:
772 return TVI_CONTROL_TRUE;
773 case TVI_CONTROL_VID_SET_WIDTH:
774 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
775 priv->format.fmt.pix.width = *(int *)arg;
776 mp_msg(MSGT_TV, MSGL_V, "%s: set width: %d\n", info.short_name,
777 *(int *)arg);
778 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
779 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set width failed: %s\n",
780 info.short_name, strerror(errno));
781 return TVI_CONTROL_FALSE;
783 return TVI_CONTROL_TRUE;
784 case TVI_CONTROL_VID_GET_HEIGHT:
785 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
786 *(int *)arg = priv->format.fmt.pix.height;
787 mp_msg(MSGT_TV, MSGL_V, "%s: get height: %d\n", info.short_name,
788 *(int *)arg);
789 return TVI_CONTROL_TRUE;
790 case TVI_CONTROL_VID_CHK_HEIGHT:
791 return TVI_CONTROL_TRUE;
792 case TVI_CONTROL_VID_SET_HEIGHT:
793 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
794 priv->format.fmt.pix.height = *(int *)arg;
795 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
796 mp_msg(MSGT_TV, MSGL_V, "%s: set height: %d\n", info.short_name,
797 *(int *)arg);
798 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
799 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set height failed: %s\n",
800 info.short_name, strerror(errno));
801 return TVI_CONTROL_FALSE;
803 return TVI_CONTROL_TRUE;
804 case TVI_CONTROL_VID_GET_BRIGHTNESS:
805 control.id = V4L2_CID_BRIGHTNESS;
806 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
807 *(int *)arg = control.value;
808 return TVI_CONTROL_TRUE;
810 return TVI_CONTROL_FALSE;
811 case TVI_CONTROL_VID_SET_BRIGHTNESS:
812 control.id = V4L2_CID_BRIGHTNESS;
813 control.value = *(int *)arg;
814 return set_control(priv, &control, 1);
815 case TVI_CONTROL_VID_GET_HUE:
816 control.id = V4L2_CID_HUE;
817 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
818 *(int *)arg = control.value;
819 return TVI_CONTROL_TRUE;
821 return TVI_CONTROL_FALSE;
822 case TVI_CONTROL_VID_SET_HUE:
823 control.id = V4L2_CID_HUE;
824 control.value = *(int *)arg;
825 return set_control(priv, &control, 1);
826 case TVI_CONTROL_VID_GET_SATURATION:
827 control.id = V4L2_CID_SATURATION;
828 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
829 *(int *)arg = control.value;
830 return TVI_CONTROL_TRUE;
832 return TVI_CONTROL_FALSE;
833 case TVI_CONTROL_VID_SET_SATURATION:
834 control.id = V4L2_CID_SATURATION;
835 control.value = *(int *)arg;
836 return set_control(priv, &control, 1);
837 case TVI_CONTROL_VID_GET_GAIN:
840 control.id = V4L2_CID_AUTOGAIN;
841 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
842 return TVI_CONTROL_FALSE;
844 if(control.value){ //Auto Gain control is enabled
845 *(int*)arg=0;
846 return TVI_CONTROL_TRUE;
849 //Manual Gain control
850 control.id = V4L2_CID_GAIN;
851 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
852 return TVI_CONTROL_FALSE;
854 *(int*)arg=control.value?control.value:1;
856 return TVI_CONTROL_TRUE;
858 case TVI_CONTROL_VID_SET_GAIN:
860 //value==0 means automatic gain control
861 int value=*(int*)arg;
863 if (value < 0 || value>100)
864 return TVI_CONTROL_FALSE;
866 control.id=value?V4L2_CID_GAIN:V4L2_CID_AUTOGAIN;
867 control.value=value?value:1;
869 return set_control(priv,&control,0);
871 case TVI_CONTROL_VID_GET_CONTRAST:
872 control.id = V4L2_CID_CONTRAST;
873 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
874 *(int *)arg = control.value;
875 return TVI_CONTROL_TRUE;
877 return TVI_CONTROL_FALSE;
878 case TVI_CONTROL_VID_SET_CONTRAST:
879 control.id = V4L2_CID_CONTRAST;
880 control.value = *(int *)arg;
881 return set_control(priv, &control, 1);
882 case TVI_CONTROL_TUN_GET_FREQ:
883 frequency.tuner = 0;
884 frequency.type = V4L2_TUNER_ANALOG_TV;
885 if (ioctl(priv->video_fd, VIDIOC_G_FREQUENCY, &frequency) < 0) {
886 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl get frequency failed: %s\n",
887 info.short_name, strerror(errno));
888 return TVI_CONTROL_FALSE;
890 *(int *)arg = frequency.frequency;
891 return TVI_CONTROL_TRUE;
892 case TVI_CONTROL_TUN_SET_FREQ:
893 #if 0
894 set_mute(priv, 1);
895 usleep(100000); // wait to suppress noise during switching
896 #endif
897 frequency.tuner = 0;
898 frequency.type = V4L2_TUNER_ANALOG_TV;
899 frequency.frequency = *(int *)arg;
900 if (ioctl(priv->video_fd, VIDIOC_S_FREQUENCY, &frequency) < 0) {
901 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set frequency failed: %s\n",
902 info.short_name, strerror(errno));
903 return TVI_CONTROL_FALSE;
905 #if 0
906 usleep(100000); // wait to suppress noise during switching
907 set_mute(priv, 0);
908 #endif
909 return TVI_CONTROL_TRUE;
910 case TVI_CONTROL_TUN_GET_TUNER:
911 mp_msg(MSGT_TV, MSGL_V, "%s: get tuner\n",info.short_name);
912 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
913 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
914 info.short_name, strerror(errno));
915 return TVI_CONTROL_FALSE;
917 return TVI_CONTROL_TRUE;
918 case TVI_CONTROL_TUN_SET_TUNER:
919 mp_msg(MSGT_TV, MSGL_V, "%s: set tuner\n",info.short_name);
920 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
921 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
922 info.short_name, strerror(errno));
923 return TVI_CONTROL_FALSE;
925 return TVI_CONTROL_TRUE;
926 case TVI_CONTROL_TUN_GET_NORM:
927 *(int *)arg = priv->standard.index;
928 return TVI_CONTROL_TRUE;
929 case TVI_CONTROL_TUN_GET_SIGNAL:
930 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
931 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
932 info.short_name, strerror(errno));
933 return TVI_CONTROL_FALSE;
935 *(int*)arg=100*(priv->tuner.signal>>8)/255;
936 return TVI_CONTROL_TRUE;
937 case TVI_CONTROL_TUN_SET_NORM:
938 priv->standard.index = *(int *)arg;
939 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
940 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum norm failed: %s\n",
941 info.short_name, strerror(errno));
942 return TVI_CONTROL_FALSE;
944 mp_msg(MSGT_TV, MSGL_V, "%s: set norm: %s\n", info.short_name, priv->standard.name);
945 if (ioctl(priv->video_fd, VIDIOC_S_STD, &priv->standard.id) < 0) {
946 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set norm failed: %s\n",
947 info.short_name, strerror(errno));
948 return TVI_CONTROL_FALSE;
950 return TVI_CONTROL_TRUE;
951 case TVI_CONTROL_SPC_GET_NORMID:
953 int i;
954 for (i = 0;; i++) {
955 struct v4l2_standard standard;
956 memset(&standard, 0, sizeof(standard));
957 standard.index = i;
958 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
959 return TVI_CONTROL_FALSE;
960 if (!strcasecmp(standard.name, (char *)arg)) {
961 *(int *)arg = i;
962 return TVI_CONTROL_TRUE;
965 return TVI_CONTROL_FALSE;
967 case TVI_CONTROL_SPC_GET_INPUT:
968 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, (int *)arg) < 0) {
969 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
970 info.short_name, strerror(errno));
971 return TVI_CONTROL_FALSE;
973 return TVI_CONTROL_TRUE;
974 case TVI_CONTROL_SPC_SET_INPUT:
975 mp_msg(MSGT_TV, MSGL_V, "%s: set input: %d\n", info.short_name, *(int *)arg);
976 priv->input.index = *(int *)arg;
977 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &priv->input) < 0) {
978 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum input failed: %s\n",
979 info.short_name, strerror(errno));
980 return TVI_CONTROL_FALSE;
982 if (ioctl(priv->video_fd, VIDIOC_S_INPUT, (int *)arg) < 0) {
983 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set input failed: %s\n",
984 info.short_name, strerror(errno));
985 return TVI_CONTROL_FALSE;
987 return TVI_CONTROL_TRUE;
988 case TVI_CONTROL_AUD_GET_FORMAT:
989 init_audio(priv);
990 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
991 *(int *)arg = AF_FORMAT_S16_LE;
992 mp_msg(MSGT_TV, MSGL_V, "%s: get audio format: %d\n",
993 info.short_name, *(int *)arg);
994 return TVI_CONTROL_TRUE;
995 case TVI_CONTROL_AUD_GET_SAMPLERATE:
996 init_audio(priv);
997 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
998 *(int *)arg = priv->audio_in.samplerate;
999 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplerate: %d\n",
1000 info.short_name, *(int *)arg);
1001 return TVI_CONTROL_TRUE;
1002 case TVI_CONTROL_AUD_GET_SAMPLESIZE:
1003 init_audio(priv);
1004 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1005 *(int *)arg = priv->audio_in.bytes_per_sample;
1006 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplesize: %d\n",
1007 info.short_name, *(int *)arg);
1008 return TVI_CONTROL_TRUE;
1009 case TVI_CONTROL_AUD_GET_CHANNELS:
1010 init_audio(priv);
1011 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1012 *(int *)arg = priv->audio_in.channels;
1013 mp_msg(MSGT_TV, MSGL_V, "%s: get audio channels: %d\n",
1014 info.short_name, *(int *)arg);
1015 return TVI_CONTROL_TRUE;
1016 case TVI_CONTROL_AUD_SET_SAMPLERATE:
1017 init_audio(priv);
1018 mp_msg(MSGT_TV, MSGL_V, "%s: set audio samplerate: %d\n",
1019 info.short_name, *(int *)arg);
1020 if (audio_in_set_samplerate(&priv->audio_in, *(int*)arg) < 0) return TVI_CONTROL_FALSE;
1021 // setup_audio_buffer_sizes(priv);
1022 return TVI_CONTROL_TRUE;
1023 #ifdef CONFIG_TV_TELETEXT
1024 case TVI_CONTROL_VBI_INIT:
1026 void* ptr;
1027 tt_stream_props tsp;
1029 if (vbi_init(priv,*(char**)arg)!=TVI_CONTROL_TRUE)
1030 return TVI_CONTROL_FALSE;
1031 if(vbi_get_props(priv,&tsp)==TVI_CONTROL_TRUE)
1033 ptr=&tsp;
1034 if(teletext_control(NULL,TV_VBI_CONTROL_START,&ptr)==TVI_CONTROL_TRUE)
1035 priv->priv_vbi=ptr;
1036 else
1037 priv->priv_vbi=NULL;
1039 return TVI_CONTROL_TRUE;
1041 default:
1042 return teletext_control(priv->priv_vbi,cmd,arg);
1043 #endif
1045 mp_msg(MSGT_TV, MSGL_V, "%s: unknown control: %d\n", info.short_name, cmd);
1046 return TVI_CONTROL_UNKNOWN;
1050 #define PRIV ((priv_t *) (tvi_handle->priv))
1052 /* handler creator - entry point ! */
1053 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param)
1055 tvi_handle_t *tvi_handle;
1057 /* new_handle initializes priv with memset 0 */
1058 tvi_handle = new_handle();
1059 if (!tvi_handle) {
1060 return NULL;
1062 PRIV->video_fd = -1;
1064 PRIV->video_dev = strdup(tv_param->device? tv_param->device: "/dev/video0");
1065 if (!PRIV->video_dev) {
1066 free_handle(tvi_handle);
1067 return NULL;
1070 if (tv_param->adevice) {
1071 PRIV->audio_dev = strdup(tv_param->adevice);
1072 if (!PRIV->audio_dev) {
1073 free(PRIV->video_dev);
1074 free_handle(tvi_handle);
1075 return NULL;
1079 PRIV->tv_param=tv_param;
1080 return tvi_handle;
1083 #undef PRIV
1086 static int uninit(priv_t *priv)
1088 int i, frames, dropped = 0;
1090 #ifdef CONFIG_TV_TELETEXT
1091 priv->vbi_shutdown=1;
1092 if(priv->vbi_grabber_thread)
1093 pthread_join(priv->vbi_grabber_thread, NULL);
1095 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_STOP,(void*)1);
1096 priv->priv_vbi=NULL;
1098 if(priv->vbi_fd){
1099 close(priv->vbi_fd);
1100 priv->vbi_fd=0;
1103 if(priv->vbi_dev){
1104 free(priv->vbi_dev);
1105 priv->vbi_dev=0;
1108 #endif
1110 priv->shutdown = 1;
1111 if(priv->video_grabber_thread)
1112 pthread_join(priv->video_grabber_thread, NULL);
1113 pthread_mutex_destroy(&priv->video_buffer_mutex);
1115 if (priv->streamon) {
1116 struct v4l2_buffer buf;
1118 /* get performance */
1119 frames = 1 + lrintf((double)(priv->curr_frame - priv->first_frame) / (1e6 * getfps(priv)));
1120 dropped = frames - priv->frames;
1122 /* turn off streaming */
1123 if (ioctl(priv->video_fd, VIDIOC_STREAMOFF, &(priv->map[0].buf.type)) < 0) {
1124 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamoff failed: %s\n",
1125 info.short_name, strerror(errno));
1127 priv->streamon = 0;
1129 /* unqueue all remaining buffers */
1130 memset(&buf,0,sizeof(buf));
1131 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1132 buf.memory = V4L2_MEMORY_MMAP;
1133 while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
1136 /* unmap all buffers */
1137 for (i = 0; i < priv->mapcount; i++) {
1138 if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {
1139 mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",
1140 info.short_name, strerror(errno));
1144 /* stop audio thread */
1145 if (!priv->tv_param->noaudio && priv->audio_grabber_thread) {
1146 pthread_join(priv->audio_grabber_thread, NULL);
1147 pthread_mutex_destroy(&priv->skew_mutex);
1148 pthread_mutex_destroy(&priv->audio_mutex);
1151 set_mute(priv, 1);
1153 /* free memory and close device */
1154 free(priv->map); priv->map = NULL;
1155 priv->mapcount = 0;
1156 if(priv->video_fd!=-1)close(priv->video_fd); priv->video_fd = -1;
1157 free(priv->video_dev); priv->video_dev = NULL;
1159 if (priv->video_ringbuffer) {
1160 int i;
1161 for (i = 0; i < priv->video_buffer_size_current; i++) {
1162 free(priv->video_ringbuffer[i].data);
1164 free(priv->video_ringbuffer);
1166 if (!priv->tv_param->noaudio) {
1167 if (priv->audio_ringbuffer)
1168 free(priv->audio_ringbuffer);
1169 if (priv->audio_skew_buffer)
1170 free(priv->audio_skew_buffer);
1171 if (priv->audio_skew_delta_buffer)
1172 free(priv->audio_skew_delta_buffer);
1174 audio_in_uninit(&priv->audio_in);
1177 /* show some nice statistics ;-) */
1178 mp_msg(MSGT_TV, MSGL_INFO,
1179 "%s: %d frames successfully processed, %d frames dropped.\n",
1180 info.short_name, priv->frames, dropped);
1181 mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",
1182 info.short_name, priv->video_buffer_size_current);
1183 return 1;
1187 /* initialisation */
1188 static int init(priv_t *priv)
1190 int i;
1192 priv->audio_ringbuffer = NULL;
1193 priv->audio_skew_buffer = NULL;
1194 priv->audio_skew_delta_buffer = NULL;
1196 priv->audio_initialized = 0;
1198 /* Open the video device. */
1199 priv->video_fd = open(priv->video_dev, O_RDWR);
1200 if (priv->video_fd < 0) {
1201 mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",
1202 info.short_name, priv->video_dev, strerror(errno));
1203 uninit(priv);
1204 return 0;
1206 mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",
1207 info.short_name, priv->video_dev, priv->video_fd);
1210 ** Query the video capabilities and current settings
1211 ** for further control calls.
1213 if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
1214 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",
1215 info.short_name, strerror(errno));
1216 uninit(priv);
1217 return 0;
1220 if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))
1222 mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",
1223 priv->video_dev);
1224 return 0;
1227 if (getfmt(priv) < 0) {
1228 uninit(priv);
1229 return 0;
1231 getstd(priv);
1233 ** if this device has got a tuner query it's settings
1234 ** otherwise set some nice defaults
1236 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1237 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
1238 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
1239 info.short_name, strerror(errno));
1240 uninit(priv);
1241 return 0;
1244 mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);
1245 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1246 mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",
1247 (priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",
1248 (priv->tuner.capability & V4L2_TUNER_CAP_LANG1) ? " LANG1" : "",
1249 (priv->tuner.capability & V4L2_TUNER_CAP_LANG2) ? " LANG2" : "");
1250 mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",
1251 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO) ? " MONO" : "",
1252 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",
1253 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1) ? " LANG1" : "",
1254 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2) ? " LANG2" : "");
1256 mp_msg(MSGT_TV, MSGL_INFO, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1257 priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
1258 " video capture": "",
1259 priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?
1260 " video output": "",
1261 priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?
1262 " video overlay": "",
1263 priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?
1264 " VBI capture device": "",
1265 priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?
1266 " VBI output": "",
1267 priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?
1268 " RDS data capture": "",
1269 priv->capability.capabilities & V4L2_CAP_TUNER?
1270 " tuner": "",
1271 priv->capability.capabilities & V4L2_CAP_AUDIO?
1272 " audio": "",
1273 priv->capability.capabilities & V4L2_CAP_READWRITE?
1274 " read/write": "",
1275 priv->capability.capabilities & V4L2_CAP_ASYNCIO?
1276 " async i/o": "",
1277 priv->capability.capabilities & V4L2_CAP_STREAMING?
1278 " streaming": "");
1279 mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");
1280 for (i = 0;; i++) {
1281 struct v4l2_standard standard;
1282 memset(&standard, 0, sizeof(standard));
1283 standard.index = i;
1284 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
1285 break;
1286 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);
1288 mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");
1289 for (i = 0; 1; i++) {
1290 struct v4l2_input input;
1292 input.index = i;
1293 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
1294 break;
1296 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);
1298 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
1299 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
1300 info.short_name, strerror(errno));
1302 mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);
1303 for (i = 0; ; i++) {
1304 struct v4l2_fmtdesc fmtdesc;
1306 fmtdesc.index = i;
1307 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1308 if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
1309 break;
1311 mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",
1312 pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),
1313 fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));
1315 mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",
1316 pixfmt2name(priv->format.fmt.pix.pixelformat));
1318 /* set some nice defaults */
1319 if (getfmt(priv) < 0) return 0;
1320 priv->format.fmt.pix.width = 640;
1321 priv->format.fmt.pix.height = 480;
1322 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
1323 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
1324 info.short_name, strerror(errno));
1325 uninit(priv);
1326 return 0;
1329 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;
1331 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1332 struct v4l2_control control;
1333 if (priv->tv_param->amode >= 0) {
1334 mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);
1335 priv->tuner.audmode = amode2v4l(priv->tv_param->amode);
1336 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
1337 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
1338 info.short_name, strerror(errno));
1339 return TVI_CONTROL_FALSE;
1342 mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,
1343 (priv->tuner.audmode == V4L2_TUNER_MODE_MONO) ? " MONO" : "",
1344 (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",
1345 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG1) ? " LANG1" : "",
1346 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG2) ? " LANG2" : "");
1348 if (priv->tv_param->volume >= 0) {
1349 control.id = V4L2_CID_AUDIO_VOLUME;
1350 control.value = priv->tv_param->volume;
1351 set_control(priv, &control, 0);
1353 if (priv->tv_param->bass >= 0) {
1354 control.id = V4L2_CID_AUDIO_BASS;
1355 control.value = priv->tv_param->bass;
1356 set_control(priv, &control, 0);
1358 if (priv->tv_param->treble >= 0) {
1359 control.id = V4L2_CID_AUDIO_TREBLE;
1360 control.value = priv->tv_param->treble;
1361 set_control(priv, &control, 0);
1363 if (priv->tv_param->balance >= 0) {
1364 control.id = V4L2_CID_AUDIO_BALANCE;
1365 control.value = priv->tv_param->balance;
1366 set_control(priv, &control, 0);
1370 return 1;
1373 static int get_capture_buffer_size(priv_t *priv)
1375 int bufsize, cnt;
1377 if (priv->tv_param->buffer_size >= 0) {
1378 bufsize = priv->tv_param->buffer_size*1024*1024;
1379 } else {
1380 #ifdef HAVE_SYS_SYSINFO_H
1381 struct sysinfo si;
1383 sysinfo(&si);
1384 if (si.totalram<2*1024*1024) {
1385 bufsize = 1024*1024;
1386 } else {
1387 bufsize = si.totalram/2;
1389 #else
1390 bufsize = 16*1024*1024;
1391 #endif
1394 cnt = bufsize/priv->format.fmt.pix.sizeimage;
1395 if (cnt < 2) cnt = 2;
1397 return cnt;
1400 /* that's the real start, we'got the format parameters (checked with control) */
1401 static int start(priv_t *priv)
1403 struct v4l2_requestbuffers request;
1404 unsigned int i;
1406 /* setup audio parameters */
1408 init_audio(priv);
1409 if (!priv->tv_param->noaudio && !priv->audio_initialized) return 0;
1411 /* we need this to size the audio buffer properly */
1412 if (priv->immediate_mode) {
1413 priv->video_buffer_size_max = 2;
1414 } else {
1415 priv->video_buffer_size_max = get_capture_buffer_size(priv);
1418 if (!priv->tv_param->noaudio) {
1419 setup_audio_buffer_sizes(priv);
1420 priv->audio_skew_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1421 if (!priv->audio_skew_buffer) {
1422 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1423 return 0;
1425 priv->audio_skew_delta_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1426 if (!priv->audio_skew_delta_buffer) {
1427 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1428 return 0;
1431 priv->audio_ringbuffer = calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
1432 if (!priv->audio_ringbuffer) {
1433 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
1434 return 0;
1437 priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate
1438 *priv->audio_in.channels
1439 *priv->audio_in.bytes_per_sample);
1440 priv->audio_usecs_per_block = 1e6*priv->audio_secs_per_block;
1441 priv->audio_head = 0;
1442 priv->audio_tail = 0;
1443 priv->audio_cnt = 0;
1444 priv->audio_drop = 0;
1445 priv->audio_skew = 0;
1446 priv->audio_skew_total = 0;
1447 priv->audio_skew_delta_total = 0;
1448 priv->audio_recv_blocks_total = 0;
1449 priv->audio_sent_blocks_total = 0;
1450 priv->audio_null_blocks_inserted = 0;
1451 priv->audio_insert_null_samples = 0;
1452 priv->dropped_frames_timeshift = 0;
1453 priv->dropped_frames_compensated = 0;
1455 pthread_mutex_init(&priv->skew_mutex, NULL);
1456 pthread_mutex_init(&priv->audio_mutex, NULL);
1459 /* setup video parameters */
1460 if (!priv->tv_param->noaudio) {
1461 if (priv->video_buffer_size_max < (3*priv->standard.frameperiod.denominator) /
1462 priv->standard.frameperiod.numerator
1463 *priv->audio_secs_per_block) {
1464 mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"
1465 "You will probably experience heavy framedrops.\n");
1470 int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1472 mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1473 priv->video_buffer_size_max,
1474 priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));
1477 priv->video_ringbuffer = calloc(priv->video_buffer_size_max, sizeof(video_buffer_entry));
1478 if (!priv->video_ringbuffer) {
1479 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
1480 return 0;
1482 memset(priv->video_ringbuffer,0,priv->video_buffer_size_max * sizeof(video_buffer_entry));
1484 pthread_mutex_init(&priv->video_buffer_mutex, NULL);
1486 priv->video_head = 0;
1487 priv->video_tail = 0;
1488 priv->video_cnt = 0;
1490 /* request buffers */
1491 if (priv->immediate_mode) {
1492 request.count = 2;
1493 } else {
1494 request.count = BUFFER_COUNT;
1497 request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1498 request.memory = V4L2_MEMORY_MMAP;
1499 if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
1500 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",
1501 info.short_name, strerror(errno));
1502 return 0;
1505 /* query buffers */
1506 if (!(priv->map = calloc(request.count, sizeof(struct map)))) {
1507 mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",
1508 info.short_name, strerror(errno));
1509 return 0;
1512 /* map and queue buffers */
1513 for (i = 0; i < request.count; i++) {
1514 memset(&priv->map[i].buf,0,sizeof(priv->map[i].buf));
1515 priv->map[i].buf.index = i;
1516 priv->map[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1517 priv->map[i].buf.memory = V4L2_MEMORY_MMAP;
1518 if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
1519 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",
1520 info.short_name, strerror(errno));
1521 free(priv->map);
1522 priv->map = NULL;
1523 return 0;
1525 priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |
1526 PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);
1527 if (priv->map[i].addr == MAP_FAILED) {
1528 mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",
1529 info.short_name, strerror(errno));
1530 priv->map[i].len = 0;
1531 return 0;
1533 priv->map[i].len = priv->map[i].buf.length;
1534 /* count up to make sure this is correct everytime */
1535 priv->mapcount++;
1537 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1538 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1539 info.short_name, strerror(errno));
1540 return 0;
1544 #ifdef CONFIG_TV_TELETEXT
1545 /* start vbi thread */
1546 if(priv->priv_vbi){
1547 priv->vbi_shutdown = 0;
1548 pthread_create(&priv->vbi_grabber_thread, NULL, vbi_grabber, priv);
1550 #endif
1551 /* start audio thread */
1552 priv->shutdown = 0;
1553 priv->audio_skew_measure_time = 0;
1554 priv->first_frame = 0;
1555 priv->audio_skew = 0;
1556 priv->first = 1;
1558 set_mute(priv, 0);
1560 return 1;
1563 // copies a video frame
1564 static inline void copy_frame(priv_t *priv, video_buffer_entry *dest, unsigned char *source,int len)
1566 dest->framesize=len;
1567 if(priv->tv_param->automute>0){
1568 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) >= 0) {
1569 if(priv->tv_param->automute<<8>priv->tuner.signal){
1570 fill_blank_frame(dest->data,dest->framesize,fcc_vl2mp(priv->format.fmt.pix.pixelformat));
1571 set_mute(priv,1);
1572 return;
1575 set_mute(priv,0);
1577 memcpy(dest->data, source, len);
1580 // maximum skew change, in frames
1581 #define MAX_SKEW_DELTA 0.6
1582 static void *video_grabber(void *data)
1584 priv_t *priv = (priv_t*)data;
1585 long long skew, prev_skew, xskew, interval, prev_interval, delta;
1586 int i;
1587 int framesize = priv->format.fmt.pix.sizeimage;
1588 fd_set rdset;
1589 struct timeval timeout;
1590 struct v4l2_buffer buf;
1592 xskew = 0;
1593 skew = 0;
1594 interval = 0;
1595 prev_interval = 0;
1596 prev_skew = 0;
1598 mp_msg(MSGT_TV, MSGL_V, "%s: going to capture\n", info.short_name);
1599 if (ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
1600 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamon failed: %s\n",
1601 info.short_name, strerror(errno));
1602 return 0;
1604 priv->streamon = 1;
1606 if (!priv->tv_param->noaudio) {
1607 pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
1610 for (priv->frames = 0; !priv->shutdown;)
1612 int ret;
1614 if (priv->immediate_mode) {
1615 while (priv->video_cnt == priv->video_buffer_size_max) {
1616 usleep(10000);
1617 if (priv->shutdown) {
1618 return NULL;
1623 FD_ZERO (&rdset);
1624 FD_SET (priv->video_fd, &rdset);
1626 timeout.tv_sec = 1;
1627 timeout.tv_usec = 0;
1629 i = select(priv->video_fd + 1, &rdset, NULL, NULL, &timeout);
1630 if (i < 0) {
1631 mp_msg(MSGT_TV, MSGL_ERR, "%s: select failed: %s\n",
1632 info.short_name, strerror(errno));
1633 continue;
1635 else if (i == 0) {
1636 mp_msg(MSGT_TV, MSGL_ERR, "%s: select timeout\n", info.short_name);
1637 continue;
1639 else if (!FD_ISSET(priv->video_fd, &rdset)) {
1640 continue;
1643 memset(&buf,0,sizeof(buf));
1644 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1645 buf.memory = V4L2_MEMORY_MMAP;
1646 ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
1648 if (ret < 0) {
1650 if there's no signal, the buffer might me dequeued
1651 so we query all the buffers to see which one we should
1652 put back to queue
1654 observed with saa7134 0.2.8
1655 don't know if is it a bug or (mis)feature
1657 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1658 info.short_name, strerror(errno), buf.index);
1659 for (i = 0; i < priv->mapcount; i++) {
1660 memset(&buf,0,sizeof(buf));
1661 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1662 buf.memory = V4L2_MEMORY_MMAP;
1663 buf.index = i;
1664 ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
1665 if (ret < 0) {
1666 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s, idx = %d\n",
1667 info.short_name, strerror(errno), buf.index);
1668 return 0;
1670 if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
1671 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1672 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1673 info.short_name, strerror(errno));
1674 return 0;
1678 continue;
1681 /* store the timestamp of the very first frame as reference */
1682 if (!priv->frames++) {
1683 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1684 priv->first_frame = (long long)1e6*buf.timestamp.tv_sec + buf.timestamp.tv_usec;
1685 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1687 priv->curr_frame = (long long)buf.timestamp.tv_sec*1e6+buf.timestamp.tv_usec;
1688 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1690 interval = priv->curr_frame - priv->first_frame;
1691 delta = interval - prev_interval;
1693 if (!priv->immediate_mode) {
1694 // interpolate the skew in time
1695 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1696 xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
1697 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1698 // correct extreme skew changes to avoid (especially) moving backwards in time
1699 if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
1700 skew = prev_skew + delta*MAX_SKEW_DELTA;
1701 } else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) {
1702 skew = prev_skew - delta*MAX_SKEW_DELTA;
1703 } else {
1704 skew = xskew;
1708 mp_msg(MSGT_TV, MSGL_DBG3, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1709 delta ? (double)1e6/delta : -1,
1710 (double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
1711 mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
1713 prev_skew = skew;
1714 prev_interval = interval;
1716 /* allocate a new buffer, if needed */
1717 pthread_mutex_lock(&priv->video_buffer_mutex);
1718 if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
1719 if (priv->video_cnt == priv->video_buffer_size_current) {
1720 unsigned char *newbuf = malloc(framesize);
1721 if (newbuf) {
1722 memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
1723 (priv->video_buffer_size_current-priv->video_tail)*sizeof(video_buffer_entry));
1724 priv->video_ringbuffer[priv->video_tail].data = newbuf;
1725 if ((priv->video_head >= priv->video_tail) && (priv->video_cnt > 0)) priv->video_head++;
1726 priv->video_buffer_size_current++;
1730 pthread_mutex_unlock(&priv->video_buffer_mutex);
1732 if (priv->video_cnt == priv->video_buffer_size_current) {
1733 if (!priv->immediate_mode) {
1734 mp_msg(MSGT_TV, MSGL_ERR, "\nvideo buffer full - dropping frame\n");
1735 if (priv->audio_insert_null_samples) {
1736 pthread_mutex_lock(&priv->audio_mutex);
1737 priv->dropped_frames_timeshift += delta;
1738 pthread_mutex_unlock(&priv->audio_mutex);
1741 } else {
1742 if (priv->immediate_mode) {
1743 priv->video_ringbuffer[priv->video_tail].timestamp = 0;
1744 } else {
1745 // compensate for audio skew
1746 // negative skew => there are more audio samples, increase interval
1747 // positive skew => less samples, shorten the interval
1748 priv->video_ringbuffer[priv->video_tail].timestamp = interval - skew;
1749 if (priv->audio_insert_null_samples && priv->video_ringbuffer[priv->video_tail].timestamp > 0) {
1750 pthread_mutex_lock(&priv->audio_mutex);
1751 priv->video_ringbuffer[priv->video_tail].timestamp +=
1752 (priv->audio_null_blocks_inserted
1753 - priv->dropped_frames_timeshift/priv->audio_usecs_per_block)
1754 *priv->audio_usecs_per_block;
1755 pthread_mutex_unlock(&priv->audio_mutex);
1758 copy_frame(priv, priv->video_ringbuffer+priv->video_tail, priv->map[buf.index].addr,buf.bytesused);
1759 priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
1760 priv->video_cnt++;
1762 if (ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
1763 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1764 info.short_name, strerror(errno));
1765 return 0;
1768 return NULL;
1771 #define MAX_LOOP 50
1772 static double grab_video_frame(priv_t *priv, char *buffer, int len)
1774 double interval;
1775 int loop_cnt = 0;
1777 if (priv->first) {
1778 pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1779 priv->first = 0;
1782 while (priv->video_cnt == 0) {
1783 usleep(10000);
1784 if (loop_cnt++ > MAX_LOOP) return 0;
1787 pthread_mutex_lock(&priv->video_buffer_mutex);
1788 interval = (double)priv->video_ringbuffer[priv->video_head].timestamp*1e-6;
1789 memcpy(buffer, priv->video_ringbuffer[priv->video_head].data, len);
1790 priv->video_cnt--;
1791 priv->video_head = (priv->video_head+1)%priv->video_buffer_size_current;
1792 pthread_mutex_unlock(&priv->video_buffer_mutex);
1794 return interval;
1797 static int get_video_framesize(priv_t *priv)
1800 this routine will be called before grab_video_frame
1801 thus let's return topmost frame's size
1803 if (priv->video_cnt)
1804 return priv->video_ringbuffer[priv->video_head].framesize;
1806 no video frames yet available. i don't know what to do in this case,
1807 thus let's return some fallback result (for compressed format this will be
1808 maximum allowed frame size.
1810 return priv->format.fmt.pix.sizeimage;
1813 //#define DOUBLESPEED
1814 #ifdef DOUBLESPEED
1815 // for testing purposes only
1816 static void read_doublespeed(priv_t *priv)
1818 char *bufx = calloc(priv->audio_in.blocksize, 2);
1819 short *s;
1820 short *d;
1821 int i;
1823 audio_in_read_chunk(&priv->audio_in, bufx);
1824 audio_in_read_chunk(&priv->audio_in, bufx+priv->audio_in.blocksize);
1826 s = bufx;
1827 d = priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize;
1828 for (i = 0; i < priv->audio_in.blocksize/2; i++) {
1829 *d++ = *s++;
1830 *s++;
1834 #endif
1836 static void *audio_grabber(void *data)
1838 priv_t *priv = (priv_t*)data;
1839 struct timeval tv;
1840 int i, audio_skew_ptr = 0;
1841 long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
1842 long long start_time_avg;
1844 gettimeofday(&tv, NULL);
1845 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1846 audio_in_start_capture(&priv->audio_in);
1847 for (i = 0; i < priv->aud_skew_cnt; i++)
1848 priv->audio_skew_buffer[i] = 0;
1849 for (i = 0; i < priv->aud_skew_cnt; i++)
1850 priv->audio_skew_delta_buffer[i] = 0;
1852 for (; !priv->shutdown;)
1854 #ifdef DOUBLESPEED
1855 read_doublespeed(priv);
1856 #else
1857 if (audio_in_read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize) < 0)
1858 continue;
1859 #endif
1860 pthread_mutex_lock(&priv->skew_mutex);
1861 if (priv->first_frame == 0) {
1862 // there is no first frame yet (unlikely to happen)
1863 gettimeofday(&tv, NULL);
1864 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1865 // fprintf(stderr, "warning - first frame not yet available!\n");
1866 pthread_mutex_unlock(&priv->skew_mutex);
1867 continue;
1869 pthread_mutex_unlock(&priv->skew_mutex);
1871 gettimeofday(&tv, NULL);
1873 priv->audio_recv_blocks_total++;
1874 current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
1876 if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
1877 start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1878 priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
1881 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1882 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1884 // put the current skew into the ring buffer
1885 priv->audio_skew_total -= priv->audio_skew_buffer[audio_skew_ptr];
1886 priv->audio_skew_buffer[audio_skew_ptr] = current_time
1887 - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1888 priv->audio_skew_total += priv->audio_skew_buffer[audio_skew_ptr];
1890 pthread_mutex_lock(&priv->skew_mutex);
1892 // skew calculation
1894 // compute the sliding average of the skews
1895 if (priv->audio_recv_blocks_total > priv->aud_skew_cnt) {
1896 priv->audio_skew = priv->audio_skew_total/priv->aud_skew_cnt;
1897 } else {
1898 priv->audio_skew = priv->audio_skew_total/priv->audio_recv_blocks_total;
1901 // put the current skew change (skew-prev_skew) into the ring buffer
1902 priv->audio_skew_delta_total -= priv->audio_skew_delta_buffer[audio_skew_ptr];
1903 priv->audio_skew_delta_buffer[audio_skew_ptr] = priv->audio_skew - prev_skew_uncorr;
1904 priv->audio_skew_delta_total += priv->audio_skew_delta_buffer[audio_skew_ptr];
1905 prev_skew_uncorr = priv->audio_skew; // remember the _uncorrected_ average value
1907 audio_skew_ptr = (audio_skew_ptr+1) % priv->aud_skew_cnt; // rotate the buffer pointer
1909 // sliding average approximates the value in the middle of the interval
1910 // so interpolate the skew value further to the current time
1911 priv->audio_skew += priv->audio_skew_delta_total/2;
1913 // now finally, priv->audio_skew contains fairly good approximation
1914 // of the current value
1916 // current skew factor (assuming linearity)
1917 // used for further interpolation in video_grabber
1918 // probably overkill but seems to be necessary for
1919 // stress testing by dropping half of the audio frames ;)
1920 // especially when using ALSA with large block sizes
1921 // where audio_skew remains a long while behind
1922 if ((priv->audio_skew_measure_time != 0) && (current_time - priv->audio_skew_measure_time != 0)) {
1923 priv->audio_skew_factor = (double)(priv->audio_skew-prev_skew)/(current_time - priv->audio_skew_measure_time);
1924 } else {
1925 priv->audio_skew_factor = 0.0;
1928 priv->audio_skew_measure_time = current_time;
1929 prev_skew = priv->audio_skew;
1930 priv->audio_skew += priv->audio_start_time - priv->first_frame;
1931 pthread_mutex_unlock(&priv->skew_mutex);
1933 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1935 pthread_mutex_lock(&priv->audio_mutex);
1936 if ((priv->audio_tail+1) % priv->audio_buffer_size == priv->audio_head) {
1937 mp_msg(MSGT_TV, MSGL_ERR, "\ntoo bad - dropping audio frame !\n");
1938 priv->audio_drop++;
1939 } else {
1940 priv->audio_tail = (priv->audio_tail+1) % priv->audio_buffer_size;
1941 priv->audio_cnt++;
1943 pthread_mutex_unlock(&priv->audio_mutex);
1945 return NULL;
1948 static double grab_audio_frame(priv_t *priv, char *buffer, int len)
1950 mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1951 priv, buffer, len);
1953 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1954 // => switch to the mode which outputs audio immediately, even if
1955 // it should be silence
1956 if (priv->first) priv->audio_insert_null_samples = 1;
1958 pthread_mutex_lock(&priv->audio_mutex);
1959 while (priv->audio_insert_null_samples
1960 && priv->dropped_frames_timeshift - priv->dropped_frames_compensated >= priv->audio_usecs_per_block) {
1961 // some frames were dropped - drop the corresponding number of audio blocks
1962 if (priv->audio_drop) {
1963 priv->audio_drop--;
1964 } else {
1965 if (priv->audio_head == priv->audio_tail) break;
1966 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1968 priv->dropped_frames_compensated += priv->audio_usecs_per_block;
1971 // compensate for dropped audio frames
1972 if (priv->audio_drop && (priv->audio_head == priv->audio_tail)) {
1973 priv->audio_drop--;
1974 memset(buffer, 0, len);
1975 goto out;
1978 if (priv->audio_insert_null_samples && (priv->audio_head == priv->audio_tail)) {
1979 // return silence to avoid desync and stuttering
1980 memset(buffer, 0, len);
1981 priv->audio_null_blocks_inserted++;
1982 goto out;
1985 pthread_mutex_unlock(&priv->audio_mutex);
1986 while (priv->audio_head == priv->audio_tail) {
1987 // this is mencoder => just wait until some audio is available
1988 usleep(10000);
1990 pthread_mutex_lock(&priv->audio_mutex);
1991 memcpy(buffer, priv->audio_ringbuffer+priv->audio_head*priv->audio_in.blocksize, len);
1992 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1993 priv->audio_cnt--;
1994 out:
1995 pthread_mutex_unlock(&priv->audio_mutex);
1996 priv->audio_sent_blocks_total++;
1997 return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
2000 static int get_audio_framesize(priv_t *priv)
2002 return priv->audio_in.blocksize;