2 ** Video 4 Linux 2 input
4 ** This file is part of MPlayer, see http://mplayerhq.hu/ for info.
6 ** (c) 2003 Martin Olschewski <olschewski@zpr.uni-koeln.de>
7 ** (c) 2003 Jindrich Makovicka <makovick@gmail.com>
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!
21 - norm setting isn't consistent with tvi_v4l
22 - the same for volume/bass/treble/balance
33 #include <sys/ioctl.h>
36 #include <sys/types.h>
38 #ifdef HAVE_SYS_SYSINFO_H
39 #include <sys/sysinfo.h>
41 #include <linux/types.h>
42 #include <linux/videodev2.h>
44 #include "libmpcodecs/img_format.h"
45 #include "libaf/af_format.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 tvi_info_t tvi_info_v4l2
= {
54 "Video 4 Linux 2 input",
56 "Martin Olschewski <olschewski@zpr.uni-koeln.de>",
57 "first try, more to come ;-)"
61 struct v4l2_buffer buf
;
66 #define BUFFER_COUNT 6
68 /** video ringbuffer entry */
70 unsigned char *data
; ///< frame contents
71 long long timestamp
; ///< frame timestamp
72 int framesize
; ///< actual frame size
80 #ifdef HAVE_TV_TELETEXT
85 pthread_t vbi_grabber_thread
;
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
;
97 volatile long long first_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 */
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
;
121 long long audio_start_time
;
122 int audio_buffer_size
;
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
;
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
;
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
)
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
;
210 ** Translate a video4linux2 fourcc aka pixel format to mplayer.
212 static int fcc_vl2mp(int 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
;
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];
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
);
276 ** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
278 static int pixfmt2depth(int pixfmt
)
281 case V4L2_PIX_FMT_RGB332
:
283 case V4L2_PIX_FMT_RGB555
:
284 case V4L2_PIX_FMT_RGB565
:
285 case V4L2_PIX_FMT_RGB555X
:
286 case V4L2_PIX_FMT_RGB565X
:
288 case V4L2_PIX_FMT_BGR24
:
289 case V4L2_PIX_FMT_RGB24
:
291 case V4L2_PIX_FMT_BGR32
:
292 case V4L2_PIX_FMT_RGB32
:
294 case V4L2_PIX_FMT_GREY
:
296 case V4L2_PIX_FMT_YVU410
:
298 case V4L2_PIX_FMT_YVU420
:
300 case V4L2_PIX_FMT_YUYV
:
301 case V4L2_PIX_FMT_UYVY
:
302 case V4L2_PIX_FMT_YUV422P
:
303 case V4L2_PIX_FMT_YUV411P
:
305 case V4L2_PIX_FMT_Y41P
:
306 case V4L2_PIX_FMT_NV12
:
307 case V4L2_PIX_FMT_NV21
:
309 case V4L2_PIX_FMT_YUV410
:
311 case V4L2_PIX_FMT_YUV420
:
313 case V4L2_PIX_FMT_YYUV
:
315 case V4L2_PIX_FMT_HI240
:
322 static int amode2v4l(int amode
)
326 return V4L2_TUNER_MODE_MONO
;
328 return V4L2_TUNER_MODE_STEREO
;
330 return V4L2_TUNER_MODE_LANG1
;
332 return V4L2_TUNER_MODE_LANG2
;
339 // sets and sanitizes audio buffer/block sizes
340 static void setup_audio_buffer_sizes(priv_t
*priv
)
342 int bytes_per_sample
= priv
->audio_in
.bytes_per_sample
;
343 double fps
= (double)priv
->standard
.frameperiod
.denominator
/
344 priv
->standard
.frameperiod
.numerator
;
345 int seconds
= priv
->video_buffer_size_max
/fps
;
347 if (seconds
< 5) seconds
= 5;
348 if (seconds
> 500) seconds
= 500;
350 // make the audio buffer at least as the video buffer capacity (or 5 seconds) long
351 priv
->audio_buffer_size
= 1 + seconds
*priv
->audio_in
.samplerate
352 *priv
->audio_in
.channels
353 *bytes_per_sample
/priv
->audio_in
.blocksize
;
354 if (priv
->audio_buffer_size
< 256) priv
->audio_buffer_size
= 256;
356 // make the skew buffer at least 1 second long
357 priv
->aud_skew_cnt
= 1 + 1*priv
->audio_in
.samplerate
358 *priv
->audio_in
.channels
359 *bytes_per_sample
/priv
->audio_in
.blocksize
;
360 if (priv
->aud_skew_cnt
< 16) priv
->aud_skew_cnt
= 16;
362 mp_msg(MSGT_TV
, MSGL_V
, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
363 priv
->audio_buffer_size
, priv
->audio_in
.blocksize
, priv
->aud_skew_cnt
);
366 static void init_audio(priv_t
*priv
)
368 if (priv
->audio_inited
) return;
370 if (!priv
->tv_param
->noaudio
) {
371 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
372 if (priv
->tv_param
->alsa
)
373 audio_in_init(&priv
->audio_in
, AUDIO_IN_ALSA
);
375 audio_in_init(&priv
->audio_in
, AUDIO_IN_OSS
);
377 audio_in_init(&priv
->audio_in
, AUDIO_IN_OSS
);
380 if (priv
->audio_dev
) {
381 audio_in_set_device(&priv
->audio_in
, priv
->audio_dev
);
384 audio_in_set_samplerate(&priv
->audio_in
, 44100);
385 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
386 if (priv
->tuner
.audmode
== V4L2_TUNER_MODE_STEREO
) {
387 audio_in_set_channels(&priv
->audio_in
, 2);
389 audio_in_set_channels(&priv
->audio_in
, 1);
392 if (priv
->tv_param
->forcechan
>= 0) {
393 audio_in_set_channels(&priv
->audio_in
, priv
->tv_param
->forcechan
);
395 audio_in_set_channels(&priv
->audio_in
, 2);
399 if (audio_in_setup(&priv
->audio_in
) < 0) return;
401 priv
->audio_inited
= 1;
407 ** the number of milliseconds elapsed between time0 and time1
409 static size_t difftv(struct timeval time1
, struct timeval time0
)
411 return (time1
.tv_sec
- time0
.tv_sec
) * 1000 +
412 (time1
.tv_usec
- time0
.tv_usec
) / 1000;
417 ** Get current video capture format.
419 static int getfmt(priv_t
*priv
)
423 priv
->format
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
424 if ((i
= ioctl(priv
->video_fd
, VIDIOC_G_FMT
, &priv
->format
)) < 0) {
425 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get format failed: %s\n",
426 info
.short_name
, strerror(errno
));
433 ** Get current video capture standard.
435 static int getstd(priv_t
*priv
)
440 if (ioctl(priv
->video_fd
, VIDIOC_G_STD
, &id
) < 0) {
441 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get standard failed: %s\n",
442 info
.short_name
, strerror(errno
));
446 priv
->standard
.index
= i
++;
447 if (ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &priv
->standard
) < 0) {
450 } while (priv
->standard
.id
!= id
);
454 /***********************************************************************\
457 * Interface to mplayer *
460 \***********************************************************************/
462 static int set_mute(priv_t
*priv
, int value
)
464 struct v4l2_control control
;
465 control
.id
= V4L2_CID_AUDIO_MUTE
;
466 control
.value
= value
;
467 if (ioctl(priv
->video_fd
, VIDIOC_S_CTRL
, &control
) < 0) {
468 mp_msg(MSGT_TV
,MSGL_ERR
,"%s: ioctl set mute failed: %s\n",
469 info
.short_name
, strerror(errno
));
476 ** MPlayer uses values from -100 up to 100 for controls.
477 ** Here they are scaled to what the tv card needs and applied.
479 static int set_control(priv_t
*priv
, struct v4l2_control
*control
, int val_signed
) {
480 struct v4l2_queryctrl qctrl
;
481 qctrl
.id
= control
->id
;
482 if (ioctl(priv
->video_fd
, VIDIOC_QUERYCTRL
, &qctrl
) < 0) {
483 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query control failed: %s\n",
484 info
.short_name
, strerror(errno
));
485 return TVI_CONTROL_FALSE
;
489 if (control
->value
< 0) {
490 control
->value
= qctrl
.default_value
+ control
->value
*
491 (qctrl
.default_value
- qctrl
.minimum
) / 100;
493 control
->value
= qctrl
.default_value
+ control
->value
*
494 (qctrl
.maximum
- qctrl
.default_value
) / 100;
497 if (control
->value
< 50) {
498 control
->value
= qctrl
.default_value
+ (control
->value
-50) *
499 (qctrl
.default_value
- qctrl
.minimum
) / 50;
501 control
->value
= qctrl
.default_value
+ (control
->value
-50) *
502 (qctrl
.maximum
- qctrl
.default_value
) / 50;
507 if (ioctl(priv
->video_fd
, VIDIOC_S_CTRL
, control
) < 0) {
508 mp_msg(MSGT_TV
, MSGL_ERR
,"%s: ioctl set %s %d failed: %s\n",
509 info
.short_name
, qctrl
.name
, control
->value
, strerror(errno
));
510 return TVI_CONTROL_FALSE
;
512 mp_msg(MSGT_TV
, MSGL_V
, "%s: set %s: %d [%d, %d]\n", info
.short_name
,
513 qctrl
.name
, control
->value
, qctrl
.minimum
, qctrl
.maximum
);
515 return TVI_CONTROL_TRUE
;
520 ** Scale the control values back to what mplayer needs.
522 static int get_control(priv_t
*priv
, struct v4l2_control
*control
, int val_signed
) {
523 struct v4l2_queryctrl qctrl
;
525 qctrl
.id
= control
->id
;
526 if (ioctl(priv
->video_fd
, VIDIOC_QUERYCTRL
, &qctrl
) < 0) {
527 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query control failed: %s\n",
528 info
.short_name
, strerror(errno
));
529 return TVI_CONTROL_FALSE
;
532 if (ioctl(priv
->video_fd
, VIDIOC_G_CTRL
, control
) < 0) {
533 mp_msg(MSGT_TV
, MSGL_ERR
,"%s: ioctl get %s failed: %s\n",
534 info
.short_name
, qctrl
.name
, strerror(errno
));
535 return TVI_CONTROL_FALSE
;
537 mp_msg(MSGT_TV
, MSGL_V
, "%s: get %s: %d [%d, %d]\n", info
.short_name
,
538 qctrl
.name
, control
->value
, qctrl
.minimum
, qctrl
.maximum
);
541 if (control
->value
< qctrl
.default_value
) {
542 control
->value
= (control
->value
- qctrl
.default_value
) * 100 /
543 (qctrl
.default_value
- qctrl
.minimum
);
545 control
->value
= (control
->value
- qctrl
.default_value
) * 100 /
546 (qctrl
.maximum
- qctrl
.default_value
);
549 if (control
->value
< qctrl
.default_value
) {
550 control
->value
= (control
->value
- qctrl
.default_value
) * 50 /
551 (qctrl
.default_value
- qctrl
.minimum
) + 50;
553 control
->value
= (control
->value
- qctrl
.default_value
) * 50 /
554 (qctrl
.maximum
- qctrl
.default_value
) + 50;
558 return TVI_CONTROL_TRUE
;
561 #ifdef HAVE_TV_TELETEXT
562 static int vbi_init(priv_t
* priv
,char* device
)
565 struct v4l2_capability cap
;
566 struct v4l2_format fmt
;
570 return TVI_CONTROL_FALSE
;
572 priv
->vbi_dev
=strdup(device
);
574 vbi_fd
=open(priv
->vbi_dev
,O_RDWR
);
576 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: could not open device %s\n",priv
->vbi_dev
);
577 return TVI_CONTROL_FALSE
;
580 if(ioctl(vbi_fd
,VIDIOC_QUERYCAP
,&cap
)<0){
581 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: Query capatibilities failed for %s\n",priv
->vbi_dev
);
583 return TVI_CONTROL_FALSE
;
585 if(!cap
.capabilities
& V4L2_CAP_VBI_CAPTURE
){
586 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: %s does not support VBI capture\n",priv
->vbi_dev
);
588 return TVI_CONTROL_FALSE
;
591 memset(&fmt
,0,sizeof(struct v4l2_format
));
592 fmt
.type
=V4L2_BUF_TYPE_VBI_CAPTURE
;
593 if((res
=ioctl(vbi_fd
,VIDIOC_G_FMT
,&fmt
))<0){
594 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: Query format failed: %x\n",res
);
596 return TVI_CONTROL_FALSE
;
598 if(fmt
.fmt
.vbi
.sample_format
!=V4L2_PIX_FMT_GREY
){
599 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: format 0x%x is not supported\n",fmt
.fmt
.vbi
.sample_format
);
601 return TVI_CONTROL_FALSE
;
604 mp_msg(MSGT_TV
,MSGL_DBG3
,"vbi: init ok\n");
605 return TVI_CONTROL_TRUE
;
608 static int vbi_get_props(priv_t
* priv
,tt_stream_props
* ptsp
)
610 struct v4l2_format fmt
;
613 return TVI_CONTROL_FALSE
;
615 memset(&fmt
,0,sizeof(struct v4l2_format
));
616 fmt
.type
=V4L2_BUF_TYPE_VBI_CAPTURE
;
617 if((res
=ioctl(priv
->vbi_fd
,VIDIOC_G_FMT
,&fmt
))<0){
618 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi_get_props: Query format failed: %x\n",res
);
619 return TVI_CONTROL_FALSE
;
622 ptsp
->interlaced
=(fmt
.fmt
.vbi
.flags
& V4L2_VBI_INTERLACED
?1:0);
624 ptsp
->offset
=fmt
.fmt
.vbi
.offset
;
625 ptsp
->sampling_rate
=fmt
.fmt
.vbi
.sampling_rate
;
626 ptsp
->samples_per_line
=fmt
.fmt
.vbi
.samples_per_line
,
628 ptsp
->count
[0]=fmt
.fmt
.vbi
.count
[0];
629 ptsp
->count
[1]=fmt
.fmt
.vbi
.count
[1];
630 ptsp
->bufsize
= ptsp
->samples_per_line
* (ptsp
->count
[0] + ptsp
->count
[1]);
632 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",
635 ptsp
->samples_per_line
,
636 ptsp
->interlaced
?"Yes":"No",
640 return TVI_CONTROL_TRUE
;
643 static void *vbi_grabber(void *data
)
645 priv_t
*priv
= (priv_t
*) data
;
646 int bytes
,seq
,prev_seq
;
651 mp_msg(MSGT_TV
,MSGL_WARN
,"vbi: vbi not initialized. stopping thread.\n");
655 if(vbi_get_props(priv
,&tsp
)!=TVI_CONTROL_TRUE
)
658 buf
=malloc(tsp
.bufsize
);
661 mp_msg(MSGT_TV
,MSGL_V
,"vbi: vbi capture thread started.\n");
663 while (!priv
->vbi_shutdown
){
664 bytes
=read(priv
->vbi_fd
,buf
,tsp
.bufsize
);
665 if(bytes
<0 && errno
==EINTR
)
667 if (bytes
!=tsp
.bufsize
){
668 mp_msg(MSGT_TV
,MSGL_WARN
,"vbi: expecting bytes: %d, got: %d\n",tsp
.bufsize
,bytes
);
671 seq
=*(int*)(buf
+bytes
-4);
673 if (prev_seq
&& seq
!=prev_seq
+1){
678 teletext_control(priv
->priv_vbi
,TV_VBI_CONTROL_DECODE_PAGE
,&buf
);
679 mp_msg(MSGT_TV
,MSGL_DBG3
,"grabber: seq:%d\n",seq
);
684 #endif //HAVE_TV_TELETEXT
686 static int control(priv_t
*priv
, int cmd
, void *arg
)
688 struct v4l2_control control
;
689 struct v4l2_frequency frequency
;
692 case TVI_CONTROL_IS_VIDEO
:
693 return priv
->capability
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
?
694 TVI_CONTROL_TRUE
: TVI_CONTROL_FALSE
;
695 case TVI_CONTROL_IS_AUDIO
:
696 if (priv
->tv_param
->force_audio
) return TVI_CONTROL_TRUE
;
697 case TVI_CONTROL_IS_TUNER
:
698 return priv
->capability
.capabilities
& V4L2_CAP_TUNER
?
699 TVI_CONTROL_TRUE
: TVI_CONTROL_FALSE
;
700 case TVI_CONTROL_IMMEDIATE
:
701 priv
->immediate_mode
= 1;
702 return TVI_CONTROL_TRUE
;
703 case TVI_CONTROL_VID_GET_FPS
:
704 *(float *)arg
= (float)priv
->standard
.frameperiod
.denominator
/
705 priv
->standard
.frameperiod
.numerator
;
706 mp_msg(MSGT_TV
, MSGL_V
, "%s: get fps: %f\n", info
.short_name
,
708 return TVI_CONTROL_TRUE
;
709 case TVI_CONTROL_VID_GET_BITS
:
710 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
711 *(int *)arg
= pixfmt2depth(priv
->format
.fmt
.pix
.pixelformat
);
712 mp_msg(MSGT_TV
, MSGL_V
, "%s: get depth: %d\n", info
.short_name
,
714 return TVI_CONTROL_TRUE
;
715 case TVI_CONTROL_VID_GET_FORMAT
:
716 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
717 *(int *)arg
= fcc_vl2mp(priv
->format
.fmt
.pix
.pixelformat
);
718 mp_msg(MSGT_TV
, MSGL_V
, "%s: get format: %s\n", info
.short_name
,
719 pixfmt2name(priv
->format
.fmt
.pix
.pixelformat
));
720 return TVI_CONTROL_TRUE
;
721 case TVI_CONTROL_VID_SET_FORMAT
:
722 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
723 priv
->format
.fmt
.pix
.pixelformat
= fcc_mp2vl(*(int *)arg
);
724 priv
->format
.fmt
.pix
.field
= V4L2_FIELD_ANY
;
726 priv
->mp_format
= *(int *)arg
;
727 mp_msg(MSGT_TV
, MSGL_V
, "%s: set format: %s\n", info
.short_name
,
728 pixfmt2name(priv
->format
.fmt
.pix
.pixelformat
));
729 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
730 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set format failed: %s\n",
731 info
.short_name
, strerror(errno
));
732 return TVI_CONTROL_FALSE
;
734 /* according to the v4l2 specs VIDIOC_S_FMT should not fail, inflexible drivers
735 might even always return the default parameters -> update the format here*/
736 priv
->mp_format
= fcc_vl2mp(priv
->format
.fmt
.pix
.pixelformat
);
737 return TVI_CONTROL_TRUE
;
738 case TVI_CONTROL_VID_GET_WIDTH
:
739 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
740 *(int *)arg
= priv
->format
.fmt
.pix
.width
;
741 mp_msg(MSGT_TV
, MSGL_V
, "%s: get width: %d\n", info
.short_name
,
743 return TVI_CONTROL_TRUE
;
744 case TVI_CONTROL_VID_CHK_WIDTH
:
745 return TVI_CONTROL_TRUE
;
746 case TVI_CONTROL_VID_SET_WIDTH
:
747 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
748 priv
->format
.fmt
.pix
.width
= *(int *)arg
;
749 mp_msg(MSGT_TV
, MSGL_V
, "%s: set width: %d\n", info
.short_name
,
751 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
752 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set width failed: %s\n",
753 info
.short_name
, strerror(errno
));
754 return TVI_CONTROL_FALSE
;
756 return TVI_CONTROL_TRUE
;
757 case TVI_CONTROL_VID_GET_HEIGHT
:
758 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
759 *(int *)arg
= priv
->format
.fmt
.pix
.height
;
760 mp_msg(MSGT_TV
, MSGL_V
, "%s: get height: %d\n", info
.short_name
,
762 return TVI_CONTROL_TRUE
;
763 case TVI_CONTROL_VID_CHK_HEIGHT
:
764 return TVI_CONTROL_TRUE
;
765 case TVI_CONTROL_VID_SET_HEIGHT
:
766 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
767 priv
->format
.fmt
.pix
.height
= *(int *)arg
;
768 priv
->format
.fmt
.pix
.field
= V4L2_FIELD_ANY
;
769 mp_msg(MSGT_TV
, MSGL_V
, "%s: set height: %d\n", info
.short_name
,
771 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
772 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set height failed: %s\n",
773 info
.short_name
, strerror(errno
));
774 return TVI_CONTROL_FALSE
;
776 return TVI_CONTROL_TRUE
;
777 case TVI_CONTROL_VID_GET_BRIGHTNESS
:
778 control
.id
= V4L2_CID_BRIGHTNESS
;
779 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
780 *(int *)arg
= control
.value
;
781 return TVI_CONTROL_TRUE
;
783 return TVI_CONTROL_FALSE
;
784 case TVI_CONTROL_VID_SET_BRIGHTNESS
:
785 control
.id
= V4L2_CID_BRIGHTNESS
;
786 control
.value
= *(int *)arg
;
787 return set_control(priv
, &control
, 1);
788 case TVI_CONTROL_VID_GET_HUE
:
789 control
.id
= V4L2_CID_HUE
;
790 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
791 *(int *)arg
= control
.value
;
792 return TVI_CONTROL_TRUE
;
794 return TVI_CONTROL_FALSE
;
795 case TVI_CONTROL_VID_SET_HUE
:
796 control
.id
= V4L2_CID_HUE
;
797 control
.value
= *(int *)arg
;
798 return set_control(priv
, &control
, 1);
799 case TVI_CONTROL_VID_GET_SATURATION
:
800 control
.id
= V4L2_CID_SATURATION
;
801 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
802 *(int *)arg
= control
.value
;
803 return TVI_CONTROL_TRUE
;
805 return TVI_CONTROL_FALSE
;
806 case TVI_CONTROL_VID_SET_SATURATION
:
807 control
.id
= V4L2_CID_SATURATION
;
808 control
.value
= *(int *)arg
;
809 return set_control(priv
, &control
, 1);
810 case TVI_CONTROL_VID_GET_GAIN
:
813 control
.id
= V4L2_CID_AUTOGAIN
;
814 if(get_control(priv
,&control
,0)!=TVI_CONTROL_TRUE
)
815 return TVI_CONTROL_FALSE
;
817 if(control
.value
){ //Auto Gain control is enabled
819 return TVI_CONTROL_TRUE
;
822 //Manual Gain control
823 control
.id
= V4L2_CID_GAIN
;
824 if(get_control(priv
,&control
,0)!=TVI_CONTROL_TRUE
)
825 return TVI_CONTROL_FALSE
;
827 *(int*)arg
=control
.value
?control
.value
:1;
829 return TVI_CONTROL_TRUE
;
831 case TVI_CONTROL_VID_SET_GAIN
:
833 //value==0 means automatic gain control
834 int value
=*(int*)arg
;
836 if (value
< 0 || value
>100)
837 return TVI_CONTROL_FALSE
;
839 control
.id
=value
?V4L2_CID_GAIN
:V4L2_CID_AUTOGAIN
;
840 control
.value
=value
?value
:1;
842 return set_control(priv
,&control
,0);
844 case TVI_CONTROL_VID_GET_CONTRAST
:
845 control
.id
= V4L2_CID_CONTRAST
;
846 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
847 *(int *)arg
= control
.value
;
848 return TVI_CONTROL_TRUE
;
850 return TVI_CONTROL_FALSE
;
851 case TVI_CONTROL_VID_SET_CONTRAST
:
852 control
.id
= V4L2_CID_CONTRAST
;
853 control
.value
= *(int *)arg
;
854 return set_control(priv
, &control
, 1);
855 case TVI_CONTROL_TUN_GET_FREQ
:
857 frequency
.type
= V4L2_TUNER_ANALOG_TV
;
858 if (ioctl(priv
->video_fd
, VIDIOC_G_FREQUENCY
, &frequency
) < 0) {
859 mp_msg(MSGT_TV
,MSGL_ERR
,"%s: ioctl get frequency failed: %s\n",
860 info
.short_name
, strerror(errno
));
861 return TVI_CONTROL_FALSE
;
863 *(int *)arg
= frequency
.frequency
;
864 return TVI_CONTROL_TRUE
;
865 case TVI_CONTROL_TUN_SET_FREQ
:
868 usleep(100000); // wait to suppress noise during switching
871 frequency
.type
= V4L2_TUNER_ANALOG_TV
;
872 frequency
.frequency
= *(int *)arg
;
873 if (ioctl(priv
->video_fd
, VIDIOC_S_FREQUENCY
, &frequency
) < 0) {
874 mp_msg(MSGT_TV
,MSGL_ERR
,"%s: ioctl set frequency failed: %s\n",
875 info
.short_name
, strerror(errno
));
876 return TVI_CONTROL_FALSE
;
879 usleep(100000); // wait to suppress noise during switching
882 return TVI_CONTROL_TRUE
;
883 case TVI_CONTROL_TUN_GET_TUNER
:
884 mp_msg(MSGT_TV
, MSGL_V
, "%s: get tuner\n",info
.short_name
);
885 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) < 0) {
886 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get tuner failed: %s\n",
887 info
.short_name
, strerror(errno
));
888 return TVI_CONTROL_FALSE
;
890 return TVI_CONTROL_TRUE
;
891 case TVI_CONTROL_TUN_SET_TUNER
:
892 mp_msg(MSGT_TV
, MSGL_V
, "%s: set tuner\n",info
.short_name
);
893 if (ioctl(priv
->video_fd
, VIDIOC_S_TUNER
, &priv
->tuner
) < 0) {
894 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set tuner failed: %s\n",
895 info
.short_name
, strerror(errno
));
896 return TVI_CONTROL_FALSE
;
898 return TVI_CONTROL_TRUE
;
899 case TVI_CONTROL_TUN_GET_NORM
:
900 *(int *)arg
= priv
->standard
.index
;
901 return TVI_CONTROL_TRUE
;
902 case TVI_CONTROL_TUN_GET_SIGNAL
:
903 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) < 0) {
904 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get tuner failed: %s\n",
905 info
.short_name
, strerror(errno
));
906 return TVI_CONTROL_FALSE
;
908 *(int*)arg
=100*(priv
->tuner
.signal
>>8)/255;
909 return TVI_CONTROL_TRUE
;
910 case TVI_CONTROL_TUN_SET_NORM
:
911 priv
->standard
.index
= *(int *)arg
;
912 if (ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &priv
->standard
) < 0) {
913 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl enum norm failed: %s\n",
914 info
.short_name
, strerror(errno
));
915 return TVI_CONTROL_FALSE
;
917 mp_msg(MSGT_TV
, MSGL_V
, "%s: set norm: %s\n", info
.short_name
, priv
->standard
.name
);
918 if (ioctl(priv
->video_fd
, VIDIOC_S_STD
, &priv
->standard
.id
) < 0) {
919 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set norm failed: %s\n",
920 info
.short_name
, strerror(errno
));
921 return TVI_CONTROL_FALSE
;
923 return TVI_CONTROL_TRUE
;
924 case TVI_CONTROL_SPC_GET_NORMID
:
928 struct v4l2_standard standard
;
929 memset(&standard
, 0, sizeof(standard
));
931 if (-1 == ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &standard
))
932 return TVI_CONTROL_FALSE
;
933 if (!strcasecmp(standard
.name
, (char *)arg
)) {
935 return TVI_CONTROL_TRUE
;
938 return TVI_CONTROL_FALSE
;
940 case TVI_CONTROL_SPC_GET_INPUT
:
941 if (ioctl(priv
->video_fd
, VIDIOC_G_INPUT
, (int *)arg
) < 0) {
942 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get input failed: %s\n",
943 info
.short_name
, strerror(errno
));
944 return TVI_CONTROL_FALSE
;
946 return TVI_CONTROL_TRUE
;
947 case TVI_CONTROL_SPC_SET_INPUT
:
948 mp_msg(MSGT_TV
, MSGL_V
, "%s: set input: %d\n", info
.short_name
, *(int *)arg
);
949 priv
->input
.index
= *(int *)arg
;
950 if (ioctl(priv
->video_fd
, VIDIOC_ENUMINPUT
, &priv
->input
) < 0) {
951 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl enum input failed: %s\n",
952 info
.short_name
, strerror(errno
));
953 return TVI_CONTROL_FALSE
;
955 if (ioctl(priv
->video_fd
, VIDIOC_S_INPUT
, (int *)arg
) < 0) {
956 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set input failed: %s\n",
957 info
.short_name
, strerror(errno
));
958 return TVI_CONTROL_FALSE
;
960 return TVI_CONTROL_TRUE
;
961 case TVI_CONTROL_AUD_GET_FORMAT
:
963 if (!priv
->audio_inited
) return TVI_CONTROL_FALSE
;
964 *(int *)arg
= AF_FORMAT_S16_LE
;
965 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio format: %d\n",
966 info
.short_name
, *(int *)arg
);
967 return TVI_CONTROL_TRUE
;
968 case TVI_CONTROL_AUD_GET_SAMPLERATE
:
970 if (!priv
->audio_inited
) return TVI_CONTROL_FALSE
;
971 *(int *)arg
= priv
->audio_in
.samplerate
;
972 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio samplerate: %d\n",
973 info
.short_name
, *(int *)arg
);
974 return TVI_CONTROL_TRUE
;
975 case TVI_CONTROL_AUD_GET_SAMPLESIZE
:
977 if (!priv
->audio_inited
) return TVI_CONTROL_FALSE
;
978 *(int *)arg
= priv
->audio_in
.bytes_per_sample
;
979 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio samplesize: %d\n",
980 info
.short_name
, *(int *)arg
);
981 return TVI_CONTROL_TRUE
;
982 case TVI_CONTROL_AUD_GET_CHANNELS
:
984 if (!priv
->audio_inited
) return TVI_CONTROL_FALSE
;
985 *(int *)arg
= priv
->audio_in
.channels
;
986 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio channels: %d\n",
987 info
.short_name
, *(int *)arg
);
988 return TVI_CONTROL_TRUE
;
989 case TVI_CONTROL_AUD_SET_SAMPLERATE
:
991 mp_msg(MSGT_TV
, MSGL_V
, "%s: set audio samplerate: %d\n",
992 info
.short_name
, *(int *)arg
);
993 if (audio_in_set_samplerate(&priv
->audio_in
, *(int*)arg
) < 0) return TVI_CONTROL_FALSE
;
994 // setup_audio_buffer_sizes(priv);
995 return TVI_CONTROL_TRUE
;
996 #ifdef HAVE_TV_TELETEXT
997 case TVI_CONTROL_VBI_INIT
:
1000 tt_stream_props tsp
;
1002 if (vbi_init(priv
,*(char**)arg
)!=TVI_CONTROL_TRUE
)
1003 return TVI_CONTROL_FALSE
;
1004 if(vbi_get_props(priv
,&tsp
)==TVI_CONTROL_TRUE
)
1007 if(teletext_control(NULL
,TV_VBI_CONTROL_START
,&ptr
)==TVI_CONTROL_TRUE
)
1010 priv
->priv_vbi
=NULL
;
1012 return TVI_CONTROL_TRUE
;
1015 return teletext_control(priv
->priv_vbi
,cmd
,arg
);
1018 mp_msg(MSGT_TV
, MSGL_V
, "%s: unknown control: %d\n", info
.short_name
, cmd
);
1019 return(TVI_CONTROL_UNKNOWN
);
1023 #define PRIV ((priv_t *) (tvi_handle->priv))
1025 /* handler creator - entry point ! */
1026 static tvi_handle_t
*tvi_init_v4l2(tv_param_t
* tv_param
)
1028 tvi_handle_t
*tvi_handle
;
1030 /* new_handle initializes priv with memset 0 */
1031 tvi_handle
= new_handle();
1035 PRIV
->video_fd
= -1;
1037 PRIV
->video_dev
= strdup(tv_param
->device
? tv_param
->device
: "/dev/video0");
1038 if (!PRIV
->video_dev
) {
1039 free_handle(tvi_handle
);
1043 if (tv_param
->adevice
) {
1044 PRIV
->audio_dev
= strdup(tv_param
->adevice
);
1045 if (!PRIV
->audio_dev
) {
1046 free(PRIV
->video_dev
);
1047 free_handle(tvi_handle
);
1052 PRIV
->tv_param
=tv_param
;
1059 static int uninit(priv_t
*priv
)
1061 int i
, frames
, dropped
= 0;
1063 #ifdef HAVE_TV_TELETEXT
1064 priv
->vbi_shutdown
=1;
1065 if(priv
->vbi_grabber_thread
)
1066 pthread_join(priv
->vbi_grabber_thread
, NULL
);
1068 teletext_control(priv
->priv_vbi
,TV_VBI_CONTROL_STOP
,(void*)1);
1069 priv
->priv_vbi
=NULL
;
1072 close(priv
->vbi_fd
);
1077 free(priv
->vbi_dev
);
1084 if(priv
->video_grabber_thread
)
1085 pthread_join(priv
->video_grabber_thread
, NULL
);
1086 pthread_mutex_destroy(&priv
->video_buffer_mutex
);
1088 if (priv
->streamon
) {
1089 struct v4l2_buffer buf
;
1091 /* get performance */
1092 frames
= 1 + (priv
->curr_frame
- priv
->first_frame
+
1093 priv
->standard
.frameperiod
.numerator
* 500000 /
1094 priv
->standard
.frameperiod
.denominator
) *
1095 priv
->standard
.frameperiod
.denominator
/
1096 priv
->standard
.frameperiod
.numerator
/ 1000000;
1097 dropped
= frames
- priv
->frames
;
1099 /* turn off streaming */
1100 if (ioctl(priv
->video_fd
, VIDIOC_STREAMOFF
, &(priv
->map
[0].buf
.type
)) < 0) {
1101 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl streamoff failed: %s\n",
1102 info
.short_name
, strerror(errno
));
1106 /* unqueue all remaining buffers */
1107 memset(&buf
,0,sizeof(buf
));
1108 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1109 buf
.memory
= V4L2_MEMORY_MMAP
;
1110 while (!ioctl(priv
->video_fd
, VIDIOC_DQBUF
, &buf
));
1113 /* unmap all buffers */
1114 for (i
= 0; i
< priv
->mapcount
; i
++) {
1115 if (munmap(priv
->map
[i
].addr
, priv
->map
[i
].len
) < 0) {
1116 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: munmap capture buffer failed: %s\n",
1117 info
.short_name
, strerror(errno
));
1121 /* stop audio thread */
1122 if (!priv
->tv_param
->noaudio
&& priv
->audio_grabber_thread
) {
1123 pthread_join(priv
->audio_grabber_thread
, NULL
);
1124 pthread_mutex_destroy(&priv
->skew_mutex
);
1125 pthread_mutex_destroy(&priv
->audio_mutex
);
1130 /* free memory and close device */
1131 free(priv
->map
); priv
->map
= NULL
;
1133 if(priv
->video_fd
!=-1)close(priv
->video_fd
); priv
->video_fd
= -1;
1134 free(priv
->video_dev
); priv
->video_dev
= NULL
;
1136 if (priv
->video_ringbuffer
) {
1138 for (i
= 0; i
< priv
->video_buffer_size_current
; i
++) {
1139 free(priv
->video_ringbuffer
[i
].data
);
1141 free(priv
->video_ringbuffer
);
1143 if (!priv
->tv_param
->noaudio
) {
1144 if (priv
->audio_ringbuffer
)
1145 free(priv
->audio_ringbuffer
);
1146 if (priv
->audio_skew_buffer
)
1147 free(priv
->audio_skew_buffer
);
1148 if (priv
->audio_skew_delta_buffer
)
1149 free(priv
->audio_skew_delta_buffer
);
1151 audio_in_uninit(&priv
->audio_in
);
1154 /* show some nice statistics ;-) */
1155 mp_msg(MSGT_TV
, MSGL_INFO
,
1156 "%s: %d frames successfully processed, %d frames dropped.\n",
1157 info
.short_name
, priv
->frames
, dropped
);
1158 mp_msg(MSGT_TV
, MSGL_V
, "%s: up to %u video frames buffered.\n",
1159 info
.short_name
, priv
->video_buffer_size_current
);
1164 /* initialisation */
1165 static int init(priv_t
*priv
)
1169 priv
->audio_ringbuffer
= NULL
;
1170 priv
->audio_skew_buffer
= NULL
;
1171 priv
->audio_skew_delta_buffer
= NULL
;
1173 priv
->audio_inited
= 0;
1175 /* Open the video device. */
1176 priv
->video_fd
= open(priv
->video_dev
, O_RDWR
);
1177 if (priv
->video_fd
< 0) {
1178 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: unable to open '%s': %s\n",
1179 info
.short_name
, priv
->video_dev
, strerror(errno
));
1183 mp_msg(MSGT_TV
, MSGL_DBG2
, "%s: video fd: %s: %d\n",
1184 info
.short_name
, priv
->video_dev
, priv
->video_fd
);
1187 ** Query the video capabilities and current settings
1188 ** for further control calls.
1190 if (ioctl(priv
->video_fd
, VIDIOC_QUERYCAP
, &priv
->capability
) < 0) {
1191 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query capabilities failed: %s\n",
1192 info
.short_name
, strerror(errno
));
1197 if (!(priv
->capability
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
))
1199 mp_msg(MSGT_TV
, MSGL_ERR
, "Device %s is not a video capture device.\n",
1204 if (getfmt(priv
) < 0) {
1210 ** if this device has got a tuner query it's settings
1211 ** otherwise set some nice defaults
1213 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
1214 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) < 0) {
1215 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get tuner failed: %s\n",
1216 info
.short_name
, strerror(errno
));
1221 mp_msg(MSGT_TV
, MSGL_INFO
, "Selected device: %s\n", priv
->capability
.card
);
1222 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
1223 mp_msg(MSGT_TV
, MSGL_INFO
, " Tuner cap:%s%s%s\n",
1224 (priv
->tuner
.capability
& V4L2_TUNER_CAP_STEREO
) ? " STEREO" : "",
1225 (priv
->tuner
.capability
& V4L2_TUNER_CAP_LANG1
) ? " LANG1" : "",
1226 (priv
->tuner
.capability
& V4L2_TUNER_CAP_LANG2
) ? " LANG2" : "");
1227 mp_msg(MSGT_TV
, MSGL_INFO
, " Tuner rxs:%s%s%s%s\n",
1228 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_MONO
) ? " MONO" : "",
1229 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_STEREO
) ? " STEREO" : "",
1230 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_LANG1
) ? " LANG1" : "",
1231 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_LANG2
) ? " LANG2" : "");
1233 mp_msg(MSGT_TV
, MSGL_INFO
, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1234 priv
->capability
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
?
1235 " video capture": "",
1236 priv
->capability
.capabilities
& V4L2_CAP_VIDEO_OUTPUT
?
1237 " video output": "",
1238 priv
->capability
.capabilities
& V4L2_CAP_VIDEO_OVERLAY
?
1239 " video overlay": "",
1240 priv
->capability
.capabilities
& V4L2_CAP_VBI_CAPTURE
?
1241 " VBI capture device": "",
1242 priv
->capability
.capabilities
& V4L2_CAP_VBI_OUTPUT
?
1244 priv
->capability
.capabilities
& V4L2_CAP_RDS_CAPTURE
?
1245 " RDS data capture": "",
1246 priv
->capability
.capabilities
& V4L2_CAP_TUNER
?
1248 priv
->capability
.capabilities
& V4L2_CAP_AUDIO
?
1250 priv
->capability
.capabilities
& V4L2_CAP_READWRITE
?
1252 priv
->capability
.capabilities
& V4L2_CAP_ASYNCIO
?
1254 priv
->capability
.capabilities
& V4L2_CAP_STREAMING
?
1256 mp_msg(MSGT_TV
, MSGL_INFO
, " supported norms:");
1258 struct v4l2_standard standard
;
1259 memset(&standard
, 0, sizeof(standard
));
1261 if (-1 == ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &standard
))
1263 mp_msg(MSGT_TV
, MSGL_INFO
, " %d = %s;", i
, standard
.name
);
1265 mp_msg(MSGT_TV
, MSGL_INFO
, "\n inputs:");
1266 for (i
= 0; 1; i
++) {
1267 struct v4l2_input input
;
1270 if (ioctl(priv
->video_fd
, VIDIOC_ENUMINPUT
, &input
) < 0) {
1273 mp_msg(MSGT_TV
, MSGL_INFO
, " %d = %s;", i
, input
.name
);
1275 if (ioctl(priv
->video_fd
, VIDIOC_G_INPUT
, &i
) < 0) {
1276 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get input failed: %s\n",
1277 info
.short_name
, strerror(errno
));
1279 mp_msg(MSGT_TV
, MSGL_INFO
, "\n Current input: %d\n", i
);
1280 for (i
= 0; ; i
++) {
1281 struct v4l2_fmtdesc fmtdesc
;
1284 fmtdesc
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1285 if (ioctl(priv
->video_fd
, VIDIOC_ENUM_FMT
, &fmtdesc
) < 0) {
1288 mp_msg(MSGT_TV
, MSGL_V
, " Format %-6s (%2d bits, %s): %s\n",
1289 pixfmt2name(fmtdesc
.pixelformat
), pixfmt2depth(fmtdesc
.pixelformat
),
1290 fmtdesc
.description
, vo_format_name(fcc_vl2mp(fmtdesc
.pixelformat
)));
1292 mp_msg(MSGT_TV
, MSGL_INFO
, " Current format: %s\n",
1293 pixfmt2name(priv
->format
.fmt
.pix
.pixelformat
));
1295 /* set some nice defaults */
1296 if (getfmt(priv
) < 0) return 0;
1297 priv
->format
.fmt
.pix
.width
= 640;
1298 priv
->format
.fmt
.pix
.height
= 480;
1299 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
1300 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set format failed: %s\n",
1301 info
.short_name
, strerror(errno
));
1306 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;
1308 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
1309 struct v4l2_control control
;
1310 if (priv
->tv_param
->amode
>= 0) {
1311 mp_msg(MSGT_TV
, MSGL_V
, "%s: setting audio mode\n", info
.short_name
);
1312 priv
->tuner
.audmode
= amode2v4l(priv
->tv_param
->amode
);
1313 if (ioctl(priv
->video_fd
, VIDIOC_S_TUNER
, &priv
->tuner
) < 0) {
1314 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set tuner failed: %s\n",
1315 info
.short_name
, strerror(errno
));
1316 return TVI_CONTROL_FALSE
;
1319 mp_msg(MSGT_TV
, MSGL_INFO
, "%s: current audio mode is :%s%s%s%s\n", info
.short_name
,
1320 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_MONO
) ? " MONO" : "",
1321 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_STEREO
) ? " STEREO" : "",
1322 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_LANG1
) ? " LANG1" : "",
1323 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_LANG2
) ? " LANG2" : "");
1325 if (priv
->tv_param
->volume
>= 0) {
1326 control
.id
= V4L2_CID_AUDIO_VOLUME
;
1327 control
.value
= priv
->tv_param
->volume
;
1328 set_control(priv
, &control
, 0);
1330 if (priv
->tv_param
->bass
>= 0) {
1331 control
.id
= V4L2_CID_AUDIO_BASS
;
1332 control
.value
= priv
->tv_param
->bass
;
1333 set_control(priv
, &control
, 0);
1335 if (priv
->tv_param
->treble
>= 0) {
1336 control
.id
= V4L2_CID_AUDIO_TREBLE
;
1337 control
.value
= priv
->tv_param
->treble
;
1338 set_control(priv
, &control
, 0);
1340 if (priv
->tv_param
->balance
>= 0) {
1341 control
.id
= V4L2_CID_AUDIO_BALANCE
;
1342 control
.value
= priv
->tv_param
->balance
;
1343 set_control(priv
, &control
, 0);
1350 static int get_capture_buffer_size(priv_t
*priv
)
1354 if (priv
->tv_param
->buffer_size
>= 0) {
1355 bufsize
= priv
->tv_param
->buffer_size
*1024*1024;
1357 #ifdef HAVE_SYS_SYSINFO_H
1361 if (si
.totalram
<2*1024*1024) {
1362 bufsize
= 1024*1024;
1364 bufsize
= si
.totalram
/2;
1367 bufsize
= 16*1024*1024;
1371 cnt
= bufsize
/priv
->format
.fmt
.pix
.sizeimage
;
1372 if (cnt
< 2) cnt
= 2;
1377 /* that's the real start, we'got the format parameters (checked with control) */
1378 static int start(priv_t
*priv
)
1380 struct v4l2_requestbuffers request
;
1383 /* setup audio parameters */
1386 if (!priv
->tv_param
->noaudio
&& !priv
->audio_inited
) return 0;
1388 /* we need this to size the audio buffer properly */
1389 if (priv
->immediate_mode
) {
1390 priv
->video_buffer_size_max
= 2;
1392 priv
->video_buffer_size_max
= get_capture_buffer_size(priv
);
1395 if (!priv
->tv_param
->noaudio
) {
1396 setup_audio_buffer_sizes(priv
);
1397 priv
->audio_skew_buffer
= calloc(priv
->aud_skew_cnt
, sizeof(long long));
1398 if (!priv
->audio_skew_buffer
) {
1399 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate skew buffer: %s\n", strerror(errno
));
1402 priv
->audio_skew_delta_buffer
= calloc(priv
->aud_skew_cnt
, sizeof(long long));
1403 if (!priv
->audio_skew_delta_buffer
) {
1404 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate skew buffer: %s\n", strerror(errno
));
1408 priv
->audio_ringbuffer
= calloc(priv
->audio_in
.blocksize
, priv
->audio_buffer_size
);
1409 if (!priv
->audio_ringbuffer
) {
1410 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate audio buffer: %s\n", strerror(errno
));
1414 priv
->audio_secs_per_block
= (double)priv
->audio_in
.blocksize
/(priv
->audio_in
.samplerate
1415 *priv
->audio_in
.channels
1416 *priv
->audio_in
.bytes_per_sample
);
1417 priv
->audio_usecs_per_block
= 1e6
*priv
->audio_secs_per_block
;
1418 priv
->audio_head
= 0;
1419 priv
->audio_tail
= 0;
1420 priv
->audio_cnt
= 0;
1421 priv
->audio_drop
= 0;
1422 priv
->audio_skew
= 0;
1423 priv
->audio_skew_total
= 0;
1424 priv
->audio_skew_delta_total
= 0;
1425 priv
->audio_recv_blocks_total
= 0;
1426 priv
->audio_sent_blocks_total
= 0;
1427 priv
->audio_null_blocks_inserted
= 0;
1428 priv
->audio_insert_null_samples
= 0;
1429 priv
->dropped_frames_timeshift
= 0;
1430 priv
->dropped_frames_compensated
= 0;
1432 pthread_mutex_init(&priv
->skew_mutex
, NULL
);
1433 pthread_mutex_init(&priv
->audio_mutex
, NULL
);
1436 /* setup video parameters */
1437 if (!priv
->tv_param
->noaudio
) {
1438 if (priv
->video_buffer_size_max
< (3*priv
->standard
.frameperiod
.denominator
) /
1439 priv
->standard
.frameperiod
.numerator
1440 *priv
->audio_secs_per_block
) {
1441 mp_msg(MSGT_TV
, MSGL_ERR
, "Video buffer shorter than 3 times audio frame duration.\n"
1442 "You will probably experience heavy framedrops.\n");
1447 int bytesperline
= priv
->format
.fmt
.pix
.width
*pixfmt2depth(priv
->format
.fmt
.pix
.pixelformat
)/8;
1449 mp_msg(MSGT_TV
, MSGL_V
, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1450 priv
->video_buffer_size_max
,
1451 priv
->video_buffer_size_max
*priv
->format
.fmt
.pix
.height
*bytesperline
/(1024*1024));
1454 priv
->video_ringbuffer
= calloc(priv
->video_buffer_size_max
, sizeof(video_buffer_entry
));
1455 if (!priv
->video_ringbuffer
) {
1456 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate video buffer: %s\n", strerror(errno
));
1459 memset(priv
->video_ringbuffer
,0,priv
->video_buffer_size_max
* sizeof(video_buffer_entry
));
1461 pthread_mutex_init(&priv
->video_buffer_mutex
, NULL
);
1463 priv
->video_head
= 0;
1464 priv
->video_tail
= 0;
1465 priv
->video_cnt
= 0;
1467 /* request buffers */
1468 if (priv
->immediate_mode
) {
1471 request
.count
= BUFFER_COUNT
;
1474 request
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1475 request
.memory
= V4L2_MEMORY_MMAP
;
1476 if (ioctl(priv
->video_fd
, VIDIOC_REQBUFS
, &request
) < 0) {
1477 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl request buffers failed: %s\n",
1478 info
.short_name
, strerror(errno
));
1483 if (!(priv
->map
= calloc(request
.count
, sizeof(struct map
)))) {
1484 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: malloc capture buffers failed: %s\n",
1485 info
.short_name
, strerror(errno
));
1489 /* map and queue buffers */
1490 for (i
= 0; i
< request
.count
; i
++) {
1491 memset(&priv
->map
[i
].buf
,0,sizeof(priv
->map
[i
].buf
));
1492 priv
->map
[i
].buf
.index
= i
;
1493 priv
->map
[i
].buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1494 priv
->map
[i
].buf
.memory
= V4L2_MEMORY_MMAP
;
1495 if (ioctl(priv
->video_fd
, VIDIOC_QUERYBUF
, &(priv
->map
[i
].buf
)) < 0) {
1496 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query buffer failed: %s\n",
1497 info
.short_name
, strerror(errno
));
1502 priv
->map
[i
].addr
= mmap (0, priv
->map
[i
].buf
.length
, PROT_READ
|
1503 PROT_WRITE
, MAP_SHARED
, priv
->video_fd
, priv
->map
[i
].buf
.m
.offset
);
1504 if (priv
->map
[i
].addr
== MAP_FAILED
) {
1505 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: mmap capture buffer failed: %s\n",
1506 info
.short_name
, strerror(errno
));
1507 priv
->map
[i
].len
= 0;
1510 priv
->map
[i
].len
= priv
->map
[i
].buf
.length
;
1511 /* count up to make sure this is correct everytime */
1514 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &(priv
->map
[i
].buf
)) < 0) {
1515 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1516 info
.short_name
, strerror(errno
));
1521 #ifdef HAVE_TV_TELETEXT
1522 /* start vbi thread */
1524 priv
->vbi_shutdown
= 0;
1525 pthread_create(&priv
->vbi_grabber_thread
, NULL
, vbi_grabber
, priv
);
1528 /* start audio thread */
1530 priv
->audio_skew_measure_time
= 0;
1531 priv
->first_frame
= 0;
1532 priv
->audio_skew
= 0;
1540 // copies a video frame
1541 static inline void copy_frame(priv_t
*priv
, video_buffer_entry
*dest
, unsigned char *source
,int len
)
1543 dest
->framesize
=len
;
1544 if(priv
->tv_param
->automute
>0){
1545 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) >= 0) {
1546 if(priv
->tv_param
->automute
<<8>priv
->tuner
.signal
){
1547 fill_blank_frame(dest
->data
,dest
->framesize
,fcc_vl2mp(priv
->format
.fmt
.pix
.pixelformat
));
1554 memcpy(dest
->data
, source
, len
);
1557 // maximum skew change, in frames
1558 #define MAX_SKEW_DELTA 0.6
1559 static void *video_grabber(void *data
)
1561 priv_t
*priv
= (priv_t
*)data
;
1562 long long skew
, prev_skew
, xskew
, interval
, prev_interval
, delta
;
1564 int framesize
= priv
->format
.fmt
.pix
.sizeimage
;
1566 struct timeval timeout
;
1567 struct v4l2_buffer buf
;
1575 mp_msg(MSGT_TV
, MSGL_V
, "%s: going to capture\n", info
.short_name
);
1576 if (ioctl(priv
->video_fd
, VIDIOC_STREAMON
, &(priv
->format
.type
)) < 0) {
1577 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl streamon failed: %s\n",
1578 info
.short_name
, strerror(errno
));
1583 if (!priv
->tv_param
->noaudio
) {
1584 pthread_create(&priv
->audio_grabber_thread
, NULL
, audio_grabber
, priv
);
1587 for (priv
->frames
= 0; !priv
->shutdown
;)
1591 if (priv
->immediate_mode
) {
1592 while (priv
->video_cnt
== priv
->video_buffer_size_max
) {
1594 if (priv
->shutdown
) {
1601 FD_SET (priv
->video_fd
, &rdset
);
1604 timeout
.tv_usec
= 0;
1606 i
= select(priv
->video_fd
+ 1, &rdset
, NULL
, NULL
, &timeout
);
1608 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: select failed: %s\n",
1609 info
.short_name
, strerror(errno
));
1613 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: select timeout\n", info
.short_name
);
1616 else if (!FD_ISSET(priv
->video_fd
, &rdset
)) {
1620 memset(&buf
,0,sizeof(buf
));
1621 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1622 buf
.memory
= V4L2_MEMORY_MMAP
;
1623 ret
= ioctl(priv
->video_fd
, VIDIOC_DQBUF
, &buf
);
1627 if there's no signal, the buffer might me dequeued
1628 so we query all the buffers to see which one we should
1631 observed with saa7134 0.2.8
1632 don't know if is it a bug or (mis)feature
1634 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1635 info
.short_name
, strerror(errno
), buf
.index
);
1636 for (i
= 0; i
< priv
->mapcount
; i
++) {
1637 memset(&buf
,0,sizeof(buf
));
1638 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1639 buf
.memory
= V4L2_MEMORY_MMAP
;
1641 ret
= ioctl(priv
->video_fd
, VIDIOC_QUERYBUF
, &buf
);
1643 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query buffer failed: %s, idx = %d\n",
1644 info
.short_name
, strerror(errno
), buf
.index
);
1647 if ((buf
.flags
& (V4L2_BUF_FLAG_QUEUED
| V4L2_BUF_FLAG_MAPPED
| V4L2_BUF_FLAG_DONE
)) == V4L2_BUF_FLAG_MAPPED
) {
1648 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &(priv
->map
[i
].buf
)) < 0) {
1649 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1650 info
.short_name
, strerror(errno
));
1658 /* store the timestamp of the very first frame as reference */
1659 if (!priv
->frames
++) {
1660 if (!priv
->tv_param
->noaudio
) pthread_mutex_lock(&priv
->skew_mutex
);
1661 priv
->first_frame
= (long long)1e6
*buf
.timestamp
.tv_sec
+ buf
.timestamp
.tv_usec
;
1662 if (!priv
->tv_param
->noaudio
) pthread_mutex_unlock(&priv
->skew_mutex
);
1664 priv
->curr_frame
= (long long)buf
.timestamp
.tv_sec
*1e6
+buf
.timestamp
.tv_usec
;
1665 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1667 interval
= priv
->curr_frame
- priv
->first_frame
;
1668 delta
= interval
- prev_interval
;
1670 if (!priv
->immediate_mode
) {
1671 // interpolate the skew in time
1672 if (!priv
->tv_param
->noaudio
) pthread_mutex_lock(&priv
->skew_mutex
);
1673 xskew
= priv
->audio_skew
+ (interval
- priv
->audio_skew_measure_time
)*priv
->audio_skew_factor
;
1674 if (!priv
->tv_param
->noaudio
) pthread_mutex_unlock(&priv
->skew_mutex
);
1675 // correct extreme skew changes to avoid (especially) moving backwards in time
1676 if (xskew
- prev_skew
> delta
*MAX_SKEW_DELTA
) {
1677 skew
= prev_skew
+ delta
*MAX_SKEW_DELTA
;
1678 } else if (xskew
- prev_skew
< -delta
*MAX_SKEW_DELTA
) {
1679 skew
= prev_skew
- delta
*MAX_SKEW_DELTA
;
1685 mp_msg(MSGT_TV
, MSGL_DBG3
, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1686 delta
? (double)1e6
/delta
: -1,
1687 (double)1e-6*interval
, (double)1e-6*xskew
, (double)1e-6*skew
);
1688 mp_msg(MSGT_TV
, MSGL_DBG3
, "vcnt = %d, acnt = %d\n", priv
->video_cnt
, priv
->audio_cnt
);
1691 prev_interval
= interval
;
1693 /* allocate a new buffer, if needed */
1694 pthread_mutex_lock(&priv
->video_buffer_mutex
);
1695 if (priv
->video_buffer_size_current
< priv
->video_buffer_size_max
) {
1696 if (priv
->video_cnt
== priv
->video_buffer_size_current
) {
1697 unsigned char *newbuf
= malloc(framesize
);
1699 memmove(priv
->video_ringbuffer
+priv
->video_tail
+1, priv
->video_ringbuffer
+priv
->video_tail
,
1700 (priv
->video_buffer_size_current
-priv
->video_tail
)*sizeof(video_buffer_entry
));
1701 priv
->video_ringbuffer
[priv
->video_tail
].data
= newbuf
;
1702 if ((priv
->video_head
>= priv
->video_tail
) && (priv
->video_cnt
> 0)) priv
->video_head
++;
1703 priv
->video_buffer_size_current
++;
1707 pthread_mutex_unlock(&priv
->video_buffer_mutex
);
1709 if (priv
->video_cnt
== priv
->video_buffer_size_current
) {
1710 if (!priv
->immediate_mode
) {
1711 mp_msg(MSGT_TV
, MSGL_ERR
, "\nvideo buffer full - dropping frame\n");
1712 if (priv
->audio_insert_null_samples
) {
1713 pthread_mutex_lock(&priv
->audio_mutex
);
1714 priv
->dropped_frames_timeshift
+= delta
;
1715 pthread_mutex_unlock(&priv
->audio_mutex
);
1719 if (priv
->immediate_mode
) {
1720 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
= 0;
1722 // compensate for audio skew
1723 // negative skew => there are more audio samples, increase interval
1724 // positive skew => less samples, shorten the interval
1725 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
= interval
- skew
;
1726 if (priv
->audio_insert_null_samples
&& priv
->video_ringbuffer
[priv
->video_tail
].timestamp
> 0) {
1727 pthread_mutex_lock(&priv
->audio_mutex
);
1728 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
+=
1729 (priv
->audio_null_blocks_inserted
1730 - priv
->dropped_frames_timeshift
/priv
->audio_usecs_per_block
)
1731 *priv
->audio_usecs_per_block
;
1732 pthread_mutex_unlock(&priv
->audio_mutex
);
1735 copy_frame(priv
, priv
->video_ringbuffer
+priv
->video_tail
, priv
->map
[buf
.index
].addr
,buf
.bytesused
);
1736 priv
->video_tail
= (priv
->video_tail
+1)%priv
->video_buffer_size_current
;
1739 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &buf
) < 0) {
1740 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1741 info
.short_name
, strerror(errno
));
1749 static double grab_video_frame(priv_t
*priv
, char *buffer
, int len
)
1755 pthread_create(&priv
->video_grabber_thread
, NULL
, video_grabber
, priv
);
1759 while (priv
->video_cnt
== 0) {
1761 if (loop_cnt
++ > MAX_LOOP
) return 0;
1764 pthread_mutex_lock(&priv
->video_buffer_mutex
);
1765 interval
= (double)priv
->video_ringbuffer
[priv
->video_head
].timestamp
*1e-6;
1766 memcpy(buffer
, priv
->video_ringbuffer
[priv
->video_head
].data
, len
);
1768 priv
->video_head
= (priv
->video_head
+1)%priv
->video_buffer_size_current
;
1769 pthread_mutex_unlock(&priv
->video_buffer_mutex
);
1774 static int get_video_framesize(priv_t
*priv
)
1777 this routine will be called before grab_video_frame
1778 thus let's return topmost frame's size
1780 if (priv
->video_cnt
)
1781 return priv
->video_ringbuffer
[priv
->video_head
].framesize
;
1783 no video frames yet available. i don't know what to do in this case,
1784 thus let's return some fallback result (for compressed format this will be
1785 maximum allowed frame size.
1787 return priv
->format
.fmt
.pix
.sizeimage
;
1790 //#define DOUBLESPEED
1792 // for testing purposes only
1793 static void read_doublespeed(priv_t
*priv
)
1795 char *bufx
= calloc(priv
->audio_in
.blocksize
, 2);
1800 audio_in_read_chunk(&priv
->audio_in
, bufx
);
1801 audio_in_read_chunk(&priv
->audio_in
, bufx
+priv
->audio_in
.blocksize
);
1804 d
= priv
->audio_ringbuffer
+priv
->audio_tail
*priv
->audio_in
.blocksize
;
1805 for (i
= 0; i
< priv
->audio_in
.blocksize
/2; i
++) {
1813 static void *audio_grabber(void *data
)
1815 priv_t
*priv
= (priv_t
*)data
;
1817 int i
, audio_skew_ptr
= 0;
1818 long long current_time
, prev_skew
= 0, prev_skew_uncorr
= 0;
1819 long long start_time_avg
;
1821 gettimeofday(&tv
, NULL
);
1822 start_time_avg
= priv
->audio_start_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
;
1823 audio_in_start_capture(&priv
->audio_in
);
1824 for (i
= 0; i
< priv
->aud_skew_cnt
; i
++)
1825 priv
->audio_skew_buffer
[i
] = 0;
1826 for (i
= 0; i
< priv
->aud_skew_cnt
; i
++)
1827 priv
->audio_skew_delta_buffer
[i
] = 0;
1829 for (; !priv
->shutdown
;)
1832 read_doublespeed(priv
);
1834 if (audio_in_read_chunk(&priv
->audio_in
, priv
->audio_ringbuffer
+priv
->audio_tail
*priv
->audio_in
.blocksize
) < 0)
1837 pthread_mutex_lock(&priv
->skew_mutex
);
1838 if (priv
->first_frame
== 0) {
1839 // there is no first frame yet (unlikely to happen)
1840 gettimeofday(&tv
, NULL
);
1841 start_time_avg
= priv
->audio_start_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
;
1842 // fprintf(stderr, "warning - first frame not yet available!\n");
1843 pthread_mutex_unlock(&priv
->skew_mutex
);
1846 pthread_mutex_unlock(&priv
->skew_mutex
);
1848 gettimeofday(&tv
, NULL
);
1850 priv
->audio_recv_blocks_total
++;
1851 current_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
- priv
->audio_start_time
;
1853 if (priv
->audio_recv_blocks_total
< priv
->aud_skew_cnt
*2) {
1854 start_time_avg
+= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
- priv
->audio_usecs_per_block
*priv
->audio_recv_blocks_total
;
1855 priv
->audio_start_time
= start_time_avg
/(priv
->audio_recv_blocks_total
+1);
1858 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1859 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1861 // put the current skew into the ring buffer
1862 priv
->audio_skew_total
-= priv
->audio_skew_buffer
[audio_skew_ptr
];
1863 priv
->audio_skew_buffer
[audio_skew_ptr
] = current_time
1864 - priv
->audio_usecs_per_block
*priv
->audio_recv_blocks_total
;
1865 priv
->audio_skew_total
+= priv
->audio_skew_buffer
[audio_skew_ptr
];
1867 pthread_mutex_lock(&priv
->skew_mutex
);
1871 // compute the sliding average of the skews
1872 if (priv
->audio_recv_blocks_total
> priv
->aud_skew_cnt
) {
1873 priv
->audio_skew
= priv
->audio_skew_total
/priv
->aud_skew_cnt
;
1875 priv
->audio_skew
= priv
->audio_skew_total
/priv
->audio_recv_blocks_total
;
1878 // put the current skew change (skew-prev_skew) into the ring buffer
1879 priv
->audio_skew_delta_total
-= priv
->audio_skew_delta_buffer
[audio_skew_ptr
];
1880 priv
->audio_skew_delta_buffer
[audio_skew_ptr
] = priv
->audio_skew
- prev_skew_uncorr
;
1881 priv
->audio_skew_delta_total
+= priv
->audio_skew_delta_buffer
[audio_skew_ptr
];
1882 prev_skew_uncorr
= priv
->audio_skew
; // remember the _uncorrected_ average value
1884 audio_skew_ptr
= (audio_skew_ptr
+1) % priv
->aud_skew_cnt
; // rotate the buffer pointer
1886 // sliding average approximates the value in the middle of the interval
1887 // so interpolate the skew value further to the current time
1888 priv
->audio_skew
+= priv
->audio_skew_delta_total
/2;
1890 // now finally, priv->audio_skew contains fairly good approximation
1891 // of the current value
1893 // current skew factor (assuming linearity)
1894 // used for further interpolation in video_grabber
1895 // probably overkill but seems to be necessary for
1896 // stress testing by dropping half of the audio frames ;)
1897 // especially when using ALSA with large block sizes
1898 // where audio_skew remains a long while behind
1899 if ((priv
->audio_skew_measure_time
!= 0) && (current_time
- priv
->audio_skew_measure_time
!= 0)) {
1900 priv
->audio_skew_factor
= (double)(priv
->audio_skew
-prev_skew
)/(current_time
- priv
->audio_skew_measure_time
);
1902 priv
->audio_skew_factor
= 0.0;
1905 priv
->audio_skew_measure_time
= current_time
;
1906 prev_skew
= priv
->audio_skew
;
1907 priv
->audio_skew
+= priv
->audio_start_time
- priv
->first_frame
;
1908 pthread_mutex_unlock(&priv
->skew_mutex
);
1910 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1912 pthread_mutex_lock(&priv
->audio_mutex
);
1913 if ((priv
->audio_tail
+1) % priv
->audio_buffer_size
== priv
->audio_head
) {
1914 mp_msg(MSGT_TV
, MSGL_ERR
, "\ntoo bad - dropping audio frame !\n");
1917 priv
->audio_tail
= (priv
->audio_tail
+1) % priv
->audio_buffer_size
;
1920 pthread_mutex_unlock(&priv
->audio_mutex
);
1925 static double grab_audio_frame(priv_t
*priv
, char *buffer
, int len
)
1927 mp_dbg(MSGT_TV
, MSGL_DBG2
, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1930 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1931 // => switch to the mode which outputs audio immediately, even if
1932 // it should be silence
1933 if (priv
->first
) priv
->audio_insert_null_samples
= 1;
1935 pthread_mutex_lock(&priv
->audio_mutex
);
1936 while (priv
->audio_insert_null_samples
1937 && priv
->dropped_frames_timeshift
- priv
->dropped_frames_compensated
>= priv
->audio_usecs_per_block
) {
1938 // some frames were dropped - drop the corresponding number of audio blocks
1939 if (priv
->audio_drop
) {
1942 if (priv
->audio_head
== priv
->audio_tail
) break;
1943 priv
->audio_head
= (priv
->audio_head
+1) % priv
->audio_buffer_size
;
1945 priv
->dropped_frames_compensated
+= priv
->audio_usecs_per_block
;
1948 // compensate for dropped audio frames
1949 if (priv
->audio_drop
&& (priv
->audio_head
== priv
->audio_tail
)) {
1951 memset(buffer
, 0, len
);
1955 if (priv
->audio_insert_null_samples
&& (priv
->audio_head
== priv
->audio_tail
)) {
1956 // return silence to avoid desync and stuttering
1957 memset(buffer
, 0, len
);
1958 priv
->audio_null_blocks_inserted
++;
1962 pthread_mutex_unlock(&priv
->audio_mutex
);
1963 while (priv
->audio_head
== priv
->audio_tail
) {
1964 // this is mencoder => just wait until some audio is available
1967 pthread_mutex_lock(&priv
->audio_mutex
);
1968 memcpy(buffer
, priv
->audio_ringbuffer
+priv
->audio_head
*priv
->audio_in
.blocksize
, len
);
1969 priv
->audio_head
= (priv
->audio_head
+1) % priv
->audio_buffer_size
;
1972 pthread_mutex_unlock(&priv
->audio_mutex
);
1973 priv
->audio_sent_blocks_total
++;
1974 return (double)priv
->audio_sent_blocks_total
*priv
->audio_secs_per_block
;
1977 static int get_audio_framesize(priv_t
*priv
)
1979 return(priv
->audio_in
.blocksize
);