2 * Video 4 Linux 2 input
4 * copyright (c) 2003 Martin Olschewski <olschewski@zpr.uni-koeln.de>
5 * copyright (c) 2003 Jindrich Makovicka <makovick@gmail.com>
7 * Some ideas are based on works from
8 * Alex Beregszaszi <alex@fsn.hu>
9 * Gerd Knorr <kraxel@bytesex.org>
11 * This file is part of MPlayer.
13 * MPlayer is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * MPlayer is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 - norm setting isn't consistent with tvi_v4l
32 - the same for volume/bass/treble/balance
43 #include <sys/ioctl.h>
46 #include <sys/types.h>
49 #ifdef HAVE_SYS_SYSINFO_H
50 #include <sys/sysinfo.h>
52 #include <linux/types.h>
53 #include <linux/videodev2.h>
55 #include "libmpcodecs/img_format.h"
56 #include "libmpcodecs/dec_teletext.h"
57 #include "libaf/af_format.h"
61 #define info tvi_info_v4l2
62 static tvi_handle_t
*tvi_init_v4l2(tv_param_t
* tv_param
);
63 /* information about this file */
64 const tvi_info_t tvi_info_v4l2
= {
66 "Video 4 Linux 2 input",
68 "Martin Olschewski <olschewski@zpr.uni-koeln.de>",
69 "first try, more to come ;-)"
73 struct v4l2_buffer buf
;
78 #define BUFFER_COUNT 6
80 /** video ringbuffer entry */
82 unsigned char *data
; ///< frame contents
83 long long timestamp
; ///< frame timestamp
84 int framesize
; ///< actual frame size
96 pthread_t vbi_grabber_thread
;
99 struct v4l2_capability capability
;
100 struct v4l2_input input
;
101 struct v4l2_format format
;
102 struct v4l2_standard standard
;
103 struct v4l2_tuner tuner
;
107 volatile long long first_frame
;
108 long long curr_frame
;
109 /* audio video interleaving ;-) */
110 volatile int streamon
;
111 pthread_t audio_grabber_thread
;
112 pthread_mutex_t skew_mutex
;
114 /* 2nd level video buffers */
118 int video_buffer_size_max
;
119 volatile int video_buffer_size_current
;
120 video_buffer_entry
*video_ringbuffer
;
121 volatile int video_head
;
122 volatile int video_tail
;
123 volatile int video_cnt
;
124 pthread_t video_grabber_thread
;
125 pthread_mutex_t video_buffer_mutex
;
131 long long audio_start_time
;
132 int audio_buffer_size
;
134 unsigned char *audio_ringbuffer
;
135 long long *audio_skew_buffer
;
136 long long *audio_skew_delta_buffer
;
137 volatile int audio_head
;
138 volatile int audio_tail
;
139 volatile int audio_cnt
;
140 volatile long long audio_skew
;
141 volatile double audio_skew_factor
;
142 volatile long long audio_skew_measure_time
;
143 volatile int audio_drop
;
144 volatile int shutdown
;
146 int audio_initialized
;
147 double audio_secs_per_block
;
148 long long audio_usecs_per_block
;
149 long long audio_skew_total
;
150 long long audio_skew_delta_total
;
151 long audio_recv_blocks_total
;
152 long audio_sent_blocks_total
;
153 pthread_mutex_t audio_mutex
;
154 int audio_insert_null_samples
;
155 volatile long audio_null_blocks_inserted
;
156 volatile long long dropped_frames_timeshift
;
157 long long dropped_frames_compensated
;
159 tv_param_t
*tv_param
;
164 static void *audio_grabber(void *data
);
165 static void *video_grabber(void *data
);
167 /**********************************************************************\
169 Only few of the fourccs are the same in v4l2 and mplayer:
171 IMGFMT_YVU9 == V4L2_PIX_FMT_YVU410
172 IMGFMT_YV12 == V4L2_PIX_FMT_YVU420
173 IMGFMT_NV12 == V4L2_PIX_FMT_NV12
174 IMGFMT_422P == V4L2_PIX_FMT_YUV422P
175 IMGFMT_411P == V4L2_PIX_FMT_YUV411P
176 IMGFMT_UYVY == V4L2_PIX_FMT_UYVY
177 IMGFMT_Y41P == V4L2_PIX_FMT_Y41P
179 This may be an useful translation table for some others:
181 IMGFMT_RGB8 == V4L2_PIX_FMT_RGB332
182 IMGFMT_BGR15 == V4L2_PIX_FMT_RGB555
183 IMGFMT_BGR16 == V4L2_PIX_FMT_RGB565
184 IMGFMT_RGB24 == V4L2_PIX_FMT_RGB24
185 IMGFMT_RGB32 == V4L2_PIX_FMT_RGB32
186 IMGFMT_BGR24 == V4L2_PIX_FMT_BGR24
187 IMGFMT_BGR32 == V4L2_PIX_FMT_BGR32
188 IMGFMT_Y800 == V4L2_PIX_FMT_GREY
189 IMGFMT_IF09 == V4L2_PIX_FMT_YUV410
190 IMGFMT_I420 == V4L2_PIX_FMT_YUV420
191 IMGFMT_YUY2 == V4L2_PIX_FMT_YUYV
193 \**********************************************************************/
196 ** Translate a mplayer fourcc to a video4linux2 pixel format.
198 static int fcc_mp2vl(int fcc
)
201 case IMGFMT_RGB8
: return V4L2_PIX_FMT_RGB332
;
202 case IMGFMT_BGR15
: return V4L2_PIX_FMT_RGB555
;
203 case IMGFMT_BGR16
: return V4L2_PIX_FMT_RGB565
;
204 case IMGFMT_RGB24
: return V4L2_PIX_FMT_RGB24
;
205 case IMGFMT_RGB32
: return V4L2_PIX_FMT_RGB32
;
206 case IMGFMT_BGR24
: return V4L2_PIX_FMT_BGR24
;
207 case IMGFMT_BGR32
: return V4L2_PIX_FMT_BGR32
;
208 case IMGFMT_Y800
: return V4L2_PIX_FMT_GREY
;
209 case IMGFMT_IF09
: return V4L2_PIX_FMT_YUV410
;
210 case IMGFMT_I420
: return V4L2_PIX_FMT_YUV420
;
211 case IMGFMT_YUY2
: return V4L2_PIX_FMT_YUYV
;
212 case IMGFMT_YV12
: return V4L2_PIX_FMT_YVU420
;
213 case IMGFMT_UYVY
: return V4L2_PIX_FMT_UYVY
;
214 case IMGFMT_MJPEG
: return V4L2_PIX_FMT_MJPEG
;
220 ** Translate a video4linux2 fourcc aka pixel format to mplayer.
222 static int fcc_vl2mp(int fcc
)
225 case V4L2_PIX_FMT_RGB332
: return IMGFMT_RGB8
;
226 case V4L2_PIX_FMT_RGB555
: return IMGFMT_BGR15
;
227 case V4L2_PIX_FMT_RGB565
: return IMGFMT_BGR16
;
228 case V4L2_PIX_FMT_RGB24
: return IMGFMT_RGB24
;
229 case V4L2_PIX_FMT_RGB32
: return IMGFMT_RGB32
;
230 case V4L2_PIX_FMT_BGR24
: return IMGFMT_BGR24
;
231 case V4L2_PIX_FMT_BGR32
: return IMGFMT_BGR32
;
232 case V4L2_PIX_FMT_GREY
: return IMGFMT_Y800
;
233 case V4L2_PIX_FMT_YUV410
: return IMGFMT_IF09
;
234 case V4L2_PIX_FMT_YUV420
: return IMGFMT_I420
;
235 case V4L2_PIX_FMT_YVU420
: return IMGFMT_YV12
;
236 case V4L2_PIX_FMT_YUYV
: return IMGFMT_YUY2
;
237 case V4L2_PIX_FMT_UYVY
: return IMGFMT_UYVY
;
238 case V4L2_PIX_FMT_MJPEG
: return IMGFMT_MJPEG
;
244 ** Translate a video4linux2 fourcc aka pixel format
245 ** to a human readable string.
247 static const char *pixfmt2name(int pixfmt
)
249 static char unknown
[24];
252 case V4L2_PIX_FMT_RGB332
: return "RGB332";
253 case V4L2_PIX_FMT_RGB555
: return "RGB555";
254 case V4L2_PIX_FMT_RGB565
: return "RGB565";
255 case V4L2_PIX_FMT_RGB555X
: return "RGB555X";
256 case V4L2_PIX_FMT_RGB565X
: return "RGB565X";
257 case V4L2_PIX_FMT_BGR24
: return "BGR24";
258 case V4L2_PIX_FMT_RGB24
: return "RGB24";
259 case V4L2_PIX_FMT_BGR32
: return "BGR32";
260 case V4L2_PIX_FMT_RGB32
: return "RGB32";
261 case V4L2_PIX_FMT_GREY
: return "GREY";
262 case V4L2_PIX_FMT_YVU410
: return "YVU410";
263 case V4L2_PIX_FMT_YVU420
: return "YVU420";
264 case V4L2_PIX_FMT_YUYV
: return "YUYV";
265 case V4L2_PIX_FMT_UYVY
: return "UYVY";
266 /* case V4L2_PIX_FMT_YVU422P: return "YVU422P"; */
267 /* case V4L2_PIX_FMT_YVU411P: return "YVU411P"; */
268 case V4L2_PIX_FMT_YUV422P
: return "YUV422P";
269 case V4L2_PIX_FMT_YUV411P
: return "YUV411P";
270 case V4L2_PIX_FMT_Y41P
: return "Y41P";
271 case V4L2_PIX_FMT_NV12
: return "NV12";
272 case V4L2_PIX_FMT_NV21
: return "NV21";
273 case V4L2_PIX_FMT_YUV410
: return "YUV410";
274 case V4L2_PIX_FMT_YUV420
: return "YUV420";
275 case V4L2_PIX_FMT_YYUV
: return "YYUV";
276 case V4L2_PIX_FMT_HI240
: return "HI240";
277 case V4L2_PIX_FMT_WNVA
: return "WNVA";
278 case V4L2_PIX_FMT_MJPEG
: return "MJPEG";
280 sprintf(unknown
, "unknown (0x%x)", pixfmt
);
286 ** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
288 static int pixfmt2depth(int pixfmt
)
291 case V4L2_PIX_FMT_RGB332
:
293 case V4L2_PIX_FMT_RGB555
:
294 case V4L2_PIX_FMT_RGB565
:
295 case V4L2_PIX_FMT_RGB555X
:
296 case V4L2_PIX_FMT_RGB565X
:
298 case V4L2_PIX_FMT_BGR24
:
299 case V4L2_PIX_FMT_RGB24
:
301 case V4L2_PIX_FMT_BGR32
:
302 case V4L2_PIX_FMT_RGB32
:
304 case V4L2_PIX_FMT_GREY
:
306 case V4L2_PIX_FMT_YVU410
:
308 case V4L2_PIX_FMT_YVU420
:
310 case V4L2_PIX_FMT_YUYV
:
311 case V4L2_PIX_FMT_UYVY
:
312 case V4L2_PIX_FMT_YUV422P
:
313 case V4L2_PIX_FMT_YUV411P
:
315 case V4L2_PIX_FMT_Y41P
:
316 case V4L2_PIX_FMT_NV12
:
317 case V4L2_PIX_FMT_NV21
:
319 case V4L2_PIX_FMT_YUV410
:
321 case V4L2_PIX_FMT_YUV420
:
323 case V4L2_PIX_FMT_YYUV
:
325 case V4L2_PIX_FMT_HI240
:
332 static int amode2v4l(int amode
)
336 return V4L2_TUNER_MODE_MONO
;
338 return V4L2_TUNER_MODE_STEREO
;
340 return V4L2_TUNER_MODE_LANG1
;
342 return V4L2_TUNER_MODE_LANG2
;
352 static double getfps(priv_t
*priv
)
354 if (priv
->tv_param
->fps
> 0)
355 return priv
->tv_param
->fps
;
356 if (priv
->standard
.frameperiod
.denominator
&& priv
->standard
.frameperiod
.numerator
)
357 return (double)priv
->standard
.frameperiod
.denominator
/ priv
->standard
.frameperiod
.numerator
;
361 // sets and sanitizes audio buffer/block sizes
362 static void setup_audio_buffer_sizes(priv_t
*priv
)
364 int bytes_per_sample
= priv
->audio_in
.bytes_per_sample
;
365 int seconds
= priv
->video_buffer_size_max
/getfps(priv
);
367 if (seconds
< 5) seconds
= 5;
368 if (seconds
> 500) seconds
= 500;
370 // make the audio buffer at least as the video buffer capacity (or 5 seconds) long
371 priv
->audio_buffer_size
= 1 + seconds
*priv
->audio_in
.samplerate
372 *priv
->audio_in
.channels
373 *bytes_per_sample
/priv
->audio_in
.blocksize
;
374 if (priv
->audio_buffer_size
< 256) priv
->audio_buffer_size
= 256;
376 // make the skew buffer at least 1 second long
377 priv
->aud_skew_cnt
= 1 + 1*priv
->audio_in
.samplerate
378 *priv
->audio_in
.channels
379 *bytes_per_sample
/priv
->audio_in
.blocksize
;
380 if (priv
->aud_skew_cnt
< 16) priv
->aud_skew_cnt
= 16;
382 mp_msg(MSGT_TV
, MSGL_V
, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
383 priv
->audio_buffer_size
, priv
->audio_in
.blocksize
, priv
->aud_skew_cnt
);
386 static void init_audio(priv_t
*priv
)
388 if (priv
->audio_initialized
) return;
390 if (!priv
->tv_param
->noaudio
) {
392 if (priv
->tv_param
->alsa
)
393 audio_in_init(&priv
->audio_in
, AUDIO_IN_ALSA
);
395 audio_in_init(&priv
->audio_in
, AUDIO_IN_OSS
);
397 audio_in_init(&priv
->audio_in
, AUDIO_IN_OSS
);
400 if (priv
->audio_dev
) {
401 audio_in_set_device(&priv
->audio_in
, priv
->audio_dev
);
404 audio_in_set_samplerate(&priv
->audio_in
, 44100);
405 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
406 if (priv
->tuner
.audmode
== V4L2_TUNER_MODE_STEREO
) {
407 audio_in_set_channels(&priv
->audio_in
, 2);
409 audio_in_set_channels(&priv
->audio_in
, 1);
412 if (priv
->tv_param
->forcechan
>= 0) {
413 audio_in_set_channels(&priv
->audio_in
, priv
->tv_param
->forcechan
);
415 audio_in_set_channels(&priv
->audio_in
, 2);
419 if (audio_in_setup(&priv
->audio_in
) < 0) return;
421 priv
->audio_initialized
= 1;
427 ** the number of milliseconds elapsed between time0 and time1
429 static size_t difftv(struct timeval time1
, struct timeval time0
)
431 return (time1
.tv_sec
- time0
.tv_sec
) * 1000 +
432 (time1
.tv_usec
- time0
.tv_usec
) / 1000;
437 ** Get current video capture format.
439 static int getfmt(priv_t
*priv
)
443 priv
->format
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
444 if ((i
= ioctl(priv
->video_fd
, VIDIOC_G_FMT
, &priv
->format
)) < 0) {
445 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get format failed: %s\n",
446 info
.short_name
, strerror(errno
));
453 ** Get current video capture standard.
455 static int getstd(priv_t
*priv
)
460 if (ioctl(priv
->video_fd
, VIDIOC_G_STD
, &id
) < 0) {
461 struct v4l2_streamparm parm
;
463 parm
.type
=V4L2_BUF_TYPE_VIDEO_CAPTURE
;
464 if(ioctl(priv
->video_fd
, VIDIOC_G_PARM
, &parm
) >= 0) {
465 mp_msg(MSGT_TV
, MSGL_WARN
, "%s: your device driver does not support VIDIOC_G_STD ioctl,"
466 " VIDIOC_G_PARM was used instead.\n", info
.short_name
);
467 priv
->standard
.index
=0;
469 priv
->standard
.frameperiod
=parm
.parm
.capture
.timeperframe
;
473 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get standard failed: %s\n",
474 info
.short_name
, strerror(errno
));
478 priv
->standard
.index
= i
++;
479 if (ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &priv
->standard
) < 0) {
482 } while (priv
->standard
.id
!= id
);
486 /***********************************************************************\
489 * Interface to mplayer *
492 \***********************************************************************/
494 static int set_mute(priv_t
*priv
, int value
)
496 struct v4l2_control control
;
497 control
.id
= V4L2_CID_AUDIO_MUTE
;
498 control
.value
= value
;
499 if (ioctl(priv
->video_fd
, VIDIOC_S_CTRL
, &control
) < 0) {
500 mp_msg(MSGT_TV
,MSGL_ERR
,"%s: ioctl set mute failed: %s\n",
501 info
.short_name
, strerror(errno
));
508 ** MPlayer uses values from -100 up to 100 for controls.
509 ** Here they are scaled to what the tv card needs and applied.
511 static int set_control(priv_t
*priv
, struct v4l2_control
*control
, int val_signed
) {
512 struct v4l2_queryctrl qctrl
;
513 qctrl
.id
= control
->id
;
514 if (ioctl(priv
->video_fd
, VIDIOC_QUERYCTRL
, &qctrl
) < 0) {
515 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query control failed: %s\n",
516 info
.short_name
, strerror(errno
));
517 return TVI_CONTROL_FALSE
;
521 if (control
->value
< 0) {
522 control
->value
= qctrl
.default_value
+ control
->value
*
523 (qctrl
.default_value
- qctrl
.minimum
) / 100;
525 control
->value
= qctrl
.default_value
+ control
->value
*
526 (qctrl
.maximum
- qctrl
.default_value
) / 100;
529 if (control
->value
< 50) {
530 control
->value
= qctrl
.default_value
+ (control
->value
-50) *
531 (qctrl
.default_value
- qctrl
.minimum
) / 50;
533 control
->value
= qctrl
.default_value
+ (control
->value
-50) *
534 (qctrl
.maximum
- qctrl
.default_value
) / 50;
539 if (ioctl(priv
->video_fd
, VIDIOC_S_CTRL
, control
) < 0) {
540 mp_msg(MSGT_TV
, MSGL_ERR
,"%s: ioctl set %s %d failed: %s\n",
541 info
.short_name
, qctrl
.name
, control
->value
, strerror(errno
));
542 return TVI_CONTROL_FALSE
;
544 mp_msg(MSGT_TV
, MSGL_V
, "%s: set %s: %d [%d, %d]\n", info
.short_name
,
545 qctrl
.name
, control
->value
, qctrl
.minimum
, qctrl
.maximum
);
547 return TVI_CONTROL_TRUE
;
552 ** Scale the control values back to what mplayer needs.
554 static int get_control(priv_t
*priv
, struct v4l2_control
*control
, int val_signed
) {
555 struct v4l2_queryctrl qctrl
;
557 qctrl
.id
= control
->id
;
558 if (ioctl(priv
->video_fd
, VIDIOC_QUERYCTRL
, &qctrl
) < 0) {
559 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query control failed: %s\n",
560 info
.short_name
, strerror(errno
));
561 return TVI_CONTROL_FALSE
;
564 if (ioctl(priv
->video_fd
, VIDIOC_G_CTRL
, control
) < 0) {
565 mp_msg(MSGT_TV
, MSGL_ERR
,"%s: ioctl get %s failed: %s\n",
566 info
.short_name
, qctrl
.name
, strerror(errno
));
567 return TVI_CONTROL_FALSE
;
569 mp_msg(MSGT_TV
, MSGL_V
, "%s: get %s: %d [%d, %d]\n", info
.short_name
,
570 qctrl
.name
, control
->value
, qctrl
.minimum
, qctrl
.maximum
);
573 if (control
->value
< qctrl
.default_value
) {
574 control
->value
= (control
->value
- qctrl
.default_value
) * 100 /
575 (qctrl
.default_value
- qctrl
.minimum
);
577 control
->value
= (control
->value
- qctrl
.default_value
) * 100 /
578 (qctrl
.maximum
- qctrl
.default_value
);
581 if (control
->value
< qctrl
.default_value
) {
582 control
->value
= (control
->value
- qctrl
.default_value
) * 50 /
583 (qctrl
.default_value
- qctrl
.minimum
) + 50;
585 control
->value
= (control
->value
- qctrl
.default_value
) * 50 /
586 (qctrl
.maximum
- qctrl
.default_value
) + 50;
590 return TVI_CONTROL_TRUE
;
593 static int vbi_init(priv_t
* priv
,char* device
)
596 struct v4l2_capability cap
;
597 struct v4l2_format fmt
;
601 return TVI_CONTROL_FALSE
;
603 priv
->vbi_dev
=strdup(device
);
605 vbi_fd
=open(priv
->vbi_dev
,O_RDWR
);
607 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: could not open device %s\n",priv
->vbi_dev
);
608 return TVI_CONTROL_FALSE
;
611 if(ioctl(vbi_fd
,VIDIOC_QUERYCAP
,&cap
)<0){
612 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: Query capatibilities failed for %s\n",priv
->vbi_dev
);
614 return TVI_CONTROL_FALSE
;
616 if(!(cap
.capabilities
& V4L2_CAP_VBI_CAPTURE
)){
617 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: %s does not support VBI capture\n",priv
->vbi_dev
);
619 return TVI_CONTROL_FALSE
;
622 memset(&fmt
,0,sizeof(struct v4l2_format
));
623 fmt
.type
=V4L2_BUF_TYPE_VBI_CAPTURE
;
624 if((res
=ioctl(vbi_fd
,VIDIOC_G_FMT
,&fmt
))<0){
625 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: Query format failed: %x\n",res
);
627 return TVI_CONTROL_FALSE
;
629 if(fmt
.fmt
.vbi
.sample_format
!=V4L2_PIX_FMT_GREY
){
630 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: format 0x%x is not supported\n",fmt
.fmt
.vbi
.sample_format
);
632 return TVI_CONTROL_FALSE
;
635 mp_msg(MSGT_TV
,MSGL_DBG3
,"vbi: init ok\n");
636 return TVI_CONTROL_TRUE
;
639 static int vbi_get_props(priv_t
* priv
,tt_stream_props
* ptsp
)
641 struct v4l2_format fmt
;
644 return TVI_CONTROL_FALSE
;
646 memset(&fmt
,0,sizeof(struct v4l2_format
));
647 fmt
.type
=V4L2_BUF_TYPE_VBI_CAPTURE
;
648 if((res
=ioctl(priv
->vbi_fd
,VIDIOC_G_FMT
,&fmt
))<0){
649 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi_get_props: Query format failed: %x\n",res
);
650 return TVI_CONTROL_FALSE
;
653 ptsp
->interlaced
=(fmt
.fmt
.vbi
.flags
& V4L2_VBI_INTERLACED
?1:0);
655 ptsp
->offset
=fmt
.fmt
.vbi
.offset
;
656 ptsp
->sampling_rate
=fmt
.fmt
.vbi
.sampling_rate
;
657 ptsp
->samples_per_line
=fmt
.fmt
.vbi
.samples_per_line
,
659 ptsp
->count
[0]=fmt
.fmt
.vbi
.count
[0];
660 ptsp
->count
[1]=fmt
.fmt
.vbi
.count
[1];
661 ptsp
->bufsize
= ptsp
->samples_per_line
* (ptsp
->count
[0] + ptsp
->count
[1]);
663 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",
666 ptsp
->samples_per_line
,
667 ptsp
->interlaced
?"Yes":"No",
671 return TVI_CONTROL_TRUE
;
674 static void *vbi_grabber(void *data
)
676 priv_t
*priv
= (priv_t
*) data
;
677 int bytes
,seq
,prev_seq
;
682 mp_msg(MSGT_TV
,MSGL_WARN
,"vbi: vbi not initialized. stopping thread.\n");
686 if(vbi_get_props(priv
,&tsp
)!=TVI_CONTROL_TRUE
)
689 buf
=malloc(tsp
.bufsize
);
692 mp_msg(MSGT_TV
,MSGL_V
,"vbi: vbi capture thread started.\n");
694 while (!priv
->vbi_shutdown
){
695 bytes
=read(priv
->vbi_fd
,buf
,tsp
.bufsize
);
696 if(bytes
<0 && errno
==EINTR
)
698 if (bytes
!=tsp
.bufsize
){
699 mp_msg(MSGT_TV
,MSGL_WARN
,"vbi: expecting bytes: %d, got: %d\n",tsp
.bufsize
,bytes
);
702 seq
=*(int*)(buf
+bytes
-4);
704 if (prev_seq
&& seq
!=prev_seq
+1){
709 teletext_control(priv
->priv_vbi
,TV_VBI_CONTROL_DECODE_PAGE
,&buf
);
710 mp_msg(MSGT_TV
,MSGL_DBG3
,"grabber: seq:%d\n",seq
);
716 static int control(priv_t
*priv
, int cmd
, void *arg
)
718 struct v4l2_control control
;
719 struct v4l2_frequency frequency
;
722 case TVI_CONTROL_IS_VIDEO
:
723 return priv
->capability
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
?
724 TVI_CONTROL_TRUE
: TVI_CONTROL_FALSE
;
725 case TVI_CONTROL_IS_AUDIO
:
726 if (priv
->tv_param
->force_audio
) return TVI_CONTROL_TRUE
;
727 case TVI_CONTROL_IS_TUNER
:
728 return priv
->capability
.capabilities
& V4L2_CAP_TUNER
?
729 TVI_CONTROL_TRUE
: TVI_CONTROL_FALSE
;
730 case TVI_CONTROL_IMMEDIATE
:
731 priv
->immediate_mode
= 1;
732 return TVI_CONTROL_TRUE
;
733 case TVI_CONTROL_VID_GET_FPS
:
734 if (!priv
->standard
.frameperiod
.denominator
|| !priv
->standard
.frameperiod
.numerator
) {
735 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: Cannot get fps\n", info
.short_name
);
736 return TVI_CONTROL_FALSE
;
738 *(float *)arg
= (float)priv
->standard
.frameperiod
.denominator
/
739 priv
->standard
.frameperiod
.numerator
;
740 mp_msg(MSGT_TV
, MSGL_V
, "%s: get fps: %f\n", info
.short_name
,
742 return TVI_CONTROL_TRUE
;
743 case TVI_CONTROL_VID_GET_BITS
:
744 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
745 *(int *)arg
= pixfmt2depth(priv
->format
.fmt
.pix
.pixelformat
);
746 mp_msg(MSGT_TV
, MSGL_V
, "%s: get depth: %d\n", info
.short_name
,
748 return TVI_CONTROL_TRUE
;
749 case TVI_CONTROL_VID_GET_FORMAT
:
750 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
751 *(int *)arg
= fcc_vl2mp(priv
->format
.fmt
.pix
.pixelformat
);
752 mp_msg(MSGT_TV
, MSGL_V
, "%s: get format: %s\n", info
.short_name
,
753 pixfmt2name(priv
->format
.fmt
.pix
.pixelformat
));
754 return TVI_CONTROL_TRUE
;
755 case TVI_CONTROL_VID_SET_FORMAT
:
756 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
757 priv
->format
.fmt
.pix
.pixelformat
= fcc_mp2vl(*(int *)arg
);
758 priv
->format
.fmt
.pix
.field
= V4L2_FIELD_ANY
;
760 priv
->mp_format
= *(int *)arg
;
761 mp_msg(MSGT_TV
, MSGL_V
, "%s: set format: %s\n", info
.short_name
,
762 pixfmt2name(priv
->format
.fmt
.pix
.pixelformat
));
763 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
764 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set format failed: %s\n",
765 info
.short_name
, strerror(errno
));
766 return TVI_CONTROL_FALSE
;
768 /* according to the v4l2 specs VIDIOC_S_FMT should not fail, inflexible drivers
769 might even always return the default parameters -> update the format here*/
770 priv
->mp_format
= fcc_vl2mp(priv
->format
.fmt
.pix
.pixelformat
);
771 return TVI_CONTROL_TRUE
;
772 case TVI_CONTROL_VID_GET_WIDTH
:
773 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
774 *(int *)arg
= priv
->format
.fmt
.pix
.width
;
775 mp_msg(MSGT_TV
, MSGL_V
, "%s: get width: %d\n", info
.short_name
,
777 return TVI_CONTROL_TRUE
;
778 case TVI_CONTROL_VID_CHK_WIDTH
:
779 return TVI_CONTROL_TRUE
;
780 case TVI_CONTROL_VID_SET_WIDTH_HEIGHT
:
781 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
782 priv
->format
.fmt
.pix
.width
= ((int *)arg
)[0];
783 priv
->format
.fmt
.pix
.height
= ((int *)arg
)[1];
784 priv
->format
.fmt
.pix
.field
= V4L2_FIELD_ANY
;
785 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0)
786 return TVI_CONTROL_FALSE
;
787 return TVI_CONTROL_TRUE
;
788 case TVI_CONTROL_VID_SET_WIDTH
:
789 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
790 priv
->format
.fmt
.pix
.width
= *(int *)arg
;
791 mp_msg(MSGT_TV
, MSGL_V
, "%s: set width: %d\n", info
.short_name
,
793 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
794 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set width failed: %s\n",
795 info
.short_name
, strerror(errno
));
796 return TVI_CONTROL_FALSE
;
798 return TVI_CONTROL_TRUE
;
799 case TVI_CONTROL_VID_GET_HEIGHT
:
800 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
801 *(int *)arg
= priv
->format
.fmt
.pix
.height
;
802 mp_msg(MSGT_TV
, MSGL_V
, "%s: get height: %d\n", info
.short_name
,
804 return TVI_CONTROL_TRUE
;
805 case TVI_CONTROL_VID_CHK_HEIGHT
:
806 return TVI_CONTROL_TRUE
;
807 case TVI_CONTROL_VID_SET_HEIGHT
:
808 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
809 priv
->format
.fmt
.pix
.height
= *(int *)arg
;
810 priv
->format
.fmt
.pix
.field
= V4L2_FIELD_ANY
;
811 mp_msg(MSGT_TV
, MSGL_V
, "%s: set height: %d\n", info
.short_name
,
813 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
814 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set height failed: %s\n",
815 info
.short_name
, strerror(errno
));
816 return TVI_CONTROL_FALSE
;
818 return TVI_CONTROL_TRUE
;
819 case TVI_CONTROL_VID_GET_BRIGHTNESS
:
820 control
.id
= V4L2_CID_BRIGHTNESS
;
821 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
822 *(int *)arg
= control
.value
;
823 return TVI_CONTROL_TRUE
;
825 return TVI_CONTROL_FALSE
;
826 case TVI_CONTROL_VID_SET_BRIGHTNESS
:
827 control
.id
= V4L2_CID_BRIGHTNESS
;
828 control
.value
= *(int *)arg
;
829 return set_control(priv
, &control
, 1);
830 case TVI_CONTROL_VID_GET_HUE
:
831 control
.id
= V4L2_CID_HUE
;
832 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
833 *(int *)arg
= control
.value
;
834 return TVI_CONTROL_TRUE
;
836 return TVI_CONTROL_FALSE
;
837 case TVI_CONTROL_VID_SET_HUE
:
838 control
.id
= V4L2_CID_HUE
;
839 control
.value
= *(int *)arg
;
840 return set_control(priv
, &control
, 1);
841 case TVI_CONTROL_VID_GET_SATURATION
:
842 control
.id
= V4L2_CID_SATURATION
;
843 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
844 *(int *)arg
= control
.value
;
845 return TVI_CONTROL_TRUE
;
847 return TVI_CONTROL_FALSE
;
848 case TVI_CONTROL_VID_SET_SATURATION
:
849 control
.id
= V4L2_CID_SATURATION
;
850 control
.value
= *(int *)arg
;
851 return set_control(priv
, &control
, 1);
852 case TVI_CONTROL_VID_GET_GAIN
:
855 control
.id
= V4L2_CID_AUTOGAIN
;
856 if(get_control(priv
,&control
,0)!=TVI_CONTROL_TRUE
)
857 return TVI_CONTROL_FALSE
;
859 if(control
.value
){ //Auto Gain control is enabled
861 return TVI_CONTROL_TRUE
;
864 //Manual Gain control
865 control
.id
= V4L2_CID_GAIN
;
866 if(get_control(priv
,&control
,0)!=TVI_CONTROL_TRUE
)
867 return TVI_CONTROL_FALSE
;
869 *(int*)arg
=control
.value
?control
.value
:1;
871 return TVI_CONTROL_TRUE
;
873 case TVI_CONTROL_VID_SET_GAIN
:
875 //value==0 means automatic gain control
876 int value
=*(int*)arg
;
878 if (value
< 0 || value
>100)
879 return TVI_CONTROL_FALSE
;
881 control
.id
=value
?V4L2_CID_GAIN
:V4L2_CID_AUTOGAIN
;
882 control
.value
=value
?value
:1;
884 return set_control(priv
,&control
,0);
886 case TVI_CONTROL_VID_GET_CONTRAST
:
887 control
.id
= V4L2_CID_CONTRAST
;
888 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
889 *(int *)arg
= control
.value
;
890 return TVI_CONTROL_TRUE
;
892 return TVI_CONTROL_FALSE
;
893 case TVI_CONTROL_VID_SET_CONTRAST
:
894 control
.id
= V4L2_CID_CONTRAST
;
895 control
.value
= *(int *)arg
;
896 return set_control(priv
, &control
, 1);
897 case TVI_CONTROL_TUN_GET_FREQ
:
899 frequency
.type
= V4L2_TUNER_ANALOG_TV
;
900 if (ioctl(priv
->video_fd
, VIDIOC_G_FREQUENCY
, &frequency
) < 0) {
901 mp_msg(MSGT_TV
,MSGL_ERR
,"%s: ioctl get frequency failed: %s\n",
902 info
.short_name
, strerror(errno
));
903 return TVI_CONTROL_FALSE
;
905 *(int *)arg
= frequency
.frequency
;
906 return TVI_CONTROL_TRUE
;
907 case TVI_CONTROL_TUN_SET_FREQ
:
910 usleep(100000); // wait to suppress noise during switching
913 frequency
.type
= V4L2_TUNER_ANALOG_TV
;
914 frequency
.frequency
= *(int *)arg
;
915 if (ioctl(priv
->video_fd
, VIDIOC_S_FREQUENCY
, &frequency
) < 0) {
916 mp_msg(MSGT_TV
,MSGL_ERR
,"%s: ioctl set frequency failed: %s\n",
917 info
.short_name
, strerror(errno
));
918 return TVI_CONTROL_FALSE
;
921 usleep(100000); // wait to suppress noise during switching
924 return TVI_CONTROL_TRUE
;
925 case TVI_CONTROL_TUN_GET_TUNER
:
926 mp_msg(MSGT_TV
, MSGL_V
, "%s: get tuner\n",info
.short_name
);
927 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) < 0) {
928 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get tuner failed: %s\n",
929 info
.short_name
, strerror(errno
));
930 return TVI_CONTROL_FALSE
;
932 return TVI_CONTROL_TRUE
;
933 case TVI_CONTROL_TUN_SET_TUNER
:
934 mp_msg(MSGT_TV
, MSGL_V
, "%s: set tuner\n",info
.short_name
);
935 if (ioctl(priv
->video_fd
, VIDIOC_S_TUNER
, &priv
->tuner
) < 0) {
936 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set tuner failed: %s\n",
937 info
.short_name
, strerror(errno
));
938 return TVI_CONTROL_FALSE
;
940 return TVI_CONTROL_TRUE
;
941 case TVI_CONTROL_TUN_GET_NORM
:
942 *(int *)arg
= priv
->standard
.index
;
943 return TVI_CONTROL_TRUE
;
944 case TVI_CONTROL_TUN_GET_SIGNAL
:
945 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) < 0) {
946 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get tuner failed: %s\n",
947 info
.short_name
, strerror(errno
));
948 return TVI_CONTROL_FALSE
;
950 *(int*)arg
=100*(priv
->tuner
.signal
>>8)/255;
951 return TVI_CONTROL_TRUE
;
952 case TVI_CONTROL_TUN_SET_NORM
:
953 priv
->standard
.index
= *(int *)arg
;
954 if (ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &priv
->standard
) < 0) {
955 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl enum norm failed: %s\n",
956 info
.short_name
, strerror(errno
));
957 return TVI_CONTROL_FALSE
;
959 mp_msg(MSGT_TV
, MSGL_V
, "%s: set norm: %s\n", info
.short_name
, priv
->standard
.name
);
960 if (ioctl(priv
->video_fd
, VIDIOC_S_STD
, &priv
->standard
.id
) < 0) {
961 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set norm failed: %s\n",
962 info
.short_name
, strerror(errno
));
963 return TVI_CONTROL_FALSE
;
965 return TVI_CONTROL_TRUE
;
966 case TVI_CONTROL_SPC_GET_NORMID
:
970 struct v4l2_standard standard
;
971 memset(&standard
, 0, sizeof(standard
));
973 if (-1 == ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &standard
))
974 return TVI_CONTROL_FALSE
;
975 if (!strcasecmp(standard
.name
, (char *)arg
)) {
977 return TVI_CONTROL_TRUE
;
980 return TVI_CONTROL_FALSE
;
982 case TVI_CONTROL_SPC_GET_INPUT
:
983 if (ioctl(priv
->video_fd
, VIDIOC_G_INPUT
, (int *)arg
) < 0) {
984 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get input failed: %s\n",
985 info
.short_name
, strerror(errno
));
986 return TVI_CONTROL_FALSE
;
988 return TVI_CONTROL_TRUE
;
989 case TVI_CONTROL_SPC_SET_INPUT
:
990 mp_msg(MSGT_TV
, MSGL_V
, "%s: set input: %d\n", info
.short_name
, *(int *)arg
);
991 priv
->input
.index
= *(int *)arg
;
992 if (ioctl(priv
->video_fd
, VIDIOC_ENUMINPUT
, &priv
->input
) < 0) {
993 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl enum input failed: %s\n",
994 info
.short_name
, strerror(errno
));
995 return TVI_CONTROL_FALSE
;
997 if (ioctl(priv
->video_fd
, VIDIOC_S_INPUT
, (int *)arg
) < 0) {
998 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set input failed: %s\n",
999 info
.short_name
, strerror(errno
));
1000 return TVI_CONTROL_FALSE
;
1002 return TVI_CONTROL_TRUE
;
1003 case TVI_CONTROL_AUD_GET_FORMAT
:
1005 if (!priv
->audio_initialized
) return TVI_CONTROL_FALSE
;
1006 *(int *)arg
= AF_FORMAT_S16_LE
;
1007 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio format: %d\n",
1008 info
.short_name
, *(int *)arg
);
1009 return TVI_CONTROL_TRUE
;
1010 case TVI_CONTROL_AUD_GET_SAMPLERATE
:
1012 if (!priv
->audio_initialized
) return TVI_CONTROL_FALSE
;
1013 *(int *)arg
= priv
->audio_in
.samplerate
;
1014 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio samplerate: %d\n",
1015 info
.short_name
, *(int *)arg
);
1016 return TVI_CONTROL_TRUE
;
1017 case TVI_CONTROL_AUD_GET_SAMPLESIZE
:
1019 if (!priv
->audio_initialized
) return TVI_CONTROL_FALSE
;
1020 *(int *)arg
= priv
->audio_in
.bytes_per_sample
;
1021 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio samplesize: %d\n",
1022 info
.short_name
, *(int *)arg
);
1023 return TVI_CONTROL_TRUE
;
1024 case TVI_CONTROL_AUD_GET_CHANNELS
:
1026 if (!priv
->audio_initialized
) return TVI_CONTROL_FALSE
;
1027 *(int *)arg
= priv
->audio_in
.channels
;
1028 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio channels: %d\n",
1029 info
.short_name
, *(int *)arg
);
1030 return TVI_CONTROL_TRUE
;
1031 case TVI_CONTROL_AUD_SET_SAMPLERATE
:
1033 mp_msg(MSGT_TV
, MSGL_V
, "%s: set audio samplerate: %d\n",
1034 info
.short_name
, *(int *)arg
);
1035 if (audio_in_set_samplerate(&priv
->audio_in
, *(int*)arg
) < 0) return TVI_CONTROL_FALSE
;
1036 // setup_audio_buffer_sizes(priv);
1037 return TVI_CONTROL_TRUE
;
1038 case TVI_CONTROL_VBI_INIT
:
1041 tt_stream_props tsp
;
1043 if (vbi_init(priv
,*(char**)arg
)!=TVI_CONTROL_TRUE
)
1044 return TVI_CONTROL_FALSE
;
1045 if(vbi_get_props(priv
,&tsp
)==TVI_CONTROL_TRUE
)
1048 if(teletext_control(NULL
,TV_VBI_CONTROL_START
,&ptr
)==VBI_CONTROL_TRUE
)
1051 priv
->priv_vbi
=NULL
;
1053 return TVI_CONTROL_TRUE
;
1055 case TVI_CONTROL_GET_VBI_PTR
:
1056 *(void **)arg
=priv
->priv_vbi
;
1057 return TVI_CONTROL_TRUE
;
1059 mp_msg(MSGT_TV
, MSGL_V
, "%s: unknown control: %d\n", info
.short_name
, cmd
);
1060 return TVI_CONTROL_UNKNOWN
;
1064 #define PRIV ((priv_t *) (tvi_handle->priv))
1066 /* handler creator - entry point ! */
1067 static tvi_handle_t
*tvi_init_v4l2(tv_param_t
* tv_param
)
1069 tvi_handle_t
*tvi_handle
;
1071 /* new_handle initializes priv with memset 0 */
1072 tvi_handle
= new_handle();
1076 PRIV
->video_fd
= -1;
1078 PRIV
->video_dev
= strdup(tv_param
->device
? tv_param
->device
: "/dev/video0");
1079 if (!PRIV
->video_dev
) {
1080 free_handle(tvi_handle
);
1084 if (tv_param
->adevice
) {
1085 PRIV
->audio_dev
= strdup(tv_param
->adevice
);
1086 if (!PRIV
->audio_dev
) {
1087 free(PRIV
->video_dev
);
1088 free_handle(tvi_handle
);
1093 PRIV
->tv_param
=tv_param
;
1100 static int uninit(priv_t
*priv
)
1102 int i
, frames
, dropped
= 0;
1104 priv
->vbi_shutdown
=1;
1105 if(priv
->vbi_grabber_thread
)
1106 pthread_join(priv
->vbi_grabber_thread
, NULL
);
1108 teletext_control(priv
->priv_vbi
,TV_VBI_CONTROL_STOP
,(void*)1);
1109 priv
->priv_vbi
=NULL
;
1112 close(priv
->vbi_fd
);
1117 free(priv
->vbi_dev
);
1121 if(priv
->video_grabber_thread
)
1122 pthread_join(priv
->video_grabber_thread
, NULL
);
1123 pthread_mutex_destroy(&priv
->video_buffer_mutex
);
1125 if (priv
->streamon
) {
1126 struct v4l2_buffer buf
;
1128 /* get performance */
1129 frames
= 1 + lrintf((double)(priv
->curr_frame
- priv
->first_frame
) / 1e6
* getfps(priv
));
1130 dropped
= frames
- priv
->frames
;
1132 /* turn off streaming */
1133 if (ioctl(priv
->video_fd
, VIDIOC_STREAMOFF
, &(priv
->map
[0].buf
.type
)) < 0) {
1134 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl streamoff failed: %s\n",
1135 info
.short_name
, strerror(errno
));
1139 /* unqueue all remaining buffers */
1140 memset(&buf
,0,sizeof(buf
));
1141 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1142 buf
.memory
= V4L2_MEMORY_MMAP
;
1143 while (!ioctl(priv
->video_fd
, VIDIOC_DQBUF
, &buf
));
1146 /* unmap all buffers */
1147 for (i
= 0; i
< priv
->mapcount
; i
++) {
1148 if (munmap(priv
->map
[i
].addr
, priv
->map
[i
].len
) < 0) {
1149 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: munmap capture buffer failed: %s\n",
1150 info
.short_name
, strerror(errno
));
1154 /* stop audio thread */
1155 if (!priv
->tv_param
->noaudio
&& priv
->audio_grabber_thread
) {
1156 pthread_join(priv
->audio_grabber_thread
, NULL
);
1157 pthread_mutex_destroy(&priv
->skew_mutex
);
1158 pthread_mutex_destroy(&priv
->audio_mutex
);
1163 /* free memory and close device */
1164 free(priv
->map
); priv
->map
= NULL
;
1166 if(priv
->video_fd
!=-1)close(priv
->video_fd
); priv
->video_fd
= -1;
1167 free(priv
->video_dev
); priv
->video_dev
= NULL
;
1169 if (priv
->video_ringbuffer
) {
1171 for (i
= 0; i
< priv
->video_buffer_size_current
; i
++) {
1172 free(priv
->video_ringbuffer
[i
].data
);
1174 free(priv
->video_ringbuffer
);
1176 if (!priv
->tv_param
->noaudio
) {
1177 if (priv
->audio_ringbuffer
)
1178 free(priv
->audio_ringbuffer
);
1179 if (priv
->audio_skew_buffer
)
1180 free(priv
->audio_skew_buffer
);
1181 if (priv
->audio_skew_delta_buffer
)
1182 free(priv
->audio_skew_delta_buffer
);
1184 audio_in_uninit(&priv
->audio_in
);
1187 /* show some nice statistics ;-) */
1188 mp_msg(MSGT_TV
, MSGL_INFO
,
1189 "%s: %d frames successfully processed, %d frames dropped.\n",
1190 info
.short_name
, priv
->frames
, dropped
);
1191 mp_msg(MSGT_TV
, MSGL_V
, "%s: up to %u video frames buffered.\n",
1192 info
.short_name
, priv
->video_buffer_size_current
);
1197 /* initialisation */
1198 static int init(priv_t
*priv
)
1202 priv
->audio_ringbuffer
= NULL
;
1203 priv
->audio_skew_buffer
= NULL
;
1204 priv
->audio_skew_delta_buffer
= NULL
;
1206 priv
->audio_initialized
= 0;
1208 /* Open the video device. */
1209 priv
->video_fd
= open(priv
->video_dev
, O_RDWR
);
1210 if (priv
->video_fd
< 0) {
1211 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: unable to open '%s': %s\n",
1212 info
.short_name
, priv
->video_dev
, strerror(errno
));
1216 mp_msg(MSGT_TV
, MSGL_DBG2
, "%s: video fd: %s: %d\n",
1217 info
.short_name
, priv
->video_dev
, priv
->video_fd
);
1220 ** Query the video capabilities and current settings
1221 ** for further control calls.
1223 if (ioctl(priv
->video_fd
, VIDIOC_QUERYCAP
, &priv
->capability
) < 0) {
1224 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query capabilities failed: %s\n",
1225 info
.short_name
, strerror(errno
));
1230 if (!(priv
->capability
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
))
1232 mp_msg(MSGT_TV
, MSGL_ERR
, "Device %s is not a video capture device.\n",
1237 if (getfmt(priv
) < 0) {
1243 ** if this device has got a tuner query it's settings
1244 ** otherwise set some nice defaults
1246 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
1247 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) < 0) {
1248 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get tuner failed: %s\n",
1249 info
.short_name
, strerror(errno
));
1254 mp_msg(MSGT_TV
, MSGL_INFO
, "Selected device: %s\n", priv
->capability
.card
);
1255 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
1256 mp_msg(MSGT_TV
, MSGL_INFO
, " Tuner cap:%s%s%s\n",
1257 (priv
->tuner
.capability
& V4L2_TUNER_CAP_STEREO
) ? " STEREO" : "",
1258 (priv
->tuner
.capability
& V4L2_TUNER_CAP_LANG1
) ? " LANG1" : "",
1259 (priv
->tuner
.capability
& V4L2_TUNER_CAP_LANG2
) ? " LANG2" : "");
1260 mp_msg(MSGT_TV
, MSGL_INFO
, " Tuner rxs:%s%s%s%s\n",
1261 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_MONO
) ? " MONO" : "",
1262 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_STEREO
) ? " STEREO" : "",
1263 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_LANG1
) ? " LANG1" : "",
1264 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_LANG2
) ? " LANG2" : "");
1266 mp_msg(MSGT_TV
, MSGL_INFO
, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1267 priv
->capability
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
?
1268 " video capture": "",
1269 priv
->capability
.capabilities
& V4L2_CAP_VIDEO_OUTPUT
?
1270 " video output": "",
1271 priv
->capability
.capabilities
& V4L2_CAP_VIDEO_OVERLAY
?
1272 " video overlay": "",
1273 priv
->capability
.capabilities
& V4L2_CAP_VBI_CAPTURE
?
1274 " VBI capture device": "",
1275 priv
->capability
.capabilities
& V4L2_CAP_VBI_OUTPUT
?
1277 priv
->capability
.capabilities
& V4L2_CAP_RDS_CAPTURE
?
1278 " RDS data capture": "",
1279 priv
->capability
.capabilities
& V4L2_CAP_TUNER
?
1281 priv
->capability
.capabilities
& V4L2_CAP_AUDIO
?
1283 priv
->capability
.capabilities
& V4L2_CAP_READWRITE
?
1285 priv
->capability
.capabilities
& V4L2_CAP_ASYNCIO
?
1287 priv
->capability
.capabilities
& V4L2_CAP_STREAMING
?
1289 mp_msg(MSGT_TV
, MSGL_INFO
, " supported norms:");
1291 struct v4l2_standard standard
;
1292 memset(&standard
, 0, sizeof(standard
));
1294 if (-1 == ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &standard
))
1296 mp_msg(MSGT_TV
, MSGL_INFO
, " %d = %s;", i
, standard
.name
);
1298 mp_msg(MSGT_TV
, MSGL_INFO
, "\n inputs:");
1299 for (i
= 0; 1; i
++) {
1300 struct v4l2_input input
;
1303 if (ioctl(priv
->video_fd
, VIDIOC_ENUMINPUT
, &input
) < 0) {
1306 mp_msg(MSGT_TV
, MSGL_INFO
, " %d = %s;", i
, input
.name
);
1309 if (ioctl(priv
->video_fd
, VIDIOC_G_INPUT
, &i
) < 0) {
1310 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get input failed: %s\n",
1311 info
.short_name
, strerror(errno
));
1313 mp_msg(MSGT_TV
, MSGL_INFO
, "\n Current input: %d\n", i
);
1314 for (i
= 0; ; i
++) {
1315 struct v4l2_fmtdesc fmtdesc
;
1318 fmtdesc
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1319 if (ioctl(priv
->video_fd
, VIDIOC_ENUM_FMT
, &fmtdesc
) < 0) {
1322 mp_msg(MSGT_TV
, MSGL_V
, " Format %-6s (%2d bits, %s): %s\n",
1323 pixfmt2name(fmtdesc
.pixelformat
), pixfmt2depth(fmtdesc
.pixelformat
),
1324 fmtdesc
.description
, vo_format_name(fcc_vl2mp(fmtdesc
.pixelformat
)));
1326 mp_msg(MSGT_TV
, MSGL_INFO
, " Current format: %s\n",
1327 pixfmt2name(priv
->format
.fmt
.pix
.pixelformat
));
1329 /* set some nice defaults */
1330 if (getfmt(priv
) < 0) return 0;
1331 priv
->format
.fmt
.pix
.width
= 640;
1332 priv
->format
.fmt
.pix
.height
= 480;
1333 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
1334 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set format failed: %s\n",
1335 info
.short_name
, strerror(errno
));
1340 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;
1342 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
1343 struct v4l2_control control
;
1344 if (priv
->tv_param
->amode
>= 0) {
1345 mp_msg(MSGT_TV
, MSGL_V
, "%s: setting audio mode\n", info
.short_name
);
1346 priv
->tuner
.audmode
= amode2v4l(priv
->tv_param
->amode
);
1347 if (ioctl(priv
->video_fd
, VIDIOC_S_TUNER
, &priv
->tuner
) < 0) {
1348 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set tuner failed: %s\n",
1349 info
.short_name
, strerror(errno
));
1350 return TVI_CONTROL_FALSE
;
1353 mp_msg(MSGT_TV
, MSGL_INFO
, "%s: current audio mode is :%s%s%s%s\n", info
.short_name
,
1354 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_MONO
) ? " MONO" : "",
1355 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_STEREO
) ? " STEREO" : "",
1356 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_LANG1
) ? " LANG1" : "",
1357 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_LANG2
) ? " LANG2" : "");
1359 if (priv
->tv_param
->volume
>= 0) {
1360 control
.id
= V4L2_CID_AUDIO_VOLUME
;
1361 control
.value
= priv
->tv_param
->volume
;
1362 set_control(priv
, &control
, 0);
1364 if (priv
->tv_param
->bass
>= 0) {
1365 control
.id
= V4L2_CID_AUDIO_BASS
;
1366 control
.value
= priv
->tv_param
->bass
;
1367 set_control(priv
, &control
, 0);
1369 if (priv
->tv_param
->treble
>= 0) {
1370 control
.id
= V4L2_CID_AUDIO_TREBLE
;
1371 control
.value
= priv
->tv_param
->treble
;
1372 set_control(priv
, &control
, 0);
1374 if (priv
->tv_param
->balance
>= 0) {
1375 control
.id
= V4L2_CID_AUDIO_BALANCE
;
1376 control
.value
= priv
->tv_param
->balance
;
1377 set_control(priv
, &control
, 0);
1384 static int get_capture_buffer_size(priv_t
*priv
)
1388 if (priv
->tv_param
->buffer_size
>= 0) {
1389 bufsize
= priv
->tv_param
->buffer_size
*1024*1024;
1391 #ifdef HAVE_SYS_SYSINFO_H
1395 if (si
.totalram
<2*1024*1024) {
1396 bufsize
= 1024*1024;
1398 bufsize
= si
.totalram
/2;
1401 bufsize
= 16*1024*1024;
1405 cnt
= bufsize
/priv
->format
.fmt
.pix
.sizeimage
;
1406 if (cnt
< 2) cnt
= 2;
1411 /* that's the real start, we'got the format parameters (checked with control) */
1412 static int start(priv_t
*priv
)
1414 struct v4l2_requestbuffers request
;
1417 /* setup audio parameters */
1420 if (!priv
->tv_param
->noaudio
&& !priv
->audio_initialized
) return 0;
1422 /* we need this to size the audio buffer properly */
1423 if (priv
->immediate_mode
) {
1424 priv
->video_buffer_size_max
= 2;
1426 priv
->video_buffer_size_max
= get_capture_buffer_size(priv
);
1429 if (!priv
->tv_param
->noaudio
) {
1430 setup_audio_buffer_sizes(priv
);
1431 priv
->audio_skew_buffer
= calloc(priv
->aud_skew_cnt
, sizeof(long long));
1432 if (!priv
->audio_skew_buffer
) {
1433 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate skew buffer: %s\n", strerror(errno
));
1436 priv
->audio_skew_delta_buffer
= calloc(priv
->aud_skew_cnt
, sizeof(long long));
1437 if (!priv
->audio_skew_delta_buffer
) {
1438 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate skew buffer: %s\n", strerror(errno
));
1442 priv
->audio_ringbuffer
= calloc(priv
->audio_in
.blocksize
, priv
->audio_buffer_size
);
1443 if (!priv
->audio_ringbuffer
) {
1444 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate audio buffer: %s\n", strerror(errno
));
1448 priv
->audio_secs_per_block
= (double)priv
->audio_in
.blocksize
/(priv
->audio_in
.samplerate
1449 *priv
->audio_in
.channels
1450 *priv
->audio_in
.bytes_per_sample
);
1451 priv
->audio_usecs_per_block
= 1e6
*priv
->audio_secs_per_block
;
1452 priv
->audio_head
= 0;
1453 priv
->audio_tail
= 0;
1454 priv
->audio_cnt
= 0;
1455 priv
->audio_drop
= 0;
1456 priv
->audio_skew
= 0;
1457 priv
->audio_skew_total
= 0;
1458 priv
->audio_skew_delta_total
= 0;
1459 priv
->audio_recv_blocks_total
= 0;
1460 priv
->audio_sent_blocks_total
= 0;
1461 priv
->audio_null_blocks_inserted
= 0;
1462 priv
->audio_insert_null_samples
= 0;
1463 priv
->dropped_frames_timeshift
= 0;
1464 priv
->dropped_frames_compensated
= 0;
1466 pthread_mutex_init(&priv
->skew_mutex
, NULL
);
1467 pthread_mutex_init(&priv
->audio_mutex
, NULL
);
1470 /* setup video parameters */
1471 if (!priv
->tv_param
->noaudio
) {
1472 if (priv
->video_buffer_size_max
< (3*priv
->standard
.frameperiod
.denominator
) /
1473 priv
->standard
.frameperiod
.numerator
1474 *priv
->audio_secs_per_block
) {
1475 mp_msg(MSGT_TV
, MSGL_ERR
, "Video buffer shorter than 3 times audio frame duration.\n"
1476 "You will probably experience heavy framedrops.\n");
1481 int bytesperline
= priv
->format
.fmt
.pix
.width
*pixfmt2depth(priv
->format
.fmt
.pix
.pixelformat
)/8;
1483 mp_msg(MSGT_TV
, MSGL_V
, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1484 priv
->video_buffer_size_max
,
1485 priv
->video_buffer_size_max
*priv
->format
.fmt
.pix
.height
*bytesperline
/(1024*1024));
1488 priv
->video_ringbuffer
= calloc(priv
->video_buffer_size_max
, sizeof(video_buffer_entry
));
1489 if (!priv
->video_ringbuffer
) {
1490 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate video buffer: %s\n", strerror(errno
));
1493 memset(priv
->video_ringbuffer
,0,priv
->video_buffer_size_max
* sizeof(video_buffer_entry
));
1495 pthread_mutex_init(&priv
->video_buffer_mutex
, NULL
);
1497 priv
->video_head
= 0;
1498 priv
->video_tail
= 0;
1499 priv
->video_cnt
= 0;
1501 /* request buffers */
1502 if (priv
->immediate_mode
) {
1505 request
.count
= BUFFER_COUNT
;
1508 request
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1509 request
.memory
= V4L2_MEMORY_MMAP
;
1510 if (ioctl(priv
->video_fd
, VIDIOC_REQBUFS
, &request
) < 0) {
1511 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl request buffers failed: %s\n",
1512 info
.short_name
, strerror(errno
));
1517 if (!(priv
->map
= calloc(request
.count
, sizeof(struct map
)))) {
1518 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: malloc capture buffers failed: %s\n",
1519 info
.short_name
, strerror(errno
));
1523 /* map and queue buffers */
1524 for (i
= 0; i
< request
.count
; i
++) {
1525 memset(&priv
->map
[i
].buf
,0,sizeof(priv
->map
[i
].buf
));
1526 priv
->map
[i
].buf
.index
= i
;
1527 priv
->map
[i
].buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1528 priv
->map
[i
].buf
.memory
= V4L2_MEMORY_MMAP
;
1529 if (ioctl(priv
->video_fd
, VIDIOC_QUERYBUF
, &(priv
->map
[i
].buf
)) < 0) {
1530 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query buffer failed: %s\n",
1531 info
.short_name
, strerror(errno
));
1536 priv
->map
[i
].addr
= mmap (0, priv
->map
[i
].buf
.length
, PROT_READ
|
1537 PROT_WRITE
, MAP_SHARED
, priv
->video_fd
, priv
->map
[i
].buf
.m
.offset
);
1538 if (priv
->map
[i
].addr
== MAP_FAILED
) {
1539 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: mmap capture buffer failed: %s\n",
1540 info
.short_name
, strerror(errno
));
1541 priv
->map
[i
].len
= 0;
1544 priv
->map
[i
].len
= priv
->map
[i
].buf
.length
;
1545 /* count up to make sure this is correct everytime */
1548 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &(priv
->map
[i
].buf
)) < 0) {
1549 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1550 info
.short_name
, strerror(errno
));
1555 /* start vbi thread */
1557 priv
->vbi_shutdown
= 0;
1558 pthread_create(&priv
->vbi_grabber_thread
, NULL
, vbi_grabber
, priv
);
1560 /* start audio thread */
1562 priv
->audio_skew_measure_time
= 0;
1563 priv
->first_frame
= 0;
1564 priv
->audio_skew
= 0;
1572 // copies a video frame
1573 static inline void copy_frame(priv_t
*priv
, video_buffer_entry
*dest
, unsigned char *source
,int len
)
1575 dest
->framesize
=len
;
1576 if(priv
->tv_param
->automute
>0){
1577 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) >= 0) {
1578 if(priv
->tv_param
->automute
<<8>priv
->tuner
.signal
){
1579 fill_blank_frame(dest
->data
,dest
->framesize
,fcc_vl2mp(priv
->format
.fmt
.pix
.pixelformat
));
1586 memcpy(dest
->data
, source
, len
);
1589 // maximum skew change, in frames
1590 #define MAX_SKEW_DELTA 0.6
1591 static void *video_grabber(void *data
)
1593 priv_t
*priv
= (priv_t
*)data
;
1594 long long skew
, prev_skew
, xskew
, interval
, prev_interval
, delta
;
1596 int framesize
= priv
->format
.fmt
.pix
.sizeimage
;
1598 struct timeval timeout
;
1599 struct v4l2_buffer buf
;
1607 mp_msg(MSGT_TV
, MSGL_V
, "%s: going to capture\n", info
.short_name
);
1608 if (ioctl(priv
->video_fd
, VIDIOC_STREAMON
, &(priv
->format
.type
)) < 0) {
1609 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl streamon failed: %s\n",
1610 info
.short_name
, strerror(errno
));
1615 if (!priv
->tv_param
->noaudio
) {
1616 pthread_create(&priv
->audio_grabber_thread
, NULL
, audio_grabber
, priv
);
1619 for (priv
->frames
= 0; !priv
->shutdown
;)
1623 if (priv
->immediate_mode
) {
1624 while (priv
->video_cnt
== priv
->video_buffer_size_max
) {
1626 if (priv
->shutdown
) {
1633 FD_SET (priv
->video_fd
, &rdset
);
1636 timeout
.tv_usec
= 0;
1638 i
= select(priv
->video_fd
+ 1, &rdset
, NULL
, NULL
, &timeout
);
1640 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: select failed: %s\n",
1641 info
.short_name
, strerror(errno
));
1645 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: select timeout\n", info
.short_name
);
1648 else if (!FD_ISSET(priv
->video_fd
, &rdset
)) {
1652 memset(&buf
,0,sizeof(buf
));
1653 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1654 buf
.memory
= V4L2_MEMORY_MMAP
;
1655 ret
= ioctl(priv
->video_fd
, VIDIOC_DQBUF
, &buf
);
1659 if there's no signal, the buffer might me dequeued
1660 so we query all the buffers to see which one we should
1663 observed with saa7134 0.2.8
1664 don't know if is it a bug or (mis)feature
1666 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1667 info
.short_name
, strerror(errno
), buf
.index
);
1668 for (i
= 0; i
< priv
->mapcount
; i
++) {
1669 memset(&buf
,0,sizeof(buf
));
1670 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1671 buf
.memory
= V4L2_MEMORY_MMAP
;
1673 ret
= ioctl(priv
->video_fd
, VIDIOC_QUERYBUF
, &buf
);
1675 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query buffer failed: %s, idx = %d\n",
1676 info
.short_name
, strerror(errno
), buf
.index
);
1679 if ((buf
.flags
& (V4L2_BUF_FLAG_QUEUED
| V4L2_BUF_FLAG_MAPPED
| V4L2_BUF_FLAG_DONE
)) == V4L2_BUF_FLAG_MAPPED
) {
1680 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &(priv
->map
[i
].buf
)) < 0) {
1681 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1682 info
.short_name
, strerror(errno
));
1690 /* store the timestamp of the very first frame as reference */
1691 if (!priv
->frames
++) {
1692 if (!priv
->tv_param
->noaudio
) pthread_mutex_lock(&priv
->skew_mutex
);
1693 priv
->first_frame
= (long long)1e6
*buf
.timestamp
.tv_sec
+ buf
.timestamp
.tv_usec
;
1694 if (!priv
->tv_param
->noaudio
) pthread_mutex_unlock(&priv
->skew_mutex
);
1696 priv
->curr_frame
= (long long)buf
.timestamp
.tv_sec
*1e6
+buf
.timestamp
.tv_usec
;
1697 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1699 interval
= priv
->curr_frame
- priv
->first_frame
;
1700 delta
= interval
- prev_interval
;
1702 if (!priv
->immediate_mode
) {
1703 // interpolate the skew in time
1704 if (!priv
->tv_param
->noaudio
) pthread_mutex_lock(&priv
->skew_mutex
);
1705 xskew
= priv
->audio_skew
+ (interval
- priv
->audio_skew_measure_time
)*priv
->audio_skew_factor
;
1706 if (!priv
->tv_param
->noaudio
) pthread_mutex_unlock(&priv
->skew_mutex
);
1707 // correct extreme skew changes to avoid (especially) moving backwards in time
1708 if (xskew
- prev_skew
> delta
*MAX_SKEW_DELTA
) {
1709 skew
= prev_skew
+ delta
*MAX_SKEW_DELTA
;
1710 } else if (xskew
- prev_skew
< -delta
*MAX_SKEW_DELTA
) {
1711 skew
= prev_skew
- delta
*MAX_SKEW_DELTA
;
1717 mp_msg(MSGT_TV
, MSGL_DBG3
, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1718 delta
? (double)1e6
/delta
: -1,
1719 (double)1e-6*interval
, (double)1e-6*xskew
, (double)1e-6*skew
);
1720 mp_msg(MSGT_TV
, MSGL_DBG3
, "vcnt = %d, acnt = %d\n", priv
->video_cnt
, priv
->audio_cnt
);
1723 prev_interval
= interval
;
1725 /* allocate a new buffer, if needed */
1726 pthread_mutex_lock(&priv
->video_buffer_mutex
);
1727 if (priv
->video_buffer_size_current
< priv
->video_buffer_size_max
) {
1728 if (priv
->video_cnt
== priv
->video_buffer_size_current
) {
1729 unsigned char *newbuf
= malloc(framesize
);
1731 memmove(priv
->video_ringbuffer
+priv
->video_tail
+1, priv
->video_ringbuffer
+priv
->video_tail
,
1732 (priv
->video_buffer_size_current
-priv
->video_tail
)*sizeof(video_buffer_entry
));
1733 priv
->video_ringbuffer
[priv
->video_tail
].data
= newbuf
;
1734 if ((priv
->video_head
>= priv
->video_tail
) && (priv
->video_cnt
> 0)) priv
->video_head
++;
1735 priv
->video_buffer_size_current
++;
1739 pthread_mutex_unlock(&priv
->video_buffer_mutex
);
1741 if (priv
->video_cnt
== priv
->video_buffer_size_current
) {
1742 if (!priv
->immediate_mode
) {
1743 mp_msg(MSGT_TV
, MSGL_ERR
, "\nvideo buffer full - dropping frame\n");
1744 if (priv
->audio_insert_null_samples
) {
1745 pthread_mutex_lock(&priv
->audio_mutex
);
1746 priv
->dropped_frames_timeshift
+= delta
;
1747 pthread_mutex_unlock(&priv
->audio_mutex
);
1751 if (priv
->immediate_mode
) {
1752 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
= 0;
1754 // compensate for audio skew
1755 // negative skew => there are more audio samples, increase interval
1756 // positive skew => less samples, shorten the interval
1757 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
= interval
- skew
;
1758 if (priv
->audio_insert_null_samples
&& priv
->video_ringbuffer
[priv
->video_tail
].timestamp
> 0) {
1759 pthread_mutex_lock(&priv
->audio_mutex
);
1760 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
+=
1761 (priv
->audio_null_blocks_inserted
1762 - priv
->dropped_frames_timeshift
/priv
->audio_usecs_per_block
)
1763 *priv
->audio_usecs_per_block
;
1764 pthread_mutex_unlock(&priv
->audio_mutex
);
1767 copy_frame(priv
, priv
->video_ringbuffer
+priv
->video_tail
, priv
->map
[buf
.index
].addr
,buf
.bytesused
);
1768 priv
->video_tail
= (priv
->video_tail
+1)%priv
->video_buffer_size_current
;
1771 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &buf
) < 0) {
1772 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1773 info
.short_name
, strerror(errno
));
1781 static double grab_video_frame(priv_t
*priv
, char *buffer
, int len
)
1787 pthread_create(&priv
->video_grabber_thread
, NULL
, video_grabber
, priv
);
1791 while (priv
->video_cnt
== 0) {
1793 if (loop_cnt
++ > MAX_LOOP
) return 0;
1796 pthread_mutex_lock(&priv
->video_buffer_mutex
);
1797 interval
= (double)priv
->video_ringbuffer
[priv
->video_head
].timestamp
*1e-6;
1798 memcpy(buffer
, priv
->video_ringbuffer
[priv
->video_head
].data
, len
);
1800 priv
->video_head
= (priv
->video_head
+1)%priv
->video_buffer_size_current
;
1801 pthread_mutex_unlock(&priv
->video_buffer_mutex
);
1806 static int get_video_framesize(priv_t
*priv
)
1809 this routine will be called before grab_video_frame
1810 thus let's return topmost frame's size
1812 if (priv
->video_cnt
)
1813 return priv
->video_ringbuffer
[priv
->video_head
].framesize
;
1815 no video frames yet available. i don't know what to do in this case,
1816 thus let's return some fallback result (for compressed format this will be
1817 maximum allowed frame size.
1819 return priv
->format
.fmt
.pix
.sizeimage
;
1822 //#define DOUBLESPEED
1824 // for testing purposes only
1825 static void read_doublespeed(priv_t
*priv
)
1827 char *bufx
= calloc(priv
->audio_in
.blocksize
, 2);
1832 audio_in_read_chunk(&priv
->audio_in
, bufx
);
1833 audio_in_read_chunk(&priv
->audio_in
, bufx
+priv
->audio_in
.blocksize
);
1836 d
= priv
->audio_ringbuffer
+priv
->audio_tail
*priv
->audio_in
.blocksize
;
1837 for (i
= 0; i
< priv
->audio_in
.blocksize
/2; i
++) {
1845 static void *audio_grabber(void *data
)
1847 priv_t
*priv
= (priv_t
*)data
;
1849 int i
, audio_skew_ptr
= 0;
1850 long long current_time
, prev_skew
= 0, prev_skew_uncorr
= 0;
1851 long long start_time_avg
;
1853 gettimeofday(&tv
, NULL
);
1854 start_time_avg
= priv
->audio_start_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
;
1855 audio_in_start_capture(&priv
->audio_in
);
1856 for (i
= 0; i
< priv
->aud_skew_cnt
; i
++)
1857 priv
->audio_skew_buffer
[i
] = 0;
1858 for (i
= 0; i
< priv
->aud_skew_cnt
; i
++)
1859 priv
->audio_skew_delta_buffer
[i
] = 0;
1861 for (; !priv
->shutdown
;)
1864 read_doublespeed(priv
);
1866 if (audio_in_read_chunk(&priv
->audio_in
, priv
->audio_ringbuffer
+priv
->audio_tail
*priv
->audio_in
.blocksize
) < 0)
1869 pthread_mutex_lock(&priv
->skew_mutex
);
1870 if (priv
->first_frame
== 0) {
1871 // there is no first frame yet (unlikely to happen)
1872 gettimeofday(&tv
, NULL
);
1873 start_time_avg
= priv
->audio_start_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
;
1874 // fprintf(stderr, "warning - first frame not yet available!\n");
1875 pthread_mutex_unlock(&priv
->skew_mutex
);
1878 pthread_mutex_unlock(&priv
->skew_mutex
);
1880 gettimeofday(&tv
, NULL
);
1882 priv
->audio_recv_blocks_total
++;
1883 current_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
- priv
->audio_start_time
;
1885 if (priv
->audio_recv_blocks_total
< priv
->aud_skew_cnt
*2) {
1886 start_time_avg
+= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
- priv
->audio_usecs_per_block
*priv
->audio_recv_blocks_total
;
1887 priv
->audio_start_time
= start_time_avg
/(priv
->audio_recv_blocks_total
+1);
1890 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1891 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1893 // put the current skew into the ring buffer
1894 priv
->audio_skew_total
-= priv
->audio_skew_buffer
[audio_skew_ptr
];
1895 priv
->audio_skew_buffer
[audio_skew_ptr
] = current_time
1896 - priv
->audio_usecs_per_block
*priv
->audio_recv_blocks_total
;
1897 priv
->audio_skew_total
+= priv
->audio_skew_buffer
[audio_skew_ptr
];
1899 pthread_mutex_lock(&priv
->skew_mutex
);
1903 // compute the sliding average of the skews
1904 if (priv
->audio_recv_blocks_total
> priv
->aud_skew_cnt
) {
1905 priv
->audio_skew
= priv
->audio_skew_total
/priv
->aud_skew_cnt
;
1907 priv
->audio_skew
= priv
->audio_skew_total
/priv
->audio_recv_blocks_total
;
1910 // put the current skew change (skew-prev_skew) into the ring buffer
1911 priv
->audio_skew_delta_total
-= priv
->audio_skew_delta_buffer
[audio_skew_ptr
];
1912 priv
->audio_skew_delta_buffer
[audio_skew_ptr
] = priv
->audio_skew
- prev_skew_uncorr
;
1913 priv
->audio_skew_delta_total
+= priv
->audio_skew_delta_buffer
[audio_skew_ptr
];
1914 prev_skew_uncorr
= priv
->audio_skew
; // remember the _uncorrected_ average value
1916 audio_skew_ptr
= (audio_skew_ptr
+1) % priv
->aud_skew_cnt
; // rotate the buffer pointer
1918 // sliding average approximates the value in the middle of the interval
1919 // so interpolate the skew value further to the current time
1920 priv
->audio_skew
+= priv
->audio_skew_delta_total
/2;
1922 // now finally, priv->audio_skew contains fairly good approximation
1923 // of the current value
1925 // current skew factor (assuming linearity)
1926 // used for further interpolation in video_grabber
1927 // probably overkill but seems to be necessary for
1928 // stress testing by dropping half of the audio frames ;)
1929 // especially when using ALSA with large block sizes
1930 // where audio_skew remains a long while behind
1931 if ((priv
->audio_skew_measure_time
!= 0) && (current_time
- priv
->audio_skew_measure_time
!= 0)) {
1932 priv
->audio_skew_factor
= (double)(priv
->audio_skew
-prev_skew
)/(current_time
- priv
->audio_skew_measure_time
);
1934 priv
->audio_skew_factor
= 0.0;
1937 priv
->audio_skew_measure_time
= current_time
;
1938 prev_skew
= priv
->audio_skew
;
1939 priv
->audio_skew
+= priv
->audio_start_time
- priv
->first_frame
;
1940 pthread_mutex_unlock(&priv
->skew_mutex
);
1942 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1944 pthread_mutex_lock(&priv
->audio_mutex
);
1945 if ((priv
->audio_tail
+1) % priv
->audio_buffer_size
== priv
->audio_head
) {
1946 mp_msg(MSGT_TV
, MSGL_ERR
, "\ntoo bad - dropping audio frame !\n");
1949 priv
->audio_tail
= (priv
->audio_tail
+1) % priv
->audio_buffer_size
;
1952 pthread_mutex_unlock(&priv
->audio_mutex
);
1957 static double grab_audio_frame(priv_t
*priv
, char *buffer
, int len
)
1959 mp_dbg(MSGT_TV
, MSGL_DBG2
, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1962 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1963 // => switch to the mode which outputs audio immediately, even if
1964 // it should be silence
1965 if (priv
->first
) priv
->audio_insert_null_samples
= 1;
1967 pthread_mutex_lock(&priv
->audio_mutex
);
1968 while (priv
->audio_insert_null_samples
1969 && priv
->dropped_frames_timeshift
- priv
->dropped_frames_compensated
>= priv
->audio_usecs_per_block
) {
1970 // some frames were dropped - drop the corresponding number of audio blocks
1971 if (priv
->audio_drop
) {
1974 if (priv
->audio_head
== priv
->audio_tail
) break;
1975 priv
->audio_head
= (priv
->audio_head
+1) % priv
->audio_buffer_size
;
1977 priv
->dropped_frames_compensated
+= priv
->audio_usecs_per_block
;
1980 // compensate for dropped audio frames
1981 if (priv
->audio_drop
&& (priv
->audio_head
== priv
->audio_tail
)) {
1983 memset(buffer
, 0, len
);
1987 if (priv
->audio_insert_null_samples
&& (priv
->audio_head
== priv
->audio_tail
)) {
1988 // return silence to avoid desync and stuttering
1989 memset(buffer
, 0, len
);
1990 priv
->audio_null_blocks_inserted
++;
1994 pthread_mutex_unlock(&priv
->audio_mutex
);
1995 while (priv
->audio_head
== priv
->audio_tail
) {
1996 // this is mencoder => just wait until some audio is available
1999 pthread_mutex_lock(&priv
->audio_mutex
);
2000 memcpy(buffer
, priv
->audio_ringbuffer
+priv
->audio_head
*priv
->audio_in
.blocksize
, len
);
2001 priv
->audio_head
= (priv
->audio_head
+1) % priv
->audio_buffer_size
;
2004 pthread_mutex_unlock(&priv
->audio_mutex
);
2005 priv
->audio_sent_blocks_total
++;
2006 return (double)priv
->audio_sent_blocks_total
*priv
->audio_secs_per_block
;
2009 static int get_audio_framesize(priv_t
*priv
)
2011 return priv
->audio_in
.blocksize
;