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 "libaf/af_format.h"
60 #define info tvi_info_v4l2
61 static tvi_handle_t
*tvi_init_v4l2(tv_param_t
* tv_param
);
62 /* information about this file */
63 const tvi_info_t tvi_info_v4l2
= {
65 "Video 4 Linux 2 input",
67 "Martin Olschewski <olschewski@zpr.uni-koeln.de>",
68 "first try, more to come ;-)"
72 struct v4l2_buffer buf
;
77 #define BUFFER_COUNT 6
79 /** video ringbuffer entry */
81 unsigned char *data
; ///< frame contents
82 long long timestamp
; ///< frame timestamp
83 int framesize
; ///< actual frame size
91 #ifdef CONFIG_TV_TELETEXT
96 pthread_t vbi_grabber_thread
;
100 struct v4l2_capability capability
;
101 struct v4l2_input input
;
102 struct v4l2_format format
;
103 struct v4l2_standard standard
;
104 struct v4l2_tuner tuner
;
108 volatile long long first_frame
;
109 long long curr_frame
;
110 /* audio video interleaving ;-) */
111 volatile int streamon
;
112 pthread_t audio_grabber_thread
;
113 pthread_mutex_t skew_mutex
;
115 /* 2nd level video buffers */
119 int video_buffer_size_max
;
120 volatile int video_buffer_size_current
;
121 video_buffer_entry
*video_ringbuffer
;
122 volatile int video_head
;
123 volatile int video_tail
;
124 volatile int video_cnt
;
125 pthread_t video_grabber_thread
;
126 pthread_mutex_t video_buffer_mutex
;
132 long long audio_start_time
;
133 int audio_buffer_size
;
135 unsigned char *audio_ringbuffer
;
136 long long *audio_skew_buffer
;
137 long long *audio_skew_delta_buffer
;
138 volatile int audio_head
;
139 volatile int audio_tail
;
140 volatile int audio_cnt
;
141 volatile long long audio_skew
;
142 volatile double audio_skew_factor
;
143 volatile long long audio_skew_measure_time
;
144 volatile int audio_drop
;
145 volatile int shutdown
;
147 int audio_initialized
;
148 double audio_secs_per_block
;
149 long long audio_usecs_per_block
;
150 long long audio_skew_total
;
151 long long audio_skew_delta_total
;
152 long audio_recv_blocks_total
;
153 long audio_sent_blocks_total
;
154 pthread_mutex_t audio_mutex
;
155 int audio_insert_null_samples
;
156 volatile long audio_null_blocks_inserted
;
157 volatile long long dropped_frames_timeshift
;
158 long long dropped_frames_compensated
;
160 tv_param_t
*tv_param
;
165 static void *audio_grabber(void *data
);
166 static void *video_grabber(void *data
);
168 /**********************************************************************\
170 Only few of the fourccs are the same in v4l2 and mplayer:
172 IMGFMT_YVU9 == V4L2_PIX_FMT_YVU410
173 IMGFMT_YV12 == V4L2_PIX_FMT_YVU420
174 IMGFMT_NV12 == V4L2_PIX_FMT_NV12
175 IMGFMT_422P == V4L2_PIX_FMT_YUV422P
176 IMGFMT_411P == V4L2_PIX_FMT_YUV411P
177 IMGFMT_UYVY == V4L2_PIX_FMT_UYVY
178 IMGFMT_Y41P == V4L2_PIX_FMT_Y41P
180 This may be an useful translation table for some others:
182 IMGFMT_RGB8 == V4L2_PIX_FMT_RGB332
183 IMGFMT_BGR15 == V4L2_PIX_FMT_RGB555
184 IMGFMT_BGR16 == V4L2_PIX_FMT_RGB565
185 IMGFMT_RGB24 == V4L2_PIX_FMT_RGB24
186 IMGFMT_RGB32 == V4L2_PIX_FMT_RGB32
187 IMGFMT_BGR24 == V4L2_PIX_FMT_BGR24
188 IMGFMT_BGR32 == V4L2_PIX_FMT_BGR32
189 IMGFMT_Y800 == V4L2_PIX_FMT_GREY
190 IMGFMT_IF09 == V4L2_PIX_FMT_YUV410
191 IMGFMT_I420 == V4L2_PIX_FMT_YUV420
192 IMGFMT_YUY2 == V4L2_PIX_FMT_YUYV
194 \**********************************************************************/
197 ** Translate a mplayer fourcc to a video4linux2 pixel format.
199 static int fcc_mp2vl(int fcc
)
202 case IMGFMT_RGB8
: return V4L2_PIX_FMT_RGB332
;
203 case IMGFMT_BGR15
: return V4L2_PIX_FMT_RGB555
;
204 case IMGFMT_BGR16
: return V4L2_PIX_FMT_RGB565
;
205 case IMGFMT_RGB24
: return V4L2_PIX_FMT_RGB24
;
206 case IMGFMT_RGB32
: return V4L2_PIX_FMT_RGB32
;
207 case IMGFMT_BGR24
: return V4L2_PIX_FMT_BGR24
;
208 case IMGFMT_BGR32
: return V4L2_PIX_FMT_BGR32
;
209 case IMGFMT_Y800
: return V4L2_PIX_FMT_GREY
;
210 case IMGFMT_IF09
: return V4L2_PIX_FMT_YUV410
;
211 case IMGFMT_I420
: return V4L2_PIX_FMT_YUV420
;
212 case IMGFMT_YUY2
: return V4L2_PIX_FMT_YUYV
;
213 case IMGFMT_YV12
: return V4L2_PIX_FMT_YVU420
;
214 case IMGFMT_UYVY
: return V4L2_PIX_FMT_UYVY
;
215 case IMGFMT_MJPEG
: return V4L2_PIX_FMT_MJPEG
;
221 ** Translate a video4linux2 fourcc aka pixel format to mplayer.
223 static int fcc_vl2mp(int fcc
)
226 case V4L2_PIX_FMT_RGB332
: return IMGFMT_RGB8
;
227 case V4L2_PIX_FMT_RGB555
: return IMGFMT_BGR15
;
228 case V4L2_PIX_FMT_RGB565
: return IMGFMT_BGR16
;
229 case V4L2_PIX_FMT_RGB24
: return IMGFMT_RGB24
;
230 case V4L2_PIX_FMT_RGB32
: return IMGFMT_RGB32
;
231 case V4L2_PIX_FMT_BGR24
: return IMGFMT_BGR24
;
232 case V4L2_PIX_FMT_BGR32
: return IMGFMT_BGR32
;
233 case V4L2_PIX_FMT_GREY
: return IMGFMT_Y800
;
234 case V4L2_PIX_FMT_YUV410
: return IMGFMT_IF09
;
235 case V4L2_PIX_FMT_YUV420
: return IMGFMT_I420
;
236 case V4L2_PIX_FMT_YVU420
: return IMGFMT_YV12
;
237 case V4L2_PIX_FMT_YUYV
: return IMGFMT_YUY2
;
238 case V4L2_PIX_FMT_UYVY
: return IMGFMT_UYVY
;
239 case V4L2_PIX_FMT_MJPEG
: return IMGFMT_MJPEG
;
245 ** Translate a video4linux2 fourcc aka pixel format
246 ** to a human readable string.
248 static const char *pixfmt2name(int pixfmt
)
250 static char unknown
[24];
253 case V4L2_PIX_FMT_RGB332
: return "RGB332";
254 case V4L2_PIX_FMT_RGB555
: return "RGB555";
255 case V4L2_PIX_FMT_RGB565
: return "RGB565";
256 case V4L2_PIX_FMT_RGB555X
: return "RGB555X";
257 case V4L2_PIX_FMT_RGB565X
: return "RGB565X";
258 case V4L2_PIX_FMT_BGR24
: return "BGR24";
259 case V4L2_PIX_FMT_RGB24
: return "RGB24";
260 case V4L2_PIX_FMT_BGR32
: return "BGR32";
261 case V4L2_PIX_FMT_RGB32
: return "RGB32";
262 case V4L2_PIX_FMT_GREY
: return "GREY";
263 case V4L2_PIX_FMT_YVU410
: return "YVU410";
264 case V4L2_PIX_FMT_YVU420
: return "YVU420";
265 case V4L2_PIX_FMT_YUYV
: return "YUYV";
266 case V4L2_PIX_FMT_UYVY
: return "UYVY";
267 /* case V4L2_PIX_FMT_YVU422P: return "YVU422P"; */
268 /* case V4L2_PIX_FMT_YVU411P: return "YVU411P"; */
269 case V4L2_PIX_FMT_YUV422P
: return "YUV422P";
270 case V4L2_PIX_FMT_YUV411P
: return "YUV411P";
271 case V4L2_PIX_FMT_Y41P
: return "Y41P";
272 case V4L2_PIX_FMT_NV12
: return "NV12";
273 case V4L2_PIX_FMT_NV21
: return "NV21";
274 case V4L2_PIX_FMT_YUV410
: return "YUV410";
275 case V4L2_PIX_FMT_YUV420
: return "YUV420";
276 case V4L2_PIX_FMT_YYUV
: return "YYUV";
277 case V4L2_PIX_FMT_HI240
: return "HI240";
278 case V4L2_PIX_FMT_WNVA
: return "WNVA";
279 case V4L2_PIX_FMT_MJPEG
: return "MJPEG";
281 sprintf(unknown
, "unknown (0x%x)", pixfmt
);
287 ** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
289 static int pixfmt2depth(int pixfmt
)
292 case V4L2_PIX_FMT_RGB332
:
294 case V4L2_PIX_FMT_RGB555
:
295 case V4L2_PIX_FMT_RGB565
:
296 case V4L2_PIX_FMT_RGB555X
:
297 case V4L2_PIX_FMT_RGB565X
:
299 case V4L2_PIX_FMT_BGR24
:
300 case V4L2_PIX_FMT_RGB24
:
302 case V4L2_PIX_FMT_BGR32
:
303 case V4L2_PIX_FMT_RGB32
:
305 case V4L2_PIX_FMT_GREY
:
307 case V4L2_PIX_FMT_YVU410
:
309 case V4L2_PIX_FMT_YVU420
:
311 case V4L2_PIX_FMT_YUYV
:
312 case V4L2_PIX_FMT_UYVY
:
313 case V4L2_PIX_FMT_YUV422P
:
314 case V4L2_PIX_FMT_YUV411P
:
316 case V4L2_PIX_FMT_Y41P
:
317 case V4L2_PIX_FMT_NV12
:
318 case V4L2_PIX_FMT_NV21
:
320 case V4L2_PIX_FMT_YUV410
:
322 case V4L2_PIX_FMT_YUV420
:
324 case V4L2_PIX_FMT_YYUV
:
326 case V4L2_PIX_FMT_HI240
:
333 static int amode2v4l(int amode
)
337 return V4L2_TUNER_MODE_MONO
;
339 return V4L2_TUNER_MODE_STEREO
;
341 return V4L2_TUNER_MODE_LANG1
;
343 return V4L2_TUNER_MODE_LANG2
;
353 static double getfps(priv_t
*priv
)
355 if (priv
->tv_param
->fps
> 0)
356 return priv
->tv_param
->fps
;
357 if (priv
->standard
.frameperiod
.denominator
&& priv
->standard
.frameperiod
.numerator
)
358 return (double)priv
->standard
.frameperiod
.denominator
/ priv
->standard
.frameperiod
.numerator
;
362 // sets and sanitizes audio buffer/block sizes
363 static void setup_audio_buffer_sizes(priv_t
*priv
)
365 int bytes_per_sample
= priv
->audio_in
.bytes_per_sample
;
366 int seconds
= priv
->video_buffer_size_max
/getfps(priv
);
368 if (seconds
< 5) seconds
= 5;
369 if (seconds
> 500) seconds
= 500;
371 // make the audio buffer at least as the video buffer capacity (or 5 seconds) long
372 priv
->audio_buffer_size
= 1 + seconds
*priv
->audio_in
.samplerate
373 *priv
->audio_in
.channels
374 *bytes_per_sample
/priv
->audio_in
.blocksize
;
375 if (priv
->audio_buffer_size
< 256) priv
->audio_buffer_size
= 256;
377 // make the skew buffer at least 1 second long
378 priv
->aud_skew_cnt
= 1 + 1*priv
->audio_in
.samplerate
379 *priv
->audio_in
.channels
380 *bytes_per_sample
/priv
->audio_in
.blocksize
;
381 if (priv
->aud_skew_cnt
< 16) priv
->aud_skew_cnt
= 16;
383 mp_msg(MSGT_TV
, MSGL_V
, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
384 priv
->audio_buffer_size
, priv
->audio_in
.blocksize
, priv
->aud_skew_cnt
);
387 static void init_audio(priv_t
*priv
)
389 if (priv
->audio_initialized
) return;
391 if (!priv
->tv_param
->noaudio
) {
393 if (priv
->tv_param
->alsa
)
394 audio_in_init(&priv
->audio_in
, AUDIO_IN_ALSA
);
396 audio_in_init(&priv
->audio_in
, AUDIO_IN_OSS
);
398 audio_in_init(&priv
->audio_in
, AUDIO_IN_OSS
);
401 if (priv
->audio_dev
) {
402 audio_in_set_device(&priv
->audio_in
, priv
->audio_dev
);
405 audio_in_set_samplerate(&priv
->audio_in
, 44100);
406 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
407 if (priv
->tuner
.audmode
== V4L2_TUNER_MODE_STEREO
) {
408 audio_in_set_channels(&priv
->audio_in
, 2);
410 audio_in_set_channels(&priv
->audio_in
, 1);
413 if (priv
->tv_param
->forcechan
>= 0) {
414 audio_in_set_channels(&priv
->audio_in
, priv
->tv_param
->forcechan
);
416 audio_in_set_channels(&priv
->audio_in
, 2);
420 if (audio_in_setup(&priv
->audio_in
) < 0) return;
422 priv
->audio_initialized
= 1;
428 ** the number of milliseconds elapsed between time0 and time1
430 static size_t difftv(struct timeval time1
, struct timeval time0
)
432 return (time1
.tv_sec
- time0
.tv_sec
) * 1000 +
433 (time1
.tv_usec
- time0
.tv_usec
) / 1000;
438 ** Get current video capture format.
440 static int getfmt(priv_t
*priv
)
444 priv
->format
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
445 if ((i
= ioctl(priv
->video_fd
, VIDIOC_G_FMT
, &priv
->format
)) < 0) {
446 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get format failed: %s\n",
447 info
.short_name
, strerror(errno
));
454 ** Get current video capture standard.
456 static int getstd(priv_t
*priv
)
461 if (ioctl(priv
->video_fd
, VIDIOC_G_STD
, &id
) < 0) {
462 struct v4l2_streamparm parm
;
464 parm
.type
=V4L2_BUF_TYPE_VIDEO_CAPTURE
;
465 if(ioctl(priv
->video_fd
, VIDIOC_G_PARM
, &parm
) >= 0) {
466 mp_msg(MSGT_TV
, MSGL_WARN
, "%s: your device driver does not support VIDIOC_G_STD ioctl,"
467 " VIDIOC_G_PARM was used instead.\n", info
.short_name
);
468 priv
->standard
.index
=0;
470 priv
->standard
.frameperiod
=parm
.parm
.capture
.timeperframe
;
474 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get standard failed: %s\n",
475 info
.short_name
, strerror(errno
));
479 priv
->standard
.index
= i
++;
480 if (ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &priv
->standard
) < 0) {
483 } while (priv
->standard
.id
!= id
);
487 /***********************************************************************\
490 * Interface to mplayer *
493 \***********************************************************************/
495 static int set_mute(priv_t
*priv
, int value
)
497 struct v4l2_control control
;
498 control
.id
= V4L2_CID_AUDIO_MUTE
;
499 control
.value
= value
;
500 if (ioctl(priv
->video_fd
, VIDIOC_S_CTRL
, &control
) < 0) {
501 mp_msg(MSGT_TV
,MSGL_ERR
,"%s: ioctl set mute failed: %s\n",
502 info
.short_name
, strerror(errno
));
509 ** MPlayer uses values from -100 up to 100 for controls.
510 ** Here they are scaled to what the tv card needs and applied.
512 static int set_control(priv_t
*priv
, struct v4l2_control
*control
, int val_signed
) {
513 struct v4l2_queryctrl qctrl
;
514 qctrl
.id
= control
->id
;
515 if (ioctl(priv
->video_fd
, VIDIOC_QUERYCTRL
, &qctrl
) < 0) {
516 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query control failed: %s\n",
517 info
.short_name
, strerror(errno
));
518 return TVI_CONTROL_FALSE
;
522 if (control
->value
< 0) {
523 control
->value
= qctrl
.default_value
+ control
->value
*
524 (qctrl
.default_value
- qctrl
.minimum
) / 100;
526 control
->value
= qctrl
.default_value
+ control
->value
*
527 (qctrl
.maximum
- qctrl
.default_value
) / 100;
530 if (control
->value
< 50) {
531 control
->value
= qctrl
.default_value
+ (control
->value
-50) *
532 (qctrl
.default_value
- qctrl
.minimum
) / 50;
534 control
->value
= qctrl
.default_value
+ (control
->value
-50) *
535 (qctrl
.maximum
- qctrl
.default_value
) / 50;
540 if (ioctl(priv
->video_fd
, VIDIOC_S_CTRL
, control
) < 0) {
541 mp_msg(MSGT_TV
, MSGL_ERR
,"%s: ioctl set %s %d failed: %s\n",
542 info
.short_name
, qctrl
.name
, control
->value
, strerror(errno
));
543 return TVI_CONTROL_FALSE
;
545 mp_msg(MSGT_TV
, MSGL_V
, "%s: set %s: %d [%d, %d]\n", info
.short_name
,
546 qctrl
.name
, control
->value
, qctrl
.minimum
, qctrl
.maximum
);
548 return TVI_CONTROL_TRUE
;
553 ** Scale the control values back to what mplayer needs.
555 static int get_control(priv_t
*priv
, struct v4l2_control
*control
, int val_signed
) {
556 struct v4l2_queryctrl qctrl
;
558 qctrl
.id
= control
->id
;
559 if (ioctl(priv
->video_fd
, VIDIOC_QUERYCTRL
, &qctrl
) < 0) {
560 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query control failed: %s\n",
561 info
.short_name
, strerror(errno
));
562 return TVI_CONTROL_FALSE
;
565 if (ioctl(priv
->video_fd
, VIDIOC_G_CTRL
, control
) < 0) {
566 mp_msg(MSGT_TV
, MSGL_ERR
,"%s: ioctl get %s failed: %s\n",
567 info
.short_name
, qctrl
.name
, strerror(errno
));
568 return TVI_CONTROL_FALSE
;
570 mp_msg(MSGT_TV
, MSGL_V
, "%s: get %s: %d [%d, %d]\n", info
.short_name
,
571 qctrl
.name
, control
->value
, qctrl
.minimum
, qctrl
.maximum
);
574 if (control
->value
< qctrl
.default_value
) {
575 control
->value
= (control
->value
- qctrl
.default_value
) * 100 /
576 (qctrl
.default_value
- qctrl
.minimum
);
578 control
->value
= (control
->value
- qctrl
.default_value
) * 100 /
579 (qctrl
.maximum
- qctrl
.default_value
);
582 if (control
->value
< qctrl
.default_value
) {
583 control
->value
= (control
->value
- qctrl
.default_value
) * 50 /
584 (qctrl
.default_value
- qctrl
.minimum
) + 50;
586 control
->value
= (control
->value
- qctrl
.default_value
) * 50 /
587 (qctrl
.maximum
- qctrl
.default_value
) + 50;
591 return TVI_CONTROL_TRUE
;
594 #ifdef CONFIG_TV_TELETEXT
595 static int vbi_init(priv_t
* priv
,char* device
)
598 struct v4l2_capability cap
;
599 struct v4l2_format fmt
;
603 return TVI_CONTROL_FALSE
;
605 priv
->vbi_dev
=strdup(device
);
607 vbi_fd
=open(priv
->vbi_dev
,O_RDWR
);
609 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: could not open device %s\n",priv
->vbi_dev
);
610 return TVI_CONTROL_FALSE
;
613 if(ioctl(vbi_fd
,VIDIOC_QUERYCAP
,&cap
)<0){
614 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: Query capatibilities failed for %s\n",priv
->vbi_dev
);
616 return TVI_CONTROL_FALSE
;
618 if(!cap
.capabilities
& V4L2_CAP_VBI_CAPTURE
){
619 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: %s does not support VBI capture\n",priv
->vbi_dev
);
621 return TVI_CONTROL_FALSE
;
624 memset(&fmt
,0,sizeof(struct v4l2_format
));
625 fmt
.type
=V4L2_BUF_TYPE_VBI_CAPTURE
;
626 if((res
=ioctl(vbi_fd
,VIDIOC_G_FMT
,&fmt
))<0){
627 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: Query format failed: %x\n",res
);
629 return TVI_CONTROL_FALSE
;
631 if(fmt
.fmt
.vbi
.sample_format
!=V4L2_PIX_FMT_GREY
){
632 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi: format 0x%x is not supported\n",fmt
.fmt
.vbi
.sample_format
);
634 return TVI_CONTROL_FALSE
;
637 mp_msg(MSGT_TV
,MSGL_DBG3
,"vbi: init ok\n");
638 return TVI_CONTROL_TRUE
;
641 static int vbi_get_props(priv_t
* priv
,tt_stream_props
* ptsp
)
643 struct v4l2_format fmt
;
646 return TVI_CONTROL_FALSE
;
648 memset(&fmt
,0,sizeof(struct v4l2_format
));
649 fmt
.type
=V4L2_BUF_TYPE_VBI_CAPTURE
;
650 if((res
=ioctl(priv
->vbi_fd
,VIDIOC_G_FMT
,&fmt
))<0){
651 mp_msg(MSGT_TV
,MSGL_ERR
,"vbi_get_props: Query format failed: %x\n",res
);
652 return TVI_CONTROL_FALSE
;
655 ptsp
->interlaced
=(fmt
.fmt
.vbi
.flags
& V4L2_VBI_INTERLACED
?1:0);
657 ptsp
->offset
=fmt
.fmt
.vbi
.offset
;
658 ptsp
->sampling_rate
=fmt
.fmt
.vbi
.sampling_rate
;
659 ptsp
->samples_per_line
=fmt
.fmt
.vbi
.samples_per_line
,
661 ptsp
->count
[0]=fmt
.fmt
.vbi
.count
[0];
662 ptsp
->count
[1]=fmt
.fmt
.vbi
.count
[1];
663 ptsp
->bufsize
= ptsp
->samples_per_line
* (ptsp
->count
[0] + ptsp
->count
[1]);
665 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",
668 ptsp
->samples_per_line
,
669 ptsp
->interlaced
?"Yes":"No",
673 return TVI_CONTROL_TRUE
;
676 static void *vbi_grabber(void *data
)
678 priv_t
*priv
= (priv_t
*) data
;
679 int bytes
,seq
,prev_seq
;
684 mp_msg(MSGT_TV
,MSGL_WARN
,"vbi: vbi not initialized. stopping thread.\n");
688 if(vbi_get_props(priv
,&tsp
)!=TVI_CONTROL_TRUE
)
691 buf
=malloc(tsp
.bufsize
);
694 mp_msg(MSGT_TV
,MSGL_V
,"vbi: vbi capture thread started.\n");
696 while (!priv
->vbi_shutdown
){
697 bytes
=read(priv
->vbi_fd
,buf
,tsp
.bufsize
);
698 if(bytes
<0 && errno
==EINTR
)
700 if (bytes
!=tsp
.bufsize
){
701 mp_msg(MSGT_TV
,MSGL_WARN
,"vbi: expecting bytes: %d, got: %d\n",tsp
.bufsize
,bytes
);
704 seq
=*(int*)(buf
+bytes
-4);
706 if (prev_seq
&& seq
!=prev_seq
+1){
711 teletext_control(priv
->priv_vbi
,TV_VBI_CONTROL_DECODE_PAGE
,&buf
);
712 mp_msg(MSGT_TV
,MSGL_DBG3
,"grabber: seq:%d\n",seq
);
717 #endif /* CONFIG_TV_TELETEXT */
719 static int control(priv_t
*priv
, int cmd
, void *arg
)
721 struct v4l2_control control
;
722 struct v4l2_frequency frequency
;
725 case TVI_CONTROL_IS_VIDEO
:
726 return priv
->capability
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
?
727 TVI_CONTROL_TRUE
: TVI_CONTROL_FALSE
;
728 case TVI_CONTROL_IS_AUDIO
:
729 if (priv
->tv_param
->force_audio
) return TVI_CONTROL_TRUE
;
730 case TVI_CONTROL_IS_TUNER
:
731 return priv
->capability
.capabilities
& V4L2_CAP_TUNER
?
732 TVI_CONTROL_TRUE
: TVI_CONTROL_FALSE
;
733 case TVI_CONTROL_IMMEDIATE
:
734 priv
->immediate_mode
= 1;
735 return TVI_CONTROL_TRUE
;
736 case TVI_CONTROL_VID_GET_FPS
:
737 if (!priv
->standard
.frameperiod
.denominator
|| !priv
->standard
.frameperiod
.numerator
) {
738 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: Cannot get fps\n", info
.short_name
);
739 return TVI_CONTROL_FALSE
;
741 *(float *)arg
= (float)priv
->standard
.frameperiod
.denominator
/
742 priv
->standard
.frameperiod
.numerator
;
743 mp_msg(MSGT_TV
, MSGL_V
, "%s: get fps: %f\n", info
.short_name
,
745 return TVI_CONTROL_TRUE
;
746 case TVI_CONTROL_VID_GET_BITS
:
747 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
748 *(int *)arg
= pixfmt2depth(priv
->format
.fmt
.pix
.pixelformat
);
749 mp_msg(MSGT_TV
, MSGL_V
, "%s: get depth: %d\n", info
.short_name
,
751 return TVI_CONTROL_TRUE
;
752 case TVI_CONTROL_VID_GET_FORMAT
:
753 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
754 *(int *)arg
= fcc_vl2mp(priv
->format
.fmt
.pix
.pixelformat
);
755 mp_msg(MSGT_TV
, MSGL_V
, "%s: get format: %s\n", info
.short_name
,
756 pixfmt2name(priv
->format
.fmt
.pix
.pixelformat
));
757 return TVI_CONTROL_TRUE
;
758 case TVI_CONTROL_VID_SET_FORMAT
:
759 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
760 priv
->format
.fmt
.pix
.pixelformat
= fcc_mp2vl(*(int *)arg
);
761 priv
->format
.fmt
.pix
.field
= V4L2_FIELD_ANY
;
763 priv
->mp_format
= *(int *)arg
;
764 mp_msg(MSGT_TV
, MSGL_V
, "%s: set format: %s\n", info
.short_name
,
765 pixfmt2name(priv
->format
.fmt
.pix
.pixelformat
));
766 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
767 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set format failed: %s\n",
768 info
.short_name
, strerror(errno
));
769 return TVI_CONTROL_FALSE
;
771 /* according to the v4l2 specs VIDIOC_S_FMT should not fail, inflexible drivers
772 might even always return the default parameters -> update the format here*/
773 priv
->mp_format
= fcc_vl2mp(priv
->format
.fmt
.pix
.pixelformat
);
774 return TVI_CONTROL_TRUE
;
775 case TVI_CONTROL_VID_GET_WIDTH
:
776 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
777 *(int *)arg
= priv
->format
.fmt
.pix
.width
;
778 mp_msg(MSGT_TV
, MSGL_V
, "%s: get width: %d\n", info
.short_name
,
780 return TVI_CONTROL_TRUE
;
781 case TVI_CONTROL_VID_CHK_WIDTH
:
782 return TVI_CONTROL_TRUE
;
783 case TVI_CONTROL_VID_SET_WIDTH_HEIGHT
:
784 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
785 priv
->format
.fmt
.pix
.width
= ((int *)arg
)[0];
786 priv
->format
.fmt
.pix
.height
= ((int *)arg
)[1];
787 priv
->format
.fmt
.pix
.field
= V4L2_FIELD_ANY
;
788 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0)
789 return TVI_CONTROL_FALSE
;
790 return TVI_CONTROL_TRUE
;
791 case TVI_CONTROL_VID_SET_WIDTH
:
792 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
793 priv
->format
.fmt
.pix
.width
= *(int *)arg
;
794 mp_msg(MSGT_TV
, MSGL_V
, "%s: set width: %d\n", info
.short_name
,
796 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
797 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set width failed: %s\n",
798 info
.short_name
, strerror(errno
));
799 return TVI_CONTROL_FALSE
;
801 return TVI_CONTROL_TRUE
;
802 case TVI_CONTROL_VID_GET_HEIGHT
:
803 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
804 *(int *)arg
= priv
->format
.fmt
.pix
.height
;
805 mp_msg(MSGT_TV
, MSGL_V
, "%s: get height: %d\n", info
.short_name
,
807 return TVI_CONTROL_TRUE
;
808 case TVI_CONTROL_VID_CHK_HEIGHT
:
809 return TVI_CONTROL_TRUE
;
810 case TVI_CONTROL_VID_SET_HEIGHT
:
811 if (getfmt(priv
) < 0) return TVI_CONTROL_FALSE
;
812 priv
->format
.fmt
.pix
.height
= *(int *)arg
;
813 priv
->format
.fmt
.pix
.field
= V4L2_FIELD_ANY
;
814 mp_msg(MSGT_TV
, MSGL_V
, "%s: set height: %d\n", info
.short_name
,
816 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
817 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set height failed: %s\n",
818 info
.short_name
, strerror(errno
));
819 return TVI_CONTROL_FALSE
;
821 return TVI_CONTROL_TRUE
;
822 case TVI_CONTROL_VID_GET_BRIGHTNESS
:
823 control
.id
= V4L2_CID_BRIGHTNESS
;
824 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
825 *(int *)arg
= control
.value
;
826 return TVI_CONTROL_TRUE
;
828 return TVI_CONTROL_FALSE
;
829 case TVI_CONTROL_VID_SET_BRIGHTNESS
:
830 control
.id
= V4L2_CID_BRIGHTNESS
;
831 control
.value
= *(int *)arg
;
832 return set_control(priv
, &control
, 1);
833 case TVI_CONTROL_VID_GET_HUE
:
834 control
.id
= V4L2_CID_HUE
;
835 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
836 *(int *)arg
= control
.value
;
837 return TVI_CONTROL_TRUE
;
839 return TVI_CONTROL_FALSE
;
840 case TVI_CONTROL_VID_SET_HUE
:
841 control
.id
= V4L2_CID_HUE
;
842 control
.value
= *(int *)arg
;
843 return set_control(priv
, &control
, 1);
844 case TVI_CONTROL_VID_GET_SATURATION
:
845 control
.id
= V4L2_CID_SATURATION
;
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_SATURATION
:
852 control
.id
= V4L2_CID_SATURATION
;
853 control
.value
= *(int *)arg
;
854 return set_control(priv
, &control
, 1);
855 case TVI_CONTROL_VID_GET_GAIN
:
858 control
.id
= V4L2_CID_AUTOGAIN
;
859 if(get_control(priv
,&control
,0)!=TVI_CONTROL_TRUE
)
860 return TVI_CONTROL_FALSE
;
862 if(control
.value
){ //Auto Gain control is enabled
864 return TVI_CONTROL_TRUE
;
867 //Manual Gain control
868 control
.id
= V4L2_CID_GAIN
;
869 if(get_control(priv
,&control
,0)!=TVI_CONTROL_TRUE
)
870 return TVI_CONTROL_FALSE
;
872 *(int*)arg
=control
.value
?control
.value
:1;
874 return TVI_CONTROL_TRUE
;
876 case TVI_CONTROL_VID_SET_GAIN
:
878 //value==0 means automatic gain control
879 int value
=*(int*)arg
;
881 if (value
< 0 || value
>100)
882 return TVI_CONTROL_FALSE
;
884 control
.id
=value
?V4L2_CID_GAIN
:V4L2_CID_AUTOGAIN
;
885 control
.value
=value
?value
:1;
887 return set_control(priv
,&control
,0);
889 case TVI_CONTROL_VID_GET_CONTRAST
:
890 control
.id
= V4L2_CID_CONTRAST
;
891 if (get_control(priv
, &control
, 1) == TVI_CONTROL_TRUE
) {
892 *(int *)arg
= control
.value
;
893 return TVI_CONTROL_TRUE
;
895 return TVI_CONTROL_FALSE
;
896 case TVI_CONTROL_VID_SET_CONTRAST
:
897 control
.id
= V4L2_CID_CONTRAST
;
898 control
.value
= *(int *)arg
;
899 return set_control(priv
, &control
, 1);
900 case TVI_CONTROL_TUN_GET_FREQ
:
902 frequency
.type
= V4L2_TUNER_ANALOG_TV
;
903 if (ioctl(priv
->video_fd
, VIDIOC_G_FREQUENCY
, &frequency
) < 0) {
904 mp_msg(MSGT_TV
,MSGL_ERR
,"%s: ioctl get frequency failed: %s\n",
905 info
.short_name
, strerror(errno
));
906 return TVI_CONTROL_FALSE
;
908 *(int *)arg
= frequency
.frequency
;
909 return TVI_CONTROL_TRUE
;
910 case TVI_CONTROL_TUN_SET_FREQ
:
913 usleep(100000); // wait to suppress noise during switching
916 frequency
.type
= V4L2_TUNER_ANALOG_TV
;
917 frequency
.frequency
= *(int *)arg
;
918 if (ioctl(priv
->video_fd
, VIDIOC_S_FREQUENCY
, &frequency
) < 0) {
919 mp_msg(MSGT_TV
,MSGL_ERR
,"%s: ioctl set frequency failed: %s\n",
920 info
.short_name
, strerror(errno
));
921 return TVI_CONTROL_FALSE
;
924 usleep(100000); // wait to suppress noise during switching
927 return TVI_CONTROL_TRUE
;
928 case TVI_CONTROL_TUN_GET_TUNER
:
929 mp_msg(MSGT_TV
, MSGL_V
, "%s: get tuner\n",info
.short_name
);
930 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) < 0) {
931 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get tuner failed: %s\n",
932 info
.short_name
, strerror(errno
));
933 return TVI_CONTROL_FALSE
;
935 return TVI_CONTROL_TRUE
;
936 case TVI_CONTROL_TUN_SET_TUNER
:
937 mp_msg(MSGT_TV
, MSGL_V
, "%s: set tuner\n",info
.short_name
);
938 if (ioctl(priv
->video_fd
, VIDIOC_S_TUNER
, &priv
->tuner
) < 0) {
939 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set tuner failed: %s\n",
940 info
.short_name
, strerror(errno
));
941 return TVI_CONTROL_FALSE
;
943 return TVI_CONTROL_TRUE
;
944 case TVI_CONTROL_TUN_GET_NORM
:
945 *(int *)arg
= priv
->standard
.index
;
946 return TVI_CONTROL_TRUE
;
947 case TVI_CONTROL_TUN_GET_SIGNAL
:
948 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) < 0) {
949 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get tuner failed: %s\n",
950 info
.short_name
, strerror(errno
));
951 return TVI_CONTROL_FALSE
;
953 *(int*)arg
=100*(priv
->tuner
.signal
>>8)/255;
954 return TVI_CONTROL_TRUE
;
955 case TVI_CONTROL_TUN_SET_NORM
:
956 priv
->standard
.index
= *(int *)arg
;
957 if (ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &priv
->standard
) < 0) {
958 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl enum norm failed: %s\n",
959 info
.short_name
, strerror(errno
));
960 return TVI_CONTROL_FALSE
;
962 mp_msg(MSGT_TV
, MSGL_V
, "%s: set norm: %s\n", info
.short_name
, priv
->standard
.name
);
963 if (ioctl(priv
->video_fd
, VIDIOC_S_STD
, &priv
->standard
.id
) < 0) {
964 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set norm failed: %s\n",
965 info
.short_name
, strerror(errno
));
966 return TVI_CONTROL_FALSE
;
968 return TVI_CONTROL_TRUE
;
969 case TVI_CONTROL_SPC_GET_NORMID
:
973 struct v4l2_standard standard
;
974 memset(&standard
, 0, sizeof(standard
));
976 if (-1 == ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &standard
))
977 return TVI_CONTROL_FALSE
;
978 if (!strcasecmp(standard
.name
, (char *)arg
)) {
980 return TVI_CONTROL_TRUE
;
983 return TVI_CONTROL_FALSE
;
985 case TVI_CONTROL_SPC_GET_INPUT
:
986 if (ioctl(priv
->video_fd
, VIDIOC_G_INPUT
, (int *)arg
) < 0) {
987 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get input failed: %s\n",
988 info
.short_name
, strerror(errno
));
989 return TVI_CONTROL_FALSE
;
991 return TVI_CONTROL_TRUE
;
992 case TVI_CONTROL_SPC_SET_INPUT
:
993 mp_msg(MSGT_TV
, MSGL_V
, "%s: set input: %d\n", info
.short_name
, *(int *)arg
);
994 priv
->input
.index
= *(int *)arg
;
995 if (ioctl(priv
->video_fd
, VIDIOC_ENUMINPUT
, &priv
->input
) < 0) {
996 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl enum input failed: %s\n",
997 info
.short_name
, strerror(errno
));
998 return TVI_CONTROL_FALSE
;
1000 if (ioctl(priv
->video_fd
, VIDIOC_S_INPUT
, (int *)arg
) < 0) {
1001 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set input failed: %s\n",
1002 info
.short_name
, strerror(errno
));
1003 return TVI_CONTROL_FALSE
;
1005 return TVI_CONTROL_TRUE
;
1006 case TVI_CONTROL_AUD_GET_FORMAT
:
1008 if (!priv
->audio_initialized
) return TVI_CONTROL_FALSE
;
1009 *(int *)arg
= AF_FORMAT_S16_LE
;
1010 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio format: %d\n",
1011 info
.short_name
, *(int *)arg
);
1012 return TVI_CONTROL_TRUE
;
1013 case TVI_CONTROL_AUD_GET_SAMPLERATE
:
1015 if (!priv
->audio_initialized
) return TVI_CONTROL_FALSE
;
1016 *(int *)arg
= priv
->audio_in
.samplerate
;
1017 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio samplerate: %d\n",
1018 info
.short_name
, *(int *)arg
);
1019 return TVI_CONTROL_TRUE
;
1020 case TVI_CONTROL_AUD_GET_SAMPLESIZE
:
1022 if (!priv
->audio_initialized
) return TVI_CONTROL_FALSE
;
1023 *(int *)arg
= priv
->audio_in
.bytes_per_sample
;
1024 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio samplesize: %d\n",
1025 info
.short_name
, *(int *)arg
);
1026 return TVI_CONTROL_TRUE
;
1027 case TVI_CONTROL_AUD_GET_CHANNELS
:
1029 if (!priv
->audio_initialized
) return TVI_CONTROL_FALSE
;
1030 *(int *)arg
= priv
->audio_in
.channels
;
1031 mp_msg(MSGT_TV
, MSGL_V
, "%s: get audio channels: %d\n",
1032 info
.short_name
, *(int *)arg
);
1033 return TVI_CONTROL_TRUE
;
1034 case TVI_CONTROL_AUD_SET_SAMPLERATE
:
1036 mp_msg(MSGT_TV
, MSGL_V
, "%s: set audio samplerate: %d\n",
1037 info
.short_name
, *(int *)arg
);
1038 if (audio_in_set_samplerate(&priv
->audio_in
, *(int*)arg
) < 0) return TVI_CONTROL_FALSE
;
1039 // setup_audio_buffer_sizes(priv);
1040 return TVI_CONTROL_TRUE
;
1041 #ifdef CONFIG_TV_TELETEXT
1042 case TVI_CONTROL_VBI_INIT
:
1045 tt_stream_props tsp
;
1047 if (vbi_init(priv
,*(char**)arg
)!=TVI_CONTROL_TRUE
)
1048 return TVI_CONTROL_FALSE
;
1049 if(vbi_get_props(priv
,&tsp
)==TVI_CONTROL_TRUE
)
1052 if(teletext_control(NULL
,TV_VBI_CONTROL_START
,&ptr
)==TVI_CONTROL_TRUE
)
1055 priv
->priv_vbi
=NULL
;
1057 return TVI_CONTROL_TRUE
;
1060 return teletext_control(priv
->priv_vbi
,cmd
,arg
);
1063 mp_msg(MSGT_TV
, MSGL_V
, "%s: unknown control: %d\n", info
.short_name
, cmd
);
1064 return TVI_CONTROL_UNKNOWN
;
1068 #define PRIV ((priv_t *) (tvi_handle->priv))
1070 /* handler creator - entry point ! */
1071 static tvi_handle_t
*tvi_init_v4l2(tv_param_t
* tv_param
)
1073 tvi_handle_t
*tvi_handle
;
1075 /* new_handle initializes priv with memset 0 */
1076 tvi_handle
= new_handle();
1080 PRIV
->video_fd
= -1;
1082 PRIV
->video_dev
= strdup(tv_param
->device
? tv_param
->device
: "/dev/video0");
1083 if (!PRIV
->video_dev
) {
1084 free_handle(tvi_handle
);
1088 if (tv_param
->adevice
) {
1089 PRIV
->audio_dev
= strdup(tv_param
->adevice
);
1090 if (!PRIV
->audio_dev
) {
1091 free(PRIV
->video_dev
);
1092 free_handle(tvi_handle
);
1097 PRIV
->tv_param
=tv_param
;
1104 static int uninit(priv_t
*priv
)
1106 int i
, frames
, dropped
= 0;
1108 #ifdef CONFIG_TV_TELETEXT
1109 priv
->vbi_shutdown
=1;
1110 if(priv
->vbi_grabber_thread
)
1111 pthread_join(priv
->vbi_grabber_thread
, NULL
);
1113 teletext_control(priv
->priv_vbi
,TV_VBI_CONTROL_STOP
,(void*)1);
1114 priv
->priv_vbi
=NULL
;
1117 close(priv
->vbi_fd
);
1122 free(priv
->vbi_dev
);
1129 if(priv
->video_grabber_thread
)
1130 pthread_join(priv
->video_grabber_thread
, NULL
);
1131 pthread_mutex_destroy(&priv
->video_buffer_mutex
);
1133 if (priv
->streamon
) {
1134 struct v4l2_buffer buf
;
1136 /* get performance */
1137 frames
= 1 + lrintf((double)(priv
->curr_frame
- priv
->first_frame
) / 1e6
* getfps(priv
));
1138 dropped
= frames
- priv
->frames
;
1140 /* turn off streaming */
1141 if (ioctl(priv
->video_fd
, VIDIOC_STREAMOFF
, &(priv
->map
[0].buf
.type
)) < 0) {
1142 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl streamoff failed: %s\n",
1143 info
.short_name
, strerror(errno
));
1147 /* unqueue all remaining buffers */
1148 memset(&buf
,0,sizeof(buf
));
1149 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1150 buf
.memory
= V4L2_MEMORY_MMAP
;
1151 while (!ioctl(priv
->video_fd
, VIDIOC_DQBUF
, &buf
));
1154 /* unmap all buffers */
1155 for (i
= 0; i
< priv
->mapcount
; i
++) {
1156 if (munmap(priv
->map
[i
].addr
, priv
->map
[i
].len
) < 0) {
1157 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: munmap capture buffer failed: %s\n",
1158 info
.short_name
, strerror(errno
));
1162 /* stop audio thread */
1163 if (!priv
->tv_param
->noaudio
&& priv
->audio_grabber_thread
) {
1164 pthread_join(priv
->audio_grabber_thread
, NULL
);
1165 pthread_mutex_destroy(&priv
->skew_mutex
);
1166 pthread_mutex_destroy(&priv
->audio_mutex
);
1171 /* free memory and close device */
1172 free(priv
->map
); priv
->map
= NULL
;
1174 if(priv
->video_fd
!=-1)close(priv
->video_fd
); priv
->video_fd
= -1;
1175 free(priv
->video_dev
); priv
->video_dev
= NULL
;
1177 if (priv
->video_ringbuffer
) {
1179 for (i
= 0; i
< priv
->video_buffer_size_current
; i
++) {
1180 free(priv
->video_ringbuffer
[i
].data
);
1182 free(priv
->video_ringbuffer
);
1184 if (!priv
->tv_param
->noaudio
) {
1185 if (priv
->audio_ringbuffer
)
1186 free(priv
->audio_ringbuffer
);
1187 if (priv
->audio_skew_buffer
)
1188 free(priv
->audio_skew_buffer
);
1189 if (priv
->audio_skew_delta_buffer
)
1190 free(priv
->audio_skew_delta_buffer
);
1192 audio_in_uninit(&priv
->audio_in
);
1195 /* show some nice statistics ;-) */
1196 mp_msg(MSGT_TV
, MSGL_INFO
,
1197 "%s: %d frames successfully processed, %d frames dropped.\n",
1198 info
.short_name
, priv
->frames
, dropped
);
1199 mp_msg(MSGT_TV
, MSGL_V
, "%s: up to %u video frames buffered.\n",
1200 info
.short_name
, priv
->video_buffer_size_current
);
1205 /* initialisation */
1206 static int init(priv_t
*priv
)
1210 priv
->audio_ringbuffer
= NULL
;
1211 priv
->audio_skew_buffer
= NULL
;
1212 priv
->audio_skew_delta_buffer
= NULL
;
1214 priv
->audio_initialized
= 0;
1216 /* Open the video device. */
1217 priv
->video_fd
= open(priv
->video_dev
, O_RDWR
);
1218 if (priv
->video_fd
< 0) {
1219 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: unable to open '%s': %s\n",
1220 info
.short_name
, priv
->video_dev
, strerror(errno
));
1224 mp_msg(MSGT_TV
, MSGL_DBG2
, "%s: video fd: %s: %d\n",
1225 info
.short_name
, priv
->video_dev
, priv
->video_fd
);
1228 ** Query the video capabilities and current settings
1229 ** for further control calls.
1231 if (ioctl(priv
->video_fd
, VIDIOC_QUERYCAP
, &priv
->capability
) < 0) {
1232 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query capabilities failed: %s\n",
1233 info
.short_name
, strerror(errno
));
1238 if (!(priv
->capability
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
))
1240 mp_msg(MSGT_TV
, MSGL_ERR
, "Device %s is not a video capture device.\n",
1245 if (getfmt(priv
) < 0) {
1251 ** if this device has got a tuner query it's settings
1252 ** otherwise set some nice defaults
1254 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
1255 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) < 0) {
1256 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get tuner failed: %s\n",
1257 info
.short_name
, strerror(errno
));
1262 mp_msg(MSGT_TV
, MSGL_INFO
, "Selected device: %s\n", priv
->capability
.card
);
1263 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
1264 mp_msg(MSGT_TV
, MSGL_INFO
, " Tuner cap:%s%s%s\n",
1265 (priv
->tuner
.capability
& V4L2_TUNER_CAP_STEREO
) ? " STEREO" : "",
1266 (priv
->tuner
.capability
& V4L2_TUNER_CAP_LANG1
) ? " LANG1" : "",
1267 (priv
->tuner
.capability
& V4L2_TUNER_CAP_LANG2
) ? " LANG2" : "");
1268 mp_msg(MSGT_TV
, MSGL_INFO
, " Tuner rxs:%s%s%s%s\n",
1269 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_MONO
) ? " MONO" : "",
1270 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_STEREO
) ? " STEREO" : "",
1271 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_LANG1
) ? " LANG1" : "",
1272 (priv
->tuner
.rxsubchans
& V4L2_TUNER_SUB_LANG2
) ? " LANG2" : "");
1274 mp_msg(MSGT_TV
, MSGL_INFO
, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1275 priv
->capability
.capabilities
& V4L2_CAP_VIDEO_CAPTURE
?
1276 " video capture": "",
1277 priv
->capability
.capabilities
& V4L2_CAP_VIDEO_OUTPUT
?
1278 " video output": "",
1279 priv
->capability
.capabilities
& V4L2_CAP_VIDEO_OVERLAY
?
1280 " video overlay": "",
1281 priv
->capability
.capabilities
& V4L2_CAP_VBI_CAPTURE
?
1282 " VBI capture device": "",
1283 priv
->capability
.capabilities
& V4L2_CAP_VBI_OUTPUT
?
1285 priv
->capability
.capabilities
& V4L2_CAP_RDS_CAPTURE
?
1286 " RDS data capture": "",
1287 priv
->capability
.capabilities
& V4L2_CAP_TUNER
?
1289 priv
->capability
.capabilities
& V4L2_CAP_AUDIO
?
1291 priv
->capability
.capabilities
& V4L2_CAP_READWRITE
?
1293 priv
->capability
.capabilities
& V4L2_CAP_ASYNCIO
?
1295 priv
->capability
.capabilities
& V4L2_CAP_STREAMING
?
1297 mp_msg(MSGT_TV
, MSGL_INFO
, " supported norms:");
1299 struct v4l2_standard standard
;
1300 memset(&standard
, 0, sizeof(standard
));
1302 if (-1 == ioctl(priv
->video_fd
, VIDIOC_ENUMSTD
, &standard
))
1304 mp_msg(MSGT_TV
, MSGL_INFO
, " %d = %s;", i
, standard
.name
);
1306 mp_msg(MSGT_TV
, MSGL_INFO
, "\n inputs:");
1307 for (i
= 0; 1; i
++) {
1308 struct v4l2_input input
;
1311 if (ioctl(priv
->video_fd
, VIDIOC_ENUMINPUT
, &input
) < 0) {
1314 mp_msg(MSGT_TV
, MSGL_INFO
, " %d = %s;", i
, input
.name
);
1317 if (ioctl(priv
->video_fd
, VIDIOC_G_INPUT
, &i
) < 0) {
1318 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get input failed: %s\n",
1319 info
.short_name
, strerror(errno
));
1321 mp_msg(MSGT_TV
, MSGL_INFO
, "\n Current input: %d\n", i
);
1322 for (i
= 0; ; i
++) {
1323 struct v4l2_fmtdesc fmtdesc
;
1326 fmtdesc
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1327 if (ioctl(priv
->video_fd
, VIDIOC_ENUM_FMT
, &fmtdesc
) < 0) {
1330 mp_msg(MSGT_TV
, MSGL_V
, " Format %-6s (%2d bits, %s): %s\n",
1331 pixfmt2name(fmtdesc
.pixelformat
), pixfmt2depth(fmtdesc
.pixelformat
),
1332 fmtdesc
.description
, vo_format_name(fcc_vl2mp(fmtdesc
.pixelformat
)));
1334 mp_msg(MSGT_TV
, MSGL_INFO
, " Current format: %s\n",
1335 pixfmt2name(priv
->format
.fmt
.pix
.pixelformat
));
1337 /* set some nice defaults */
1338 if (getfmt(priv
) < 0) return 0;
1339 priv
->format
.fmt
.pix
.width
= 640;
1340 priv
->format
.fmt
.pix
.height
= 480;
1341 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
1342 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set format failed: %s\n",
1343 info
.short_name
, strerror(errno
));
1348 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;
1350 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
1351 struct v4l2_control control
;
1352 if (priv
->tv_param
->amode
>= 0) {
1353 mp_msg(MSGT_TV
, MSGL_V
, "%s: setting audio mode\n", info
.short_name
);
1354 priv
->tuner
.audmode
= amode2v4l(priv
->tv_param
->amode
);
1355 if (ioctl(priv
->video_fd
, VIDIOC_S_TUNER
, &priv
->tuner
) < 0) {
1356 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set tuner failed: %s\n",
1357 info
.short_name
, strerror(errno
));
1358 return TVI_CONTROL_FALSE
;
1361 mp_msg(MSGT_TV
, MSGL_INFO
, "%s: current audio mode is :%s%s%s%s\n", info
.short_name
,
1362 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_MONO
) ? " MONO" : "",
1363 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_STEREO
) ? " STEREO" : "",
1364 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_LANG1
) ? " LANG1" : "",
1365 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_LANG2
) ? " LANG2" : "");
1367 if (priv
->tv_param
->volume
>= 0) {
1368 control
.id
= V4L2_CID_AUDIO_VOLUME
;
1369 control
.value
= priv
->tv_param
->volume
;
1370 set_control(priv
, &control
, 0);
1372 if (priv
->tv_param
->bass
>= 0) {
1373 control
.id
= V4L2_CID_AUDIO_BASS
;
1374 control
.value
= priv
->tv_param
->bass
;
1375 set_control(priv
, &control
, 0);
1377 if (priv
->tv_param
->treble
>= 0) {
1378 control
.id
= V4L2_CID_AUDIO_TREBLE
;
1379 control
.value
= priv
->tv_param
->treble
;
1380 set_control(priv
, &control
, 0);
1382 if (priv
->tv_param
->balance
>= 0) {
1383 control
.id
= V4L2_CID_AUDIO_BALANCE
;
1384 control
.value
= priv
->tv_param
->balance
;
1385 set_control(priv
, &control
, 0);
1392 static int get_capture_buffer_size(priv_t
*priv
)
1396 if (priv
->tv_param
->buffer_size
>= 0) {
1397 bufsize
= priv
->tv_param
->buffer_size
*1024*1024;
1399 #ifdef HAVE_SYS_SYSINFO_H
1403 if (si
.totalram
<2*1024*1024) {
1404 bufsize
= 1024*1024;
1406 bufsize
= si
.totalram
/2;
1409 bufsize
= 16*1024*1024;
1413 cnt
= bufsize
/priv
->format
.fmt
.pix
.sizeimage
;
1414 if (cnt
< 2) cnt
= 2;
1419 /* that's the real start, we'got the format parameters (checked with control) */
1420 static int start(priv_t
*priv
)
1422 struct v4l2_requestbuffers request
;
1425 /* setup audio parameters */
1428 if (!priv
->tv_param
->noaudio
&& !priv
->audio_initialized
) return 0;
1430 /* we need this to size the audio buffer properly */
1431 if (priv
->immediate_mode
) {
1432 priv
->video_buffer_size_max
= 2;
1434 priv
->video_buffer_size_max
= get_capture_buffer_size(priv
);
1437 if (!priv
->tv_param
->noaudio
) {
1438 setup_audio_buffer_sizes(priv
);
1439 priv
->audio_skew_buffer
= calloc(priv
->aud_skew_cnt
, sizeof(long long));
1440 if (!priv
->audio_skew_buffer
) {
1441 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate skew buffer: %s\n", strerror(errno
));
1444 priv
->audio_skew_delta_buffer
= calloc(priv
->aud_skew_cnt
, sizeof(long long));
1445 if (!priv
->audio_skew_delta_buffer
) {
1446 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate skew buffer: %s\n", strerror(errno
));
1450 priv
->audio_ringbuffer
= calloc(priv
->audio_in
.blocksize
, priv
->audio_buffer_size
);
1451 if (!priv
->audio_ringbuffer
) {
1452 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate audio buffer: %s\n", strerror(errno
));
1456 priv
->audio_secs_per_block
= (double)priv
->audio_in
.blocksize
/(priv
->audio_in
.samplerate
1457 *priv
->audio_in
.channels
1458 *priv
->audio_in
.bytes_per_sample
);
1459 priv
->audio_usecs_per_block
= 1e6
*priv
->audio_secs_per_block
;
1460 priv
->audio_head
= 0;
1461 priv
->audio_tail
= 0;
1462 priv
->audio_cnt
= 0;
1463 priv
->audio_drop
= 0;
1464 priv
->audio_skew
= 0;
1465 priv
->audio_skew_total
= 0;
1466 priv
->audio_skew_delta_total
= 0;
1467 priv
->audio_recv_blocks_total
= 0;
1468 priv
->audio_sent_blocks_total
= 0;
1469 priv
->audio_null_blocks_inserted
= 0;
1470 priv
->audio_insert_null_samples
= 0;
1471 priv
->dropped_frames_timeshift
= 0;
1472 priv
->dropped_frames_compensated
= 0;
1474 pthread_mutex_init(&priv
->skew_mutex
, NULL
);
1475 pthread_mutex_init(&priv
->audio_mutex
, NULL
);
1478 /* setup video parameters */
1479 if (!priv
->tv_param
->noaudio
) {
1480 if (priv
->video_buffer_size_max
< (3*priv
->standard
.frameperiod
.denominator
) /
1481 priv
->standard
.frameperiod
.numerator
1482 *priv
->audio_secs_per_block
) {
1483 mp_msg(MSGT_TV
, MSGL_ERR
, "Video buffer shorter than 3 times audio frame duration.\n"
1484 "You will probably experience heavy framedrops.\n");
1489 int bytesperline
= priv
->format
.fmt
.pix
.width
*pixfmt2depth(priv
->format
.fmt
.pix
.pixelformat
)/8;
1491 mp_msg(MSGT_TV
, MSGL_V
, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1492 priv
->video_buffer_size_max
,
1493 priv
->video_buffer_size_max
*priv
->format
.fmt
.pix
.height
*bytesperline
/(1024*1024));
1496 priv
->video_ringbuffer
= calloc(priv
->video_buffer_size_max
, sizeof(video_buffer_entry
));
1497 if (!priv
->video_ringbuffer
) {
1498 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate video buffer: %s\n", strerror(errno
));
1501 memset(priv
->video_ringbuffer
,0,priv
->video_buffer_size_max
* sizeof(video_buffer_entry
));
1503 pthread_mutex_init(&priv
->video_buffer_mutex
, NULL
);
1505 priv
->video_head
= 0;
1506 priv
->video_tail
= 0;
1507 priv
->video_cnt
= 0;
1509 /* request buffers */
1510 if (priv
->immediate_mode
) {
1513 request
.count
= BUFFER_COUNT
;
1516 request
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1517 request
.memory
= V4L2_MEMORY_MMAP
;
1518 if (ioctl(priv
->video_fd
, VIDIOC_REQBUFS
, &request
) < 0) {
1519 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl request buffers failed: %s\n",
1520 info
.short_name
, strerror(errno
));
1525 if (!(priv
->map
= calloc(request
.count
, sizeof(struct map
)))) {
1526 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: malloc capture buffers failed: %s\n",
1527 info
.short_name
, strerror(errno
));
1531 /* map and queue buffers */
1532 for (i
= 0; i
< request
.count
; i
++) {
1533 memset(&priv
->map
[i
].buf
,0,sizeof(priv
->map
[i
].buf
));
1534 priv
->map
[i
].buf
.index
= i
;
1535 priv
->map
[i
].buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1536 priv
->map
[i
].buf
.memory
= V4L2_MEMORY_MMAP
;
1537 if (ioctl(priv
->video_fd
, VIDIOC_QUERYBUF
, &(priv
->map
[i
].buf
)) < 0) {
1538 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query buffer failed: %s\n",
1539 info
.short_name
, strerror(errno
));
1544 priv
->map
[i
].addr
= mmap (0, priv
->map
[i
].buf
.length
, PROT_READ
|
1545 PROT_WRITE
, MAP_SHARED
, priv
->video_fd
, priv
->map
[i
].buf
.m
.offset
);
1546 if (priv
->map
[i
].addr
== MAP_FAILED
) {
1547 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: mmap capture buffer failed: %s\n",
1548 info
.short_name
, strerror(errno
));
1549 priv
->map
[i
].len
= 0;
1552 priv
->map
[i
].len
= priv
->map
[i
].buf
.length
;
1553 /* count up to make sure this is correct everytime */
1556 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &(priv
->map
[i
].buf
)) < 0) {
1557 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1558 info
.short_name
, strerror(errno
));
1563 #ifdef CONFIG_TV_TELETEXT
1564 /* start vbi thread */
1566 priv
->vbi_shutdown
= 0;
1567 pthread_create(&priv
->vbi_grabber_thread
, NULL
, vbi_grabber
, priv
);
1570 /* start audio thread */
1572 priv
->audio_skew_measure_time
= 0;
1573 priv
->first_frame
= 0;
1574 priv
->audio_skew
= 0;
1582 // copies a video frame
1583 static inline void copy_frame(priv_t
*priv
, video_buffer_entry
*dest
, unsigned char *source
,int len
)
1585 dest
->framesize
=len
;
1586 if(priv
->tv_param
->automute
>0){
1587 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) >= 0) {
1588 if(priv
->tv_param
->automute
<<8>priv
->tuner
.signal
){
1589 fill_blank_frame(dest
->data
,dest
->framesize
,fcc_vl2mp(priv
->format
.fmt
.pix
.pixelformat
));
1596 memcpy(dest
->data
, source
, len
);
1599 // maximum skew change, in frames
1600 #define MAX_SKEW_DELTA 0.6
1601 static void *video_grabber(void *data
)
1603 priv_t
*priv
= (priv_t
*)data
;
1604 long long skew
, prev_skew
, xskew
, interval
, prev_interval
, delta
;
1606 int framesize
= priv
->format
.fmt
.pix
.sizeimage
;
1608 struct timeval timeout
;
1609 struct v4l2_buffer buf
;
1617 mp_msg(MSGT_TV
, MSGL_V
, "%s: going to capture\n", info
.short_name
);
1618 if (ioctl(priv
->video_fd
, VIDIOC_STREAMON
, &(priv
->format
.type
)) < 0) {
1619 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl streamon failed: %s\n",
1620 info
.short_name
, strerror(errno
));
1625 if (!priv
->tv_param
->noaudio
) {
1626 pthread_create(&priv
->audio_grabber_thread
, NULL
, audio_grabber
, priv
);
1629 for (priv
->frames
= 0; !priv
->shutdown
;)
1633 if (priv
->immediate_mode
) {
1634 while (priv
->video_cnt
== priv
->video_buffer_size_max
) {
1636 if (priv
->shutdown
) {
1643 FD_SET (priv
->video_fd
, &rdset
);
1646 timeout
.tv_usec
= 0;
1648 i
= select(priv
->video_fd
+ 1, &rdset
, NULL
, NULL
, &timeout
);
1650 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: select failed: %s\n",
1651 info
.short_name
, strerror(errno
));
1655 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: select timeout\n", info
.short_name
);
1658 else if (!FD_ISSET(priv
->video_fd
, &rdset
)) {
1662 memset(&buf
,0,sizeof(buf
));
1663 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1664 buf
.memory
= V4L2_MEMORY_MMAP
;
1665 ret
= ioctl(priv
->video_fd
, VIDIOC_DQBUF
, &buf
);
1669 if there's no signal, the buffer might me dequeued
1670 so we query all the buffers to see which one we should
1673 observed with saa7134 0.2.8
1674 don't know if is it a bug or (mis)feature
1676 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1677 info
.short_name
, strerror(errno
), buf
.index
);
1678 for (i
= 0; i
< priv
->mapcount
; i
++) {
1679 memset(&buf
,0,sizeof(buf
));
1680 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1681 buf
.memory
= V4L2_MEMORY_MMAP
;
1683 ret
= ioctl(priv
->video_fd
, VIDIOC_QUERYBUF
, &buf
);
1685 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query buffer failed: %s, idx = %d\n",
1686 info
.short_name
, strerror(errno
), buf
.index
);
1689 if ((buf
.flags
& (V4L2_BUF_FLAG_QUEUED
| V4L2_BUF_FLAG_MAPPED
| V4L2_BUF_FLAG_DONE
)) == V4L2_BUF_FLAG_MAPPED
) {
1690 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &(priv
->map
[i
].buf
)) < 0) {
1691 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1692 info
.short_name
, strerror(errno
));
1700 /* store the timestamp of the very first frame as reference */
1701 if (!priv
->frames
++) {
1702 if (!priv
->tv_param
->noaudio
) pthread_mutex_lock(&priv
->skew_mutex
);
1703 priv
->first_frame
= (long long)1e6
*buf
.timestamp
.tv_sec
+ buf
.timestamp
.tv_usec
;
1704 if (!priv
->tv_param
->noaudio
) pthread_mutex_unlock(&priv
->skew_mutex
);
1706 priv
->curr_frame
= (long long)buf
.timestamp
.tv_sec
*1e6
+buf
.timestamp
.tv_usec
;
1707 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1709 interval
= priv
->curr_frame
- priv
->first_frame
;
1710 delta
= interval
- prev_interval
;
1712 if (!priv
->immediate_mode
) {
1713 // interpolate the skew in time
1714 if (!priv
->tv_param
->noaudio
) pthread_mutex_lock(&priv
->skew_mutex
);
1715 xskew
= priv
->audio_skew
+ (interval
- priv
->audio_skew_measure_time
)*priv
->audio_skew_factor
;
1716 if (!priv
->tv_param
->noaudio
) pthread_mutex_unlock(&priv
->skew_mutex
);
1717 // correct extreme skew changes to avoid (especially) moving backwards in time
1718 if (xskew
- prev_skew
> delta
*MAX_SKEW_DELTA
) {
1719 skew
= prev_skew
+ delta
*MAX_SKEW_DELTA
;
1720 } else if (xskew
- prev_skew
< -delta
*MAX_SKEW_DELTA
) {
1721 skew
= prev_skew
- delta
*MAX_SKEW_DELTA
;
1727 mp_msg(MSGT_TV
, MSGL_DBG3
, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1728 delta
? (double)1e6
/delta
: -1,
1729 (double)1e-6*interval
, (double)1e-6*xskew
, (double)1e-6*skew
);
1730 mp_msg(MSGT_TV
, MSGL_DBG3
, "vcnt = %d, acnt = %d\n", priv
->video_cnt
, priv
->audio_cnt
);
1733 prev_interval
= interval
;
1735 /* allocate a new buffer, if needed */
1736 pthread_mutex_lock(&priv
->video_buffer_mutex
);
1737 if (priv
->video_buffer_size_current
< priv
->video_buffer_size_max
) {
1738 if (priv
->video_cnt
== priv
->video_buffer_size_current
) {
1739 unsigned char *newbuf
= malloc(framesize
);
1741 memmove(priv
->video_ringbuffer
+priv
->video_tail
+1, priv
->video_ringbuffer
+priv
->video_tail
,
1742 (priv
->video_buffer_size_current
-priv
->video_tail
)*sizeof(video_buffer_entry
));
1743 priv
->video_ringbuffer
[priv
->video_tail
].data
= newbuf
;
1744 if ((priv
->video_head
>= priv
->video_tail
) && (priv
->video_cnt
> 0)) priv
->video_head
++;
1745 priv
->video_buffer_size_current
++;
1749 pthread_mutex_unlock(&priv
->video_buffer_mutex
);
1751 if (priv
->video_cnt
== priv
->video_buffer_size_current
) {
1752 if (!priv
->immediate_mode
) {
1753 mp_msg(MSGT_TV
, MSGL_ERR
, "\nvideo buffer full - dropping frame\n");
1754 if (priv
->audio_insert_null_samples
) {
1755 pthread_mutex_lock(&priv
->audio_mutex
);
1756 priv
->dropped_frames_timeshift
+= delta
;
1757 pthread_mutex_unlock(&priv
->audio_mutex
);
1761 if (priv
->immediate_mode
) {
1762 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
= 0;
1764 // compensate for audio skew
1765 // negative skew => there are more audio samples, increase interval
1766 // positive skew => less samples, shorten the interval
1767 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
= interval
- skew
;
1768 if (priv
->audio_insert_null_samples
&& priv
->video_ringbuffer
[priv
->video_tail
].timestamp
> 0) {
1769 pthread_mutex_lock(&priv
->audio_mutex
);
1770 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
+=
1771 (priv
->audio_null_blocks_inserted
1772 - priv
->dropped_frames_timeshift
/priv
->audio_usecs_per_block
)
1773 *priv
->audio_usecs_per_block
;
1774 pthread_mutex_unlock(&priv
->audio_mutex
);
1777 copy_frame(priv
, priv
->video_ringbuffer
+priv
->video_tail
, priv
->map
[buf
.index
].addr
,buf
.bytesused
);
1778 priv
->video_tail
= (priv
->video_tail
+1)%priv
->video_buffer_size_current
;
1781 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &buf
) < 0) {
1782 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1783 info
.short_name
, strerror(errno
));
1791 static double grab_video_frame(priv_t
*priv
, char *buffer
, int len
)
1797 pthread_create(&priv
->video_grabber_thread
, NULL
, video_grabber
, priv
);
1801 while (priv
->video_cnt
== 0) {
1803 if (loop_cnt
++ > MAX_LOOP
) return 0;
1806 pthread_mutex_lock(&priv
->video_buffer_mutex
);
1807 interval
= (double)priv
->video_ringbuffer
[priv
->video_head
].timestamp
*1e-6;
1808 memcpy(buffer
, priv
->video_ringbuffer
[priv
->video_head
].data
, len
);
1810 priv
->video_head
= (priv
->video_head
+1)%priv
->video_buffer_size_current
;
1811 pthread_mutex_unlock(&priv
->video_buffer_mutex
);
1816 static int get_video_framesize(priv_t
*priv
)
1819 this routine will be called before grab_video_frame
1820 thus let's return topmost frame's size
1822 if (priv
->video_cnt
)
1823 return priv
->video_ringbuffer
[priv
->video_head
].framesize
;
1825 no video frames yet available. i don't know what to do in this case,
1826 thus let's return some fallback result (for compressed format this will be
1827 maximum allowed frame size.
1829 return priv
->format
.fmt
.pix
.sizeimage
;
1832 //#define DOUBLESPEED
1834 // for testing purposes only
1835 static void read_doublespeed(priv_t
*priv
)
1837 char *bufx
= calloc(priv
->audio_in
.blocksize
, 2);
1842 audio_in_read_chunk(&priv
->audio_in
, bufx
);
1843 audio_in_read_chunk(&priv
->audio_in
, bufx
+priv
->audio_in
.blocksize
);
1846 d
= priv
->audio_ringbuffer
+priv
->audio_tail
*priv
->audio_in
.blocksize
;
1847 for (i
= 0; i
< priv
->audio_in
.blocksize
/2; i
++) {
1855 static void *audio_grabber(void *data
)
1857 priv_t
*priv
= (priv_t
*)data
;
1859 int i
, audio_skew_ptr
= 0;
1860 long long current_time
, prev_skew
= 0, prev_skew_uncorr
= 0;
1861 long long start_time_avg
;
1863 gettimeofday(&tv
, NULL
);
1864 start_time_avg
= priv
->audio_start_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
;
1865 audio_in_start_capture(&priv
->audio_in
);
1866 for (i
= 0; i
< priv
->aud_skew_cnt
; i
++)
1867 priv
->audio_skew_buffer
[i
] = 0;
1868 for (i
= 0; i
< priv
->aud_skew_cnt
; i
++)
1869 priv
->audio_skew_delta_buffer
[i
] = 0;
1871 for (; !priv
->shutdown
;)
1874 read_doublespeed(priv
);
1876 if (audio_in_read_chunk(&priv
->audio_in
, priv
->audio_ringbuffer
+priv
->audio_tail
*priv
->audio_in
.blocksize
) < 0)
1879 pthread_mutex_lock(&priv
->skew_mutex
);
1880 if (priv
->first_frame
== 0) {
1881 // there is no first frame yet (unlikely to happen)
1882 gettimeofday(&tv
, NULL
);
1883 start_time_avg
= priv
->audio_start_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
;
1884 // fprintf(stderr, "warning - first frame not yet available!\n");
1885 pthread_mutex_unlock(&priv
->skew_mutex
);
1888 pthread_mutex_unlock(&priv
->skew_mutex
);
1890 gettimeofday(&tv
, NULL
);
1892 priv
->audio_recv_blocks_total
++;
1893 current_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
- priv
->audio_start_time
;
1895 if (priv
->audio_recv_blocks_total
< priv
->aud_skew_cnt
*2) {
1896 start_time_avg
+= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
- priv
->audio_usecs_per_block
*priv
->audio_recv_blocks_total
;
1897 priv
->audio_start_time
= start_time_avg
/(priv
->audio_recv_blocks_total
+1);
1900 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1901 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1903 // put the current skew into the ring buffer
1904 priv
->audio_skew_total
-= priv
->audio_skew_buffer
[audio_skew_ptr
];
1905 priv
->audio_skew_buffer
[audio_skew_ptr
] = current_time
1906 - priv
->audio_usecs_per_block
*priv
->audio_recv_blocks_total
;
1907 priv
->audio_skew_total
+= priv
->audio_skew_buffer
[audio_skew_ptr
];
1909 pthread_mutex_lock(&priv
->skew_mutex
);
1913 // compute the sliding average of the skews
1914 if (priv
->audio_recv_blocks_total
> priv
->aud_skew_cnt
) {
1915 priv
->audio_skew
= priv
->audio_skew_total
/priv
->aud_skew_cnt
;
1917 priv
->audio_skew
= priv
->audio_skew_total
/priv
->audio_recv_blocks_total
;
1920 // put the current skew change (skew-prev_skew) into the ring buffer
1921 priv
->audio_skew_delta_total
-= priv
->audio_skew_delta_buffer
[audio_skew_ptr
];
1922 priv
->audio_skew_delta_buffer
[audio_skew_ptr
] = priv
->audio_skew
- prev_skew_uncorr
;
1923 priv
->audio_skew_delta_total
+= priv
->audio_skew_delta_buffer
[audio_skew_ptr
];
1924 prev_skew_uncorr
= priv
->audio_skew
; // remember the _uncorrected_ average value
1926 audio_skew_ptr
= (audio_skew_ptr
+1) % priv
->aud_skew_cnt
; // rotate the buffer pointer
1928 // sliding average approximates the value in the middle of the interval
1929 // so interpolate the skew value further to the current time
1930 priv
->audio_skew
+= priv
->audio_skew_delta_total
/2;
1932 // now finally, priv->audio_skew contains fairly good approximation
1933 // of the current value
1935 // current skew factor (assuming linearity)
1936 // used for further interpolation in video_grabber
1937 // probably overkill but seems to be necessary for
1938 // stress testing by dropping half of the audio frames ;)
1939 // especially when using ALSA with large block sizes
1940 // where audio_skew remains a long while behind
1941 if ((priv
->audio_skew_measure_time
!= 0) && (current_time
- priv
->audio_skew_measure_time
!= 0)) {
1942 priv
->audio_skew_factor
= (double)(priv
->audio_skew
-prev_skew
)/(current_time
- priv
->audio_skew_measure_time
);
1944 priv
->audio_skew_factor
= 0.0;
1947 priv
->audio_skew_measure_time
= current_time
;
1948 prev_skew
= priv
->audio_skew
;
1949 priv
->audio_skew
+= priv
->audio_start_time
- priv
->first_frame
;
1950 pthread_mutex_unlock(&priv
->skew_mutex
);
1952 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1954 pthread_mutex_lock(&priv
->audio_mutex
);
1955 if ((priv
->audio_tail
+1) % priv
->audio_buffer_size
== priv
->audio_head
) {
1956 mp_msg(MSGT_TV
, MSGL_ERR
, "\ntoo bad - dropping audio frame !\n");
1959 priv
->audio_tail
= (priv
->audio_tail
+1) % priv
->audio_buffer_size
;
1962 pthread_mutex_unlock(&priv
->audio_mutex
);
1967 static double grab_audio_frame(priv_t
*priv
, char *buffer
, int len
)
1969 mp_dbg(MSGT_TV
, MSGL_DBG2
, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1972 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1973 // => switch to the mode which outputs audio immediately, even if
1974 // it should be silence
1975 if (priv
->first
) priv
->audio_insert_null_samples
= 1;
1977 pthread_mutex_lock(&priv
->audio_mutex
);
1978 while (priv
->audio_insert_null_samples
1979 && priv
->dropped_frames_timeshift
- priv
->dropped_frames_compensated
>= priv
->audio_usecs_per_block
) {
1980 // some frames were dropped - drop the corresponding number of audio blocks
1981 if (priv
->audio_drop
) {
1984 if (priv
->audio_head
== priv
->audio_tail
) break;
1985 priv
->audio_head
= (priv
->audio_head
+1) % priv
->audio_buffer_size
;
1987 priv
->dropped_frames_compensated
+= priv
->audio_usecs_per_block
;
1990 // compensate for dropped audio frames
1991 if (priv
->audio_drop
&& (priv
->audio_head
== priv
->audio_tail
)) {
1993 memset(buffer
, 0, len
);
1997 if (priv
->audio_insert_null_samples
&& (priv
->audio_head
== priv
->audio_tail
)) {
1998 // return silence to avoid desync and stuttering
1999 memset(buffer
, 0, len
);
2000 priv
->audio_null_blocks_inserted
++;
2004 pthread_mutex_unlock(&priv
->audio_mutex
);
2005 while (priv
->audio_head
== priv
->audio_tail
) {
2006 // this is mencoder => just wait until some audio is available
2009 pthread_mutex_lock(&priv
->audio_mutex
);
2010 memcpy(buffer
, priv
->audio_ringbuffer
+priv
->audio_head
*priv
->audio_in
.blocksize
, len
);
2011 priv
->audio_head
= (priv
->audio_head
+1) % priv
->audio_buffer_size
;
2014 pthread_mutex_unlock(&priv
->audio_mutex
);
2015 priv
->audio_sent_blocks_total
++;
2016 return (double)priv
->audio_sent_blocks_total
*priv
->audio_secs_per_block
;
2019 static int get_audio_framesize(priv_t
*priv
)
2021 return priv
->audio_in
.blocksize
;