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
);
1316 if (ioctl(priv
->video_fd
, VIDIOC_G_INPUT
, &i
) < 0) {
1317 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl get input failed: %s\n",
1318 info
.short_name
, strerror(errno
));
1320 mp_msg(MSGT_TV
, MSGL_INFO
, "\n Current input: %d\n", i
);
1321 for (i
= 0; ; i
++) {
1322 struct v4l2_fmtdesc fmtdesc
;
1325 fmtdesc
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1326 if (ioctl(priv
->video_fd
, VIDIOC_ENUM_FMT
, &fmtdesc
) < 0) {
1329 mp_msg(MSGT_TV
, MSGL_V
, " Format %-6s (%2d bits, %s): %s\n",
1330 pixfmt2name(fmtdesc
.pixelformat
), pixfmt2depth(fmtdesc
.pixelformat
),
1331 fmtdesc
.description
, vo_format_name(fcc_vl2mp(fmtdesc
.pixelformat
)));
1333 mp_msg(MSGT_TV
, MSGL_INFO
, " Current format: %s\n",
1334 pixfmt2name(priv
->format
.fmt
.pix
.pixelformat
));
1336 /* set some nice defaults */
1337 if (getfmt(priv
) < 0) return 0;
1338 priv
->format
.fmt
.pix
.width
= 640;
1339 priv
->format
.fmt
.pix
.height
= 480;
1340 if (ioctl(priv
->video_fd
, VIDIOC_S_FMT
, &priv
->format
) < 0) {
1341 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set format failed: %s\n",
1342 info
.short_name
, strerror(errno
));
1347 // if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !priv->tv_param->force_audio) priv->tv_param->noaudio = 1;
1349 if (priv
->capability
.capabilities
& V4L2_CAP_TUNER
) {
1350 struct v4l2_control control
;
1351 if (priv
->tv_param
->amode
>= 0) {
1352 mp_msg(MSGT_TV
, MSGL_V
, "%s: setting audio mode\n", info
.short_name
);
1353 priv
->tuner
.audmode
= amode2v4l(priv
->tv_param
->amode
);
1354 if (ioctl(priv
->video_fd
, VIDIOC_S_TUNER
, &priv
->tuner
) < 0) {
1355 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl set tuner failed: %s\n",
1356 info
.short_name
, strerror(errno
));
1357 return TVI_CONTROL_FALSE
;
1360 mp_msg(MSGT_TV
, MSGL_INFO
, "%s: current audio mode is :%s%s%s%s\n", info
.short_name
,
1361 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_MONO
) ? " MONO" : "",
1362 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_STEREO
) ? " STEREO" : "",
1363 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_LANG1
) ? " LANG1" : "",
1364 (priv
->tuner
.audmode
== V4L2_TUNER_MODE_LANG2
) ? " LANG2" : "");
1366 if (priv
->tv_param
->volume
>= 0) {
1367 control
.id
= V4L2_CID_AUDIO_VOLUME
;
1368 control
.value
= priv
->tv_param
->volume
;
1369 set_control(priv
, &control
, 0);
1371 if (priv
->tv_param
->bass
>= 0) {
1372 control
.id
= V4L2_CID_AUDIO_BASS
;
1373 control
.value
= priv
->tv_param
->bass
;
1374 set_control(priv
, &control
, 0);
1376 if (priv
->tv_param
->treble
>= 0) {
1377 control
.id
= V4L2_CID_AUDIO_TREBLE
;
1378 control
.value
= priv
->tv_param
->treble
;
1379 set_control(priv
, &control
, 0);
1381 if (priv
->tv_param
->balance
>= 0) {
1382 control
.id
= V4L2_CID_AUDIO_BALANCE
;
1383 control
.value
= priv
->tv_param
->balance
;
1384 set_control(priv
, &control
, 0);
1391 static int get_capture_buffer_size(priv_t
*priv
)
1395 if (priv
->tv_param
->buffer_size
>= 0) {
1396 bufsize
= priv
->tv_param
->buffer_size
*1024*1024;
1398 #ifdef HAVE_SYS_SYSINFO_H
1402 if (si
.totalram
<2*1024*1024) {
1403 bufsize
= 1024*1024;
1405 bufsize
= si
.totalram
/2;
1408 bufsize
= 16*1024*1024;
1412 cnt
= bufsize
/priv
->format
.fmt
.pix
.sizeimage
;
1413 if (cnt
< 2) cnt
= 2;
1418 /* that's the real start, we'got the format parameters (checked with control) */
1419 static int start(priv_t
*priv
)
1421 struct v4l2_requestbuffers request
;
1424 /* setup audio parameters */
1427 if (!priv
->tv_param
->noaudio
&& !priv
->audio_initialized
) return 0;
1429 /* we need this to size the audio buffer properly */
1430 if (priv
->immediate_mode
) {
1431 priv
->video_buffer_size_max
= 2;
1433 priv
->video_buffer_size_max
= get_capture_buffer_size(priv
);
1436 if (!priv
->tv_param
->noaudio
) {
1437 setup_audio_buffer_sizes(priv
);
1438 priv
->audio_skew_buffer
= calloc(priv
->aud_skew_cnt
, sizeof(long long));
1439 if (!priv
->audio_skew_buffer
) {
1440 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate skew buffer: %s\n", strerror(errno
));
1443 priv
->audio_skew_delta_buffer
= calloc(priv
->aud_skew_cnt
, sizeof(long long));
1444 if (!priv
->audio_skew_delta_buffer
) {
1445 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate skew buffer: %s\n", strerror(errno
));
1449 priv
->audio_ringbuffer
= calloc(priv
->audio_in
.blocksize
, priv
->audio_buffer_size
);
1450 if (!priv
->audio_ringbuffer
) {
1451 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate audio buffer: %s\n", strerror(errno
));
1455 priv
->audio_secs_per_block
= (double)priv
->audio_in
.blocksize
/(priv
->audio_in
.samplerate
1456 *priv
->audio_in
.channels
1457 *priv
->audio_in
.bytes_per_sample
);
1458 priv
->audio_usecs_per_block
= 1e6
*priv
->audio_secs_per_block
;
1459 priv
->audio_head
= 0;
1460 priv
->audio_tail
= 0;
1461 priv
->audio_cnt
= 0;
1462 priv
->audio_drop
= 0;
1463 priv
->audio_skew
= 0;
1464 priv
->audio_skew_total
= 0;
1465 priv
->audio_skew_delta_total
= 0;
1466 priv
->audio_recv_blocks_total
= 0;
1467 priv
->audio_sent_blocks_total
= 0;
1468 priv
->audio_null_blocks_inserted
= 0;
1469 priv
->audio_insert_null_samples
= 0;
1470 priv
->dropped_frames_timeshift
= 0;
1471 priv
->dropped_frames_compensated
= 0;
1473 pthread_mutex_init(&priv
->skew_mutex
, NULL
);
1474 pthread_mutex_init(&priv
->audio_mutex
, NULL
);
1477 /* setup video parameters */
1478 if (!priv
->tv_param
->noaudio
) {
1479 if (priv
->video_buffer_size_max
< (3*priv
->standard
.frameperiod
.denominator
) /
1480 priv
->standard
.frameperiod
.numerator
1481 *priv
->audio_secs_per_block
) {
1482 mp_msg(MSGT_TV
, MSGL_ERR
, "Video buffer shorter than 3 times audio frame duration.\n"
1483 "You will probably experience heavy framedrops.\n");
1488 int bytesperline
= priv
->format
.fmt
.pix
.width
*pixfmt2depth(priv
->format
.fmt
.pix
.pixelformat
)/8;
1490 mp_msg(MSGT_TV
, MSGL_V
, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1491 priv
->video_buffer_size_max
,
1492 priv
->video_buffer_size_max
*priv
->format
.fmt
.pix
.height
*bytesperline
/(1024*1024));
1495 priv
->video_ringbuffer
= calloc(priv
->video_buffer_size_max
, sizeof(video_buffer_entry
));
1496 if (!priv
->video_ringbuffer
) {
1497 mp_msg(MSGT_TV
, MSGL_ERR
, "cannot allocate video buffer: %s\n", strerror(errno
));
1500 memset(priv
->video_ringbuffer
,0,priv
->video_buffer_size_max
* sizeof(video_buffer_entry
));
1502 pthread_mutex_init(&priv
->video_buffer_mutex
, NULL
);
1504 priv
->video_head
= 0;
1505 priv
->video_tail
= 0;
1506 priv
->video_cnt
= 0;
1508 /* request buffers */
1509 if (priv
->immediate_mode
) {
1512 request
.count
= BUFFER_COUNT
;
1515 request
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1516 request
.memory
= V4L2_MEMORY_MMAP
;
1517 if (ioctl(priv
->video_fd
, VIDIOC_REQBUFS
, &request
) < 0) {
1518 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl request buffers failed: %s\n",
1519 info
.short_name
, strerror(errno
));
1524 if (!(priv
->map
= calloc(request
.count
, sizeof(struct map
)))) {
1525 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: malloc capture buffers failed: %s\n",
1526 info
.short_name
, strerror(errno
));
1530 /* map and queue buffers */
1531 for (i
= 0; i
< request
.count
; i
++) {
1532 memset(&priv
->map
[i
].buf
,0,sizeof(priv
->map
[i
].buf
));
1533 priv
->map
[i
].buf
.index
= i
;
1534 priv
->map
[i
].buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1535 priv
->map
[i
].buf
.memory
= V4L2_MEMORY_MMAP
;
1536 if (ioctl(priv
->video_fd
, VIDIOC_QUERYBUF
, &(priv
->map
[i
].buf
)) < 0) {
1537 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query buffer failed: %s\n",
1538 info
.short_name
, strerror(errno
));
1543 priv
->map
[i
].addr
= mmap (0, priv
->map
[i
].buf
.length
, PROT_READ
|
1544 PROT_WRITE
, MAP_SHARED
, priv
->video_fd
, priv
->map
[i
].buf
.m
.offset
);
1545 if (priv
->map
[i
].addr
== MAP_FAILED
) {
1546 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: mmap capture buffer failed: %s\n",
1547 info
.short_name
, strerror(errno
));
1548 priv
->map
[i
].len
= 0;
1551 priv
->map
[i
].len
= priv
->map
[i
].buf
.length
;
1552 /* count up to make sure this is correct everytime */
1555 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &(priv
->map
[i
].buf
)) < 0) {
1556 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1557 info
.short_name
, strerror(errno
));
1562 #ifdef CONFIG_TV_TELETEXT
1563 /* start vbi thread */
1565 priv
->vbi_shutdown
= 0;
1566 pthread_create(&priv
->vbi_grabber_thread
, NULL
, vbi_grabber
, priv
);
1569 /* start audio thread */
1571 priv
->audio_skew_measure_time
= 0;
1572 priv
->first_frame
= 0;
1573 priv
->audio_skew
= 0;
1581 // copies a video frame
1582 static inline void copy_frame(priv_t
*priv
, video_buffer_entry
*dest
, unsigned char *source
,int len
)
1584 dest
->framesize
=len
;
1585 if(priv
->tv_param
->automute
>0){
1586 if (ioctl(priv
->video_fd
, VIDIOC_G_TUNER
, &priv
->tuner
) >= 0) {
1587 if(priv
->tv_param
->automute
<<8>priv
->tuner
.signal
){
1588 fill_blank_frame(dest
->data
,dest
->framesize
,fcc_vl2mp(priv
->format
.fmt
.pix
.pixelformat
));
1595 memcpy(dest
->data
, source
, len
);
1598 // maximum skew change, in frames
1599 #define MAX_SKEW_DELTA 0.6
1600 static void *video_grabber(void *data
)
1602 priv_t
*priv
= (priv_t
*)data
;
1603 long long skew
, prev_skew
, xskew
, interval
, prev_interval
, delta
;
1605 int framesize
= priv
->format
.fmt
.pix
.sizeimage
;
1607 struct timeval timeout
;
1608 struct v4l2_buffer buf
;
1616 mp_msg(MSGT_TV
, MSGL_V
, "%s: going to capture\n", info
.short_name
);
1617 if (ioctl(priv
->video_fd
, VIDIOC_STREAMON
, &(priv
->format
.type
)) < 0) {
1618 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl streamon failed: %s\n",
1619 info
.short_name
, strerror(errno
));
1624 if (!priv
->tv_param
->noaudio
) {
1625 pthread_create(&priv
->audio_grabber_thread
, NULL
, audio_grabber
, priv
);
1628 for (priv
->frames
= 0; !priv
->shutdown
;)
1632 if (priv
->immediate_mode
) {
1633 while (priv
->video_cnt
== priv
->video_buffer_size_max
) {
1635 if (priv
->shutdown
) {
1642 FD_SET (priv
->video_fd
, &rdset
);
1645 timeout
.tv_usec
= 0;
1647 i
= select(priv
->video_fd
+ 1, &rdset
, NULL
, NULL
, &timeout
);
1649 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: select failed: %s\n",
1650 info
.short_name
, strerror(errno
));
1654 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: select timeout\n", info
.short_name
);
1657 else if (!FD_ISSET(priv
->video_fd
, &rdset
)) {
1661 memset(&buf
,0,sizeof(buf
));
1662 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1663 buf
.memory
= V4L2_MEMORY_MMAP
;
1664 ret
= ioctl(priv
->video_fd
, VIDIOC_DQBUF
, &buf
);
1668 if there's no signal, the buffer might me dequeued
1669 so we query all the buffers to see which one we should
1672 observed with saa7134 0.2.8
1673 don't know if is it a bug or (mis)feature
1675 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1676 info
.short_name
, strerror(errno
), buf
.index
);
1677 for (i
= 0; i
< priv
->mapcount
; i
++) {
1678 memset(&buf
,0,sizeof(buf
));
1679 buf
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
1680 buf
.memory
= V4L2_MEMORY_MMAP
;
1682 ret
= ioctl(priv
->video_fd
, VIDIOC_QUERYBUF
, &buf
);
1684 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl query buffer failed: %s, idx = %d\n",
1685 info
.short_name
, strerror(errno
), buf
.index
);
1688 if ((buf
.flags
& (V4L2_BUF_FLAG_QUEUED
| V4L2_BUF_FLAG_MAPPED
| V4L2_BUF_FLAG_DONE
)) == V4L2_BUF_FLAG_MAPPED
) {
1689 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &(priv
->map
[i
].buf
)) < 0) {
1690 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1691 info
.short_name
, strerror(errno
));
1699 /* store the timestamp of the very first frame as reference */
1700 if (!priv
->frames
++) {
1701 if (!priv
->tv_param
->noaudio
) pthread_mutex_lock(&priv
->skew_mutex
);
1702 priv
->first_frame
= (long long)1e6
*buf
.timestamp
.tv_sec
+ buf
.timestamp
.tv_usec
;
1703 if (!priv
->tv_param
->noaudio
) pthread_mutex_unlock(&priv
->skew_mutex
);
1705 priv
->curr_frame
= (long long)buf
.timestamp
.tv_sec
*1e6
+buf
.timestamp
.tv_usec
;
1706 // fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1708 interval
= priv
->curr_frame
- priv
->first_frame
;
1709 delta
= interval
- prev_interval
;
1711 if (!priv
->immediate_mode
) {
1712 // interpolate the skew in time
1713 if (!priv
->tv_param
->noaudio
) pthread_mutex_lock(&priv
->skew_mutex
);
1714 xskew
= priv
->audio_skew
+ (interval
- priv
->audio_skew_measure_time
)*priv
->audio_skew_factor
;
1715 if (!priv
->tv_param
->noaudio
) pthread_mutex_unlock(&priv
->skew_mutex
);
1716 // correct extreme skew changes to avoid (especially) moving backwards in time
1717 if (xskew
- prev_skew
> delta
*MAX_SKEW_DELTA
) {
1718 skew
= prev_skew
+ delta
*MAX_SKEW_DELTA
;
1719 } else if (xskew
- prev_skew
< -delta
*MAX_SKEW_DELTA
) {
1720 skew
= prev_skew
- delta
*MAX_SKEW_DELTA
;
1726 mp_msg(MSGT_TV
, MSGL_DBG3
, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1727 delta
? (double)1e6
/delta
: -1,
1728 (double)1e-6*interval
, (double)1e-6*xskew
, (double)1e-6*skew
);
1729 mp_msg(MSGT_TV
, MSGL_DBG3
, "vcnt = %d, acnt = %d\n", priv
->video_cnt
, priv
->audio_cnt
);
1732 prev_interval
= interval
;
1734 /* allocate a new buffer, if needed */
1735 pthread_mutex_lock(&priv
->video_buffer_mutex
);
1736 if (priv
->video_buffer_size_current
< priv
->video_buffer_size_max
) {
1737 if (priv
->video_cnt
== priv
->video_buffer_size_current
) {
1738 unsigned char *newbuf
= malloc(framesize
);
1740 memmove(priv
->video_ringbuffer
+priv
->video_tail
+1, priv
->video_ringbuffer
+priv
->video_tail
,
1741 (priv
->video_buffer_size_current
-priv
->video_tail
)*sizeof(video_buffer_entry
));
1742 priv
->video_ringbuffer
[priv
->video_tail
].data
= newbuf
;
1743 if ((priv
->video_head
>= priv
->video_tail
) && (priv
->video_cnt
> 0)) priv
->video_head
++;
1744 priv
->video_buffer_size_current
++;
1748 pthread_mutex_unlock(&priv
->video_buffer_mutex
);
1750 if (priv
->video_cnt
== priv
->video_buffer_size_current
) {
1751 if (!priv
->immediate_mode
) {
1752 mp_msg(MSGT_TV
, MSGL_ERR
, "\nvideo buffer full - dropping frame\n");
1753 if (priv
->audio_insert_null_samples
) {
1754 pthread_mutex_lock(&priv
->audio_mutex
);
1755 priv
->dropped_frames_timeshift
+= delta
;
1756 pthread_mutex_unlock(&priv
->audio_mutex
);
1760 if (priv
->immediate_mode
) {
1761 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
= 0;
1763 // compensate for audio skew
1764 // negative skew => there are more audio samples, increase interval
1765 // positive skew => less samples, shorten the interval
1766 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
= interval
- skew
;
1767 if (priv
->audio_insert_null_samples
&& priv
->video_ringbuffer
[priv
->video_tail
].timestamp
> 0) {
1768 pthread_mutex_lock(&priv
->audio_mutex
);
1769 priv
->video_ringbuffer
[priv
->video_tail
].timestamp
+=
1770 (priv
->audio_null_blocks_inserted
1771 - priv
->dropped_frames_timeshift
/priv
->audio_usecs_per_block
)
1772 *priv
->audio_usecs_per_block
;
1773 pthread_mutex_unlock(&priv
->audio_mutex
);
1776 copy_frame(priv
, priv
->video_ringbuffer
+priv
->video_tail
, priv
->map
[buf
.index
].addr
,buf
.bytesused
);
1777 priv
->video_tail
= (priv
->video_tail
+1)%priv
->video_buffer_size_current
;
1780 if (ioctl(priv
->video_fd
, VIDIOC_QBUF
, &buf
) < 0) {
1781 mp_msg(MSGT_TV
, MSGL_ERR
, "%s: ioctl queue buffer failed: %s\n",
1782 info
.short_name
, strerror(errno
));
1790 static double grab_video_frame(priv_t
*priv
, char *buffer
, int len
)
1796 pthread_create(&priv
->video_grabber_thread
, NULL
, video_grabber
, priv
);
1800 while (priv
->video_cnt
== 0) {
1802 if (loop_cnt
++ > MAX_LOOP
) return 0;
1805 pthread_mutex_lock(&priv
->video_buffer_mutex
);
1806 interval
= (double)priv
->video_ringbuffer
[priv
->video_head
].timestamp
*1e-6;
1807 memcpy(buffer
, priv
->video_ringbuffer
[priv
->video_head
].data
, len
);
1809 priv
->video_head
= (priv
->video_head
+1)%priv
->video_buffer_size_current
;
1810 pthread_mutex_unlock(&priv
->video_buffer_mutex
);
1815 static int get_video_framesize(priv_t
*priv
)
1818 this routine will be called before grab_video_frame
1819 thus let's return topmost frame's size
1821 if (priv
->video_cnt
)
1822 return priv
->video_ringbuffer
[priv
->video_head
].framesize
;
1824 no video frames yet available. i don't know what to do in this case,
1825 thus let's return some fallback result (for compressed format this will be
1826 maximum allowed frame size.
1828 return priv
->format
.fmt
.pix
.sizeimage
;
1831 //#define DOUBLESPEED
1833 // for testing purposes only
1834 static void read_doublespeed(priv_t
*priv
)
1836 char *bufx
= calloc(priv
->audio_in
.blocksize
, 2);
1841 audio_in_read_chunk(&priv
->audio_in
, bufx
);
1842 audio_in_read_chunk(&priv
->audio_in
, bufx
+priv
->audio_in
.blocksize
);
1845 d
= priv
->audio_ringbuffer
+priv
->audio_tail
*priv
->audio_in
.blocksize
;
1846 for (i
= 0; i
< priv
->audio_in
.blocksize
/2; i
++) {
1854 static void *audio_grabber(void *data
)
1856 priv_t
*priv
= (priv_t
*)data
;
1858 int i
, audio_skew_ptr
= 0;
1859 long long current_time
, prev_skew
= 0, prev_skew_uncorr
= 0;
1860 long long start_time_avg
;
1862 gettimeofday(&tv
, NULL
);
1863 start_time_avg
= priv
->audio_start_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
;
1864 audio_in_start_capture(&priv
->audio_in
);
1865 for (i
= 0; i
< priv
->aud_skew_cnt
; i
++)
1866 priv
->audio_skew_buffer
[i
] = 0;
1867 for (i
= 0; i
< priv
->aud_skew_cnt
; i
++)
1868 priv
->audio_skew_delta_buffer
[i
] = 0;
1870 for (; !priv
->shutdown
;)
1873 read_doublespeed(priv
);
1875 if (audio_in_read_chunk(&priv
->audio_in
, priv
->audio_ringbuffer
+priv
->audio_tail
*priv
->audio_in
.blocksize
) < 0)
1878 pthread_mutex_lock(&priv
->skew_mutex
);
1879 if (priv
->first_frame
== 0) {
1880 // there is no first frame yet (unlikely to happen)
1881 gettimeofday(&tv
, NULL
);
1882 start_time_avg
= priv
->audio_start_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
;
1883 // fprintf(stderr, "warning - first frame not yet available!\n");
1884 pthread_mutex_unlock(&priv
->skew_mutex
);
1887 pthread_mutex_unlock(&priv
->skew_mutex
);
1889 gettimeofday(&tv
, NULL
);
1891 priv
->audio_recv_blocks_total
++;
1892 current_time
= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
- priv
->audio_start_time
;
1894 if (priv
->audio_recv_blocks_total
< priv
->aud_skew_cnt
*2) {
1895 start_time_avg
+= (long long)1e6
*tv
.tv_sec
+ tv
.tv_usec
- priv
->audio_usecs_per_block
*priv
->audio_recv_blocks_total
;
1896 priv
->audio_start_time
= start_time_avg
/(priv
->audio_recv_blocks_total
+1);
1899 // fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1900 // (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1902 // put the current skew into the ring buffer
1903 priv
->audio_skew_total
-= priv
->audio_skew_buffer
[audio_skew_ptr
];
1904 priv
->audio_skew_buffer
[audio_skew_ptr
] = current_time
1905 - priv
->audio_usecs_per_block
*priv
->audio_recv_blocks_total
;
1906 priv
->audio_skew_total
+= priv
->audio_skew_buffer
[audio_skew_ptr
];
1908 pthread_mutex_lock(&priv
->skew_mutex
);
1912 // compute the sliding average of the skews
1913 if (priv
->audio_recv_blocks_total
> priv
->aud_skew_cnt
) {
1914 priv
->audio_skew
= priv
->audio_skew_total
/priv
->aud_skew_cnt
;
1916 priv
->audio_skew
= priv
->audio_skew_total
/priv
->audio_recv_blocks_total
;
1919 // put the current skew change (skew-prev_skew) into the ring buffer
1920 priv
->audio_skew_delta_total
-= priv
->audio_skew_delta_buffer
[audio_skew_ptr
];
1921 priv
->audio_skew_delta_buffer
[audio_skew_ptr
] = priv
->audio_skew
- prev_skew_uncorr
;
1922 priv
->audio_skew_delta_total
+= priv
->audio_skew_delta_buffer
[audio_skew_ptr
];
1923 prev_skew_uncorr
= priv
->audio_skew
; // remember the _uncorrected_ average value
1925 audio_skew_ptr
= (audio_skew_ptr
+1) % priv
->aud_skew_cnt
; // rotate the buffer pointer
1927 // sliding average approximates the value in the middle of the interval
1928 // so interpolate the skew value further to the current time
1929 priv
->audio_skew
+= priv
->audio_skew_delta_total
/2;
1931 // now finally, priv->audio_skew contains fairly good approximation
1932 // of the current value
1934 // current skew factor (assuming linearity)
1935 // used for further interpolation in video_grabber
1936 // probably overkill but seems to be necessary for
1937 // stress testing by dropping half of the audio frames ;)
1938 // especially when using ALSA with large block sizes
1939 // where audio_skew remains a long while behind
1940 if ((priv
->audio_skew_measure_time
!= 0) && (current_time
- priv
->audio_skew_measure_time
!= 0)) {
1941 priv
->audio_skew_factor
= (double)(priv
->audio_skew
-prev_skew
)/(current_time
- priv
->audio_skew_measure_time
);
1943 priv
->audio_skew_factor
= 0.0;
1946 priv
->audio_skew_measure_time
= current_time
;
1947 prev_skew
= priv
->audio_skew
;
1948 priv
->audio_skew
+= priv
->audio_start_time
- priv
->first_frame
;
1949 pthread_mutex_unlock(&priv
->skew_mutex
);
1951 // fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1953 pthread_mutex_lock(&priv
->audio_mutex
);
1954 if ((priv
->audio_tail
+1) % priv
->audio_buffer_size
== priv
->audio_head
) {
1955 mp_msg(MSGT_TV
, MSGL_ERR
, "\ntoo bad - dropping audio frame !\n");
1958 priv
->audio_tail
= (priv
->audio_tail
+1) % priv
->audio_buffer_size
;
1961 pthread_mutex_unlock(&priv
->audio_mutex
);
1966 static double grab_audio_frame(priv_t
*priv
, char *buffer
, int len
)
1968 mp_dbg(MSGT_TV
, MSGL_DBG2
, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1971 // hack: if grab_audio_frame is called first, it means we are used by mplayer
1972 // => switch to the mode which outputs audio immediately, even if
1973 // it should be silence
1974 if (priv
->first
) priv
->audio_insert_null_samples
= 1;
1976 pthread_mutex_lock(&priv
->audio_mutex
);
1977 while (priv
->audio_insert_null_samples
1978 && priv
->dropped_frames_timeshift
- priv
->dropped_frames_compensated
>= priv
->audio_usecs_per_block
) {
1979 // some frames were dropped - drop the corresponding number of audio blocks
1980 if (priv
->audio_drop
) {
1983 if (priv
->audio_head
== priv
->audio_tail
) break;
1984 priv
->audio_head
= (priv
->audio_head
+1) % priv
->audio_buffer_size
;
1986 priv
->dropped_frames_compensated
+= priv
->audio_usecs_per_block
;
1989 // compensate for dropped audio frames
1990 if (priv
->audio_drop
&& (priv
->audio_head
== priv
->audio_tail
)) {
1992 memset(buffer
, 0, len
);
1996 if (priv
->audio_insert_null_samples
&& (priv
->audio_head
== priv
->audio_tail
)) {
1997 // return silence to avoid desync and stuttering
1998 memset(buffer
, 0, len
);
1999 priv
->audio_null_blocks_inserted
++;
2003 pthread_mutex_unlock(&priv
->audio_mutex
);
2004 while (priv
->audio_head
== priv
->audio_tail
) {
2005 // this is mencoder => just wait until some audio is available
2008 pthread_mutex_lock(&priv
->audio_mutex
);
2009 memcpy(buffer
, priv
->audio_ringbuffer
+priv
->audio_head
*priv
->audio_in
.blocksize
, len
);
2010 priv
->audio_head
= (priv
->audio_head
+1) % priv
->audio_buffer_size
;
2013 pthread_mutex_unlock(&priv
->audio_mutex
);
2014 priv
->audio_sent_blocks_total
++;
2015 return (double)priv
->audio_sent_blocks_total
*priv
->audio_secs_per_block
;
2018 static int get_audio_framesize(priv_t
*priv
)
2020 return priv
->audio_in
.blocksize
;