2
** Video 4 Linux 2 input
4
** This file is part of MPlayer, see http://mplayerhq.hu/ for info.
6
** (c) 2003 Martin Olschewski <olschewski@zpr.uni-koeln.de>
7
** (c) 2003 Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
9
** File licensed under the GPL, see http://www.fsf.org/ for more info.
11
** Some ideas are based on works from
12
** Alex Beregszaszi <alex@fsn.hu>
13
** Gerd Knorr <kraxel@bytesex.org>
15
** CODE IS UNDER DEVELOPMENT, NO FEATURE REQUESTS PLEASE!
21
- norm setting isn't consistent with tvi_v4l
22
- the same for volume/bass/treble/balance
28
#if defined(USE_TV) && defined(HAVE_TV_V4L2)
35
#include <sys/ioctl.h>
38
#include <sys/types.h>
40
#ifdef HAVE_SYS_SYSINFO_H
41
#include <sys/sysinfo.h>
43
#include <linux/types.h>
44
#include <linux/videodev2.h>
46
#include "libvo/img_format.h"
47
#include "libaf/af_format.h"
51
/* information about this file */
52
static tvi_info_t info = {
53
"Video 4 Linux 2 input",
55
"Martin Olschewski <olschewski@zpr.uni-koeln.de>",
56
"first try, more to come ;-)"
60
struct v4l2_buffer buf;
65
#define BUFFER_COUNT 6
73
struct v4l2_capability capability;
74
struct v4l2_input input;
75
struct v4l2_format format;
76
struct v4l2_standard standard;
77
struct v4l2_tuner tuner;
81
volatile long long first_frame;
83
/* audio video interleaving ;-) */
84
volatile int streamon;
85
pthread_t audio_grabber_thread;
86
pthread_mutex_t skew_mutex;
88
/* 2nd level video buffers */
92
int video_buffer_size_max;
93
volatile int video_buffer_size_current;
94
unsigned char **video_ringbuffer;
95
long long *video_timebuffer;
96
volatile int video_head;
97
volatile int video_tail;
98
volatile int video_cnt;
99
pthread_t video_grabber_thread;
100
pthread_mutex_t video_buffer_mutex;
106
long long audio_start_time;
107
int audio_buffer_size;
109
unsigned char *audio_ringbuffer;
110
long long *audio_skew_buffer;
111
long long *audio_skew_delta_buffer;
112
volatile int audio_head;
113
volatile int audio_tail;
114
volatile int audio_cnt;
115
volatile long long audio_skew;
116
volatile double audio_skew_factor;
117
volatile long long audio_skew_measure_time;
118
volatile int audio_drop;
119
volatile int shutdown;
122
double audio_secs_per_block;
123
long long audio_usecs_per_block;
124
long long audio_skew_total;
125
long long audio_skew_delta_total;
126
long audio_recv_blocks_total;
127
long audio_sent_blocks_total;
128
pthread_mutex_t audio_mutex;
129
int audio_insert_null_samples;
130
volatile long audio_null_blocks_inserted;
131
volatile long long dropped_frames_timeshift;
132
long long dropped_frames_compensated;
137
static void *audio_grabber(void *data);
138
static void *video_grabber(void *data);
140
/**********************************************************************\
142
Only few of the fourccs are the same in v4l2 and mplayer:
144
IMGFMT_YVU9 == V4L2_PIX_FMT_YVU410
145
IMGFMT_YV12 == V4L2_PIX_FMT_YVU420
146
IMGFMT_NV12 == V4L2_PIX_FMT_NV12
147
IMGFMT_422P == V4L2_PIX_FMT_YUV422P
148
IMGFMT_411P == V4L2_PIX_FMT_YUV411P
149
IMGFMT_UYVY == V4L2_PIX_FMT_UYVY
150
IMGFMT_Y41P == V4L2_PIX_FMT_Y41P
152
This may be an useful translation table for some others:
154
IMGFMT_RGB8 == V4L2_PIX_FMT_RGB332
155
IMGFMT_BGR15 == V4L2_PIX_FMT_RGB555
156
IMGFMT_BGR16 == V4L2_PIX_FMT_RGB565
157
IMGFMT_RGB24 == V4L2_PIX_FMT_RGB24
158
IMGFMT_RGB32 == V4L2_PIX_FMT_RGB32
159
IMGFMT_BGR24 == V4L2_PIX_FMT_BGR24
160
IMGFMT_BGR32 == V4L2_PIX_FMT_BGR32
161
IMGFMT_Y800 == V4L2_PIX_FMT_GREY
162
IMGFMT_IF09 == V4L2_PIX_FMT_YUV410
163
IMGFMT_I420 == V4L2_PIX_FMT_YUV420
164
IMGFMT_YUY2 == V4L2_PIX_FMT_YUYV
166
\**********************************************************************/
169
** Translate a mplayer fourcc to a video4linux2 pixel format.
171
static int fcc_mp2vl(int fcc)
174
case IMGFMT_RGB8: return V4L2_PIX_FMT_RGB332;
175
case IMGFMT_BGR15: return V4L2_PIX_FMT_RGB555;
176
case IMGFMT_BGR16: return V4L2_PIX_FMT_RGB565;
177
case IMGFMT_RGB24: return V4L2_PIX_FMT_RGB24;
178
case IMGFMT_RGB32: return V4L2_PIX_FMT_RGB32;
179
case IMGFMT_BGR24: return V4L2_PIX_FMT_BGR24;
180
case IMGFMT_BGR32: return V4L2_PIX_FMT_BGR32;
181
case IMGFMT_Y800: return V4L2_PIX_FMT_GREY;
182
case IMGFMT_IF09: return V4L2_PIX_FMT_YUV410;
183
case IMGFMT_I420: return V4L2_PIX_FMT_YUV420;
184
case IMGFMT_YUY2: return V4L2_PIX_FMT_YUYV;
185
case IMGFMT_YV12: return V4L2_PIX_FMT_YVU420;
186
case IMGFMT_UYVY: return V4L2_PIX_FMT_UYVY;
192
** Translate a video4linux2 fourcc aka pixel format to mplayer.
194
static int fcc_vl2mp(int fcc)
197
case V4L2_PIX_FMT_RGB332: return IMGFMT_RGB8;
198
case V4L2_PIX_FMT_RGB555: return IMGFMT_BGR15;
199
case V4L2_PIX_FMT_RGB565: return IMGFMT_BGR16;
200
case V4L2_PIX_FMT_RGB24: return IMGFMT_RGB24;
201
case V4L2_PIX_FMT_RGB32: return IMGFMT_RGB32;
202
case V4L2_PIX_FMT_BGR24: return IMGFMT_BGR24;
203
case V4L2_PIX_FMT_BGR32: return IMGFMT_BGR32;
204
case V4L2_PIX_FMT_GREY: return IMGFMT_Y800;
205
case V4L2_PIX_FMT_YUV410: return IMGFMT_IF09;
206
case V4L2_PIX_FMT_YUV420: return IMGFMT_I420;
207
case V4L2_PIX_FMT_YVU420: return IMGFMT_YV12;
208
case V4L2_PIX_FMT_YUYV: return IMGFMT_YUY2;
209
case V4L2_PIX_FMT_UYVY: return IMGFMT_UYVY;
215
** Translate a video4linux2 fourcc aka pixel format
216
** to a human readable string.
218
static char *pixfmt2name(int pixfmt)
220
static char unknown[24];
223
case V4L2_PIX_FMT_RGB332: return "RGB332";
224
case V4L2_PIX_FMT_RGB555: return "RGB555";
225
case V4L2_PIX_FMT_RGB565: return "RGB565";
226
case V4L2_PIX_FMT_RGB555X: return "RGB555X";
227
case V4L2_PIX_FMT_RGB565X: return "RGB565X";
228
case V4L2_PIX_FMT_BGR24: return "BGR24";
229
case V4L2_PIX_FMT_RGB24: return "RGB24";
230
case V4L2_PIX_FMT_BGR32: return "BGR32";
231
case V4L2_PIX_FMT_RGB32: return "RGB32";
232
case V4L2_PIX_FMT_GREY: return "GREY";
233
case V4L2_PIX_FMT_YVU410: return "YVU410";
234
case V4L2_PIX_FMT_YVU420: return "YVU420";
235
case V4L2_PIX_FMT_YUYV: return "YUYV";
236
case V4L2_PIX_FMT_UYVY: return "UYVY";
237
/* case V4L2_PIX_FMT_YVU422P: return "YVU422P"; */
238
/* case V4L2_PIX_FMT_YVU411P: return "YVU411P"; */
239
case V4L2_PIX_FMT_YUV422P: return "YUV422P";
240
case V4L2_PIX_FMT_YUV411P: return "YUV411P";
241
case V4L2_PIX_FMT_Y41P: return "Y41P";
242
case V4L2_PIX_FMT_NV12: return "NV12";
243
case V4L2_PIX_FMT_NV21: return "NV21";
244
case V4L2_PIX_FMT_YUV410: return "YUV410";
245
case V4L2_PIX_FMT_YUV420: return "YUV420";
246
case V4L2_PIX_FMT_YYUV: return "YYUV";
247
case V4L2_PIX_FMT_HI240: return "HI240";
248
case V4L2_PIX_FMT_WNVA: return "WNVA";
250
sprintf(unknown, "unknown (0x%x)", pixfmt);
256
** Gives the depth of a video4linux2 fourcc aka pixel format in bits.
258
static int pixfmt2depth(int pixfmt)
261
case V4L2_PIX_FMT_RGB332:
263
case V4L2_PIX_FMT_RGB555:
264
case V4L2_PIX_FMT_RGB565:
265
case V4L2_PIX_FMT_RGB555X:
266
case V4L2_PIX_FMT_RGB565X:
268
case V4L2_PIX_FMT_BGR24:
269
case V4L2_PIX_FMT_RGB24:
271
case V4L2_PIX_FMT_BGR32:
272
case V4L2_PIX_FMT_RGB32:
274
case V4L2_PIX_FMT_GREY:
276
case V4L2_PIX_FMT_YVU410:
278
case V4L2_PIX_FMT_YVU420:
280
case V4L2_PIX_FMT_YUYV:
281
case V4L2_PIX_FMT_UYVY:
282
case V4L2_PIX_FMT_YUV422P:
283
case V4L2_PIX_FMT_YUV411P:
285
case V4L2_PIX_FMT_Y41P:
286
case V4L2_PIX_FMT_NV12:
287
case V4L2_PIX_FMT_NV21:
289
case V4L2_PIX_FMT_YUV410:
291
case V4L2_PIX_FMT_YUV420:
293
case V4L2_PIX_FMT_YYUV:
295
case V4L2_PIX_FMT_HI240:
302
static int amode2v4l(int amode)
306
return V4L2_TUNER_MODE_MONO;
308
return V4L2_TUNER_MODE_STEREO;
310
return V4L2_TUNER_MODE_LANG1;
312
return V4L2_TUNER_MODE_LANG2;
319
// sets and sanitizes audio buffer/block sizes
320
static void setup_audio_buffer_sizes(priv_t *priv)
322
int bytes_per_sample = priv->audio_in.bytes_per_sample;
323
double fps = (double)priv->standard.frameperiod.denominator /
324
priv->standard.frameperiod.numerator;
325
int seconds = priv->video_buffer_size_max/fps;
327
if (seconds < 5) seconds = 5;
328
if (seconds > 500) seconds = 500;
330
// make the audio buffer at least as the video buffer capacity (or 5 seconds) long
331
priv->audio_buffer_size = 1 + seconds*priv->audio_in.samplerate
332
*priv->audio_in.channels
333
*bytes_per_sample/priv->audio_in.blocksize;
334
if (priv->audio_buffer_size < 256) priv->audio_buffer_size = 256;
336
// make the skew buffer at least 1 second long
337
priv->aud_skew_cnt = 1 + 1*priv->audio_in.samplerate
338
*priv->audio_in.channels
339
*bytes_per_sample/priv->audio_in.blocksize;
340
if (priv->aud_skew_cnt < 16) priv->aud_skew_cnt = 16;
342
mp_msg(MSGT_TV, MSGL_V, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
343
priv->audio_buffer_size, priv->audio_in.blocksize, priv->aud_skew_cnt);
346
static void init_audio(priv_t *priv)
348
if (priv->audio_inited) return;
350
if (!tv_param_noaudio) {
351
#if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
353
audio_in_init(&priv->audio_in, AUDIO_IN_ALSA);
355
audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
357
audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
360
if (priv->audio_dev) {
361
audio_in_set_device(&priv->audio_in, priv->audio_dev);
364
audio_in_set_samplerate(&priv->audio_in, 44100);
365
if (priv->capability.capabilities & V4L2_CAP_TUNER) {
366
if (priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) {
367
audio_in_set_channels(&priv->audio_in, 2);
369
audio_in_set_channels(&priv->audio_in, 1);
372
if (tv_param_forcechan >= 0) {
373
audio_in_set_channels(&priv->audio_in, tv_param_forcechan);
375
audio_in_set_channels(&priv->audio_in, 2);
379
if (audio_in_setup(&priv->audio_in) < 0) return;
381
priv->audio_inited = 1;
387
** the number of milliseconds elapsed between time0 and time1
389
static size_t difftv(struct timeval time1, struct timeval time0)
391
return (time1.tv_sec - time0.tv_sec) * 1000 +
392
(time1.tv_usec - time0.tv_usec) / 1000;
397
** Get current video capture format.
399
static int getfmt(priv_t *priv)
403
priv->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
404
if ((i = ioctl(priv->video_fd, VIDIOC_G_FMT, &priv->format)) < 0) {
405
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get format failed: %s\n",
406
info.short_name, strerror(errno));
413
** Get current video capture standard.
415
static int getstd(priv_t *priv)
420
if (ioctl(priv->video_fd, VIDIOC_G_STD, &id) < 0) {
421
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get standard failed: %s\n",
422
info.short_name, strerror(errno));
426
priv->standard.index = i++;
427
if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
430
} while (priv->standard.id != id);
434
/***********************************************************************\
437
* Interface to mplayer *
440
\***********************************************************************/
442
static int set_mute(priv_t *priv, int value)
444
struct v4l2_control control;
445
control.id = V4L2_CID_AUDIO_MUTE;
446
control.value = value;
447
if (ioctl(priv->video_fd, VIDIOC_S_CTRL, &control) < 0) {
448
mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set mute failed: %s\n",
449
info.short_name, strerror(errno));
456
** MPlayer uses values from -100 up to 100 for controls.
457
** Here they are scaled to what the tv card needs and applied.
459
static int set_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
460
struct v4l2_queryctrl qctrl;
462
qctrl.id = control->id;
463
if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
464
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
465
info.short_name, strerror(errno));
466
return TVI_CONTROL_FALSE;
470
if (control->value < 0) {
471
control->value = qctrl.default_value + control->value *
472
(qctrl.default_value - qctrl.minimum) / 100;
474
control->value = qctrl.default_value + control->value *
475
(qctrl.maximum - qctrl.default_value) / 100;
478
if (control->value < 50) {
479
control->value = qctrl.default_value + (control->value-50) *
480
(qctrl.default_value - qctrl.minimum) / 50;
482
control->value = qctrl.default_value + (control->value-50) *
483
(qctrl.maximum - qctrl.default_value) / 50;
488
if (ioctl(priv->video_fd, VIDIOC_S_CTRL, control) < 0) {
489
mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl set %s %d failed: %s\n",
490
info.short_name, qctrl.name, control->value, strerror(errno));
491
return TVI_CONTROL_FALSE;
493
mp_msg(MSGT_TV, MSGL_V, "%s: set %s: %d [%d, %d]\n", info.short_name,
494
qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
496
return TVI_CONTROL_TRUE;
501
** Scale the control values back to what mplayer needs.
503
static int get_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
504
struct v4l2_queryctrl qctrl;
506
qctrl.id = control->id;
507
if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
508
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
509
info.short_name, strerror(errno));
510
return TVI_CONTROL_FALSE;
513
if (ioctl(priv->video_fd, VIDIOC_G_CTRL, control) < 0) {
514
mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl get %s failed: %s\n",
515
info.short_name, qctrl.name, strerror(errno));
516
return TVI_CONTROL_FALSE;
518
mp_msg(MSGT_TV, MSGL_V, "%s: get %s: %d [%d, %d]\n", info.short_name,
519
qctrl.name, control->value, qctrl.minimum, qctrl.maximum);
522
if (control->value < qctrl.default_value) {
523
control->value = (control->value - qctrl.default_value) * 100 /
524
(qctrl.default_value - qctrl.minimum);
526
control->value = (control->value - qctrl.default_value) * 100 /
527
(qctrl.maximum - qctrl.default_value);
530
if (control->value < qctrl.default_value) {
531
control->value = (control->value - qctrl.default_value) * 50 /
532
(qctrl.default_value - qctrl.minimum) + 50;
534
control->value = (control->value - qctrl.default_value) * 50 /
535
(qctrl.maximum - qctrl.default_value) + 50;
539
return TVI_CONTROL_TRUE;
542
static int control(priv_t *priv, int cmd, void *arg)
544
struct v4l2_control control;
545
struct v4l2_frequency frequency;
548
case TVI_CONTROL_IS_VIDEO:
549
return priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
550
TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
551
case TVI_CONTROL_IS_AUDIO:
552
if (tv_param_force_audio) return TVI_CONTROL_TRUE;
553
case TVI_CONTROL_IS_TUNER:
554
return priv->capability.capabilities & V4L2_CAP_TUNER?
555
TVI_CONTROL_TRUE: TVI_CONTROL_FALSE;
556
case TVI_CONTROL_IMMEDIATE:
557
priv->immediate_mode = 1;
558
return TVI_CONTROL_TRUE;
559
case TVI_CONTROL_VID_GET_FPS:
560
*(float *)arg = (float)priv->standard.frameperiod.denominator /
561
priv->standard.frameperiod.numerator;
562
mp_msg(MSGT_TV, MSGL_V, "%s: get fps: %f\n", info.short_name,
564
return TVI_CONTROL_TRUE;
565
case TVI_CONTROL_VID_GET_BITS:
566
if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
567
*(int *)arg = pixfmt2depth(priv->format.fmt.pix.pixelformat);
568
mp_msg(MSGT_TV, MSGL_V, "%s: get depth: %d\n", info.short_name,
570
return TVI_CONTROL_TRUE;
571
case TVI_CONTROL_VID_GET_FORMAT:
572
if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
573
*(int *)arg = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
574
mp_msg(MSGT_TV, MSGL_V, "%s: get format: %s\n", info.short_name,
575
pixfmt2name(priv->format.fmt.pix.pixelformat));
576
return TVI_CONTROL_TRUE;
577
case TVI_CONTROL_VID_SET_FORMAT:
578
if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
579
priv->format.fmt.pix.pixelformat = fcc_mp2vl(*(int *)arg);
580
priv->format.fmt.pix.field = V4L2_FIELD_ANY;
582
priv->mp_format = *(int *)arg;
583
mp_msg(MSGT_TV, MSGL_V, "%s: set format: %s\n", info.short_name,
584
pixfmt2name(priv->format.fmt.pix.pixelformat));
585
if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
586
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
587
info.short_name, strerror(errno));
588
return TVI_CONTROL_FALSE;
590
/* according to the v4l2 specs VIDIOC_S_FMT should not fail, inflexible drivers
591
might even always return the default parameters -> update the format here*/
592
priv->mp_format = fcc_vl2mp(priv->format.fmt.pix.pixelformat);
593
return TVI_CONTROL_TRUE;
594
case TVI_CONTROL_VID_GET_WIDTH:
595
if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
596
*(int *)arg = priv->format.fmt.pix.width;
597
mp_msg(MSGT_TV, MSGL_V, "%s: get width: %d\n", info.short_name,
599
return TVI_CONTROL_TRUE;
600
case TVI_CONTROL_VID_CHK_WIDTH:
601
return TVI_CONTROL_TRUE;
602
case TVI_CONTROL_VID_SET_WIDTH:
603
if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
604
priv->format.fmt.pix.width = *(int *)arg;
605
mp_msg(MSGT_TV, MSGL_V, "%s: set width: %d\n", info.short_name,
607
if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
608
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set width failed: %s\n",
609
info.short_name, strerror(errno));
610
return TVI_CONTROL_FALSE;
612
return TVI_CONTROL_TRUE;
613
case TVI_CONTROL_VID_GET_HEIGHT:
614
if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
615
*(int *)arg = priv->format.fmt.pix.height;
616
mp_msg(MSGT_TV, MSGL_V, "%s: get height: %d\n", info.short_name,
618
return TVI_CONTROL_TRUE;
619
case TVI_CONTROL_VID_CHK_HEIGHT:
620
return TVI_CONTROL_TRUE;
621
case TVI_CONTROL_VID_SET_HEIGHT:
622
if (getfmt(priv) < 0) return TVI_CONTROL_FALSE;
623
priv->format.fmt.pix.height = *(int *)arg;
624
priv->format.fmt.pix.field = V4L2_FIELD_ANY;
625
mp_msg(MSGT_TV, MSGL_V, "%s: set height: %d\n", info.short_name,
627
if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
628
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set height failed: %s\n",
629
info.short_name, strerror(errno));
630
return TVI_CONTROL_FALSE;
632
return TVI_CONTROL_TRUE;
633
case TVI_CONTROL_VID_GET_BRIGHTNESS:
634
control.id = V4L2_CID_BRIGHTNESS;
635
if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
636
*(int *)arg = control.value;
637
return TVI_CONTROL_TRUE;
639
return TVI_CONTROL_FALSE;
640
case TVI_CONTROL_VID_SET_BRIGHTNESS:
641
control.id = V4L2_CID_BRIGHTNESS;
642
control.value = *(int *)arg;
643
return set_control(priv, &control, 1);
644
case TVI_CONTROL_VID_GET_HUE:
645
control.id = V4L2_CID_HUE;
646
if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
647
*(int *)arg = control.value;
648
return TVI_CONTROL_TRUE;
650
return TVI_CONTROL_FALSE;
651
case TVI_CONTROL_VID_SET_HUE:
652
control.id = V4L2_CID_HUE;
653
control.value = *(int *)arg;
654
return set_control(priv, &control, 1);
655
case TVI_CONTROL_VID_GET_SATURATION:
656
control.id = V4L2_CID_SATURATION;
657
if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
658
*(int *)arg = control.value;
659
return TVI_CONTROL_TRUE;
661
return TVI_CONTROL_FALSE;
662
case TVI_CONTROL_VID_SET_SATURATION:
663
control.id = V4L2_CID_SATURATION;
664
control.value = *(int *)arg;
665
return set_control(priv, &control, 1);
666
case TVI_CONTROL_VID_GET_CONTRAST:
667
control.id = V4L2_CID_CONTRAST;
668
if (get_control(priv, &control, 1) == TVI_CONTROL_TRUE) {
669
*(int *)arg = control.value;
670
return TVI_CONTROL_TRUE;
672
return TVI_CONTROL_FALSE;
673
case TVI_CONTROL_VID_SET_CONTRAST:
674
control.id = V4L2_CID_CONTRAST;
675
control.value = *(int *)arg;
676
return set_control(priv, &control, 1);
677
case TVI_CONTROL_TUN_GET_FREQ:
679
frequency.type = V4L2_TUNER_ANALOG_TV;
680
if (ioctl(priv->video_fd, VIDIOC_G_FREQUENCY, &frequency) < 0) {
681
mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl get frequency failed: %s\n",
682
info.short_name, strerror(errno));
683
return TVI_CONTROL_FALSE;
685
*(int *)arg = frequency.frequency;
686
return TVI_CONTROL_TRUE;
687
case TVI_CONTROL_TUN_SET_FREQ:
690
usleep(100000); // wait to suppress noise during switching
693
frequency.type = V4L2_TUNER_ANALOG_TV;
694
frequency.frequency = *(int *)arg;
695
if (ioctl(priv->video_fd, VIDIOC_S_FREQUENCY, &frequency) < 0) {
696
mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set frequency failed: %s\n",
697
info.short_name, strerror(errno));
698
return TVI_CONTROL_FALSE;
701
usleep(100000); // wait to suppress noise during switching
704
return TVI_CONTROL_TRUE;
705
case TVI_CONTROL_TUN_GET_TUNER:
706
mp_msg(MSGT_TV, MSGL_V, "%s: get tuner\n",info.short_name);
707
if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
708
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
709
info.short_name, strerror(errno));
710
return TVI_CONTROL_FALSE;
712
return TVI_CONTROL_TRUE;
713
case TVI_CONTROL_TUN_SET_TUNER:
714
mp_msg(MSGT_TV, MSGL_V, "%s: set tuner\n",info.short_name);
715
if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
716
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
717
info.short_name, strerror(errno));
718
return TVI_CONTROL_FALSE;
720
return TVI_CONTROL_TRUE;
721
case TVI_CONTROL_TUN_GET_NORM:
722
*(int *)arg = priv->standard.index;
723
return TVI_CONTROL_TRUE;
724
case TVI_CONTROL_TUN_SET_NORM:
725
priv->standard.index = *(int *)arg;
726
if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
727
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum norm failed: %s\n",
728
info.short_name, strerror(errno));
729
return TVI_CONTROL_FALSE;
731
mp_msg(MSGT_TV, MSGL_V, "%s: set norm: %s\n", info.short_name, priv->standard.name);
732
if (ioctl(priv->video_fd, VIDIOC_S_STD, &priv->standard.id) < 0) {
733
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set norm failed: %s\n",
734
info.short_name, strerror(errno));
735
return TVI_CONTROL_FALSE;
737
return TVI_CONTROL_TRUE;
738
case TVI_CONTROL_SPC_GET_NORMID:
742
struct v4l2_standard standard;
743
memset(&standard, 0, sizeof(standard));
745
if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
746
return TVI_CONTROL_FALSE;
747
if (!strcasecmp(standard.name, (char *)arg)) {
749
return TVI_CONTROL_TRUE;
752
return TVI_CONTROL_FALSE;
754
case TVI_CONTROL_SPC_GET_INPUT:
755
if (ioctl(priv->video_fd, VIDIOC_G_INPUT, (int *)arg) < 0) {
756
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
757
info.short_name, strerror(errno));
758
return TVI_CONTROL_FALSE;
760
return TVI_CONTROL_TRUE;
761
case TVI_CONTROL_SPC_SET_INPUT:
762
mp_msg(MSGT_TV, MSGL_V, "%s: set input: %d\n", info.short_name, *(int *)arg);
763
priv->input.index = *(int *)arg;
764
if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &priv->input) < 0) {
765
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum input failed: %s\n",
766
info.short_name, strerror(errno));
767
return TVI_CONTROL_FALSE;
769
if (ioctl(priv->video_fd, VIDIOC_S_INPUT, (int *)arg) < 0) {
770
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set input failed: %s\n",
771
info.short_name, strerror(errno));
772
return TVI_CONTROL_FALSE;
774
return TVI_CONTROL_TRUE;
775
case TVI_CONTROL_AUD_GET_FORMAT:
777
if (!priv->audio_inited) return TVI_CONTROL_FALSE;
778
*(int *)arg = AF_FORMAT_S16_LE;
779
mp_msg(MSGT_TV, MSGL_V, "%s: get audio format: %d\n",
780
info.short_name, *(int *)arg);
781
return TVI_CONTROL_TRUE;
782
case TVI_CONTROL_AUD_GET_SAMPLERATE:
784
if (!priv->audio_inited) return TVI_CONTROL_FALSE;
785
*(int *)arg = priv->audio_in.samplerate;
786
mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplerate: %d\n",
787
info.short_name, *(int *)arg);
788
return TVI_CONTROL_TRUE;
789
case TVI_CONTROL_AUD_GET_SAMPLESIZE:
791
if (!priv->audio_inited) return TVI_CONTROL_FALSE;
792
*(int *)arg = priv->audio_in.bytes_per_sample;
793
mp_msg(MSGT_TV, MSGL_V, "%s: get audio samplesize: %d\n",
794
info.short_name, *(int *)arg);
795
return TVI_CONTROL_TRUE;
796
case TVI_CONTROL_AUD_GET_CHANNELS:
798
if (!priv->audio_inited) return TVI_CONTROL_FALSE;
799
*(int *)arg = priv->audio_in.channels;
800
mp_msg(MSGT_TV, MSGL_V, "%s: get audio channels: %d\n",
801
info.short_name, *(int *)arg);
802
return TVI_CONTROL_TRUE;
803
case TVI_CONTROL_AUD_SET_SAMPLERATE:
805
mp_msg(MSGT_TV, MSGL_V, "%s: set audio samplerate: %d\n",
806
info.short_name, *(int *)arg);
807
if (audio_in_set_samplerate(&priv->audio_in, *(int*)arg) < 0) return TVI_CONTROL_FALSE;
808
// setup_audio_buffer_sizes(priv);
809
return TVI_CONTROL_TRUE;
811
mp_msg(MSGT_TV, MSGL_V, "%s: unknown control: %d\n", info.short_name, cmd);
812
return(TVI_CONTROL_UNKNOWN);
816
#define PRIV ((priv_t *) (tvi_handle->priv))
818
/* handler creator - entry point ! */
819
tvi_handle_t *tvi_init_v4l2(char *video_dev, char *audio_dev)
821
tvi_handle_t *tvi_handle;
823
/* new_handle initializes priv with memset 0 */
824
tvi_handle = new_handle();
830
PRIV->video_dev = strdup(video_dev? video_dev: "/dev/video0");
831
if (!PRIV->video_dev) {
832
free_handle(tvi_handle);
837
PRIV->audio_dev = strdup(audio_dev);
838
if (!PRIV->audio_dev) {
839
free(PRIV->video_dev);
840
free_handle(tvi_handle);
851
static int uninit(priv_t *priv)
853
int i, frames, dropped = 0;
856
if(priv->video_grabber_thread)
857
pthread_join(priv->video_grabber_thread, NULL);
858
pthread_mutex_destroy(&priv->video_buffer_mutex);
860
if (priv->streamon) {
861
struct v4l2_buffer buf;
863
/* get performance */
864
frames = 1 + (priv->curr_frame - priv->first_frame +
865
priv->standard.frameperiod.numerator * 500000 /
866
priv->standard.frameperiod.denominator) *
867
priv->standard.frameperiod.denominator /
868
priv->standard.frameperiod.numerator / 1000000;
869
dropped = frames - priv->frames;
871
/* turn off streaming */
872
if (ioctl(priv->video_fd, VIDIOC_STREAMOFF, &(priv->map[0].buf.type)) < 0) {
873
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamoff failed: %s\n",
874
info.short_name, strerror(errno));
878
/* unqueue all remaining buffers */
879
memset(&buf,0,sizeof(buf));
880
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
881
while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
884
/* unmap all buffers */
885
for (i = 0; i < priv->mapcount; i++) {
886
if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {
887
mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",
888
info.short_name, strerror(errno));
892
/* stop audio thread */
893
if (!tv_param_noaudio && priv->audio_grabber_thread) {
894
pthread_join(priv->audio_grabber_thread, NULL);
895
pthread_mutex_destroy(&priv->skew_mutex);
896
pthread_mutex_destroy(&priv->audio_mutex);
901
/* free memory and close device */
902
free(priv->map); priv->map = NULL;
904
if(priv->video_fd!=-1)close(priv->video_fd); priv->video_fd = -1;
905
free(priv->video_dev); priv->video_dev = NULL;
907
if (priv->video_ringbuffer) {
909
for (i = 0; i < priv->video_buffer_size_current; i++) {
910
free(priv->video_ringbuffer[i]);
912
free(priv->video_ringbuffer);
914
if (priv->video_timebuffer)
915
free(priv->video_timebuffer);
916
if (!tv_param_noaudio) {
917
if (priv->audio_ringbuffer)
918
free(priv->audio_ringbuffer);
919
if (priv->audio_skew_buffer)
920
free(priv->audio_skew_buffer);
921
if (priv->audio_skew_delta_buffer)
922
free(priv->audio_skew_delta_buffer);
925
/* show some nice statistics ;-) */
926
mp_msg(MSGT_TV, MSGL_INFO,
927
"%s: %d frames successfully processed, %d frames dropped.\n",
928
info.short_name, priv->frames, dropped);
929
mp_msg(MSGT_TV, MSGL_V, "%s: up to %u video frames buffered.\n",
930
info.short_name, priv->video_buffer_size_current);
936
static int init(priv_t *priv)
940
priv->audio_ringbuffer = NULL;
941
priv->audio_skew_buffer = NULL;
942
priv->audio_skew_delta_buffer = NULL;
944
priv->audio_inited = 0;
946
/* Open the video device. */
947
priv->video_fd = open(priv->video_dev, O_RDWR);
948
if (priv->video_fd < 0) {
949
mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",
950
info.short_name, priv->video_dev, strerror(errno));
954
mp_msg(MSGT_TV, MSGL_DBG2, "%s: video fd: %s: %d\n",
955
info.short_name, priv->video_dev, priv->video_fd);
958
** Query the video capabilities and current settings
959
** for further control calls.
961
if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
962
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",
963
info.short_name, strerror(errno));
968
if (!(priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))
970
mp_msg(MSGT_TV, MSGL_ERR, "Device %s is not a video capture device.\n",
975
if (getfmt(priv) < 0) {
981
** if this device has got a tuner query it's settings
982
** otherwise set some nice defaults
984
if (priv->capability.capabilities & V4L2_CAP_TUNER) {
985
if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
986
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
987
info.short_name, strerror(errno));
992
mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.card);
993
if (priv->capability.capabilities & V4L2_CAP_TUNER) {
994
mp_msg(MSGT_TV, MSGL_INFO, " Tuner cap:%s%s%s\n",
995
(priv->tuner.capability & V4L2_TUNER_CAP_STEREO) ? " STEREO" : "",
996
(priv->tuner.capability & V4L2_TUNER_CAP_LANG1) ? " LANG1" : "",
997
(priv->tuner.capability & V4L2_TUNER_CAP_LANG2) ? " LANG2" : "");
998
mp_msg(MSGT_TV, MSGL_INFO, " Tuner rxs:%s%s%s%s\n",
999
(priv->tuner.rxsubchans & V4L2_TUNER_SUB_MONO) ? " MONO" : "",
1000
(priv->tuner.rxsubchans & V4L2_TUNER_SUB_STEREO) ? " STEREO" : "",
1001
(priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG1) ? " LANG1" : "",
1002
(priv->tuner.rxsubchans & V4L2_TUNER_SUB_LANG2) ? " LANG2" : "");
1004
mp_msg(MSGT_TV, MSGL_INFO, " Capabilites:%s%s%s%s%s%s%s%s%s%s%s\n",
1005
priv->capability.capabilities & V4L2_CAP_VIDEO_CAPTURE?
1006
" video capture": "",
1007
priv->capability.capabilities & V4L2_CAP_VIDEO_OUTPUT?
1008
" video output": "",
1009
priv->capability.capabilities & V4L2_CAP_VIDEO_OVERLAY?
1010
" video overlay": "",
1011
priv->capability.capabilities & V4L2_CAP_VBI_CAPTURE?
1012
" VBI capture device": "",
1013
priv->capability.capabilities & V4L2_CAP_VBI_OUTPUT?
1015
priv->capability.capabilities & V4L2_CAP_RDS_CAPTURE?
1016
" RDS data capture": "",
1017
priv->capability.capabilities & V4L2_CAP_TUNER?
1019
priv->capability.capabilities & V4L2_CAP_AUDIO?
1021
priv->capability.capabilities & V4L2_CAP_READWRITE?
1023
priv->capability.capabilities & V4L2_CAP_ASYNCIO?
1025
priv->capability.capabilities & V4L2_CAP_STREAMING?
1027
mp_msg(MSGT_TV, MSGL_INFO, " supported norms:");
1029
struct v4l2_standard standard;
1030
memset(&standard, 0, sizeof(standard));
1032
if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
1034
mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);
1036
mp_msg(MSGT_TV, MSGL_INFO, "\n inputs:");
1037
for (i = 0; 1; i++) {
1038
struct v4l2_input input;
1041
if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
1044
mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);
1046
if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
1047
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
1048
info.short_name, strerror(errno));
1050
mp_msg(MSGT_TV, MSGL_INFO, "\n Current input: %d\n", i);
1051
for (i = 0; ; i++) {
1052
struct v4l2_fmtdesc fmtdesc;
1055
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1056
if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
1059
mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s): %s\n",
1060
pixfmt2name(fmtdesc.pixelformat), pixfmt2depth(fmtdesc.pixelformat),
1061
fmtdesc.description, vo_format_name(fcc_vl2mp(fmtdesc.pixelformat)));
1063
mp_msg(MSGT_TV, MSGL_INFO, " Current format: %s\n",
1064
pixfmt2name(priv->format.fmt.pix.pixelformat));
1066
/* set some nice defaults */
1067
if (getfmt(priv) < 0) return 0;
1068
priv->format.fmt.pix.width = 640;
1069
priv->format.fmt.pix.height = 480;
1070
if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
1071
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
1072
info.short_name, strerror(errno));
1077
// if (!(priv->capability.capabilities & V4L2_CAP_AUDIO) && !tv_param_force_audio) tv_param_noaudio = 1;
1079
if (priv->capability.capabilities & V4L2_CAP_TUNER) {
1080
struct v4l2_control control;
1081
if (tv_param_amode >= 0) {
1082
mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);
1083
priv->tuner.audmode = amode2v4l(tv_param_amode);
1084
if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
1085
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
1086
info.short_name, strerror(errno));
1087
return TVI_CONTROL_FALSE;
1090
mp_msg(MSGT_TV, MSGL_INFO, "%s: current audio mode is :%s%s%s%s\n", info.short_name,
1091
(priv->tuner.audmode == V4L2_TUNER_MODE_MONO) ? " MONO" : "",
1092
(priv->tuner.audmode == V4L2_TUNER_MODE_STEREO) ? " STEREO" : "",
1093
(priv->tuner.audmode == V4L2_TUNER_MODE_LANG1) ? " LANG1" : "",
1094
(priv->tuner.audmode == V4L2_TUNER_MODE_LANG2) ? " LANG2" : "");
1096
if (tv_param_volume >= 0) {
1097
control.id = V4L2_CID_AUDIO_VOLUME;
1098
control.value = tv_param_volume;
1099
set_control(priv, &control, 0);
1101
if (tv_param_bass >= 0) {
1102
control.id = V4L2_CID_AUDIO_BASS;
1103
control.value = tv_param_bass;
1104
set_control(priv, &control, 0);
1106
if (tv_param_treble >= 0) {
1107
control.id = V4L2_CID_AUDIO_TREBLE;
1108
control.value = tv_param_treble;
1109
set_control(priv, &control, 0);
1111
if (tv_param_balance >= 0) {
1112
control.id = V4L2_CID_AUDIO_BALANCE;
1113
control.value = tv_param_balance;
1114
set_control(priv, &control, 0);
1121
static int get_capture_buffer_size(priv_t *priv)
1124
int w = priv->format.fmt.pix.width;
1125
int h = priv->format.fmt.pix.height;
1126
int d = pixfmt2depth(priv->format.fmt.pix.pixelformat);
1127
int bytesperline = w*d/8;
1129
if (tv_param_buffer_size >= 0) {
1130
bufsize = tv_param_buffer_size*1024*1024;
1132
#ifdef HAVE_SYS_SYSINFO_H
1136
if (si.totalram<2*1024*1024) {
1137
bufsize = 1024*1024;
1139
bufsize = si.totalram/2;
1142
bufsize = 16*1024*1024;
1146
cnt = bufsize/(h*bytesperline);
1147
if (cnt < 2) cnt = 2;
1152
/* that's the real start, we'got the format parameters (checked with control) */
1153
static int start(priv_t *priv)
1155
struct v4l2_requestbuffers request;
1158
/* setup audio parameters */
1161
if (!tv_param_noaudio && !priv->audio_inited) return 0;
1163
/* we need this to size the audio buffer properly */
1164
if (priv->immediate_mode) {
1165
priv->video_buffer_size_max = 2;
1167
priv->video_buffer_size_max = get_capture_buffer_size(priv);
1170
if (!tv_param_noaudio) {
1171
setup_audio_buffer_sizes(priv);
1172
priv->audio_skew_buffer = (long long*)calloc(priv->aud_skew_cnt, sizeof(long long));
1173
if (!priv->audio_skew_buffer) {
1174
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1177
priv->audio_skew_delta_buffer = (long long*)calloc(priv->aud_skew_cnt, sizeof(long long));
1178
if (!priv->audio_skew_delta_buffer) {
1179
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
1183
priv->audio_ringbuffer = (unsigned char*)calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
1184
if (!priv->audio_ringbuffer) {
1185
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
1189
priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate
1190
*priv->audio_in.channels
1191
*priv->audio_in.bytes_per_sample);
1192
priv->audio_usecs_per_block = 1e6*priv->audio_secs_per_block;
1193
priv->audio_head = 0;
1194
priv->audio_tail = 0;
1195
priv->audio_cnt = 0;
1196
priv->audio_drop = 0;
1197
priv->audio_skew = 0;
1198
priv->audio_skew_total = 0;
1199
priv->audio_skew_delta_total = 0;
1200
priv->audio_recv_blocks_total = 0;
1201
priv->audio_sent_blocks_total = 0;
1202
priv->audio_null_blocks_inserted = 0;
1203
priv->audio_insert_null_samples = 0;
1204
priv->dropped_frames_timeshift = 0;
1205
priv->dropped_frames_compensated = 0;
1207
pthread_mutex_init(&priv->skew_mutex, NULL);
1208
pthread_mutex_init(&priv->audio_mutex, NULL);
1211
/* setup video parameters */
1212
if (!tv_param_noaudio) {
1213
if (priv->video_buffer_size_max < (3*priv->standard.frameperiod.denominator) /
1214
priv->standard.frameperiod.numerator
1215
*priv->audio_secs_per_block) {
1216
mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"
1217
"You will probably experience heavy framedrops.\n");
1222
int bytesperline = priv->format.fmt.pix.width*pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1224
mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
1225
priv->video_buffer_size_max,
1226
priv->video_buffer_size_max*priv->format.fmt.pix.height*bytesperline/(1024*1024));
1229
priv->video_ringbuffer = (unsigned char**)calloc(priv->video_buffer_size_max, sizeof(unsigned char*));
1230
if (!priv->video_ringbuffer) {
1231
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
1234
for (i = 0; i < priv->video_buffer_size_max; i++)
1235
priv->video_ringbuffer[i] = NULL;
1236
priv->video_timebuffer = (long long*)calloc(priv->video_buffer_size_max, sizeof(long long));
1237
if (!priv->video_timebuffer) {
1238
mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate time buffer: %s\n", strerror(errno));
1242
pthread_mutex_init(&priv->video_buffer_mutex, NULL);
1244
priv->video_head = 0;
1245
priv->video_tail = 0;
1246
priv->video_cnt = 0;
1248
/* request buffers */
1249
if (priv->immediate_mode) {
1252
request.count = BUFFER_COUNT;
1255
request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1256
request.memory = V4L2_MEMORY_MMAP;
1257
if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
1258
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",
1259
info.short_name, strerror(errno));
1264
if (!(priv->map = calloc(request.count, sizeof(struct map)))) {
1265
mp_msg(MSGT_TV, MSGL_ERR, "%s: malloc capture buffers failed: %s\n",
1266
info.short_name, strerror(errno));
1270
/* map and queue buffers */
1271
for (i = 0; i < request.count; i++) {
1272
memset(&priv->map[i].buf,0,sizeof(priv->map[i].buf));
1273
priv->map[i].buf.index = i;
1274
priv->map[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1275
priv->map[i].buf.memory = V4L2_MEMORY_MMAP;
1276
if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
1277
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",
1278
info.short_name, strerror(errno));
1283
priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |
1284
PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);
1285
if (priv->map[i].addr == MAP_FAILED) {
1286
mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",
1287
info.short_name, strerror(errno));
1288
priv->map[i].len = 0;
1291
priv->map[i].len = priv->map[i].buf.length;
1292
/* count up to make sure this is correct everytime */
1295
if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1296
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1297
info.short_name, strerror(errno));
1302
/* start audio thread */
1304
priv->audio_skew_measure_time = 0;
1305
priv->first_frame = 0;
1306
priv->audio_skew = 0;
1315
#ifdef HAVE_TV_BSDBT848
1316
static double grabimmediate_video_frame(priv_t *priv, char *buffer, int len)
1318
memset(buffer, 0xCC, len);
1321
#endif /* HAVE_TV_BSDBT848 */
1323
// copies a video frame
1324
static inline void copy_frame(priv_t *priv, unsigned char *dest, unsigned char *source)
1326
int w = priv->format.fmt.pix.width;
1327
int h = priv->format.fmt.pix.height;
1328
int d = pixfmt2depth(priv->format.fmt.pix.pixelformat);
1329
int bytesperline = w*d/8;
1331
memcpy(dest, source, bytesperline * h);
1334
// maximum skew change, in frames
1335
#define MAX_SKEW_DELTA 0.6
1336
static void *video_grabber(void *data)
1338
priv_t *priv = (priv_t*)data;
1339
long long skew, prev_skew, xskew, interval, prev_interval, delta;
1342
int framesize = priv->format.fmt.pix.height*priv->format.fmt.pix.width*
1343
pixfmt2depth(priv->format.fmt.pix.pixelformat)/8;
1345
struct timeval timeout;
1346
struct v4l2_buffer buf;
1354
mp_msg(MSGT_TV, MSGL_V, "%s: going to capture\n", info.short_name);
1355
if (ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
1356
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamon failed: %s\n",
1357
info.short_name, strerror(errno));
1362
if (!tv_param_noaudio) {
1363
pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
1366
for (priv->frames = 0; !priv->shutdown;)
1370
if (priv->immediate_mode) {
1371
while (priv->video_cnt == priv->video_buffer_size_max) {
1373
if (priv->shutdown) {
1380
FD_SET (priv->video_fd, &rdset);
1383
timeout.tv_usec = 0;
1385
i = select(priv->video_fd + 1, &rdset, NULL, NULL, &timeout);
1387
mp_msg(MSGT_TV, MSGL_ERR, "%s: select failed: %s\n",
1388
info.short_name, strerror(errno));
1392
mp_msg(MSGT_TV, MSGL_ERR, "%s: select timeout\n", info.short_name);
1395
else if (!FD_ISSET(priv->video_fd, &rdset)) {
1399
memset(&buf,0,sizeof(buf));
1400
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1401
ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
1405
if there's no signal, the buffer might me dequeued
1406
so we query all the buffers to see which one we should
1409
observed with saa7134 0.2.8
1410
don't know if is it a bug or (mis)feature
1412
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl dequeue buffer failed: %s, idx = %d\n",
1413
info.short_name, strerror(errno), buf.index);
1414
for (i = 0; i < priv->mapcount; i++) {
1415
memset(&buf,0,sizeof(buf));
1416
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1418
ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
1420
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s, idx = %d\n",
1421
info.short_name, strerror(errno), buf.index);
1424
if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
1425
if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
1426
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1427
info.short_name, strerror(errno));
1435
/* store the timestamp of the very first frame as reference */
1436
if (!priv->frames++) {
1437
if (!tv_param_noaudio) pthread_mutex_lock(&priv->skew_mutex);
1438
priv->first_frame = (long long)1e6*buf.timestamp.tv_sec + buf.timestamp.tv_usec;
1439
if (!tv_param_noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1441
priv->curr_frame = (long long)buf.timestamp.tv_sec*1e6+buf.timestamp.tv_usec;
1442
// fprintf(stderr, "idx = %d, ts = %lf\n", buf.index, (double)(priv->curr_frame) / 1e6);
1444
interval = priv->curr_frame - priv->first_frame;
1445
delta = interval - prev_interval;
1447
if (!priv->immediate_mode) {
1448
// interpolate the skew in time
1449
if (!tv_param_noaudio) pthread_mutex_lock(&priv->skew_mutex);
1450
xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
1451
if (!tv_param_noaudio) pthread_mutex_unlock(&priv->skew_mutex);
1452
// correct extreme skew changes to avoid (especially) moving backwards in time
1453
if (xskew - prev_skew > delta*MAX_SKEW_DELTA) {
1454
skew = prev_skew + delta*MAX_SKEW_DELTA;
1455
} else if (xskew - prev_skew < -delta*MAX_SKEW_DELTA) {
1456
skew = prev_skew - delta*MAX_SKEW_DELTA;
1462
mp_msg(MSGT_TV, MSGL_DBG3, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1463
delta ? (double)1e6/delta : -1,
1464
(double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
1465
mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
1468
prev_interval = interval;
1470
/* allocate a new buffer, if needed */
1471
pthread_mutex_lock(&priv->video_buffer_mutex);
1472
if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
1473
if (priv->video_cnt == priv->video_buffer_size_current) {
1474
unsigned char *newbuf = (unsigned char*)malloc(framesize);
1476
memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
1477
(priv->video_buffer_size_current-priv->video_tail)*sizeof(unsigned char *));
1478
memmove(priv->video_timebuffer+priv->video_tail+1, priv->video_timebuffer+priv->video_tail,
1479
(priv->video_buffer_size_current-priv->video_tail)*sizeof(long long));
1480
priv->video_ringbuffer[priv->video_tail] = newbuf;
1481
if ((priv->video_head >= priv->video_tail) && (priv->video_cnt > 0)) priv->video_head++;
1482
priv->video_buffer_size_current++;
1486
pthread_mutex_unlock(&priv->video_buffer_mutex);
1488
if (priv->video_cnt == priv->video_buffer_size_current) {
1489
if (!priv->immediate_mode) {
1490
mp_msg(MSGT_TV, MSGL_ERR, "\nvideo buffer full - dropping frame\n");
1491
if (priv->audio_insert_null_samples) {
1492
pthread_mutex_lock(&priv->audio_mutex);
1493
priv->dropped_frames_timeshift += delta;
1494
pthread_mutex_unlock(&priv->audio_mutex);
1498
if (priv->immediate_mode) {
1499
priv->video_timebuffer[priv->video_tail] = 0;
1501
// compensate for audio skew
1502
// negative skew => there are more audio samples, increase interval
1503
// positive skew => less samples, shorten the interval
1504
priv->video_timebuffer[priv->video_tail] = interval - skew;
1505
if (priv->audio_insert_null_samples && priv->video_timebuffer[priv->video_tail] > 0) {
1506
pthread_mutex_lock(&priv->audio_mutex);
1507
priv->video_timebuffer[priv->video_tail] +=
1508
(priv->audio_null_blocks_inserted
1509
- priv->dropped_frames_timeshift/priv->audio_usecs_per_block)
1510
*priv->audio_usecs_per_block;
1511
pthread_mutex_unlock(&priv->audio_mutex);
1515
copy_frame(priv, priv->video_ringbuffer[priv->video_tail], priv->map[buf.index].addr);
1516
priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
1519
if (ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
1520
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
1521
info.short_name, strerror(errno));
1529
static double grab_video_frame(priv_t *priv, char *buffer, int len)
1535
pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1539
while (priv->video_cnt == 0) {
1541
if (loop_cnt++ > MAX_LOOP) return 0;
1544
pthread_mutex_lock(&priv->video_buffer_mutex);
1545
interval = (double)priv->video_timebuffer[priv->video_head]*1e-6;
1546
memcpy(buffer, priv->video_ringbuffer[priv->video_head], len);
1548
priv->video_head = (priv->video_head+1)%priv->video_buffer_size_current;
1549
pthread_mutex_unlock(&priv->video_buffer_mutex);
1554
static int get_video_framesize(priv_t *priv)
1556
return priv->format.fmt.pix.sizeimage;
1559
//#define DOUBLESPEED
1561
// for testing purposes only
1562
static void read_doublespeed(priv_t *priv)
1564
char *bufx = (char*)calloc(priv->audio_in.blocksize, 2);
1569
audio_in_read_chunk(&priv->audio_in, bufx);
1570
audio_in_read_chunk(&priv->audio_in, bufx+priv->audio_in.blocksize);
1573
d = priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize;
1574
for (i = 0; i < priv->audio_in.blocksize/2; i++) {
1582
static void *audio_grabber(void *data)
1584
priv_t *priv = (priv_t*)data;
1586
int i, audio_skew_ptr = 0;
1587
long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
1588
long long start_time_avg;
1590
gettimeofday(&tv, NULL);
1591
start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1592
audio_in_start_capture(&priv->audio_in);
1593
for (i = 0; i < priv->aud_skew_cnt; i++)
1594
priv->audio_skew_buffer[i] = 0;
1595
for (i = 0; i < priv->aud_skew_cnt; i++)
1596
priv->audio_skew_delta_buffer[i] = 0;
1598
for (; !priv->shutdown;)
1601
read_doublespeed(priv);
1603
if (audio_in_read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize) < 0)
1606
pthread_mutex_lock(&priv->skew_mutex);
1607
if (priv->first_frame == 0) {
1608
// there is no first frame yet (unlikely to happen)
1609
gettimeofday(&tv, NULL);
1610
start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
1611
// fprintf(stderr, "warning - first frame not yet available!\n");
1612
pthread_mutex_unlock(&priv->skew_mutex);
1615
pthread_mutex_unlock(&priv->skew_mutex);
1617
gettimeofday(&tv, NULL);
1619
priv->audio_recv_blocks_total++;
1620
current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
1622
if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
1623
start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1624
priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
1627
// fprintf(stderr, "spb = %lf, bs = %d, skew = %lf\n", priv->audio_secs_per_block, priv->audio_in.blocksize,
1628
// (double)(current_time - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total)/1e6);
1630
// put the current skew into the ring buffer
1631
priv->audio_skew_total -= priv->audio_skew_buffer[audio_skew_ptr];
1632
priv->audio_skew_buffer[audio_skew_ptr] = current_time
1633
- priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
1634
priv->audio_skew_total += priv->audio_skew_buffer[audio_skew_ptr];
1636
pthread_mutex_lock(&priv->skew_mutex);
1640
// compute the sliding average of the skews
1641
if (priv->audio_recv_blocks_total > priv->aud_skew_cnt) {
1642
priv->audio_skew = priv->audio_skew_total/priv->aud_skew_cnt;
1644
priv->audio_skew = priv->audio_skew_total/priv->audio_recv_blocks_total;
1647
// put the current skew change (skew-prev_skew) into the ring buffer
1648
priv->audio_skew_delta_total -= priv->audio_skew_delta_buffer[audio_skew_ptr];
1649
priv->audio_skew_delta_buffer[audio_skew_ptr] = priv->audio_skew - prev_skew_uncorr;
1650
priv->audio_skew_delta_total += priv->audio_skew_delta_buffer[audio_skew_ptr];
1651
prev_skew_uncorr = priv->audio_skew; // remember the _uncorrected_ average value
1653
audio_skew_ptr = (audio_skew_ptr+1) % priv->aud_skew_cnt; // rotate the buffer pointer
1655
// sliding average approximates the value in the middle of the interval
1656
// so interpolate the skew value further to the current time
1657
priv->audio_skew += priv->audio_skew_delta_total/2;
1659
// now finally, priv->audio_skew contains fairly good approximation
1660
// of the current value
1662
// current skew factor (assuming linearity)
1663
// used for further interpolation in video_grabber
1664
// probably overkill but seems to be necessary for
1665
// stress testing by dropping half of the audio frames ;)
1666
// especially when using ALSA with large block sizes
1667
// where audio_skew remains a long while behind
1668
if ((priv->audio_skew_measure_time != 0) && (current_time - priv->audio_skew_measure_time != 0)) {
1669
priv->audio_skew_factor = (double)(priv->audio_skew-prev_skew)/(current_time - priv->audio_skew_measure_time);
1671
priv->audio_skew_factor = 0.0;
1674
priv->audio_skew_measure_time = current_time;
1675
prev_skew = priv->audio_skew;
1676
priv->audio_skew += priv->audio_start_time - priv->first_frame;
1677
pthread_mutex_unlock(&priv->skew_mutex);
1679
// fprintf(stderr, "audio_skew = %lf, delta = %lf\n", (double)priv->audio_skew/1e6, (double)priv->audio_skew_delta_total/1e6);
1681
pthread_mutex_lock(&priv->audio_mutex);
1682
if ((priv->audio_tail+1) % priv->audio_buffer_size == priv->audio_head) {
1683
mp_msg(MSGT_TV, MSGL_ERR, "\ntoo bad - dropping audio frame !\n");
1686
priv->audio_tail = (priv->audio_tail+1) % priv->audio_buffer_size;
1689
pthread_mutex_unlock(&priv->audio_mutex);
1694
static double grab_audio_frame(priv_t *priv, char *buffer, int len)
1696
mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1699
// hack: if grab_audio_frame is called first, it means we are used by mplayer
1700
// => switch to the mode which outputs audio immediately, even if
1701
// it should be silence
1702
if (priv->first) priv->audio_insert_null_samples = 1;
1704
pthread_mutex_lock(&priv->audio_mutex);
1705
while (priv->audio_insert_null_samples
1706
&& priv->dropped_frames_timeshift - priv->dropped_frames_compensated >= priv->audio_usecs_per_block) {
1707
// some frames were dropped - drop the corresponding number of audio blocks
1708
if (priv->audio_drop) {
1711
if (priv->audio_head == priv->audio_tail) break;
1712
priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1714
priv->dropped_frames_compensated += priv->audio_usecs_per_block;
1717
// compensate for dropped audio frames
1718
if (priv->audio_drop && (priv->audio_head == priv->audio_tail)) {
1720
memset(buffer, 0, len);
1724
if (priv->audio_insert_null_samples && (priv->audio_head == priv->audio_tail)) {
1725
// return silence to avoid desync and stuttering
1726
memset(buffer, 0, len);
1727
priv->audio_null_blocks_inserted++;
1731
pthread_mutex_unlock(&priv->audio_mutex);
1732
while (priv->audio_head == priv->audio_tail) {
1733
// this is mencoder => just wait until some audio is available
1736
pthread_mutex_lock(&priv->audio_mutex);
1737
memcpy(buffer, priv->audio_ringbuffer+priv->audio_head*priv->audio_in.blocksize, len);
1738
priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1741
pthread_mutex_unlock(&priv->audio_mutex);
1742
priv->audio_sent_blocks_total++;
1743
return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
1746
static int get_audio_framesize(priv_t *priv)
1748
return(priv->audio_in.blocksize);
1751
#endif /* USE_TV && HAVE_TV_V4L2 */