Rename exit_player() use outside core to exit_player_bad()
[mplayer.git] / stream / tvi_v4l2.c
blobfc23727f9f3c79564170652213700193ed3867e3
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 #ifdef HAVE_SYS_SYSINFO_H
39 #include <sys/sysinfo.h>
40 #endif
41 #include <linux/types.h>
42 #include <linux/videodev2.h>
43 #include "mp_msg.h"
44 #include "libmpcodecs/img_format.h"
45 #include "libaf/af_format.h"
46 #include "tv.h"
47 #include "audio_in.h"
49 #define info tvi_info_v4l2
50 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param);
51 /* information about this file */
52 const tvi_info_t tvi_info_v4l2 = {
53 tvi_init_v4l2,
54 "Video 4 Linux 2 input",
55 "v4l2",
56 "Martin Olschewski <olschewski@zpr.uni-koeln.de>",
57 "first try, more to come ;-)"
60 struct map {
61 struct v4l2_buffer buf;
62 void *addr;
63 size_t len;
66 #define BUFFER_COUNT 6
68 /** video ringbuffer entry */
69 typedef struct {
70 unsigned char *data; ///< frame contents
71 long long timestamp; ///< frame timestamp
72 int framesize; ///< actual frame size
73 } video_buffer_entry;
75 /* private data */
76 typedef struct {
77 /* video */
78 char *video_dev;
79 int video_fd;
80 #ifdef CONFIG_TV_TELETEXT
81 char *vbi_dev;
82 int vbi_fd;
83 int vbi_bufsize;
84 int vbi_shutdown;
85 pthread_t vbi_grabber_thread;
86 void *priv_vbi;
87 #endif
88 int mp_format;
89 struct v4l2_capability capability;
90 struct v4l2_input input;
91 struct v4l2_format format;
92 struct v4l2_standard standard;
93 struct v4l2_tuner tuner;
94 struct map *map;
95 int mapcount;
96 int frames;
97 volatile long long first_frame;
98 long long curr_frame;
99 /* audio video interleaving ;-) */
100 volatile int streamon;
101 pthread_t audio_grabber_thread;
102 pthread_mutex_t skew_mutex;
104 /* 2nd level video buffers */
105 int first;
106 int immediate_mode;
108 int video_buffer_size_max;
109 volatile int video_buffer_size_current;
110 video_buffer_entry *video_ringbuffer;
111 volatile int video_head;
112 volatile int video_tail;
113 volatile int video_cnt;
114 pthread_t video_grabber_thread;
115 pthread_mutex_t video_buffer_mutex;
117 /* audio */
118 char *audio_dev;
119 audio_in_t audio_in;
121 long long audio_start_time;
122 int audio_buffer_size;
123 int aud_skew_cnt;
124 unsigned char *audio_ringbuffer;
125 long long *audio_skew_buffer;
126 long long *audio_skew_delta_buffer;
127 volatile int audio_head;
128 volatile int audio_tail;
129 volatile int audio_cnt;
130 volatile long long audio_skew;
131 volatile double audio_skew_factor;
132 volatile long long audio_skew_measure_time;
133 volatile int audio_drop;
134 volatile int shutdown;
136 int audio_initialized;
137 double audio_secs_per_block;
138 long long audio_usecs_per_block;
139 long long audio_skew_total;
140 long long audio_skew_delta_total;
141 long audio_recv_blocks_total;
142 long audio_sent_blocks_total;
143 pthread_mutex_t audio_mutex;
144 int audio_insert_null_samples;
145 volatile long audio_null_blocks_inserted;
146 volatile long long dropped_frames_timeshift;
147 long long dropped_frames_compensated;
149 tv_param_t *tv_param;
150 } priv_t;
152 #include "tvi_def.h"
154 static void *audio_grabber(void *data);
155 static void *video_grabber(void *data);
157 /**********************************************************************\
159 Only few of the fourccs are the same in v4l2 and mplayer:
161 IMGFMT_YVU9 == V4L2_PIX_FMT_YVU410
162 IMGFMT_YV12 == V4L2_PIX_FMT_YVU420
163 IMGFMT_NV12 == V4L2_PIX_FMT_NV12
164 IMGFMT_422P == V4L2_PIX_FMT_YUV422P
165 IMGFMT_411P == V4L2_PIX_FMT_YUV411P
166 IMGFMT_UYVY == V4L2_PIX_FMT_UYVY
167 IMGFMT_Y41P == V4L2_PIX_FMT_Y41P
169 This may be an useful translation table for some others:
171 IMGFMT_RGB8 == V4L2_PIX_FMT_RGB332
172 IMGFMT_BGR15 == V4L2_PIX_FMT_RGB555
173 IMGFMT_BGR16 == V4L2_PIX_FMT_RGB565
174 IMGFMT_RGB24 == V4L2_PIX_FMT_RGB24
175 IMGFMT_RGB32 == V4L2_PIX_FMT_RGB32
176 IMGFMT_BGR24 == V4L2_PIX_FMT_BGR24
177 IMGFMT_BGR32 == V4L2_PIX_FMT_BGR32
178 IMGFMT_Y800 == V4L2_PIX_FMT_GREY
179 IMGFMT_IF09 == V4L2_PIX_FMT_YUV410
180 IMGFMT_I420 == V4L2_PIX_FMT_YUV420
181 IMGFMT_YUY2 == V4L2_PIX_FMT_YUYV
183 \**********************************************************************/
186 ** Translate a mplayer fourcc to a video4linux2 pixel format.
188 static int fcc_mp2vl(int fcc)
190 switch (fcc) {
191 case IMGFMT_RGB8: return V4L2_PIX_FMT_RGB332;
192 case IMGFMT_BGR15: return V4L2_PIX_FMT_RGB555;
193 case IMGFMT_BGR16: return V4L2_PIX_FMT_RGB565;
194 case IMGFMT_RGB24: return V4L2_PIX_FMT_RGB24;
195 case IMGFMT_RGB32: return V4L2_PIX_FMT_RGB32;
196 case IMGFMT_BGR24: return V4L2_PIX_FMT_BGR24;
197 case IMGFMT_BGR32: return V4L2_PIX_FMT_BGR32;
198 case IMGFMT_Y800: return V4L2_PIX_FMT_GREY;
199 case IMGFMT_IF09: return V4L2_PIX_FMT_YUV410;
200 case IMGFMT_I420: return V4L2_PIX_FMT_YUV420;
201 case IMGFMT_YUY2: return V4L2_PIX_FMT_YUYV;
202 case IMGFMT_YV12: return V4L2_PIX_FMT_YVU420;
203 case IMGFMT_UYVY: return V4L2_PIX_FMT_UYVY;
204 case IMGFMT_MJPEG: return V4L2_PIX_FMT_MJPEG;
206 return fcc;
210 ** Translate a video4linux2 fourcc aka pixel format to mplayer.
212 static int fcc_vl2mp(int fcc)
214 switch (fcc) {
215 case V4L2_PIX_FMT_RGB332: return IMGFMT_RGB8;
216 case V4L2_PIX_FMT_RGB555: return IMGFMT_BGR15;
217 case V4L2_PIX_FMT_RGB565: return IMGFMT_BGR16;
218 case V4L2_PIX_FMT_RGB24: return IMGFMT_RGB24;
219 case V4L2_PIX_FMT_RGB32: return IMGFMT_RGB32;
220 case V4L2_PIX_FMT_BGR24: return IMGFMT_BGR24;
221 case V4L2_PIX_FMT_BGR32: return IMGFMT_BGR32;
222 case V4L2_PIX_FMT_GREY: return IMGFMT_Y800;
223 case V4L2_PIX_FMT_YUV410: return IMGFMT_IF09;
224 case V4L2_PIX_FMT_YUV420: return IMGFMT_I420;
225 case V4L2_PIX_FMT_YVU420: return IMGFMT_YV12;
226 case V4L2_PIX_FMT_YUYV: return IMGFMT_YUY2;
227 case V4L2_PIX_FMT_UYVY: return IMGFMT_UYVY;
228 case V4L2_PIX_FMT_MJPEG: return IMGFMT_MJPEG;
230 return fcc;
234 ** Translate a video4linux2 fourcc aka pixel format
235 ** to a human readable string.
237 static const char *pixfmt2name(int pixfmt)
239 static char unknown[24];
241 switch (pixfmt) {
242 case V4L2_PIX_FMT_RGB332: return "RGB332";
243 case V4L2_PIX_FMT_RGB555: return "RGB555";
244 case V4L2_PIX_FMT_RGB565: return "RGB565";
245 case V4L2_PIX_FMT_RGB555X: return "RGB555X";
246 case V4L2_PIX_FMT_RGB565X: return "RGB565X";
247 case V4L2_PIX_FMT_BGR24: return "BGR24";
248 case V4L2_PIX_FMT_RGB24: return "RGB24";
249 case V4L2_PIX_FMT_BGR32: return "BGR32";
250 case V4L2_PIX_FMT_RGB32: return "RGB32";
251 case V4L2_PIX_FMT_GREY: return "GREY";
252 case V4L2_PIX_FMT_YVU410: return "YVU410";
253 case V4L2_PIX_FMT_YVU420: return "YVU420";
254 case V4L2_PIX_FMT_YUYV: return "YUYV";
255 case V4L2_PIX_FMT_UYVY: return "UYVY";
256 /* case V4L2_PIX_FMT_YVU422P: return "YVU422P"; */
257 /* case V4L2_PIX_FMT_YVU411P: return "YVU411P"; */
258 case V4L2_PIX_FMT_YUV422P: return "YUV422P";
259 case V4L2_PIX_FMT_YUV411P: return "YUV411P";
260 case V4L2_PIX_FMT_Y41P: return "Y41P";
261 case V4L2_PIX_FMT_NV12: return "NV12";
262 case V4L2_PIX_FMT_NV21: return "NV21";
263 case V4L2_PIX_FMT_YUV410: return "YUV410";
264 case V4L2_PIX_FMT_YUV420: return "YUV420";
265 case V4L2_PIX_FMT_YYUV: return "YYUV";
266 case V4L2_PIX_FMT_HI240: return "HI240";
267 case V4L2_PIX_FMT_WNVA: return "WNVA";
268 case V4L2_PIX_FMT_MJPEG: return "MJPEG";
270 sprintf(unknown, "unknown (0x%x)", pixfmt);
271 return unknown;
276 ** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
278 static int pixfmt2depth(int pixfmt)
280 switch (pixfmt) {
281 case V4L2_PIX_FMT_RGB332:
282 return 8;
283 case V4L2_PIX_FMT_RGB555:
284 case V4L2_PIX_FMT_RGB565:
285 case V4L2_PIX_FMT_RGB555X:
286 case V4L2_PIX_FMT_RGB565X:
287 return 16;
288 case V4L2_PIX_FMT_BGR24:
289 case V4L2_PIX_FMT_RGB24:
290 return 24;
291 case V4L2_PIX_FMT_BGR32:
292 case V4L2_PIX_FMT_RGB32:
293 return 32;
294 case V4L2_PIX_FMT_GREY:
295 return 8;
296 case V4L2_PIX_FMT_YVU410:
297 return 9;
298 case V4L2_PIX_FMT_YVU420:
299 return 12;
300 case V4L2_PIX_FMT_YUYV:
301 case V4L2_PIX_FMT_UYVY:
302 case V4L2_PIX_FMT_YUV422P:
303 case V4L2_PIX_FMT_YUV411P:
304 return 16;
305 case V4L2_PIX_FMT_Y41P:
306 case V4L2_PIX_FMT_NV12:
307 case V4L2_PIX_FMT_NV21:
308 return 12;
309 case V4L2_PIX_FMT_YUV410:
310 return 9;
311 case V4L2_PIX_FMT_YUV420:
312 return 12;
313 case V4L2_PIX_FMT_YYUV:
314 return 16;
315 case V4L2_PIX_FMT_HI240:
316 return 8;
319 return 0;
322 static int amode2v4l(int amode)
324 switch (amode) {
325 case 0:
326 return V4L2_TUNER_MODE_MONO;
327 case 1:
328 return V4L2_TUNER_MODE_STEREO;
329 case 2:
330 return V4L2_TUNER_MODE_LANG1;
331 case 3:
332 return V4L2_TUNER_MODE_LANG2;
333 default:
334 return -1;
340 ** Get current FPS.
342 static double getfps(priv_t *priv)
344 if (priv->tv_param->fps > 0)
345 return priv->tv_param->fps;
346 if (priv->standard.frameperiod.denominator && priv->standard.frameperiod.numerator)
347 return (double)priv->standard.frameperiod.denominator / priv->standard.frameperiod.numerator;
348 return 25.0;
351 // sets and sanitizes audio buffer/block sizes
352 static void setup_audio_buffer_sizes(priv_t *priv)
354 int bytes_per_sample = priv->audio_in.bytes_per_sample;
355 int seconds = priv->video_buffer_size_max/getfps(priv);
357 if (seconds < 5) seconds = 5;
358 if (seconds > 500) seconds = 500;
360 // make the audio buffer at least as the video buffer capacity (or 5 seconds) long
361 priv->audio_buffer_size = 1 + seconds*priv->audio_in.samplerate
362 *priv->audio_in.channels
363 *bytes_per_sample/priv->audio_in.blocksize;
364 if (priv->audio_buffer_size < 256) priv->audio_buffer_size = 256;
366 // make the skew buffer at least 1 second long
367 priv->aud_skew_cnt = 1 + 1*priv->audio_in.samplerate
368 *priv->audio_in.channels
369 *bytes_per_sample/priv->audio_in.blocksize;
370 if (priv->aud_skew_cnt < 16) priv->aud_skew_cnt = 16;
372 mp_msg(MSGT_TV, MSGL_V, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
373 priv->audio_buffer_size, priv->audio_in.blocksize, priv->aud_skew_cnt);
376 static void init_audio(priv_t *priv)
378 if (priv->audio_initialized) return;
380 if (!priv->tv_param->noaudio) {
381 #ifdef CONFIG_ALSA
382 if (priv->tv_param->alsa)
383 audio_in_init(&priv->audio_in, AUDIO_IN_ALSA);
384 else
385 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
386 #else
387 audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
388 #endif
390 if (priv->audio_dev) {
391 audio_in_set_device(&priv->audio_in, priv->audio_dev);
394 audio_in_set_samplerate(&priv->audio_in, 44100);
395 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
396 if (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) {
397 audio_in_set_channels(&priv->audio_in, 2);
398 } else {
399 audio_in_set_channels(&priv->audio_in, 1);
401 } else {
402 if (priv->tv_param->forcechan >= 0) {
403 audio_in_set_channels(&priv->audio_in, priv->tv_param->forcechan);
404 } else {
405 audio_in_set_channels(&priv->audio_in, 2);
409 if (audio_in_setup(&priv->audio_in) < 0) return;
411 priv->audio_initialized = 1;
415 #if 0
417 ** the number of milliseconds elapsed between time0 and time1
419 static size_t difftv(struct timeval time1, struct timeval time0)
421 return (time1.tv_sec - time0.tv_sec) * 1000 +
422 (time1.tv_usec - time0.tv_usec) / 1000;
424 #endif
427 ** Get current video capture format.
429 static int getfmt(priv_t *priv)
431 int i;
433 priv->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
434 if ((i = ioctl(priv->video_fd, VIDIOC_G_FMT, &priv->format)) < 0) {
435 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get format failed: %s\n",
436 info.short_name, strerror(errno));
438 return i;
443 ** Get current video capture standard.
445 static int getstd(priv_t *priv)
447 v4l2_std_id id;
448 int i=0;
450 if (ioctl(priv->video_fd, VIDIOC_G_STD, &id) < 0) {
451 struct v4l2_streamparm parm;
453 parm.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
454 if(ioctl(priv->video_fd, VIDIOC_G_PARM, &parm) >= 0) {
455 mp_msg(MSGT_TV, MSGL_WARN, "%s: your device driver does not support VIDIOC_G_STD ioctl,"
456 " VIDIOC_G_PARM was used instead.\n", info.short_name);
457 priv->standard.index=0;
458 priv->standard.id=0;
459 priv->standard.frameperiod=parm.parm.capture.timeperframe;
460 return 0;
463 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get standard failed: %s\n",
464 info.short_name, strerror(errno));
465 return -1;
467 do {
468 priv->standard.index = i++;
469 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
470 return -1;
472 } while (priv->standard.id != id);
473 return 0;
476 /***********************************************************************\
479 * Interface to mplayer *
482 \***********************************************************************/
484 static int set_mute(priv_t *priv, int value)
486 struct v4l2_control control;
487 control.id = V4L2_CID_AUDIO_MUTE;
488 control.value = value;
489 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, &control) < 0) {
490 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set mute failed: %s\n",
491 info.short_name, strerror(errno));
492 return 0;
494 return 1;
498 ** MPlayer uses values from -100 up to 100 for controls.
499 ** Here they are scaled to what the tv card needs and applied.
501 static int set_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
502 struct v4l2_queryctrl qctrl;
503 qctrl.id = control->id;
504 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
505 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
506 info.short_name, strerror(errno));
507 return TVI_CONTROL_FALSE;
510 if (val_signed) {
511 if (control->value < 0) {
512 control->value = qctrl.default_value + control->value *
513 (qctrl.default_value - qctrl.minimum) / 100;
514 } else {
515 control->value = qctrl.default_value + control->value *
516 (qctrl.maximum - qctrl.default_value) / 100;
518 } else {
519 if (control->value < 50) {
520 control->value = qctrl.default_value + (control->value-50) *
521 (qctrl.default_value - qctrl.minimum) / 50;
522 } else {
523 control->value = qctrl.default_value + (control->value-50) *
524 (qctrl.maximum - qctrl.default_value) / 50;
529 if (ioctl(priv->video_fd, VIDIOC_S_CTRL, control) < 0) {
530 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl set %s %d failed: %s\n",
531 info.short_name, qctrl.name, control->value, strerror(errno));
532 return TVI_CONTROL_FALSE;
534 mp_msg(MSGT_TV, MSGL_V, "%s: set %s: %d [%d, %d]\n", info.short_name,
535 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
537 return TVI_CONTROL_TRUE;
542 ** Scale the control values back to what mplayer needs.
544 static int get_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
545 struct v4l2_queryctrl qctrl;
547 qctrl.id = control->id;
548 if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
549 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
550 info.short_name, strerror(errno));
551 return TVI_CONTROL_FALSE;
554 if (ioctl(priv->video_fd, VIDIOC_G_CTRL, control) < 0) {
555 mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl get %s failed: %s\n",
556 info.short_name, qctrl.name, strerror(errno));
557 return TVI_CONTROL_FALSE;
559 mp_msg(MSGT_TV, MSGL_V, "%s: get %s: %d [%d, %d]\n", info.short_name,
560 qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
562 if (val_signed) {
563 if (control->value < qctrl.default_value) {
564 control->value = (control->value - qctrl.default_value) * 100 /
565 (qctrl.default_value - qctrl.minimum);
566 } else {
567 control->value = (control->value - qctrl.default_value) * 100 /
568 (qctrl.maximum - qctrl.default_value);
570 } else {
571 if (control->value < qctrl.default_value) {
572 control->value = (control->value - qctrl.default_value) * 50 /
573 (qctrl.default_value - qctrl.minimum) + 50;
574 } else {
575 control->value = (control->value - qctrl.default_value) * 50 /
576 (qctrl.maximum - qctrl.default_value) + 50;
580 return TVI_CONTROL_TRUE;
583 #ifdef CONFIG_TV_TELETEXT
584 static int vbi_init(priv_t* priv,char* device)
586 int vbi_fd=0;
587 struct v4l2_capability cap;
588 struct v4l2_format fmt;
589 int res;
591 if(!device)
592 return TVI_CONTROL_FALSE;
594 priv->vbi_dev=strdup(device);
596 vbi_fd=open(priv->vbi_dev,O_RDWR);
597 if(vbi_fd<0){
598 mp_msg(MSGT_TV,MSGL_ERR,"vbi: could not open device %s\n",priv->vbi_dev);
599 return TVI_CONTROL_FALSE;
602 if(ioctl(vbi_fd,VIDIOC_QUERYCAP,&cap)<0){
603 mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query capatibilities failed for %s\n",priv->vbi_dev);
604 close(vbi_fd);
605 return TVI_CONTROL_FALSE;
607 if(!cap.capabilities & V4L2_CAP_VBI_CAPTURE){
608 mp_msg(MSGT_TV,MSGL_ERR,"vbi: %s does not support VBI capture\n",priv->vbi_dev);
609 close(vbi_fd);
610 return TVI_CONTROL_FALSE;
613 memset(&fmt,0,sizeof(struct v4l2_format));
614 fmt.type=V4L2_BUF_TYPE_VBI_CAPTURE;
615 if((res=ioctl(vbi_fd,VIDIOC_G_FMT,&fmt))<0){
616 mp_msg(MSGT_TV,MSGL_ERR,"vbi: Query format failed: %x\n",res);
617 close(vbi_fd);
618 return TVI_CONTROL_FALSE;
620 if(fmt.fmt.vbi.sample_format!=V4L2_PIX_FMT_GREY){
621 mp_msg(MSGT_TV,MSGL_ERR,"vbi: format 0x%x is not supported\n",fmt.fmt.vbi.sample_format);
622 close(vbi_fd);
623 return TVI_CONTROL_FALSE;
625 priv->vbi_fd=vbi_fd;
626 mp_msg(MSGT_TV,MSGL_DBG3,"vbi: init ok\n");
627 return TVI_CONTROL_TRUE;
630 static int vbi_get_props(priv_t* priv,tt_stream_props* ptsp)
632 struct v4l2_format fmt;
633 int res;
634 if(!priv || !ptsp)
635 return TVI_CONTROL_FALSE;
637 memset(&fmt,0,sizeof(struct v4l2_format));
638 fmt.type=V4L2_BUF_TYPE_VBI_CAPTURE;
639 if((res=ioctl(priv->vbi_fd,VIDIOC_G_FMT,&fmt))<0){
640 mp_msg(MSGT_TV,MSGL_ERR,"vbi_get_props: Query format failed: %x\n",res);
641 return TVI_CONTROL_FALSE;
644 ptsp->interlaced=(fmt.fmt.vbi.flags& V4L2_VBI_INTERLACED?1:0);
646 ptsp->offset=fmt.fmt.vbi.offset;
647 ptsp->sampling_rate=fmt.fmt.vbi.sampling_rate;
648 ptsp->samples_per_line=fmt.fmt.vbi.samples_per_line,
650 ptsp->count[0]=fmt.fmt.vbi.count[0];
651 ptsp->count[1]=fmt.fmt.vbi.count[1];
652 ptsp->bufsize = ptsp->samples_per_line * (ptsp->count[0] + ptsp->count[1]);
654 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",
655 ptsp->sampling_rate,
656 ptsp->offset,
657 ptsp->samples_per_line,
658 ptsp->interlaced?"Yes":"No",
659 ptsp->count[0],
660 ptsp->count[1]);
662 return TVI_CONTROL_TRUE;
665 static void *vbi_grabber(void *data)
667 priv_t *priv = (priv_t *) data;
668 int bytes,seq,prev_seq;
669 unsigned char* buf;
670 tt_stream_props tsp;
672 if(!priv->priv_vbi){
673 mp_msg(MSGT_TV,MSGL_WARN,"vbi: vbi not initialized. stopping thread.\n");
674 return NULL;
677 if(vbi_get_props(priv,&tsp)!=TVI_CONTROL_TRUE)
678 return NULL;
680 buf=malloc(tsp.bufsize);
681 seq=0;
682 prev_seq=0;
683 mp_msg(MSGT_TV,MSGL_V,"vbi: vbi capture thread started.\n");
685 while (!priv->vbi_shutdown){
686 bytes=read(priv->vbi_fd,buf,tsp.bufsize);
687 if(bytes<0 && errno==EINTR)
688 continue;
689 if (bytes!=tsp.bufsize){
690 mp_msg(MSGT_TV,MSGL_WARN,"vbi: expecting bytes: %d, got: %d\n",tsp.bufsize,bytes);
691 break;
693 seq=*(int*)(buf+bytes-4);
694 if(seq<=1) continue;
695 if (prev_seq && seq!=prev_seq+1){
696 prev_seq=0;
697 seq=0;
699 prev_seq=seq;
700 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_DECODE_PAGE,&buf);
701 mp_msg(MSGT_TV,MSGL_DBG3,"grabber: seq:%d\n",seq);
703 free(buf);
704 return NULL;
706 #endif /* CONFIG_TV_TELETEXT */
708 static int control(priv_t *priv, int cmd, void *arg)
710 struct v4l2_control control;
711 struct v4l2_frequency frequency;
713 switch(cmd) {
714 case TVI_CONTROL_IS_VIDEO:
715 return priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
716 TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
717 case TVI_CONTROL_IS_AUDIO:
718 if (priv->tv_param->force_audio) return TVI_CONTROL_TRUE;
719 case TVI_CONTROL_IS_TUNER:
720 return priv->capability.capabilities & V4L2_CAP_TUNER?
721 TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
722 case TVI_CONTROL_IMMEDIATE:
723 priv->immediate_mode = 1;
724 return TVI_CONTROL_TRUE;
725 case TVI_CONTROL_VID_GET_FPS:
726 if (!priv->standard.frameperiod.denominator || !priv->standard.frameperiod.numerator) {
727 mp_msg(MSGT_TV, MSGL_ERR, "%s: Cannot get fps\n", info.short_name);
728 return TVI_CONTROL_FALSE;
730 *(float *)arg = (float)priv->standard.frameperiod.denominator /
731 priv->standard.frameperiod.numerator;
732 mp_msg(MSGT_TV, MSGL_V, "%s: get fps: %f\n", info.short_name,
733 *(float *)arg);
734 return TVI_CONTROL_TRUE;
735 case TVI_CONTROL_VID_GET_BITS:
736 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
737 *(int *)arg = pixfmt2depth(priv->format.fmt.pix.pixelformat);
738 mp_msg(MSGT_TV, MSGL_V, "%s: get depth: %d\n", info.short_name,
739 *(int *)arg);
740 return TVI_CONTROL_TRUE;
741 case TVI_CONTROL_VID_GET_FORMAT:
742 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
743 *(int *)arg = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
744 mp_msg(MSGT_TV, MSGL_V, "%s: get format: %s\n", info.short_name,
745 pixfmt2name(priv->format.fmt.pix.pixelformat));
746 return TVI_CONTROL_TRUE;
747 case TVI_CONTROL_VID_SET_FORMAT:
748 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
749 priv->format.fmt.pix.pixelformat = fcc_mp2vl(*(int *)arg);
750 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
752 priv->mp_format = *(int *)arg;
753 mp_msg(MSGT_TV, MSGL_V, "%s: set format: %s\n", info.short_name,
754 pixfmt2name(priv->format.fmt.pix.pixelformat));
755 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
756 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
757 info.short_name, strerror(errno));
758 return TVI_CONTROL_FALSE;
760 /* according to the v4l2 specs VIDIOC_S_FMT should not fail, inflexible drivers
761 might even always return the default parameters -> update the format here*/
762 priv->mp_format = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
763 return TVI_CONTROL_TRUE;
764 case TVI_CONTROL_VID_GET_WIDTH:
765 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
766 *(int *)arg = priv->format.fmt.pix.width;
767 mp_msg(MSGT_TV, MSGL_V, "%s: get width: %d\n", info.short_name,
768 *(int *)arg);
769 return TVI_CONTROL_TRUE;
770 case TVI_CONTROL_VID_CHK_WIDTH:
771 return TVI_CONTROL_TRUE;
772 case TVI_CONTROL_VID_SET_WIDTH:
773 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
774 priv->format.fmt.pix.width = *(int *)arg;
775 mp_msg(MSGT_TV, MSGL_V, "%s: set width: %d\n", info.short_name,
776 *(int *)arg);
777 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
778 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set width failed: %s\n",
779 info.short_name, strerror(errno));
780 return TVI_CONTROL_FALSE;
782 return TVI_CONTROL_TRUE;
783 case TVI_CONTROL_VID_GET_HEIGHT:
784 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
785 *(int *)arg = priv->format.fmt.pix.height;
786 mp_msg(MSGT_TV, MSGL_V, "%s: get height: %d\n", info.short_name,
787 *(int *)arg);
788 return TVI_CONTROL_TRUE;
789 case TVI_CONTROL_VID_CHK_HEIGHT:
790 return TVI_CONTROL_TRUE;
791 case TVI_CONTROL_VID_SET_HEIGHT:
792 if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
793 priv->format.fmt.pix.height = *(int *)arg;
794 priv->format.fmt.pix.field = V4L2_FIELD_ANY;
795 mp_msg(MSGT_TV, MSGL_V, "%s: set height: %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 height 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_BRIGHTNESS:
804 control.id = V4L2_CID_BRIGHTNESS;
805 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
806 *(int *)arg = control.value;
807 return TVI_CONTROL_TRUE;
809 return TVI_CONTROL_FALSE;
810 case TVI_CONTROL_VID_SET_BRIGHTNESS:
811 control.id = V4L2_CID_BRIGHTNESS;
812 control.value = *(int *)arg;
813 return set_control(priv, &control, 1);
814 case TVI_CONTROL_VID_GET_HUE:
815 control.id = V4L2_CID_HUE;
816 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
817 *(int *)arg = control.value;
818 return TVI_CONTROL_TRUE;
820 return TVI_CONTROL_FALSE;
821 case TVI_CONTROL_VID_SET_HUE:
822 control.id = V4L2_CID_HUE;
823 control.value = *(int *)arg;
824 return set_control(priv, &control, 1);
825 case TVI_CONTROL_VID_GET_SATURATION:
826 control.id = V4L2_CID_SATURATION;
827 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
828 *(int *)arg = control.value;
829 return TVI_CONTROL_TRUE;
831 return TVI_CONTROL_FALSE;
832 case TVI_CONTROL_VID_SET_SATURATION:
833 control.id = V4L2_CID_SATURATION;
834 control.value = *(int *)arg;
835 return set_control(priv, &control, 1);
836 case TVI_CONTROL_VID_GET_GAIN:
839 control.id = V4L2_CID_AUTOGAIN;
840 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
841 return TVI_CONTROL_FALSE;
843 if(control.value){ //Auto Gain control is enabled
844 *(int*)arg=0;
845 return TVI_CONTROL_TRUE;
848 //Manual Gain control
849 control.id = V4L2_CID_GAIN;
850 if(get_control(priv,&control,0)!=TVI_CONTROL_TRUE)
851 return TVI_CONTROL_FALSE;
853 *(int*)arg=control.value?control.value:1;
855 return TVI_CONTROL_TRUE;
857 case TVI_CONTROL_VID_SET_GAIN:
859 //value==0 means automatic gain control
860 int value=*(int*)arg;
862 if (value < 0 || value>100)
863 return TVI_CONTROL_FALSE;
865 control.id=value?V4L2_CID_GAIN:V4L2_CID_AUTOGAIN;
866 control.value=value?value:1;
868 return set_control(priv,&control,0);
870 case TVI_CONTROL_VID_GET_CONTRAST:
871 control.id = V4L2_CID_CONTRAST;
872 if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
873 *(int *)arg = control.value;
874 return TVI_CONTROL_TRUE;
876 return TVI_CONTROL_FALSE;
877 case TVI_CONTROL_VID_SET_CONTRAST:
878 control.id = V4L2_CID_CONTRAST;
879 control.value = *(int *)arg;
880 return set_control(priv, &control, 1);
881 case TVI_CONTROL_TUN_GET_FREQ:
882 frequency.tuner = 0;
883 frequency.type = V4L2_TUNER_ANALOG_TV;
884 if (ioctl(priv->video_fd, VIDIOC_G_FREQUENCY, &frequency) < 0) {
885 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl get frequency failed: %s\n",
886 info.short_name, strerror(errno));
887 return TVI_CONTROL_FALSE;
889 *(int *)arg = frequency.frequency;
890 return TVI_CONTROL_TRUE;
891 case TVI_CONTROL_TUN_SET_FREQ:
892 #if 0
893 set_mute(priv, 1);
894 usleep(100000); // wait to suppress noise during switching
895 #endif
896 frequency.tuner = 0;
897 frequency.type = V4L2_TUNER_ANALOG_TV;
898 frequency.frequency = *(int *)arg;
899 if (ioctl(priv->video_fd, VIDIOC_S_FREQUENCY, &frequency) < 0) {
900 mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set frequency failed: %s\n",
901 info.short_name, strerror(errno));
902 return TVI_CONTROL_FALSE;
904 #if 0
905 usleep(100000); // wait to suppress noise during switching
906 set_mute(priv, 0);
907 #endif
908 return TVI_CONTROL_TRUE;
909 case TVI_CONTROL_TUN_GET_TUNER:
910 mp_msg(MSGT_TV, MSGL_V, "%s: get tuner\n",info.short_name);
911 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
912 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
913 info.short_name, strerror(errno));
914 return TVI_CONTROL_FALSE;
916 return TVI_CONTROL_TRUE;
917 case TVI_CONTROL_TUN_SET_TUNER:
918 mp_msg(MSGT_TV, MSGL_V, "%s: set tuner\n",info.short_name);
919 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
920 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
921 info.short_name, strerror(errno));
922 return TVI_CONTROL_FALSE;
924 return TVI_CONTROL_TRUE;
925 case TVI_CONTROL_TUN_GET_NORM:
926 *(int *)arg = priv->standard.index;
927 return TVI_CONTROL_TRUE;
928 case TVI_CONTROL_TUN_GET_SIGNAL:
929 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
930 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
931 info.short_name, strerror(errno));
932 return TVI_CONTROL_FALSE;
934 *(int*)arg=100*(priv->tuner.signal>>8)/255;
935 return TVI_CONTROL_TRUE;
936 case TVI_CONTROL_TUN_SET_NORM:
937 priv->standard.index = *(int *)arg;
938 if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
939 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum norm failed: %s\n",
940 info.short_name, strerror(errno));
941 return TVI_CONTROL_FALSE;
943 mp_msg(MSGT_TV, MSGL_V, "%s: set norm: %s\n", info.short_name, priv->standard.name);
944 if (ioctl(priv->video_fd, VIDIOC_S_STD, &priv->standard.id) < 0) {
945 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set norm failed: %s\n",
946 info.short_name, strerror(errno));
947 return TVI_CONTROL_FALSE;
949 return TVI_CONTROL_TRUE;
950 case TVI_CONTROL_SPC_GET_NORMID:
952 int i;
953 for (i = 0;; i++) {
954 struct v4l2_standard standard;
955 memset(&standard, 0, sizeof(standard));
956 standard.index = i;
957 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
958 return TVI_CONTROL_FALSE;
959 if (!strcasecmp(standard.name, (char *)arg)) {
960 *(int *)arg = i;
961 return TVI_CONTROL_TRUE;
964 return TVI_CONTROL_FALSE;
966 case TVI_CONTROL_SPC_GET_INPUT:
967 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, (int *)arg) < 0) {
968 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
969 info.short_name, strerror(errno));
970 return TVI_CONTROL_FALSE;
972 return TVI_CONTROL_TRUE;
973 case TVI_CONTROL_SPC_SET_INPUT:
974 mp_msg(MSGT_TV, MSGL_V, "%s: set input: %d\n", info.short_name, *(int *)arg);
975 priv->input.index = *(int *)arg;
976 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &priv->input) < 0) {
977 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum input failed: %s\n",
978 info.short_name, strerror(errno));
979 return TVI_CONTROL_FALSE;
981 if (ioctl(priv->video_fd, VIDIOC_S_INPUT, (int *)arg) < 0) {
982 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set input failed: %s\n",
983 info.short_name, strerror(errno));
984 return TVI_CONTROL_FALSE;
986 return TVI_CONTROL_TRUE;
987 case TVI_CONTROL_AUD_GET_FORMAT:
988 init_audio(priv);
989 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
990 *(int *)arg = AF_FORMAT_S16_LE;
991 mp_msg(MSGT_TV, MSGL_V, "%s: get audio format: %d\n",
992 info.short_name, *(int *)arg);
993 return TVI_CONTROL_TRUE;
994 case TVI_CONTROL_AUD_GET_SAMPLERATE:
995 init_audio(priv);
996 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
997 *(int *)arg = priv->audio_in.samplerate;
998 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplerate: %d\n",
999 info.short_name, *(int *)arg);
1000 return TVI_CONTROL_TRUE;
1001 case TVI_CONTROL_AUD_GET_SAMPLESIZE:
1002 init_audio(priv);
1003 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1004 *(int *)arg = priv->audio_in.bytes_per_sample;
1005 mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplesize: %d\n",
1006 info.short_name, *(int *)arg);
1007 return TVI_CONTROL_TRUE;
1008 case TVI_CONTROL_AUD_GET_CHANNELS:
1009 init_audio(priv);
1010 if (!priv->audio_initialized) return TVI_CONTROL_FALSE;
1011 *(int *)arg = priv->audio_in.channels;
1012 mp_msg(MSGT_TV, MSGL_V, "%s: get audio channels: %d\n",
1013 info.short_name, *(int *)arg);
1014 return TVI_CONTROL_TRUE;
1015 case TVI_CONTROL_AUD_SET_SAMPLERATE:
1016 init_audio(priv);
1017 mp_msg(MSGT_TV, MSGL_V, "%s: set audio samplerate: %d\n",
1018 info.short_name, *(int *)arg);
1019 if (audio_in_set_samplerate(&priv->audio_in, *(int*)arg) < 0) return TVI_CONTROL_FALSE;
1020 // setup_audio_buffer_sizes(priv);
1021 return TVI_CONTROL_TRUE;
1022 #ifdef CONFIG_TV_TELETEXT
1023 case TVI_CONTROL_VBI_INIT:
1025 void* ptr;
1026 tt_stream_props tsp;
1028 if (vbi_init(priv,*(char**)arg)!=TVI_CONTROL_TRUE)
1029 return TVI_CONTROL_FALSE;
1030 if(vbi_get_props(priv,&tsp)==TVI_CONTROL_TRUE)
1032 ptr=&tsp;
1033 if(teletext_control(NULL,TV_VBI_CONTROL_START,&ptr)==TVI_CONTROL_TRUE)
1034 priv->priv_vbi=ptr;
1035 else
1036 priv->priv_vbi=NULL;
1038 return TVI_CONTROL_TRUE;
1040 default:
1041 return teletext_control(priv->priv_vbi,cmd,arg);
1042 #endif
1044 mp_msg(MSGT_TV, MSGL_V, "%s: unknown control: %d\n", info.short_name, cmd);
1045 return TVI_CONTROL_UNKNOWN;
1049 #define PRIV ((priv_t *) (tvi_handle->priv))
1051 /* handler creator - entry point ! */
1052 static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param)
1054 tvi_handle_t *tvi_handle;
1056 /* new_handle initializes priv with memset 0 */
1057 tvi_handle = new_handle();
1058 if (!tvi_handle) {
1059 return NULL;
1061 PRIV->video_fd = -1;
1063 PRIV->video_dev = strdup(tv_param->device? tv_param->device: "/dev/video0");
1064 if (!PRIV->video_dev) {
1065 free_handle(tvi_handle);
1066 return NULL;
1069 if (tv_param->adevice) {
1070 PRIV->audio_dev = strdup(tv_param->adevice);
1071 if (!PRIV->audio_dev) {
1072 free(PRIV->video_dev);
1073 free_handle(tvi_handle);
1074 return NULL;
1078 PRIV->tv_param=tv_param;
1079 return tvi_handle;
1082 #undef PRIV
1085 static int uninit(priv_t *priv)
1087 int i, frames, dropped = 0;
1089 #ifdef CONFIG_TV_TELETEXT
1090 priv->vbi_shutdown=1;
1091 if(priv->vbi_grabber_thread)
1092 pthread_join(priv->vbi_grabber_thread, NULL);
1094 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_STOP,(void*)1);
1095 priv->priv_vbi=NULL;
1097 if(priv->vbi_fd){
1098 close(priv->vbi_fd);
1099 priv->vbi_fd=0;
1102 if(priv->vbi_dev){
1103 free(priv->vbi_dev);
1104 priv->vbi_dev=0;
1107 #endif
1109 priv->shutdown = 1;
1110 if(priv->video_grabber_thread)
1111 pthread_join(priv->video_grabber_thread, NULL);
1112 pthread_mutex_destroy(&priv->video_buffer_mutex);
1114 if (priv->streamon) {
1115 struct v4l2_buffer buf;
1117 /* get performance */
1118 frames = 1 + lrintf((double)(priv->curr_frame - priv->first_frame) / (1e6 * getfps(priv)));
1119 dropped = frames - priv->frames;
1121 /* turn off streaming */
1122 if (ioctl(priv->video_fd, VIDIOC_STREAMOFF, &(priv->map[0].buf.type)) < 0) {
1123 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamoff failed: %s\n",
1124 info.short_name, strerror(errno));
1126 priv->streamon = 0;
1128 /* unqueue all remaining buffers */
1129 memset(&buf,0,sizeof(buf));
1130 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1131 buf.memory = V4L2_MEMORY_MMAP;
1132 while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
1135 /* unmap all buffers */
1136 for (i = 0; i < priv->mapcount; i++) {
1137 if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {
1138 mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",
1139 info.short_name, strerror(errno));
1143 /* stop audio thread */
1144 if (!priv->tv_param->noaudio && priv->audio_grabber_thread) {
1145 pthread_join(priv->audio_grabber_thread, NULL);
1146 pthread_mutex_destroy(&priv->skew_mutex);
1147 pthread_mutex_destroy(&priv->audio_mutex);
1150 set_mute(priv, 1);
1152 /* free memory and close device */
1153 free(priv->map); priv->map = NULL;
1154 priv->mapcount = 0;
1155 if(priv->video_fd!=-1)close(priv->video_fd); priv->video_fd = -1;
1156 free(priv->video_dev); priv->video_dev = NULL;
1158 if (priv->video_ringbuffer) {
1159 int i;
1160 for (i = 0; i < priv->video_buffer_size_current; i++) {
1161 free(priv->video_ringbuffer[i].data);
1163 free(priv->video_ringbuffer);
1165 if (!priv->tv_param->noaudio) {
1166 if (priv->audio_ringbuffer)
1167 free(priv->audio_ringbuffer);
1168 if (priv->audio_skew_buffer)
1169 free(priv->audio_skew_buffer);
1170 if (priv->audio_skew_delta_buffer)
1171 free(priv->audio_skew_delta_buffer);
1173 audio_in_uninit(&priv->audio_in);
1176 /* show some nice statistics ;-) */
1177 mp_msg(MSGT_TV, MSGL_INFO,
1178 "%s: %d frames successfully processed, %d frames dropped.\n",
1179 info.short_name, priv->frames, dropped);
1180 mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",
1181 info.short_name, priv->video_buffer_size_current);
1182 return 1;
1186 /* initialisation */
1187 static int init(priv_t *priv)
1189 int i;
1191 priv->audio_ringbuffer = NULL;
1192 priv->audio_skew_buffer = NULL;
1193 priv->audio_skew_delta_buffer = NULL;
1195 priv->audio_initialized = 0;
1197 /* Open the video device. */
1198 priv->video_fd = open(priv->video_dev, O_RDWR);
1199 if (priv->video_fd < 0) {
1200 mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",
1201 info.short_name, priv->video_dev, strerror(errno));
1202 uninit(priv);
1203 return 0;
1205 mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",
1206 info.short_name, priv->video_dev, priv->video_fd);
1209 ** Query the video capabilities and current settings
1210 ** for further control calls.
1212 if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
1213 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",
1214 info.short_name, strerror(errno));
1215 uninit(priv);
1216 return 0;
1219 if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))
1221 mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",
1222 priv->video_dev);
1223 return 0;
1226 if (getfmt(priv) < 0) {
1227 uninit(priv);
1228 return 0;
1230 getstd(priv);
1232 ** if this device has got a tuner query it's settings
1233 ** otherwise set some nice defaults
1235 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1236 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
1237 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
1238 info.short_name, strerror(errno));
1239 uninit(priv);
1240 return 0;
1243 mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);
1244 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1245 mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",
1246 (priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",
1247 (priv->tuner.capability & V4L2_TUNER_CAP_LANG1) ? " LANG1" : "",
1248 (priv->tuner.capability & V4L2_TUNER_CAP_LANG2) ? " LANG2" : "");
1249 mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",
1250 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO) ? " MONO" : "",
1251 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",
1252 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1) ? " LANG1" : "",
1253 (priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2) ? " LANG2" : "");
1255 mp_msg(MSGT_TV, MSGL_INFO, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1256 priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
1257 " video capture": "",
1258 priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?
1259 " video output": "",
1260 priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?
1261 " video overlay": "",
1262 priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?
1263 " VBI capture device": "",
1264 priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?
1265 " VBI output": "",
1266 priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?
1267 " RDS data capture": "",
1268 priv->capability.capabilities & V4L2_CAP_TUNER?
1269 " tuner": "",
1270 priv->capability.capabilities & V4L2_CAP_AUDIO?
1271 " audio": "",
1272 priv->capability.capabilities & V4L2_CAP_READWRITE?
1273 " read/write": "",
1274 priv->capability.capabilities & V4L2_CAP_ASYNCIO?
1275 " async i/o": "",
1276 priv->capability.capabilities & V4L2_CAP_STREAMING?
1277 " streaming": "");
1278 mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");
1279 for (i = 0;; i++) {
1280 struct v4l2_standard standard;
1281 memset(&standard, 0, sizeof(standard));
1282 standard.index = i;
1283 if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
1284 break;
1285 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);
1287 mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");
1288 for (i = 0; 1; i++) {
1289 struct v4l2_input input;
1291 input.index = i;
1292 if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
1293 break;
1295 mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);
1297 if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
1298 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
1299 info.short_name, strerror(errno));
1301 mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);
1302 for (i = 0; ; i++) {
1303 struct v4l2_fmtdesc fmtdesc;
1305 fmtdesc.index = i;
1306 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1307 if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
1308 break;
1310 mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",
1311 pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),
1312 fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));
1314 mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",
1315 pixfmt2name(priv->format.fmt.pix.pixelformat));
1317 /* set some nice defaults */
1318 if (getfmt(priv) < 0) return 0;
1319 priv->format.fmt.pix.width = 640;
1320 priv->format.fmt.pix.height = 480;
1321 if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
1322 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
1323 info.short_name, strerror(errno));
1324 uninit(priv);
1325 return 0;
1328 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;
1330 if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1331 struct v4l2_control control;
1332 if (priv->tv_param->amode >= 0) {
1333 mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);
1334 priv->tuner.audmode = amode2v4l(priv->tv_param->amode);
1335 if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
1336 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
1337 info.short_name, strerror(errno));
1338 return TVI_CONTROL_FALSE;
1341 mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,
1342 (priv->tuner.audmode == V4L2_TUNER_MODE_MONO) ? " MONO" : "",
1343 (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",
1344 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG1) ? " LANG1" : "",
1345 (priv->tuner.audmode == V4L2_TUNER_MODE_LANG2) ? " LANG2" : "");
1347 if (priv->tv_param->volume >= 0) {
1348 control.id = V4L2_CID_AUDIO_VOLUME;
1349 control.value = priv->tv_param->volume;
1350 set_control(priv, &control, 0);
1352 if (priv->tv_param->bass >= 0) {
1353 control.id = V4L2_CID_AUDIO_BASS;
1354 control.value = priv->tv_param->bass;
1355 set_control(priv, &control, 0);
1357 if (priv->tv_param->treble >= 0) {
1358 control.id = V4L2_CID_AUDIO_TREBLE;
1359 control.value = priv->tv_param->treble;
1360 set_control(priv, &control, 0);
1362 if (priv->tv_param->balance >= 0) {
1363 control.id = V4L2_CID_AUDIO_BALANCE;
1364 control.value = priv->tv_param->balance;
1365 set_control(priv, &control, 0);
1369 return 1;
1372 static int get_capture_buffer_size(priv_t *priv)
1374 int bufsize, cnt;
1376 if (priv->tv_param->buffer_size >= 0) {
1377 bufsize = priv->tv_param->buffer_size*1024*1024;
1378 } else {
1379 #ifdef HAVE_SYS_SYSINFO_H
1380 struct sysinfo si;
1382 sysinfo(&si);
1383 if (si.totalram<2*1024*1024) {
1384 bufsize = 1024*1024;
1385 } else {
1386 bufsize = si.totalram/2;
1388 #else
1389 bufsize = 16*1024*1024;
1390 #endif
1393 cnt = bufsize/priv->format.fmt.pix.sizeimage;
1394 if (cnt < 2) cnt = 2;
1396 return cnt;
1399 /* that's the real start, we'got the format parameters (checked with control) */
1400 static int start(priv_t *priv)
1402 struct v4l2_requestbuffers request;
1403 unsigned int i;
1405 /* setup audio parameters */
1407 init_audio(priv);
1408 if (!priv->tv_param->noaudio && !priv->audio_initialized) return 0;
1410 /* we need this to size the audio buffer properly */
1411 if (priv->immediate_mode) {
1412 priv->video_buffer_size_max = 2;
1413 } else {
1414 priv->video_buffer_size_max = get_capture_buffer_size(priv);
1417 if (!priv->tv_param->noaudio) {
1418 setup_audio_buffer_sizes(priv);
1419 priv->audio_skew_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1420 if (!priv->audio_skew_buffer) {
1421 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1422 return 0;
1424 priv->audio_skew_delta_buffer = calloc(priv->aud_skew_cnt, sizeof(long long));
1425 if (!priv->audio_skew_delta_buffer) {
1426 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1427 return 0;
1430 priv->audio_ringbuffer = calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
1431 if (!priv->audio_ringbuffer) {
1432 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
1433 return 0;
1436 priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate
1437 *priv->audio_in.channels
1438 *priv->audio_in.bytes_per_sample);
1439 priv->audio_usecs_per_block = 1e6*priv->audio_secs_per_block;
1440 priv->audio_head = 0;
1441 priv->audio_tail = 0;
1442 priv->audio_cnt = 0;
1443 priv->audio_drop = 0;
1444 priv->audio_skew = 0;
1445 priv->audio_skew_total = 0;
1446 priv->audio_skew_delta_total = 0;
1447 priv->audio_recv_blocks_total = 0;
1448 priv->audio_sent_blocks_total = 0;
1449 priv->audio_null_blocks_inserted = 0;
1450 priv->audio_insert_null_samples = 0;
1451 priv->dropped_frames_timeshift = 0;
1452 priv->dropped_frames_compensated = 0;
1454 pthread_mutex_init(&priv->skew_mutex, NULL);
1455 pthread_mutex_init(&priv->audio_mutex, NULL);
1458 /* setup video parameters */
1459 if (!priv->tv_param->noaudio) {
1460 if (priv->video_buffer_size_max < (3*priv->standard.frameperiod.denominator) /
1461 priv->standard.frameperiod.numerator
1462 *priv->audio_secs_per_block) {
1463 mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"
1464 "You will probably experience heavy framedrops.\n");
1469 int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1471 mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1472 priv->video_buffer_size_max,
1473 priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));
1476 priv->video_ringbuffer = calloc(priv->video_buffer_size_max, sizeof(video_buffer_entry));
1477 if (!priv->video_ringbuffer) {
1478 mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
1479 return 0;
1481 memset(priv->video_ringbuffer,0,priv->video_buffer_size_max * sizeof(video_buffer_entry));
1483 pthread_mutex_init(&priv->video_buffer_mutex, NULL);
1485 priv->video_head = 0;
1486 priv->video_tail = 0;
1487 priv->video_cnt = 0;
1489 /* request buffers */
1490 if (priv->immediate_mode) {
1491 request.count = 2;
1492 } else {
1493 request.count = BUFFER_COUNT;
1496 request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1497 request.memory = V4L2_MEMORY_MMAP;
1498 if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
1499 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",
1500 info.short_name, strerror(errno));
1501 return 0;
1504 /* query buffers */
1505 if (!(priv->map = calloc(request.count, sizeof(struct map)))) {
1506 mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",
1507 info.short_name, strerror(errno));
1508 return 0;
1511 /* map and queue buffers */
1512 for (i = 0; i < request.count; i++) {
1513 memset(&priv->map[i].buf,0,sizeof(priv->map[i].buf));
1514 priv->map[i].buf.index = i;
1515 priv->map[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1516 priv->map[i].buf.memory = V4L2_MEMORY_MMAP;
1517 if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
1518 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",
1519 info.short_name, strerror(errno));
1520 free(priv->map);
1521 priv->map = NULL;
1522 return 0;
1524 priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |
1525 PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);
1526 if (priv->map[i].addr == MAP_FAILED) {
1527 mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",
1528 info.short_name, strerror(errno));
1529 priv->map[i].len = 0;
1530 return 0;
1532 priv->map[i].len = priv->map[i].buf.length;
1533 /* count up to make sure this is correct everytime */
1534 priv->mapcount++;
1536 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1537 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1538 info.short_name, strerror(errno));
1539 return 0;
1543 #ifdef CONFIG_TV_TELETEXT
1544 /* start vbi thread */
1545 if(priv->priv_vbi){
1546 priv->vbi_shutdown = 0;
1547 pthread_create(&priv->vbi_grabber_thread, NULL, vbi_grabber, priv);
1549 #endif
1550 /* start audio thread */
1551 priv->shutdown = 0;
1552 priv->audio_skew_measure_time = 0;
1553 priv->first_frame = 0;
1554 priv->audio_skew = 0;
1555 priv->first = 1;
1557 set_mute(priv, 0);
1559 return 1;
1562 // copies a video frame
1563 static inline void copy_frame(priv_t *priv, video_buffer_entry *dest, unsigned char *source,int len)
1565 dest->framesize=len;
1566 if(priv->tv_param->automute>0){
1567 if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) >= 0) {
1568 if(priv->tv_param->automute<<8>priv->tuner.signal){
1569 fill_blank_frame(dest->data,dest->framesize,fcc_vl2mp(priv->format.fmt.pix.pixelformat));
1570 set_mute(priv,1);
1571 return;
1574 set_mute(priv,0);
1576 memcpy(dest->data, source, len);
1579 // maximum skew change, in frames
1580 #define MAX_SKEW_DELTA 0.6
1581 static void *video_grabber(void *data)
1583 priv_t *priv = (priv_t*)data;
1584 long long skew, prev_skew, xskew, interval, prev_interval, delta;
1585 int i;
1586 int framesize = priv->format.fmt.pix.sizeimage;
1587 fd_set rdset;
1588 struct timeval timeout;
1589 struct v4l2_buffer buf;
1591 xskew = 0;
1592 skew = 0;
1593 interval = 0;
1594 prev_interval = 0;
1595 prev_skew = 0;
1597 mp_msg(MSGT_TV, MSGL_V, "%s: going to capture\n", info.short_name);
1598 if (ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
1599 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamon failed: %s\n",
1600 info.short_name, strerror(errno));
1601 return 0;
1603 priv->streamon = 1;
1605 if (!priv->tv_param->noaudio) {
1606 pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
1609 for (priv->frames = 0; !priv->shutdown;)
1611 int ret;
1613 if (priv->immediate_mode) {
1614 while (priv->video_cnt == priv->video_buffer_size_max) {
1615 usleep(10000);
1616 if (priv->shutdown) {
1617 return NULL;
1622 FD_ZERO (&rdset);
1623 FD_SET (priv->video_fd, &rdset);
1625 timeout.tv_sec = 1;
1626 timeout.tv_usec = 0;
1628 i = select(priv->video_fd + 1, &rdset, NULL, NULL, &timeout);
1629 if (i < 0) {
1630 mp_msg(MSGT_TV, MSGL_ERR, "%s: select failed: %s\n",
1631 info.short_name, strerror(errno));
1632 continue;
1634 else if (i == 0) {
1635 mp_msg(MSGT_TV, MSGL_ERR, "%s: select timeout\n", info.short_name);
1636 continue;
1638 else if (!FD_ISSET(priv->video_fd, &rdset)) {
1639 continue;
1642 memset(&buf,0,sizeof(buf));
1643 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1644 buf.memory = V4L2_MEMORY_MMAP;
1645 ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
1647 if (ret < 0) {
1649 if there's no signal, the buffer might me dequeued
1650 so we query all the buffers to see which one we should
1651 put back to queue
1653 observed with saa7134 0.2.8
1654 don't know if is it a bug or (mis)feature
1656 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1657 info.short_name, strerror(errno), buf.index);
1658 for (i = 0; i < priv->mapcount; i++) {
1659 memset(&buf,0,sizeof(buf));
1660 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1661 buf.memory = V4L2_MEMORY_MMAP;
1662 buf.index = i;
1663 ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
1664 if (ret < 0) {
1665 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s, idx = %d\n",
1666 info.short_name, strerror(errno), buf.index);
1667 return 0;
1669 if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
1670 if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1671 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1672 info.short_name, strerror(errno));
1673 return 0;
1677 continue;
1680 /* store the timestamp of the very first frame as reference */
1681 if (!priv->frames++) {
1682 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1683 priv->first_frame = (long long)1e6*buf.timestamp.tv_sec + buf.timestamp.tv_usec;
1684 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1686 priv->curr_frame = (long long)buf.timestamp.tv_sec*1e6+buf.timestamp.tv_usec;
1687 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1689 interval = priv->curr_frame - priv->first_frame;
1690 delta = interval - prev_interval;
1692 if (!priv->immediate_mode) {
1693 // interpolate the skew in time
1694 if (!priv->tv_param->noaudio) pthread_mutex_lock(&priv->skew_mutex);
1695 xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
1696 if (!priv->tv_param->noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1697 // correct extreme skew changes to avoid (especially) moving backwards in time
1698 if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
1699 skew = prev_skew + delta*MAX_SKEW_DELTA;
1700 } else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) {
1701 skew = prev_skew - delta*MAX_SKEW_DELTA;
1702 } else {
1703 skew = xskew;
1707 mp_msg(MSGT_TV, MSGL_DBG3, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1708 delta ? (double)1e6/delta : -1,
1709 (double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
1710 mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
1712 prev_skew = skew;
1713 prev_interval = interval;
1715 /* allocate a new buffer, if needed */
1716 pthread_mutex_lock(&priv->video_buffer_mutex);
1717 if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
1718 if (priv->video_cnt == priv->video_buffer_size_current) {
1719 unsigned char *newbuf = malloc(framesize);
1720 if (newbuf) {
1721 memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
1722 (priv->video_buffer_size_current-priv->video_tail)*sizeof(video_buffer_entry));
1723 priv->video_ringbuffer[priv->video_tail].data = newbuf;
1724 if ((priv->video_head >= priv->video_tail) && (priv->video_cnt > 0)) priv->video_head++;
1725 priv->video_buffer_size_current++;
1729 pthread_mutex_unlock(&priv->video_buffer_mutex);
1731 if (priv->video_cnt == priv->video_buffer_size_current) {
1732 if (!priv->immediate_mode) {
1733 mp_msg(MSGT_TV, MSGL_ERR, "\nvideo buffer full - dropping frame\n");
1734 if (priv->audio_insert_null_samples) {
1735 pthread_mutex_lock(&priv->audio_mutex);
1736 priv->dropped_frames_timeshift += delta;
1737 pthread_mutex_unlock(&priv->audio_mutex);
1740 } else {
1741 if (priv->immediate_mode) {
1742 priv->video_ringbuffer[priv->video_tail].timestamp = 0;
1743 } else {
1744 // compensate for audio skew
1745 // negative skew => there are more audio samples, increase interval
1746 // positive skew => less samples, shorten the interval
1747 priv->video_ringbuffer[priv->video_tail].timestamp = interval - skew;
1748 if (priv->audio_insert_null_samples && priv->video_ringbuffer[priv->video_tail].timestamp > 0) {
1749 pthread_mutex_lock(&priv->audio_mutex);
1750 priv->video_ringbuffer[priv->video_tail].timestamp +=
1751 (priv->audio_null_blocks_inserted
1752 - priv->dropped_frames_timeshift/priv->audio_usecs_per_block)
1753 *priv->audio_usecs_per_block;
1754 pthread_mutex_unlock(&priv->audio_mutex);
1757 copy_frame(priv, priv->video_ringbuffer+priv->video_tail, priv->map[buf.index].addr,buf.bytesused);
1758 priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
1759 priv->video_cnt++;
1761 if (ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
1762 mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1763 info.short_name, strerror(errno));
1764 return 0;
1767 return NULL;
1770 #define MAX_LOOP 50
1771 static double grab_video_frame(priv_t *priv, char *buffer, int len)
1773 double interval;
1774 int loop_cnt = 0;
1776 if (priv->first) {
1777 pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1778 priv->first = 0;
1781 while (priv->video_cnt == 0) {
1782 usleep(10000);
1783 if (loop_cnt++ > MAX_LOOP) return 0;
1786 pthread_mutex_lock(&priv->video_buffer_mutex);
1787 interval = (double)priv->video_ringbuffer[priv->video_head].timestamp*1e-6;
1788 memcpy(buffer, priv->video_ringbuffer[priv->video_head].data, len);
1789 priv->video_cnt--;
1790 priv->video_head = (priv->video_head+1)%priv->video_buffer_size_current;
1791 pthread_mutex_unlock(&priv->video_buffer_mutex);
1793 return interval;
1796 static int get_video_framesize(priv_t *priv)
1799 this routine will be called before grab_video_frame
1800 thus let's return topmost frame's size
1802 if (priv->video_cnt)
1803 return priv->video_ringbuffer[priv->video_head].framesize;
1805 no video frames yet available. i don't know what to do in this case,
1806 thus let's return some fallback result (for compressed format this will be
1807 maximum allowed frame size.
1809 return priv->format.fmt.pix.sizeimage;
1812 //#define DOUBLESPEED
1813 #ifdef DOUBLESPEED
1814 // for testing purposes only
1815 static void read_doublespeed(priv_t *priv)
1817 char *bufx = calloc(priv->audio_in.blocksize, 2);
1818 short *s;
1819 short *d;
1820 int i;
1822 audio_in_read_chunk(&priv->audio_in, bufx);
1823 audio_in_read_chunk(&priv->audio_in, bufx+priv->audio_in.blocksize);
1825 s = bufx;
1826 d = priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize;
1827 for (i = 0; i < priv->audio_in.blocksize/2; i++) {
1828 *d++ = *s++;
1829 *s++;
1833 #endif
1835 static void *audio_grabber(void *data)
1837 priv_t *priv = (priv_t*)data;
1838 struct timeval tv;
1839 int i, audio_skew_ptr = 0;
1840 long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
1841 long long start_time_avg;
1843 gettimeofday(&tv, NULL);
1844 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1845 audio_in_start_capture(&priv->audio_in);
1846 for (i = 0; i < priv->aud_skew_cnt; i++)
1847 priv->audio_skew_buffer[i] = 0;
1848 for (i = 0; i < priv->aud_skew_cnt; i++)
1849 priv->audio_skew_delta_buffer[i] = 0;
1851 for (; !priv->shutdown;)
1853 #ifdef DOUBLESPEED
1854 read_doublespeed(priv);
1855 #else
1856 if (audio_in_read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize) < 0)
1857 continue;
1858 #endif
1859 pthread_mutex_lock(&priv->skew_mutex);
1860 if (priv->first_frame == 0) {
1861 // there is no first frame yet (unlikely to happen)
1862 gettimeofday(&tv, NULL);
1863 start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1864 // fprintf(stderr, "warning - first frame not yet available!\n");
1865 pthread_mutex_unlock(&priv->skew_mutex);
1866 continue;
1868 pthread_mutex_unlock(&priv->skew_mutex);
1870 gettimeofday(&tv, NULL);
1872 priv->audio_recv_blocks_total++;
1873 current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
1875 if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
1876 start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1877 priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
1880 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1881 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1883 // put the current skew into the ring buffer
1884 priv->audio_skew_total -= priv->audio_skew_buffer[audio_skew_ptr];
1885 priv->audio_skew_buffer[audio_skew_ptr] = current_time
1886 - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1887 priv->audio_skew_total += priv->audio_skew_buffer[audio_skew_ptr];
1889 pthread_mutex_lock(&priv->skew_mutex);
1891 // skew calculation
1893 // compute the sliding average of the skews
1894 if (priv->audio_recv_blocks_total > priv->aud_skew_cnt) {
1895 priv->audio_skew = priv->audio_skew_total/priv->aud_skew_cnt;
1896 } else {
1897 priv->audio_skew = priv->audio_skew_total/priv->audio_recv_blocks_total;
1900 // put the current skew change (skew-prev_skew) into the ring buffer
1901 priv->audio_skew_delta_total -= priv->audio_skew_delta_buffer[audio_skew_ptr];
1902 priv->audio_skew_delta_buffer[audio_skew_ptr] = priv->audio_skew - prev_skew_uncorr;
1903 priv->audio_skew_delta_total += priv->audio_skew_delta_buffer[audio_skew_ptr];
1904 prev_skew_uncorr = priv->audio_skew; // remember the _uncorrected_ average value
1906 audio_skew_ptr = (audio_skew_ptr+1) % priv->aud_skew_cnt; // rotate the buffer pointer
1908 // sliding average approximates the value in the middle of the interval
1909 // so interpolate the skew value further to the current time
1910 priv->audio_skew += priv->audio_skew_delta_total/2;
1912 // now finally, priv->audio_skew contains fairly good approximation
1913 // of the current value
1915 // current skew factor (assuming linearity)
1916 // used for further interpolation in video_grabber
1917 // probably overkill but seems to be necessary for
1918 // stress testing by dropping half of the audio frames ;)
1919 // especially when using ALSA with large block sizes
1920 // where audio_skew remains a long while behind
1921 if ((priv->audio_skew_measure_time != 0) && (current_time - priv->audio_skew_measure_time != 0)) {
1922 priv->audio_skew_factor = (double)(priv->audio_skew-prev_skew)/(current_time - priv->audio_skew_measure_time);
1923 } else {
1924 priv->audio_skew_factor = 0.0;
1927 priv->audio_skew_measure_time = current_time;
1928 prev_skew = priv->audio_skew;
1929 priv->audio_skew += priv->audio_start_time - priv->first_frame;
1930 pthread_mutex_unlock(&priv->skew_mutex);
1932 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1934 pthread_mutex_lock(&priv->audio_mutex);
1935 if ((priv->audio_tail+1) % priv->audio_buffer_size == priv->audio_head) {
1936 mp_msg(MSGT_TV, MSGL_ERR, "\ntoo bad - dropping audio frame !\n");
1937 priv->audio_drop++;
1938 } else {
1939 priv->audio_tail = (priv->audio_tail+1) % priv->audio_buffer_size;
1940 priv->audio_cnt++;
1942 pthread_mutex_unlock(&priv->audio_mutex);
1944 return NULL;
1947 static double grab_audio_frame(priv_t *priv, char *buffer, int len)
1949 mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1950 priv, buffer, len);
1952 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1953 // => switch to the mode which outputs audio immediately, even if
1954 // it should be silence
1955 if (priv->first) priv->audio_insert_null_samples = 1;
1957 pthread_mutex_lock(&priv->audio_mutex);
1958 while (priv->audio_insert_null_samples
1959 && priv->dropped_frames_timeshift - priv->dropped_frames_compensated >= priv->audio_usecs_per_block) {
1960 // some frames were dropped - drop the corresponding number of audio blocks
1961 if (priv->audio_drop) {
1962 priv->audio_drop--;
1963 } else {
1964 if (priv->audio_head == priv->audio_tail) break;
1965 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1967 priv->dropped_frames_compensated += priv->audio_usecs_per_block;
1970 // compensate for dropped audio frames
1971 if (priv->audio_drop && (priv->audio_head == priv->audio_tail)) {
1972 priv->audio_drop--;
1973 memset(buffer, 0, len);
1974 goto out;
1977 if (priv->audio_insert_null_samples && (priv->audio_head == priv->audio_tail)) {
1978 // return silence to avoid desync and stuttering
1979 memset(buffer, 0, len);
1980 priv->audio_null_blocks_inserted++;
1981 goto out;
1984 pthread_mutex_unlock(&priv->audio_mutex);
1985 while (priv->audio_head == priv->audio_tail) {
1986 // this is mencoder => just wait until some audio is available
1987 usleep(10000);
1989 pthread_mutex_lock(&priv->audio_mutex);
1990 memcpy(buffer, priv->audio_ringbuffer+priv->audio_head*priv->audio_in.blocksize, len);
1991 priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1992 priv->audio_cnt--;
1993 out:
1994 pthread_mutex_unlock(&priv->audio_mutex);
1995 priv->audio_sent_blocks_total++;
1996 return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
1999 static int get_audio_framesize(priv_t *priv)
2001 return priv->audio_in.blocksize;