~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libmpdemux/tvi_v4l.c

  • Committer: William Grant
  • Date: 2007-02-03 03:16:07 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: william.grant@ubuntu.org.au-20070203031607-08gc2ompbz6spt9i
Update to 1.0rc1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
  Video 4 Linux input
3
 
 
4
 
  (C) Alex Beregszaszi
5
 
  
6
 
  Some ideas are based on xawtv/libng's grab-v4l.c written by
7
 
    Gerd Knorr <kraxel@bytesex.org>
8
 
 
9
 
  Multithreading, a/v sync and native ALSA support by
10
 
    Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>
11
 
 
12
 
  Mjpeg hardware encoding support by 
13
 
    Iv�n Sz�nt� <szivan@freemail.hu>
14
 
 
15
 
  CODE IS UNDER DEVELOPMENT, NO FEATURE REQUESTS PLEASE!
16
 
*/
17
 
 
18
 
#include "config.h"
19
 
 
20
 
#if defined(USE_TV) && defined(HAVE_TV_V4L)
21
 
 
22
 
#include <stdio.h>
23
 
#include <errno.h>
24
 
#include <fcntl.h>
25
 
#include <signal.h>
26
 
#include <sys/ioctl.h>
27
 
#include <sys/types.h>
28
 
#include <sys/time.h>
29
 
 
30
 
/* Necessary to prevent collisions between <linux/time.h> and <sys/time.h> when V4L2 is installed. */
31
 
#define _LINUX_TIME_H
32
 
 
33
 
#include <linux/videodev.h>
34
 
#include <unistd.h>
35
 
#include <sys/mman.h>
36
 
#include <stdlib.h>
37
 
#include <string.h>
38
 
#include <pthread.h>
39
 
#ifdef HAVE_SYS_SYSINFO_H
40
 
#include <sys/sysinfo.h>
41
 
#endif
42
 
 
43
 
#include "mp_msg.h"
44
 
#include "libaf/af_format.h"
45
 
#include "libvo/img_format.h"
46
 
#include "libvo/fastmemcpy.h"
47
 
#include "libvo/videodev_mjpeg.h"
48
 
 
49
 
#include "tv.h"
50
 
 
51
 
#include "audio_in.h"
52
 
 
53
 
static tvi_info_t info = {
54
 
        "Video 4 Linux input",
55
 
        "v4l",
56
 
        "Alex Beregszaszi",
57
 
        "under development"
58
 
};
59
 
 
60
 
#define PAL_WIDTH  768
61
 
#define PAL_HEIGHT 576
62
 
#define PAL_FPS    25
63
 
 
64
 
#define NTSC_WIDTH  640
65
 
#define NTSC_HEIGHT 480
66
 
#define NTSC_FPS    (30000.0/1001.0)
67
 
 
68
 
#define MAX_AUDIO_CHANNELS      10
69
 
 
70
 
#define VID_BUF_SIZE_IMMEDIATE 2
71
 
#define VIDEO_AVG_BUFFER_SIZE 600
72
 
 
73
 
typedef struct {
74
 
    /* general */
75
 
    char                        *video_device;
76
 
    int                         video_fd;
77
 
    struct video_capability     capability;
78
 
    struct video_channel        *channels;
79
 
    int                         act_channel;
80
 
    struct video_tuner          tuner;
81
 
 
82
 
    /* video */
83
 
    struct video_picture        picture;
84
 
    int                         format;         /* output format */
85
 
    int                         width;
86
 
    int                         height;
87
 
    int                         bytesperline;
88
 
    float                       fps;
89
 
 
90
 
    struct video_mbuf           mbuf;
91
 
    unsigned char               *mmap;
92
 
    struct video_mmap           *buf;
93
 
    int                         nbuf;
94
 
 
95
 
    /* audio */
96
 
    char                        *audio_device;
97
 
    audio_in_t                  audio_in;
98
 
 
99
 
    int                         audio_id;
100
 
    struct video_audio          audio[MAX_AUDIO_CHANNELS];
101
 
    int                         audio_channels[MAX_AUDIO_CHANNELS];
102
 
 
103
 
    /* buffering stuff */
104
 
    int                         immediate_mode;
105
 
 
106
 
    int                         audio_buffer_size;
107
 
    int                         aud_skew_cnt;
108
 
    unsigned char               *audio_ringbuffer;
109
 
    long long                   *audio_skew_buffer;
110
 
    volatile int                audio_head;
111
 
    volatile int                audio_tail;
112
 
    volatile int                audio_cnt;
113
 
    volatile long long          audio_skew;
114
 
    volatile double             audio_skew_factor;
115
 
    volatile long long          audio_skew_measure_time;
116
 
    volatile int                audio_drop;
117
 
 
118
 
    int                         first;
119
 
    int                         video_buffer_size_max;
120
 
    volatile int                video_buffer_size_current;
121
 
    unsigned char               **video_ringbuffer;
122
 
    long long                   *video_timebuffer;
123
 
    long long                   *video_avg_buffer;
124
 
    int                         video_avg_ptr;
125
 
    int                         video_interval_sum;
126
 
    volatile int                video_head;
127
 
    volatile int                video_tail;
128
 
    volatile int                video_cnt;
129
 
 
130
 
    volatile int                shutdown;
131
 
 
132
 
    pthread_t                   audio_grabber_thread;
133
 
    pthread_t                   video_grabber_thread;
134
 
    pthread_mutex_t             audio_starter;
135
 
    pthread_mutex_t             skew_mutex;
136
 
    pthread_mutex_t             video_buffer_mutex;
137
 
 
138
 
    long long                   starttime;
139
 
    double                      audio_secs_per_block;
140
 
    long long                   audio_skew_total;
141
 
    long                        audio_recv_blocks_total;
142
 
    long                        audio_sent_blocks_total;
143
 
    long                        mjpeg_bufsize;
144
 
    
145
 
} priv_t;
146
 
 
147
 
#include "tvi_def.h"
148
 
 
149
 
static const char *device_cap2name[] = {
150
 
    "capture", "tuner", "teletext", "overlay", "chromakey", "clipping",
151
 
    "frameram", "scales", "monochrome", "subcapture", "mpeg-decoder",
152
 
    "mpeg-encoder", "mjpeg-decoder", "mjpeg-encoder", NULL
153
 
};
154
 
 
155
 
static const char *device_palette2name[] = {
156
 
    "-", "grey", "hi240", "rgb16", "rgb24", "rgb32", "rgb15", "yuv422",
157
 
    "yuyv", "uyvy", "yuv420", "yuv411", "raw", "yuv422p", "yuv411p",
158
 
    "yuv420p", "yuv410p"
159
 
};
160
 
#define PALETTE(x) ((x < sizeof(device_palette2name)/sizeof(char*)) ? device_palette2name[x] : "UNKNOWN")
161
 
 
162
 
static const char *norm2name(int mode)
163
 
{
164
 
    switch (mode) {
165
 
    case VIDEO_MODE_PAL:
166
 
        return "pal";
167
 
    case VIDEO_MODE_SECAM:
168
 
        return "secam";
169
 
    case VIDEO_MODE_NTSC:
170
 
        return "ntsc";
171
 
    case VIDEO_MODE_AUTO:
172
 
        return "auto";
173
 
    default:
174
 
        return "unknown";
175
 
    }
176
 
};
177
 
 
178
 
static const char *audio_mode2name(int mode)
179
 
{
180
 
    switch (mode) {
181
 
    case VIDEO_SOUND_MONO:
182
 
        return "mono";
183
 
    case VIDEO_SOUND_STEREO:
184
 
        return "stereo";
185
 
    case VIDEO_SOUND_LANG1:
186
 
        return "language1";
187
 
    case VIDEO_SOUND_LANG2:
188
 
        return "language2";
189
 
    default:
190
 
        return "unknown";
191
 
    }
192
 
};
193
 
 
194
 
static void *audio_grabber(void *data);
195
 
static void *video_grabber(void *data);
196
 
 
197
 
static int palette2depth(int palette)
198
 
{
199
 
    switch(palette)
200
 
    {
201
 
        /* component */
202
 
        case VIDEO_PALETTE_RGB555:
203
 
            return(15);
204
 
        case VIDEO_PALETTE_RGB565:
205
 
            return(16);
206
 
        case VIDEO_PALETTE_RGB24:
207
 
            return(24);
208
 
        case VIDEO_PALETTE_RGB32:
209
 
            return(32);
210
 
        /* planar */
211
 
        case VIDEO_PALETTE_YUV411P:
212
 
        case VIDEO_PALETTE_YUV420P:
213
 
        case VIDEO_PALETTE_YUV410P:
214
 
            return(12);
215
 
        /* packed */
216
 
        case VIDEO_PALETTE_YUV422P:
217
 
        case VIDEO_PALETTE_YUV422:
218
 
        case VIDEO_PALETTE_YUYV:
219
 
        case VIDEO_PALETTE_UYVY:
220
 
        case VIDEO_PALETTE_YUV420:
221
 
        case VIDEO_PALETTE_YUV411:
222
 
            return(16);
223
 
    }
224
 
    return(-1);
225
 
}
226
 
 
227
 
static int format2palette(int format)
228
 
{
229
 
    switch(format)
230
 
    {
231
 
        case IMGFMT_BGR15:
232
 
            return(VIDEO_PALETTE_RGB555);
233
 
        case IMGFMT_BGR16:
234
 
            return(VIDEO_PALETTE_RGB565);
235
 
        case IMGFMT_BGR24:
236
 
            return(VIDEO_PALETTE_RGB24);
237
 
        case IMGFMT_BGR32:
238
 
            return(VIDEO_PALETTE_RGB32);
239
 
        case IMGFMT_YV12:
240
 
        case IMGFMT_I420:
241
 
            return(VIDEO_PALETTE_YUV420P);
242
 
        case IMGFMT_YUY2:
243
 
            return(VIDEO_PALETTE_YUV422);
244
 
    case IMGFMT_UYVY:
245
 
       return(VIDEO_PALETTE_UYVY);
246
 
    }
247
 
    return(-1);
248
 
}
249
 
 
250
 
// sets and sanitizes audio buffer/block sizes
251
 
static void setup_audio_buffer_sizes(priv_t *priv)
252
 
{
253
 
    int bytes_per_sample = priv->audio_in.bytes_per_sample;
254
 
 
255
 
    // make the audio buffer at least 5 seconds long
256
 
    priv->audio_buffer_size = 1 + 5*priv->audio_in.samplerate
257
 
        *priv->audio_in.channels
258
 
        *bytes_per_sample/priv->audio_in.blocksize;
259
 
    if (priv->audio_buffer_size < 256) priv->audio_buffer_size = 256;
260
 
 
261
 
    // make the skew buffer at least 1 second long
262
 
    priv->aud_skew_cnt = 1 + 1*priv->audio_in.samplerate
263
 
        *priv->audio_in.channels
264
 
        *bytes_per_sample/priv->audio_in.blocksize;
265
 
    if (priv->aud_skew_cnt < 16) priv->aud_skew_cnt = 16;
266
 
 
267
 
    mp_msg(MSGT_TV, MSGL_V, "Audio capture - buffer %d blocks of %d bytes, skew average from %d meas.\n",
268
 
           priv->audio_buffer_size, priv->audio_in.blocksize, priv->aud_skew_cnt);
269
 
}
270
 
 
271
 
tvi_handle_t *tvi_init_v4l(char *device, char *adevice)
272
 
{
273
 
    tvi_handle_t *h;
274
 
    priv_t *priv;
275
 
    
276
 
    h = new_handle();
277
 
    if (!h)
278
 
        return(NULL);
279
 
 
280
 
    priv = h->priv;
281
 
 
282
 
    /* set video device name */
283
 
    if (!device)
284
 
        priv->video_device = strdup("/dev/video0");
285
 
    else
286
 
        priv->video_device = strdup(device);
287
 
 
288
 
    /* set video device name */
289
 
    if (!adevice)
290
 
        priv->audio_device = NULL;
291
 
    else {
292
 
        priv->audio_device = strdup(adevice);
293
 
    }
294
 
    
295
 
    /* allocation failed */
296
 
    if (!priv->video_device) {
297
 
        free_handle(h);
298
 
        return(NULL);
299
 
    }
300
 
 
301
 
    return(h);
302
 
}
303
 
 
304
 
/* retrieves info about audio channels from the BTTV */
305
 
static void init_v4l_audio(priv_t *priv)
306
 
{
307
 
    int i;
308
 
    int reqmode;
309
 
 
310
 
    if (!priv->capability.audios) return;
311
 
 
312
 
    /* audio chanlist */
313
 
 
314
 
    mp_msg(MSGT_TV, MSGL_V, " Audio devices: %d\n", priv->capability.audios);
315
 
 
316
 
    mp_msg(MSGT_TV, MSGL_V, "Video capture card reports the audio setup as follows:\n");
317
 
    for (i = 0; i < priv->capability.audios; i++)
318
 
    {
319
 
        if (i >= MAX_AUDIO_CHANNELS)
320
 
        {
321
 
            mp_msg(MSGT_TV, MSGL_ERR, "no space for more audio channels (increase in source!) (%d > %d)\n",
322
 
                   i, MAX_AUDIO_CHANNELS);
323
 
            i = priv->capability.audios;
324
 
            break;
325
 
        }
326
 
 
327
 
        priv->audio[i].audio = i;
328
 
        if (ioctl(priv->video_fd, VIDIOCGAUDIO, &priv->audio[i]) == -1)
329
 
        {
330
 
            mp_msg(MSGT_TV, MSGL_ERR, "ioctl get audio failed: %s\n", strerror(errno));
331
 
            break;
332
 
        }
333
 
 
334
 
        /* mute all channels */
335
 
        priv->audio[i].flags |= VIDEO_AUDIO_MUTE;
336
 
        reqmode = -1;
337
 
        if (tv_param_amode >= 0) {
338
 
            switch (tv_param_amode) {
339
 
            case 0:
340
 
                reqmode = VIDEO_SOUND_MONO;
341
 
                break;
342
 
            case 1:
343
 
                reqmode = VIDEO_SOUND_STEREO;
344
 
                break;
345
 
            case 2:
346
 
                reqmode = VIDEO_SOUND_LANG1;
347
 
                break;
348
 
            case 3:
349
 
                reqmode = VIDEO_SOUND_LANG2;
350
 
                break;
351
 
            default:
352
 
                mp_msg(MSGT_TV, MSGL_ERR, "Unknown audio mode requested.\n");
353
 
                break;
354
 
            }
355
 
            if (reqmode >= 0) priv->audio[i].mode = reqmode;
356
 
        }
357
 
        ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[i]);
358
 
        
359
 
        // get the parameters back
360
 
        if (ioctl(priv->video_fd, VIDIOCGAUDIO, &priv->audio[i]) == -1)
361
 
        {
362
 
            mp_msg(MSGT_TV, MSGL_ERR, "ioctl get audio failed: %s\n", strerror(errno));
363
 
            break;
364
 
        }
365
 
            
366
 
        switch(priv->audio[i].mode)
367
 
        {
368
 
        case VIDEO_SOUND_MONO:
369
 
        case VIDEO_SOUND_LANG1:
370
 
        case VIDEO_SOUND_LANG2:
371
 
            priv->audio_channels[i] = 1;
372
 
            break;
373
 
        case VIDEO_SOUND_STEREO:
374
 
            priv->audio_channels[i] = 2;
375
 
            break;
376
 
        default:
377
 
            mp_msg(MSGT_TV, MSGL_ERR, "Card reports an unknown audio mode !\n");
378
 
            mp_msg(MSGT_TV, MSGL_ERR, "Trying two channel audio. Use forcechan to override.\n");
379
 
            priv->audio_channels[i] = 2;
380
 
            break;
381
 
        }
382
 
 
383
 
        if (reqmode >= 0 && priv->audio[i].mode != reqmode) {
384
 
            mp_msg(MSGT_TV, MSGL_ERR, "Audio mode setup warning!\n");
385
 
            mp_msg(MSGT_TV, MSGL_ERR, "Requested mode was %s, but v4l still reports %s.\n",
386
 
                   audio_mode2name(reqmode), audio_mode2name(priv->audio[i].mode));
387
 
            mp_msg(MSGT_TV, MSGL_ERR, "You may need \"forcechan\" option to force stereo/mono audio recording.\n");
388
 
        }
389
 
 
390
 
        /* display stuff */
391
 
        mp_msg(MSGT_TV, MSGL_V, "  %d: %s: ", priv->audio[i].audio,
392
 
               priv->audio[i].name);
393
 
        if (priv->audio[i].flags & VIDEO_AUDIO_MUTABLE) {
394
 
            mp_msg(MSGT_TV, MSGL_V, "muted=%s ",
395
 
                   (priv->audio[i].flags & VIDEO_AUDIO_MUTE) ? "yes" : "no");
396
 
        }
397
 
        mp_msg(MSGT_TV, MSGL_V, "vol=%d bass=%d treble=%d balance=%d mode=%s",
398
 
               priv->audio[i].volume, priv->audio[i].bass, priv->audio[i].treble,
399
 
               priv->audio[i].balance, audio_mode2name(priv->audio[i].mode));
400
 
        mp_msg(MSGT_TV, MSGL_V, " chan=%d\n", priv->audio_channels[i]);
401
 
 
402
 
        if (tv_param_forcechan >= 0)
403
 
            priv->audio_channels[i] = tv_param_forcechan;
404
 
 
405
 
        // we'll call VIDIOCSAUDIO again when starting capture
406
 
        // let's set audio mode to requested mode again for the case
407
 
        // when VIDIOCGAUDIO just cannot report the mode correctly
408
 
        if (reqmode >= 0) priv->audio[i].mode = reqmode;
409
 
    }
410
 
}
411
 
 
412
 
#if !defined(__LINUX_VIDEODEV2_H) && !defined(VIDIOC_QUERYCAP)
413
 
struct v4l2_capability
414
 
{
415
 
        __u8    driver[16];     /* i.e. "bttv" */
416
 
        __u8    card[32];       /* i.e. "Hauppauge WinTV" */
417
 
        __u8    bus_info[32];   /* "PCI:" + pci_dev->slot_name */
418
 
        __u32   version;        /* should use KERNEL_VERSION() */
419
 
        __u32   capabilities;   /* Device capabilities */
420
 
        __u32   reserved[4];
421
 
};
422
 
 
423
 
#define VIDIOC_QUERYCAP         _IOR  ('V',  0, struct v4l2_capability)
424
 
#endif
425
 
 
426
 
static int init(priv_t *priv)
427
 
{
428
 
    int i;
429
 
 
430
 
    if (tv_param_immediate == 1)
431
 
        tv_param_noaudio = 1;
432
 
    
433
 
    priv->video_ringbuffer = NULL;
434
 
    priv->video_timebuffer = NULL;
435
 
    priv->video_avg_buffer = NULL;
436
 
    priv->audio_ringbuffer = NULL;
437
 
    priv->audio_skew_buffer = NULL;
438
 
 
439
 
    priv->video_fd = open(priv->video_device, O_RDWR);
440
 
    mp_msg(MSGT_TV, MSGL_DBG2, "Video fd: %d, %p\n", priv->video_fd,
441
 
        priv->video_device);
442
 
    if (priv->video_fd == -1)
443
 
    {
444
 
        mp_msg(MSGT_TV, MSGL_ERR, "unable to open '%s': %s\n",
445
 
            priv->video_device, strerror(errno));
446
 
        goto err;
447
 
    }
448
 
    
449
 
    /* check for v4l2 */
450
 
    if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) == 0) {
451
 
        mp_msg(MSGT_TV, MSGL_ERR, "=================================================================\n");
452
 
        mp_msg(MSGT_TV, MSGL_ERR, " WARNING: YOU ARE USING V4L DEMUXER WITH V4L2 DRIVERS!!!\n");
453
 
        mp_msg(MSGT_TV, MSGL_ERR, " As the V4L1 compatibility layer is broken, this may not work.\n");
454
 
        mp_msg(MSGT_TV, MSGL_ERR, " If you encounter any problems, use driver=v4l2 instead.\n");
455
 
        mp_msg(MSGT_TV, MSGL_ERR, " Bugreports on driver=v4l with v4l2 drivers will be ignored.\n");
456
 
        mp_msg(MSGT_TV, MSGL_ERR, "=================================================================\n");
457
 
    }
458
 
    
459
 
    /* get capabilities (priv->capability is needed!) */
460
 
    if (ioctl(priv->video_fd, VIDIOCGCAP, &priv->capability) == -1)
461
 
    {
462
 
        mp_msg(MSGT_TV, MSGL_ERR, "ioctl get capabilites failed: %s\n", strerror(errno));
463
 
        goto err;
464
 
    }
465
 
 
466
 
    fcntl(priv->video_fd, F_SETFD, FD_CLOEXEC);
467
 
 
468
 
    mp_msg(MSGT_TV, MSGL_INFO, "Selected device: %s\n", priv->capability.name);
469
 
    mp_msg(MSGT_TV, MSGL_INFO, " Capabilites: ");
470
 
    for (i = 0; device_cap2name[i] != NULL; i++)
471
 
        if (priv->capability.type & (1 << i))
472
 
            mp_msg(MSGT_TV, MSGL_INFO, "%s ", device_cap2name[i]);
473
 
    mp_msg(MSGT_TV, MSGL_INFO, "\n");
474
 
    mp_msg(MSGT_TV, MSGL_INFO, " Device type: %d\n", priv->capability.type);
475
 
    mp_msg(MSGT_TV, MSGL_INFO, " Supported sizes: %dx%d => %dx%d\n",
476
 
        priv->capability.minwidth, priv->capability.minheight,
477
 
        priv->capability.maxwidth, priv->capability.maxheight);
478
 
    priv->width = priv->capability.minwidth;
479
 
    priv->height = priv->capability.minheight;
480
 
 
481
 
    /* somewhere here could disable tv_param_mjpeg, if it is not a capability */
482
 
 
483
 
    /* initialize if necessary */
484
 
    if ( tv_param_mjpeg )
485
 
      {
486
 
        struct mjpeg_params bparm;
487
 
        struct mjpeg_requestbuffers breq;          /* buffer requests */
488
 
 
489
 
        if (ioctl(priv->video_fd, MJPIOC_G_PARAMS, &bparm) < 0)
490
 
        {
491
 
           mp_msg(MSGT_TV, MSGL_ERR, 
492
 
              "  MJP: Error getting video parameters: %s\n", strerror(errno));
493
 
           goto err;
494
 
        }
495
 
 
496
 
        mp_msg(MSGT_TV, MSGL_INFO, 
497
 
               "  MJP: previous params: x: %d, y: %d, w: %d, h: %d, decim: %d, fields: %d,\n",
498
 
                   bparm.img_x, bparm.img_y, bparm.img_width, bparm.img_height,          
499
 
                   bparm.decimation, bparm.field_per_buff);
500
 
 
501
 
        mp_msg(MSGT_TV, MSGL_INFO, 
502
 
               "  MJP: HorDcm: %d, VerDcm: %d, TmpDcm: %d\n",
503
 
                   bparm.HorDcm, bparm.VerDcm, bparm.TmpDcm);
504
 
 
505
 
        bparm.input = tv_param_input; /* tv */
506
 
        if (!strcasecmp(tv_param_norm, "pal"))
507
 
          bparm.norm =  0; /* PAL */
508
 
        else if (!strcasecmp(tv_param_norm, "ntsc"))
509
 
          bparm.norm =  1; /* NTSC */
510
 
        else if (!strcasecmp(tv_param_norm, "secam"))
511
 
          bparm.norm =  2; /* SECAM */
512
 
        bparm.quality = tv_param_quality;
513
 
        bparm.decimation = tv_param_decimation;
514
 
 
515
 
        mp_msg(MSGT_TV, MSGL_INFO, "  MJP: setting params to decimation: %d, quality: %d\n", 
516
 
                                         bparm.decimation, bparm.quality);
517
 
 
518
 
        if (ioctl(priv->video_fd, MJPIOC_S_PARAMS, &bparm) < 0)
519
 
         {
520
 
            mp_msg(MSGT_TV, MSGL_ERR,
521
 
               "  MJP: Error setting video parameters: %s\n", strerror(errno));
522
 
            goto err;
523
 
         }
524
 
 
525
 
        if (ioctl(priv->video_fd, MJPIOC_G_PARAMS, &bparm) < 0)
526
 
        {
527
 
           mp_msg(MSGT_TV, MSGL_ERR, 
528
 
              "  MJP: Error getting video parameters: %s\n", strerror(errno));
529
 
           goto err;
530
 
        }
531
 
 
532
 
        mp_msg(MSGT_TV, MSGL_INFO, 
533
 
               "  MJP: current params: x: %d, y: %d, w: %d, h: %d, decim: %d, fields: %d,\n",
534
 
                   bparm.img_x, bparm.img_y, bparm.img_width, bparm.img_height,          
535
 
                   bparm.decimation, bparm.field_per_buff);
536
 
 
537
 
        mp_msg(MSGT_TV, MSGL_INFO, 
538
 
               "  MJP: HorDcm: %d, VerDcm: %d, TmpDcm: %d\n",
539
 
                   bparm.HorDcm, bparm.VerDcm, bparm.TmpDcm);
540
 
 
541
 
 
542
 
        breq.count = 64;
543
 
        priv -> nbuf = breq.count;
544
 
        priv->mbuf.frames = priv -> nbuf;
545
 
        priv->mjpeg_bufsize = 256*1024;
546
 
        if (tv_param_buffer_size >= 0) {
547
 
          priv->mjpeg_bufsize = tv_param_buffer_size*1024;
548
 
          }
549
 
        breq.size  = priv -> mjpeg_bufsize;
550
 
        if (ioctl(priv->video_fd, MJPIOC_REQBUFS,&(breq)) < 0)
551
 
        {
552
 
           mp_msg (MSGT_TV, MSGL_ERR,
553
 
              "  MJP: Error requesting video buffers: %s\n", strerror(errno));
554
 
           goto err;
555
 
        }
556
 
        mp_msg(MSGT_TV, MSGL_INFO,
557
 
           "  MJP: Got %ld buffers of size %ld KB\n", 
558
 
                    breq.count, breq.size/1024);
559
 
 
560
 
        priv -> mmap = mmap(0, breq.count * breq.size, 
561
 
           PROT_READ|PROT_WRITE, MAP_SHARED, priv->video_fd, 0);
562
 
        if (priv -> mmap == MAP_FAILED)
563
 
        {
564
 
           mp_msg(MSGT_TV, MSGL_INFO,
565
 
              "  MJP: Error mapping video buffers: %s\n", strerror(errno));
566
 
           goto err;
567
 
        }
568
 
      }
569
 
 
570
 
    mp_msg(MSGT_TV, MSGL_INFO, " Inputs: %d\n", priv->capability.channels);
571
 
    priv->channels = (struct video_channel *)calloc(priv->capability.channels, sizeof(struct video_channel));
572
 
    if (!priv->channels)
573
 
        goto malloc_failed;
574
 
    memset(priv->channels, 0, sizeof(struct video_channel)*priv->capability.channels);
575
 
    for (i = 0; i < priv->capability.channels; i++)
576
 
    {
577
 
        priv->channels[i].channel = i;
578
 
        if (ioctl(priv->video_fd, VIDIOCGCHAN, &priv->channels[i]) == -1)
579
 
        {
580
 
            mp_msg(MSGT_TV, MSGL_ERR, "ioctl get channel failed: %s\n", strerror(errno));
581
 
            break;
582
 
        }
583
 
        mp_msg(MSGT_TV, MSGL_INFO, "  %d: %s: %s%s%s%s (tuner:%d, norm:%s)\n", i,
584
 
            priv->channels[i].name,
585
 
            (priv->channels[i].flags & VIDEO_VC_TUNER) ? "tuner " : "",
586
 
            (priv->channels[i].flags & VIDEO_VC_AUDIO) ? "audio " : "",
587
 
            (priv->channels[i].flags & VIDEO_TYPE_TV) ? "tv " : "",
588
 
            (priv->channels[i].flags & VIDEO_TYPE_CAMERA) ? "camera " : "",
589
 
            priv->channels[i].tuners,
590
 
            norm2name(priv->channels[i].norm));
591
 
    }
592
 
    priv->act_channel = 0;
593
 
 
594
 
    if (!(priv->capability.type & VID_TYPE_CAPTURE))
595
 
    {
596
 
        mp_msg(MSGT_TV, MSGL_ERR, "Only grabbing supported (for overlay use another program)\n");
597
 
        goto err;
598
 
    }
599
 
    
600
 
    if ( !tv_param_mjpeg )
601
 
    {
602
 
    /* map grab buffer */
603
 
    if (ioctl(priv->video_fd, VIDIOCGMBUF, &priv->mbuf) == -1)
604
 
    {
605
 
        mp_msg(MSGT_TV, MSGL_ERR, "ioctl get mbuf failed: %s\n", strerror(errno));
606
 
        goto err;
607
 
    }
608
 
 
609
 
    mp_msg(MSGT_TV, MSGL_V, "mbuf: size=%d, frames=%d\n",
610
 
        priv->mbuf.size, priv->mbuf.frames);
611
 
    priv->mmap = mmap(0, priv->mbuf.size, PROT_READ|PROT_WRITE,
612
 
                MAP_SHARED, priv->video_fd, 0);
613
 
    if (priv->mmap == (unsigned char *)-1)
614
 
    {
615
 
        mp_msg(MSGT_TV, MSGL_ERR, "Unable to map memory for buffers: %s\n", strerror(errno));
616
 
        goto err;
617
 
    }
618
 
    mp_msg(MSGT_TV, MSGL_DBG2, "our buffer: %p\n", priv->mmap);
619
 
 
620
 
    /* num of buffers */
621
 
    priv->nbuf = priv->mbuf.frames;
622
 
    
623
 
    /* video buffers */
624
 
    priv->buf = (struct video_mmap *)calloc(priv->nbuf, sizeof(struct video_mmap));
625
 
    if (!priv->buf)
626
 
        goto malloc_failed;
627
 
    memset(priv->buf, 0, priv->nbuf * sizeof(struct video_mmap));
628
 
    }
629
 
    
630
 
    /* init v4l audio even when we don't capture */
631
 
    init_v4l_audio(priv);
632
 
 
633
 
    if (!priv->capability.audios && !tv_param_force_audio) tv_param_noaudio = 1;
634
 
 
635
 
    /* audio init */
636
 
    if (!tv_param_noaudio) {
637
 
        
638
 
#if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
639
 
        if (tv_param_alsa)
640
 
            audio_in_init(&priv->audio_in, AUDIO_IN_ALSA);
641
 
        else
642
 
            audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
643
 
#else
644
 
        audio_in_init(&priv->audio_in, AUDIO_IN_OSS);
645
 
#endif
646
 
 
647
 
        if (priv->audio_device) {
648
 
            audio_in_set_device(&priv->audio_in, priv->audio_device);
649
 
        }
650
 
 
651
 
        if (tv_param_audio_id < priv->capability.audios)
652
 
            priv->audio_id = tv_param_audio_id;
653
 
        else
654
 
            priv->audio_id = 0;
655
 
        audio_in_set_samplerate(&priv->audio_in, 44100);
656
 
        if (priv->capability.audios) {
657
 
            audio_in_set_channels(&priv->audio_in, priv->audio_channels[priv->audio_id]);
658
 
        } else {
659
 
            if (tv_param_forcechan >= 0) {
660
 
                audio_in_set_channels(&priv->audio_in, tv_param_forcechan);
661
 
            } else {
662
 
                audio_in_set_channels(&priv->audio_in, 2);
663
 
            }
664
 
        }
665
 
        if (audio_in_setup(&priv->audio_in) < 0) return 0;
666
 
        setup_audio_buffer_sizes(priv);
667
 
    }
668
 
 
669
 
    return(1);
670
 
 
671
 
malloc_failed:
672
 
    if (priv->channels)
673
 
        free(priv->channels);
674
 
    if (priv->buf)
675
 
        free(priv->buf);
676
 
err:
677
 
    if (priv->video_fd != -1)
678
 
        close(priv->video_fd);
679
 
    return(0);
680
 
}
681
 
 
682
 
static int uninit(priv_t *priv)
683
 
{
684
 
    unsigned long num;
685
 
    priv->shutdown = 1;
686
 
 
687
 
    mp_msg(MSGT_TV, MSGL_V, "Waiting for threads to finish... ");
688
 
    if (!tv_param_noaudio) {
689
 
        pthread_join(priv->audio_grabber_thread, NULL);
690
 
        pthread_mutex_destroy(&priv->audio_starter);
691
 
        pthread_mutex_destroy(&priv->skew_mutex);
692
 
    }
693
 
    pthread_mutex_destroy(&priv->video_buffer_mutex);
694
 
    pthread_join(priv->video_grabber_thread, NULL);
695
 
    mp_msg(MSGT_TV, MSGL_V, "done\n");
696
 
 
697
 
    if (priv->capability.audios) {
698
 
        priv->audio[priv->audio_id].flags |= VIDEO_AUDIO_MUTE;
699
 
        ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]);
700
 
    }
701
 
    
702
 
    if ( tv_param_mjpeg )
703
 
      {
704
 
        num = -1;
705
 
        if (ioctl(priv->video_fd, MJPIOC_QBUF_CAPT, &num) < 0)
706
 
          {
707
 
            mp_msg(MSGT_TV, MSGL_ERR, "\n  MJP: ioctl MJPIOC_QBUF_CAPT failed: %s\n", strerror(errno));
708
 
          }
709
 
      }
710
 
    else
711
 
      {
712
 
        // We need to munmap as close don't close mem mappings
713
 
        if(munmap(priv->mmap,priv->mbuf.size))
714
 
          mp_msg(MSGT_TV, MSGL_ERR, "Munmap failed: %s\n",strerror(errno));
715
 
      }
716
 
 
717
 
    if(close(priv->video_fd))
718
 
      mp_msg(MSGT_TV, MSGL_ERR, "Close tv failed: %s\n",strerror(errno));
719
 
 
720
 
    audio_in_uninit(&priv->audio_in);
721
 
 
722
 
    if (priv->video_ringbuffer) {
723
 
        int i;
724
 
        for (i = 0; i < priv->video_buffer_size_current; i++) {
725
 
            free(priv->video_ringbuffer[i]);
726
 
        }
727
 
        free(priv->video_ringbuffer);
728
 
    }
729
 
    
730
 
    if (priv->video_timebuffer)
731
 
        free(priv->video_timebuffer);
732
 
    if (priv->video_avg_buffer)
733
 
        free(priv->video_avg_buffer);
734
 
    if (!tv_param_noaudio) {
735
 
        if (priv->audio_ringbuffer)
736
 
            free(priv->audio_ringbuffer);
737
 
        if (priv->audio_skew_buffer)
738
 
            free(priv->audio_skew_buffer);
739
 
    }
740
 
 
741
 
    return(1);
742
 
}
743
 
 
744
 
static int get_capture_buffer_size(priv_t *priv)
745
 
{
746
 
    int bufsize, cnt;
747
 
 
748
 
    if (tv_param_buffer_size >= 0) {
749
 
        bufsize = tv_param_buffer_size*1024*1024;
750
 
    } else {
751
 
#ifdef HAVE_SYS_SYSINFO_H
752
 
        struct sysinfo si;
753
 
        
754
 
        sysinfo(&si);
755
 
        if (si.totalram<2*1024*1024) {
756
 
            bufsize = 1024*1024;
757
 
        } else {
758
 
            bufsize = si.totalram/2;
759
 
        }
760
 
#else
761
 
        bufsize = 16*1024*1024;
762
 
#endif
763
 
    }
764
 
    
765
 
    cnt = bufsize/(priv->height*priv->bytesperline);
766
 
    if (cnt < 2) cnt = 2;
767
 
    
768
 
    return cnt;
769
 
}
770
 
 
771
 
static int start(priv_t *priv)
772
 
{
773
 
    int i;
774
 
    int bytes_per_sample;
775
 
    
776
 
    if (ioctl(priv->video_fd, VIDIOCGPICT, &priv->picture) == -1)
777
 
    {
778
 
        mp_msg(MSGT_TV, MSGL_ERR, "ioctl get picture failed: %s\n", strerror(errno));
779
 
        return(0);
780
 
    }
781
 
 
782
 
    priv->picture.palette = format2palette(priv->format);
783
 
    priv->picture.depth = palette2depth(priv->picture.palette);
784
 
 
785
 
    if (priv->format != IMGFMT_BGR15) {
786
 
        priv->bytesperline = priv->width * priv->picture.depth / 8;
787
 
    } else {
788
 
        priv->bytesperline = priv->width * 2;
789
 
    }
790
 
 
791
 
    mp_msg(MSGT_TV, MSGL_V, "Picture values:\n");
792
 
    mp_msg(MSGT_TV, MSGL_V, " Depth: %d, Palette: %s (Format: %s)\n", priv->picture.depth,
793
 
        PALETTE(priv->picture.palette), vo_format_name(priv->format));
794
 
    mp_msg(MSGT_TV, MSGL_V, " Brightness: %d, Hue: %d, Colour: %d, Contrast: %d\n",
795
 
        priv->picture.brightness, priv->picture.hue,
796
 
        priv->picture.colour, priv->picture.contrast);
797
 
    
798
 
 
799
 
    if (ioctl(priv->video_fd, VIDIOCSPICT, &priv->picture) == -1)
800
 
    {
801
 
        mp_msg(MSGT_TV, MSGL_ERR, "ioctl set picture failed: %s\n", strerror(errno));
802
 
    }
803
 
 
804
 
    if ( !tv_param_mjpeg )
805
 
    {
806
 
    priv->nbuf = priv->mbuf.frames;
807
 
    for (i=0; i < priv->nbuf; i++)
808
 
    {
809
 
        priv->buf[i].format = priv->picture.palette;
810
 
        priv->buf[i].frame = i;
811
 
        priv->buf[i].width = priv->width;
812
 
        priv->buf[i].height = priv->height;
813
 
        mp_msg(MSGT_TV, MSGL_DBG2, "buffer: %d => %p\n", i, &priv->buf[i]);
814
 
    } 
815
 
    } 
816
 
 
817
 
#if 0
818
 
    {
819
 
        struct video_play_mode pmode;
820
 
        
821
 
        pmode.mode = VID_PLAY_NORMAL;
822
 
        pmode.p1 = 1;
823
 
        pmode.p2 = 0;
824
 
        if (ioctl(priv->video_fd, VIDIOCSPLAYMODE, &pmode) == -1)
825
 
        {
826
 
            mp_msg(MSGT_TV, MSGL_ERR, "ioctl set play mode failed: %s\n", strerror(errno));
827
 
//          return(0);
828
 
        }
829
 
    }
830
 
#endif
831
 
 
832
 
#if 0
833
 
    {
834
 
        struct video_window win;
835
 
 
836
 
        win.x = 0;
837
 
        win.y = 0;
838
 
        win.width = priv->width;
839
 
        win.height = priv->height;
840
 
        win.chromakey = -1;
841
 
        win.flags = 0;
842
 
        //win.clipcount = 0;
843
 
        
844
 
        ioctl(priv->video_fd, VIDIOCSWIN, &win);
845
 
    }
846
 
 
847
 
    // initialize video capture
848
 
    if (ioctl(priv->video_fd, VIDIOCCAPTURE, &one) == -1)
849
 
    {
850
 
        mp_msg(MSGT_TV, MSGL_ERR, "FATAL: ioctl ccapture failed: %s\n", strerror(errno));
851
 
        return(0);
852
 
    }
853
 
#endif
854
 
 
855
 
    /* setup audio parameters */
856
 
    if (!tv_param_noaudio) {
857
 
        setup_audio_buffer_sizes(priv);
858
 
        bytes_per_sample = priv->audio_in.bytes_per_sample;
859
 
        priv->audio_skew_buffer = (long long*)calloc(priv->aud_skew_cnt, sizeof(long long));
860
 
        if (!priv->audio_skew_buffer) {
861
 
            mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate skew buffer: %s\n", strerror(errno));
862
 
            return 0;
863
 
        }
864
 
 
865
 
        priv->audio_ringbuffer = (unsigned char*)calloc(priv->audio_in.blocksize, priv->audio_buffer_size);
866
 
        if (!priv->audio_ringbuffer) {
867
 
            mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate audio buffer: %s\n", strerror(errno));
868
 
            return 0;
869
 
        }
870
 
 
871
 
        priv->audio_secs_per_block = (double)priv->audio_in.blocksize/(priv->audio_in.samplerate
872
 
                                                                    *priv->audio_in.channels
873
 
                                                                    *bytes_per_sample);
874
 
        priv->audio_head = 0;
875
 
        priv->audio_tail = 0;
876
 
        priv->audio_cnt = 0;
877
 
        priv->audio_drop = 0;
878
 
        priv->audio_skew = 0;
879
 
        priv->audio_skew_total = 0;
880
 
        priv->audio_recv_blocks_total = 0;
881
 
        priv->audio_sent_blocks_total = 0;
882
 
    }
883
 
 
884
 
    /* setup video parameters */
885
 
    if (priv->immediate_mode) {
886
 
        priv->video_buffer_size_max = VID_BUF_SIZE_IMMEDIATE;
887
 
    } else {
888
 
        priv->video_buffer_size_max = get_capture_buffer_size(priv);
889
 
    }
890
 
    priv->video_buffer_size_current = 0;
891
 
 
892
 
    if (!tv_param_noaudio) {
893
 
        if (priv->video_buffer_size_max < 3.0*priv->fps*priv->audio_secs_per_block) {
894
 
            mp_msg(MSGT_TV, MSGL_ERR, "Video buffer shorter than 3 times audio frame duration.\n"
895
 
                   "You will probably experience heavy framedrops.\n");
896
 
        }
897
 
    }
898
 
 
899
 
    mp_msg(MSGT_TV, MSGL_V, "Using a ring buffer for maximum %d frames, %d MB total size.\n",
900
 
           priv->video_buffer_size_max,
901
 
           priv->video_buffer_size_max*priv->height*priv->bytesperline/(1024*1024));
902
 
 
903
 
    priv->video_ringbuffer = (unsigned char**)calloc(priv->video_buffer_size_max, sizeof(unsigned char*));
904
 
    if (!priv->video_ringbuffer) {
905
 
        mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate video buffer: %s\n", strerror(errno));
906
 
        return 0;
907
 
    }
908
 
    for (i = 0; i < priv->video_buffer_size_max; i++)
909
 
        priv->video_ringbuffer[i] = NULL;
910
 
    
911
 
    priv->video_timebuffer = (long long*)calloc(priv->video_buffer_size_max, sizeof(long long));
912
 
    if (!priv->video_timebuffer) {
913
 
        mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate time buffer: %s\n", strerror(errno));
914
 
        return 0;
915
 
    }
916
 
    priv->video_avg_buffer = (long long*)malloc(sizeof(long long) * VIDEO_AVG_BUFFER_SIZE);
917
 
    if (!priv->video_avg_buffer) {
918
 
        mp_msg(MSGT_TV, MSGL_ERR, "cannot allocate period buffer: %s\n", strerror(errno));
919
 
        return 0;
920
 
    }
921
 
    priv->video_interval_sum = (1e6/priv->fps)*VIDEO_AVG_BUFFER_SIZE;
922
 
    for (i = 0; i < VIDEO_AVG_BUFFER_SIZE; i++) {
923
 
        priv->video_avg_buffer[i] = 1e6/priv->fps;
924
 
    }
925
 
 
926
 
    priv->video_avg_ptr = 0;
927
 
    
928
 
    priv->video_head = 0;
929
 
    priv->video_tail = 0;
930
 
    priv->video_cnt = 0;
931
 
    priv->first = 1;
932
 
 
933
 
    if (priv->capability.audios) {
934
 
        /* enable audio */
935
 
        if (tv_param_volume >= 0)
936
 
            priv->audio[priv->audio_id].volume = tv_param_volume;
937
 
        if (tv_param_bass >= 0)
938
 
            priv->audio[priv->audio_id].bass = tv_param_bass;
939
 
        if (tv_param_treble >= 0)
940
 
            priv->audio[priv->audio_id].treble = tv_param_treble;
941
 
        if (tv_param_balance >= 0)
942
 
            priv->audio[priv->audio_id].balance = tv_param_balance;
943
 
        priv->audio[priv->audio_id].flags &= ~VIDEO_AUDIO_MUTE;
944
 
        mp_msg(MSGT_TV, MSGL_V, "Enabling tv audio. Requested setup is:\n");
945
 
        mp_msg(MSGT_TV, MSGL_V, "id=%d vol=%d bass=%d treble=%d balance=%d mode=%s",
946
 
               priv->audio_id,
947
 
               priv->audio[priv->audio_id].volume, priv->audio[priv->audio_id].bass, priv->audio[priv->audio_id].treble,
948
 
               priv->audio[priv->audio_id].balance, audio_mode2name(priv->audio[priv->audio_id].mode));
949
 
        mp_msg(MSGT_TV, MSGL_V, " chan=%d\n", priv->audio_channels[priv->audio_id]);
950
 
        ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]);
951
 
    }
952
 
    
953
 
    /* launch capture threads */
954
 
    priv->shutdown = 0;
955
 
    if (!tv_param_noaudio) {
956
 
        pthread_mutex_init(&priv->audio_starter, NULL);
957
 
        pthread_mutex_init(&priv->skew_mutex, NULL);
958
 
        pthread_mutex_lock(&priv->audio_starter);
959
 
        pthread_create(&priv->audio_grabber_thread, NULL, audio_grabber, priv);
960
 
    }
961
 
    pthread_mutex_init(&priv->video_buffer_mutex, NULL);
962
 
    /* we'll launch the video capture later, when a first request for a frame arrives */
963
 
 
964
 
    return(1);
965
 
}
966
 
 
967
 
 
968
 
static int control(priv_t *priv, int cmd, void *arg)
969
 
{
970
 
    mp_msg(MSGT_TV, MSGL_DBG2, "\ndebug: control(priv=%p, cmd=%d, arg=%p)\n",
971
 
        priv, cmd, arg);
972
 
    switch(cmd)
973
 
    {
974
 
        /* ========== GENERIC controls =========== */
975
 
        case TVI_CONTROL_IS_VIDEO:
976
 
        {
977
 
            if (priv->capability.type & VID_TYPE_CAPTURE)
978
 
                return(TVI_CONTROL_TRUE);
979
 
            return(TVI_CONTROL_FALSE);
980
 
        }
981
 
        case TVI_CONTROL_IS_AUDIO:
982
 
            if (tv_param_force_audio) return(TVI_CONTROL_TRUE);
983
 
            if (priv->channels[priv->act_channel].flags & VIDEO_VC_AUDIO)
984
 
            {
985
 
                return(TVI_CONTROL_TRUE);
986
 
            }
987
 
            return(TVI_CONTROL_FALSE);
988
 
        case TVI_CONTROL_IS_TUNER:
989
 
        {
990
 
//          if (priv->capability.type & VID_TYPE_TUNER)
991
 
            if (priv->channels[priv->act_channel].flags & VIDEO_VC_TUNER)
992
 
                return(TVI_CONTROL_TRUE);
993
 
            return(TVI_CONTROL_FALSE);
994
 
        }
995
 
 
996
 
        /* ========== VIDEO controls =========== */
997
 
        case TVI_CONTROL_VID_GET_FORMAT:
998
 
        {
999
 
            int output_fmt = -1;
1000
 
 
1001
 
            output_fmt = priv->format;
1002
 
            if ( tv_param_mjpeg )
1003
 
            {
1004
 
              mp_msg(MSGT_TV, MSGL_INFO, "  MJP: setting sh_video->format to mjpg\n");
1005
 
              output_fmt = 0x47504a4d;
1006
 
              output_fmt = 0x67706a6d;
1007
 
              *(int *)arg = output_fmt;
1008
 
              mp_msg(MSGT_TV, MSGL_V, "Output format: %s\n", "mjpg");
1009
 
            }
1010
 
            else
1011
 
            {
1012
 
            *(int *)arg = output_fmt;
1013
 
            mp_msg(MSGT_TV, MSGL_V, "Output format: %s\n", vo_format_name(output_fmt));
1014
 
            }
1015
 
            return(TVI_CONTROL_TRUE);
1016
 
        }
1017
 
        case TVI_CONTROL_VID_SET_FORMAT:
1018
 
            priv->format = *(int *)arg;
1019
 
            // !HACK! v4l uses BGR format instead of RGB
1020
 
            // and we have to correct this. Fortunately,
1021
 
            // tv.c reads later the format back so we
1022
 
            // can persuade it to use what we want.
1023
 
            if (IMGFMT_IS_RGB(priv->format)) {
1024
 
                priv->format &= ~IMGFMT_RGB_MASK;
1025
 
                priv->format |= IMGFMT_BGR;
1026
 
            }
1027
 
            return(TVI_CONTROL_TRUE);
1028
 
        case TVI_CONTROL_VID_GET_PLANES:
1029
 
            *(int *)arg = 1; /* FIXME, also not needed at this time */
1030
 
            return(TVI_CONTROL_TRUE);
1031
 
        case TVI_CONTROL_VID_GET_BITS:
1032
 
            *(int *)arg = palette2depth(format2palette(priv->format));
1033
 
            return(TVI_CONTROL_TRUE);
1034
 
        case TVI_CONTROL_VID_GET_WIDTH:
1035
 
            *(int *)arg = priv->width;
1036
 
            return(TVI_CONTROL_TRUE);
1037
 
        case TVI_CONTROL_VID_CHK_WIDTH:
1038
 
        {
1039
 
            int req_width = *(int *)arg;
1040
 
            
1041
 
            mp_msg(MSGT_TV, MSGL_V, "Requested width: %d\n", req_width);
1042
 
            if ((req_width >= priv->capability.minwidth) &&
1043
 
                (req_width <= priv->capability.maxwidth))
1044
 
                return(TVI_CONTROL_TRUE);
1045
 
            return(TVI_CONTROL_FALSE);
1046
 
        }
1047
 
        case TVI_CONTROL_VID_SET_WIDTH:
1048
 
            priv->width = *(int *)arg;
1049
 
            return(TVI_CONTROL_TRUE);
1050
 
        case TVI_CONTROL_VID_GET_HEIGHT:
1051
 
            *(int *)arg = priv->height;
1052
 
            return(TVI_CONTROL_TRUE);
1053
 
        case TVI_CONTROL_VID_CHK_HEIGHT:
1054
 
        {
1055
 
            int req_height = *(int *)arg;
1056
 
            
1057
 
            mp_msg(MSGT_TV, MSGL_V, "Requested height: %d\n", req_height);
1058
 
            if ((req_height >= priv->capability.minheight) &&
1059
 
                (req_height <= priv->capability.maxheight))
1060
 
                return(TVI_CONTROL_TRUE);
1061
 
            return(TVI_CONTROL_FALSE);
1062
 
        }
1063
 
        case TVI_CONTROL_VID_SET_HEIGHT:
1064
 
            priv->height = *(int *)arg;
1065
 
            return(TVI_CONTROL_TRUE);
1066
 
        case TVI_CONTROL_VID_GET_PICTURE:
1067
 
            if (ioctl(priv->video_fd, VIDIOCGPICT, &priv->picture) == -1)
1068
 
            {
1069
 
                mp_msg(MSGT_TV, MSGL_ERR, "ioctl get picture failed: %s\n", strerror(errno));
1070
 
                return(TVI_CONTROL_FALSE);
1071
 
            }
1072
 
            return(TVI_CONTROL_TRUE);
1073
 
        case TVI_CONTROL_VID_SET_PICTURE:
1074
 
            if (ioctl(priv->video_fd, VIDIOCSPICT, &priv->picture) == -1)
1075
 
            {
1076
 
                mp_msg(MSGT_TV, MSGL_ERR, "ioctl get picture failed: %s\n", strerror(errno));
1077
 
                return(TVI_CONTROL_FALSE);
1078
 
            }
1079
 
            return(TVI_CONTROL_TRUE);
1080
 
        case TVI_CONTROL_VID_SET_BRIGHTNESS:
1081
 
            priv->picture.brightness = (327*(*(int *)arg+100)) + 68;
1082
 
            return control(priv, TVI_CONTROL_VID_SET_PICTURE, 0);
1083
 
        case TVI_CONTROL_VID_SET_HUE:
1084
 
            priv->picture.hue = (327*(*(int *)arg+100)) + 68;
1085
 
            return control(priv, TVI_CONTROL_VID_SET_PICTURE, 0);
1086
 
        case TVI_CONTROL_VID_SET_SATURATION:
1087
 
            priv->picture.colour = (327*(*(int *)arg+100)) + 68;
1088
 
            return control(priv, TVI_CONTROL_VID_SET_PICTURE, 0);
1089
 
        case TVI_CONTROL_VID_SET_CONTRAST:
1090
 
            priv->picture.contrast = (327*(*(int *)arg+100)) + 68;
1091
 
            return control(priv, TVI_CONTROL_VID_SET_PICTURE, 0);
1092
 
        case TVI_CONTROL_VID_GET_BRIGHTNESS:
1093
 
            if(!control(priv, TVI_CONTROL_VID_GET_PICTURE, 0)) return 0;
1094
 
            *(int*)arg = ((int)priv->picture.brightness-68)/327-100;
1095
 
            return 1;
1096
 
        case TVI_CONTROL_VID_GET_HUE:
1097
 
            if(!control(priv, TVI_CONTROL_VID_GET_PICTURE, 0)) return 0;
1098
 
            *(int*)arg = ((int)priv->picture.hue-68)/327-100;
1099
 
            return 1;
1100
 
        case TVI_CONTROL_VID_GET_SATURATION:
1101
 
            if(!control(priv, TVI_CONTROL_VID_GET_PICTURE, 0)) return 0;
1102
 
            *(int*)arg = ((int)priv->picture.colour-68)/327-100;
1103
 
            return 1;
1104
 
        case TVI_CONTROL_VID_GET_CONTRAST:
1105
 
            if(!control(priv, TVI_CONTROL_VID_GET_PICTURE, 0)) return 0;
1106
 
            *(int*)arg = ((int)priv->picture.contrast-68)/327-100;
1107
 
            return 1;
1108
 
        case TVI_CONTROL_VID_GET_FPS:
1109
 
            *(float *)arg=priv->fps;
1110
 
            return(TVI_CONTROL_TRUE);
1111
 
 
1112
 
        /* ========== TUNER controls =========== */
1113
 
        case TVI_CONTROL_TUN_GET_FREQ:
1114
 
        {
1115
 
            unsigned long freq;
1116
 
            
1117
 
            if (ioctl(priv->video_fd, VIDIOCGFREQ, &freq) == -1)
1118
 
            {
1119
 
                mp_msg(MSGT_TV, MSGL_ERR, "ioctl get freq failed: %s\n", strerror(errno));
1120
 
                return(TVI_CONTROL_FALSE);
1121
 
            }
1122
 
            
1123
 
            /* tuner uses khz not mhz ! */
1124
 
//          if (priv->tuner.flags & VIDEO_TUNER_LOW)
1125
 
//              freq /= 1000;
1126
 
            *(unsigned long *)arg = freq;
1127
 
            return(TVI_CONTROL_TRUE);
1128
 
        }
1129
 
        case TVI_CONTROL_TUN_SET_FREQ:
1130
 
        {
1131
 
            /* argument is in MHz ! */
1132
 
            unsigned long freq = *(unsigned long *)arg;
1133
 
            
1134
 
            if (priv->capability.audios) {
1135
 
                priv->audio[priv->audio_id].flags |= VIDEO_AUDIO_MUTE;
1136
 
                ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]);
1137
 
            }
1138
 
 
1139
 
            mp_msg(MSGT_TV, MSGL_V, "requested frequency: %.3f\n", (float)freq/16);
1140
 
            
1141
 
            /* tuner uses khz not mhz ! */
1142
 
//          if (priv->tuner.flags & VIDEO_TUNER_LOW)
1143
 
//              freq *= 1000;
1144
 
//          mp_msg(MSGT_TV, MSGL_V, " requesting from driver: freq=%.3f\n", (float)freq/16);
1145
 
            if (ioctl(priv->video_fd, VIDIOCSFREQ, &freq) == -1)
1146
 
            {
1147
 
                mp_msg(MSGT_TV, MSGL_ERR, "ioctl set freq failed: %s\n", strerror(errno));
1148
 
                return(TVI_CONTROL_FALSE);
1149
 
            }
1150
 
            usleep(100000); // wait to suppress noise during switching
1151
 
 
1152
 
            if (priv->capability.audios) {
1153
 
                priv->audio[priv->audio_id].flags &= ~VIDEO_AUDIO_MUTE;
1154
 
                ioctl(priv->video_fd, VIDIOCSAUDIO, &priv->audio[priv->audio_id]);
1155
 
            }
1156
 
 
1157
 
            return(TVI_CONTROL_TRUE);
1158
 
        }
1159
 
        case TVI_CONTROL_TUN_GET_TUNER:
1160
 
        {
1161
 
            if (ioctl(priv->video_fd, VIDIOCGTUNER, &priv->tuner) == -1)
1162
 
            {
1163
 
                mp_msg(MSGT_TV, MSGL_ERR, "ioctl get tuner failed: %s\n", strerror(errno));
1164
 
                return(TVI_CONTROL_FALSE);
1165
 
            }
1166
 
            
1167
 
            mp_msg(MSGT_TV, MSGL_V, "Tuner (%s) range: %lu -> %lu\n", priv->tuner.name,
1168
 
                priv->tuner.rangelow, priv->tuner.rangehigh);
1169
 
            return(TVI_CONTROL_TRUE);
1170
 
        }
1171
 
        case TVI_CONTROL_TUN_SET_TUNER:
1172
 
        {
1173
 
            if (ioctl(priv->video_fd, VIDIOCSTUNER, &priv->tuner) == -1)
1174
 
            {
1175
 
                mp_msg(MSGT_TV, MSGL_ERR, "ioctl set tuner failed: %s\n", strerror(errno));
1176
 
                return(TVI_CONTROL_FALSE);
1177
 
            }
1178
 
            return(TVI_CONTROL_TRUE);
1179
 
        }
1180
 
        case TVI_CONTROL_TUN_SET_NORM:
1181
 
        {
1182
 
            int req_mode = *(int *)arg;
1183
 
 
1184
 
            if ((req_mode != TV_NORM_PAL) && (req_mode != TV_NORM_NTSC) && (req_mode != TV_NORM_SECAM)
1185
 
                && (req_mode != TV_NORM_PALNC) && (req_mode != TV_NORM_PALM) && (req_mode != TV_NORM_PALN)
1186
 
                && (req_mode != TV_NORM_NTSCJP)) {
1187
 
                mp_msg(MSGT_TV, MSGL_ERR, "Unknown norm!\n");
1188
 
                return(TVI_CONTROL_FALSE);
1189
 
            }
1190
 
 
1191
 
            if (priv->channels[priv->act_channel].flags & VIDEO_VC_TUNER) {
1192
 
                int prev_mode;
1193
 
                
1194
 
                control(priv, TVI_CONTROL_TUN_GET_TUNER, 0);
1195
 
                if (((req_mode == TV_NORM_PAL
1196
 
                      || req_mode == TV_NORM_PALNC
1197
 
                      || req_mode == TV_NORM_PALN) && !(priv->tuner.flags & VIDEO_TUNER_PAL)) ||
1198
 
                    ((req_mode == TV_NORM_NTSC
1199
 
                      || req_mode == TV_NORM_NTSCJP
1200
 
                      || req_mode == TV_NORM_PALM) && !(priv->tuner.flags & VIDEO_TUNER_NTSC)) ||
1201
 
                    ((req_mode == TV_NORM_SECAM) && !(priv->tuner.flags & VIDEO_TUNER_SECAM)))
1202
 
                {
1203
 
                    mp_msg(MSGT_TV, MSGL_ERR, "Tuner isn't capable to set norm!\n");
1204
 
                    return(TVI_CONTROL_FALSE);
1205
 
                }
1206
 
 
1207
 
                prev_mode = priv->tuner.mode;
1208
 
 
1209
 
                switch(req_mode) {
1210
 
                case TV_NORM_PAL:
1211
 
                case TV_NORM_PALNC:
1212
 
                case TV_NORM_PALN:
1213
 
                    priv->tuner.mode = VIDEO_MODE_PAL;
1214
 
                    break;
1215
 
                case TV_NORM_NTSC:
1216
 
                case TV_NORM_NTSCJP:
1217
 
                case TV_NORM_PALM:
1218
 
                    priv->tuner.mode = VIDEO_MODE_NTSC;
1219
 
                    break;
1220
 
                case TV_NORM_SECAM:
1221
 
                    priv->tuner.mode = VIDEO_MODE_SECAM;
1222
 
                    break;
1223
 
                }
1224
 
            
1225
 
                if (control(priv, TVI_CONTROL_TUN_SET_TUNER, &priv->tuner) != TVI_CONTROL_TRUE) {
1226
 
                    // norm setting failed, but maybe it's only because it's fixed
1227
 
                    if (priv->tuner.mode != prev_mode) return(TVI_CONTROL_FALSE); // no it really failed
1228
 
                }
1229
 
 
1230
 
            }
1231
 
 
1232
 
            switch(req_mode) {
1233
 
            case TV_NORM_PAL:
1234
 
                priv->channels[priv->act_channel].norm = VIDEO_MODE_PAL;
1235
 
                break;
1236
 
            case TV_NORM_NTSC:
1237
 
                priv->channels[priv->act_channel].norm = VIDEO_MODE_NTSC;
1238
 
                break;
1239
 
            case TV_NORM_SECAM:
1240
 
                priv->channels[priv->act_channel].norm = VIDEO_MODE_SECAM;
1241
 
                break;
1242
 
            case TV_NORM_PALNC:
1243
 
                priv->channels[priv->act_channel].norm = 3;
1244
 
                break;
1245
 
            case TV_NORM_PALM:
1246
 
                priv->channels[priv->act_channel].norm = 4;
1247
 
                break;
1248
 
            case TV_NORM_PALN:
1249
 
                priv->channels[priv->act_channel].norm = 5;
1250
 
                break;
1251
 
            case TV_NORM_NTSCJP:
1252
 
                priv->channels[priv->act_channel].norm = 6;
1253
 
                break;
1254
 
            }
1255
 
            if (ioctl(priv->video_fd, VIDIOCSCHAN, &priv->channels[priv->act_channel]) == -1)
1256
 
            {
1257
 
                mp_msg(MSGT_TV, MSGL_ERR, "ioctl set chan failed: %s\n", strerror(errno));
1258
 
                return(TVI_CONTROL_FALSE);
1259
 
            }
1260
 
 
1261
 
            if (ioctl(priv->video_fd, VIDIOCGCAP, &priv->capability) == -1) {
1262
 
                mp_msg(MSGT_TV, MSGL_ERR, "ioctl get capabilites failed: %s\n", strerror(errno));
1263
 
                return(TVI_CONTROL_FALSE);
1264
 
            }
1265
 
 
1266
 
            if(req_mode == TV_NORM_PAL || req_mode == TV_NORM_SECAM || req_mode == TV_NORM_PALN || req_mode == TV_NORM_PALNC) {
1267
 
                priv->fps = PAL_FPS;
1268
 
            }
1269
 
 
1270
 
            if(req_mode == TV_NORM_NTSC || req_mode == TV_NORM_NTSCJP || req_mode == TV_NORM_PALM) {
1271
 
                priv->fps = NTSC_FPS;
1272
 
            }
1273
 
 
1274
 
            if(priv->height > priv->capability.maxheight) {
1275
 
                priv->height = priv->capability.maxheight;
1276
 
            }
1277
 
 
1278
 
            if(priv->width > priv->capability.maxwidth) {
1279
 
                priv->width = priv->capability.maxwidth;
1280
 
            }
1281
 
            
1282
 
            return(TVI_CONTROL_TRUE);
1283
 
        }
1284
 
        case TVI_CONTROL_TUN_GET_NORM:
1285
 
        {
1286
 
            *(int *)arg = priv->tuner.mode;
1287
 
 
1288
 
            return(TVI_CONTROL_TRUE);
1289
 
        }
1290
 
        
1291
 
        /* ========== AUDIO controls =========== */
1292
 
        case TVI_CONTROL_AUD_GET_FORMAT:
1293
 
        {
1294
 
            *(int *)arg = AF_FORMAT_S16_LE;
1295
 
            return(TVI_CONTROL_TRUE);
1296
 
        }
1297
 
        case TVI_CONTROL_AUD_GET_CHANNELS:
1298
 
        {
1299
 
            *(int *)arg = priv->audio_in.channels;
1300
 
            return(TVI_CONTROL_TRUE);
1301
 
        }
1302
 
        case TVI_CONTROL_AUD_GET_SAMPLERATE:
1303
 
        {
1304
 
            *(int *)arg = priv->audio_in.samplerate;
1305
 
            return(TVI_CONTROL_TRUE);
1306
 
        }
1307
 
        case TVI_CONTROL_AUD_GET_SAMPLESIZE:
1308
 
        {
1309
 
            *(int *)arg = priv->audio_in.bytes_per_sample;
1310
 
            return(TVI_CONTROL_TRUE);
1311
 
        }
1312
 
        case TVI_CONTROL_AUD_SET_SAMPLERATE:
1313
 
        {
1314
 
            if (audio_in_set_samplerate(&priv->audio_in, *(int *)arg) < 0) return TVI_CONTROL_FALSE;
1315
 
            setup_audio_buffer_sizes(priv);
1316
 
            return(TVI_CONTROL_TRUE);
1317
 
        }
1318
 
        /* ========== SPECIFIC controls =========== */
1319
 
        case TVI_CONTROL_SPC_GET_INPUT:
1320
 
        {
1321
 
            int req_chan = *(int *)arg;
1322
 
            int i;
1323
 
 
1324
 
            for (i = 0; i < priv->capability.channels; i++)
1325
 
            {
1326
 
                if (priv->channels[i].channel == req_chan)
1327
 
                    break;
1328
 
            }
1329
 
            
1330
 
            priv->act_channel = i;
1331
 
 
1332
 
            if (ioctl(priv->video_fd, VIDIOCGCHAN, &priv->channels[i]) == -1)
1333
 
            {
1334
 
                mp_msg(MSGT_TV, MSGL_ERR, "ioctl get channel failed: %s\n", strerror(errno));
1335
 
                return(TVI_CONTROL_FALSE);
1336
 
            }
1337
 
            return(TVI_CONTROL_TRUE);
1338
 
        }
1339
 
 
1340
 
        case TVI_CONTROL_SPC_SET_INPUT:
1341
 
        {
1342
 
            struct video_channel chan;
1343
 
            int req_chan = *(int *)arg;
1344
 
            int i;
1345
 
            
1346
 
            if (req_chan >= priv->capability.channels)
1347
 
            {
1348
 
                mp_msg(MSGT_TV, MSGL_ERR, "Invalid input requested: %d, valid: 0-%d\n",
1349
 
                    req_chan, priv->capability.channels - 1);
1350
 
                return(TVI_CONTROL_FALSE);
1351
 
            }
1352
 
 
1353
 
            for (i = 0; i < priv->capability.channels; i++)
1354
 
            {
1355
 
                if (priv->channels[i].channel == req_chan)
1356
 
                    chan = priv->channels[i];
1357
 
            }
1358
 
 
1359
 
            if (ioctl(priv->video_fd, VIDIOCSCHAN, &chan) == -1)
1360
 
            {
1361
 
                mp_msg(MSGT_TV, MSGL_ERR, "ioctl set chan failed: %s\n", strerror(errno));
1362
 
                return(TVI_CONTROL_FALSE);
1363
 
            }
1364
 
            mp_msg(MSGT_TV, MSGL_INFO, "Using input '%s'\n", chan.name);
1365
 
 
1366
 
            priv->act_channel = i;
1367
 
 
1368
 
            /* update tuner state */
1369
 
//          if (priv->capability.type & VID_TYPE_TUNER)
1370
 
            if (priv->channels[priv->act_channel].flags & VIDEO_VC_TUNER)
1371
 
                control(priv, TVI_CONTROL_TUN_GET_TUNER, 0);
1372
 
 
1373
 
            /* update local channel list */     
1374
 
            control(priv, TVI_CONTROL_SPC_GET_INPUT, &req_chan);
1375
 
            return(TVI_CONTROL_TRUE);
1376
 
        case TVI_CONTROL_IMMEDIATE:
1377
 
            priv->immediate_mode = 1;
1378
 
            return(TVI_CONTROL_TRUE);
1379
 
        }
1380
 
    }
1381
 
 
1382
 
    return(TVI_CONTROL_UNKNOWN);
1383
 
}
1384
 
 
1385
 
// copies a video frame
1386
 
// for RGB (i.e. BGR in mplayer) flips the image upside down
1387
 
// for YV12 swaps the 2nd and 3rd plane
1388
 
static inline void copy_frame(priv_t *priv, unsigned char *dest, unsigned char *source)
1389
 
{
1390
 
    int i;
1391
 
    unsigned char *sptr;
1392
 
 
1393
 
    // YV12 uses VIDEO_PALETTE_YUV420P, but the planes are swapped
1394
 
    if (priv->format == IMGFMT_YV12) {
1395
 
        memcpy(dest, source, priv->width * priv->height);
1396
 
        memcpy(dest+priv->width * priv->height*5/4, source+priv->width * priv->height, priv->width * priv->height/4);
1397
 
        memcpy(dest+priv->width * priv->height, source+priv->width * priv->height*5/4, priv->width * priv->height/4);
1398
 
        return;
1399
 
    }
1400
 
 
1401
 
    switch (priv->picture.palette) {
1402
 
    case VIDEO_PALETTE_RGB24:
1403
 
    case VIDEO_PALETTE_RGB32:
1404
 
    case VIDEO_PALETTE_RGB555:
1405
 
    case VIDEO_PALETTE_RGB565:
1406
 
        sptr = source + (priv->height-1)*priv->bytesperline;
1407
 
        for (i = 0; i < priv->height; i++) {
1408
 
            memcpy(dest, sptr, priv->bytesperline);
1409
 
            dest += priv->bytesperline;
1410
 
            sptr -= priv->bytesperline;
1411
 
        }
1412
 
        break;
1413
 
    case VIDEO_PALETTE_UYVY:
1414
 
    case VIDEO_PALETTE_YUV420P:
1415
 
    default:
1416
 
        memcpy(dest, source, priv->bytesperline * priv->height);
1417
 
    }
1418
 
    
1419
 
}
1420
 
 
1421
 
// maximum skew change, in frames
1422
 
#define MAX_SKEW_DELTA 0.6
1423
 
static void *video_grabber(void *data)
1424
 
{
1425
 
#define MAXTOL (priv->nbuf)
1426
 
    priv_t *priv = (priv_t*)data;
1427
 
    struct timeval curtime;
1428
 
    long long skew, prev_skew, xskew, interval, prev_interval;
1429
 
    int frame;
1430
 
    int i;
1431
 
    int framecount;
1432
 
    int tolerance;
1433
 
    unsigned long num;
1434
 
 
1435
 
    /* start the capture process */
1436
 
 
1437
 
    if ( tv_param_mjpeg )
1438
 
      {
1439
 
        mp_msg(MSGT_TV, MSGL_INFO, "  MJP: gonna capture ! \n");
1440
 
        for (i=0; i < priv->nbuf; i++) {
1441
 
        num = i;
1442
 
        if (ioctl(priv->video_fd, MJPIOC_QBUF_CAPT, &num) < 0)
1443
 
          {
1444
 
            mp_msg(MSGT_TV, MSGL_ERR, 
1445
 
                   "\n  MJP: ioctl MJPIOC_QBUF_CAPT b failed: %s\n", strerror(errno));
1446
 
          }
1447
 
          }
1448
 
      }
1449
 
    else
1450
 
      {
1451
 
    for (i=0; i < priv->nbuf; i++) {
1452
 
        if (ioctl(priv->video_fd, VIDIOCMCAPTURE, &priv->buf[i]) == -1)
1453
 
        {
1454
 
            mp_msg(MSGT_TV, MSGL_ERR, "\nioctl mcapture failed: %s\n", strerror(errno));
1455
 
        }
1456
 
      }
1457
 
    }
1458
 
 
1459
 
    gettimeofday(&curtime, NULL);
1460
 
    priv->starttime = (long long)1e6*curtime.tv_sec + curtime.tv_usec;
1461
 
    priv->audio_skew_measure_time = 0;
1462
 
    pthread_mutex_unlock(&priv->audio_starter);
1463
 
    xskew = 0;
1464
 
    skew = 0;
1465
 
    interval = 0;
1466
 
 
1467
 
    prev_interval = 0;
1468
 
    prev_skew = 0;
1469
 
 
1470
 
    tolerance = MAXTOL;
1471
 
 
1472
 
    for (framecount = 0; !priv->shutdown;)
1473
 
    {
1474
 
        for (i = 0; i < priv->nbuf && !priv->shutdown; i++, framecount++) {
1475
 
 
1476
 
            if (priv->immediate_mode) {
1477
 
                while (priv->video_cnt == priv->video_buffer_size_max) {
1478
 
                    usleep(10000);
1479
 
                    if (priv->shutdown) {
1480
 
                      return NULL;
1481
 
                    }
1482
 
                }
1483
 
            }
1484
 
                
1485
 
            frame = i;
1486
 
 
1487
 
            if ( tv_param_mjpeg )
1488
 
            {
1489
 
            while (ioctl(priv->video_fd, MJPIOC_SYNC, &priv->buf[frame].frame) < 0 &&
1490
 
                   (errno == EAGAIN || errno == EINTR));
1491
 
 
1492
 
            }
1493
 
            else
1494
 
            {
1495
 
            while (ioctl(priv->video_fd, VIDIOCSYNC, &priv->buf[frame].frame) < 0 &&
1496
 
                   (errno == EAGAIN || errno == EINTR));
1497
 
            }
1498
 
            mp_dbg(MSGT_TV, MSGL_DBG3, "\npicture sync failed\n");
1499
 
 
1500
 
            gettimeofday(&curtime, NULL);
1501
 
            if (!priv->immediate_mode) {
1502
 
                interval = (long long)1e6*curtime.tv_sec + curtime.tv_usec - priv->starttime;
1503
 
            } else {
1504
 
                interval = (long long)1e6*framecount/priv->fps;
1505
 
            }
1506
 
 
1507
 
            if (!priv->immediate_mode) {
1508
 
                long long period, orig_interval;
1509
 
 
1510
 
                if (tolerance == 0) {
1511
 
                    if (interval - prev_interval == 0) {
1512
 
                        mp_msg(MSGT_TV, MSGL_V, "\nvideo capture thread: frame delta = 0\n");
1513
 
                    } else if ((interval - prev_interval < (long long)0.85e6/priv->fps)
1514
 
                               || (interval - prev_interval > (long long)1.15e6/priv->fps) ) {
1515
 
                        mp_msg(MSGT_TV, MSGL_V, "\nvideo capture thread: frame delta ~ %.1lf fps\n",
1516
 
                               (double)1e6/(interval - prev_interval));
1517
 
                    }
1518
 
                }
1519
 
 
1520
 
                // correct the rate fluctuations on a small scale
1521
 
                orig_interval = interval;
1522
 
                period = priv->video_interval_sum/VIDEO_AVG_BUFFER_SIZE;
1523
 
                if (interval - prev_interval > 105*period/100) {
1524
 
                    if (tolerance > 0) {
1525
 
                        mp_msg(MSGT_TV, MSGL_DBG3, "correcting timestamp\n");
1526
 
                        interval = prev_interval + priv->video_interval_sum/VIDEO_AVG_BUFFER_SIZE;
1527
 
                        tolerance--;
1528
 
                    } else {
1529
 
                        mp_msg(MSGT_TV, MSGL_DBG3, "bad - frames were dropped\n");
1530
 
                        tolerance = MAXTOL;
1531
 
                    }
1532
 
                } else {
1533
 
                    if (tolerance < MAXTOL) {
1534
 
                        mp_msg(MSGT_TV, MSGL_DBG3, "fluctuation overcome\n");
1535
 
                    }
1536
 
                    tolerance = MAXTOL;
1537
 
                }
1538
 
                    
1539
 
                priv->video_interval_sum -= priv->video_avg_buffer[priv->video_avg_ptr];
1540
 
                priv->video_avg_buffer[priv->video_avg_ptr++] = orig_interval-prev_interval;
1541
 
                priv->video_interval_sum += orig_interval-prev_interval;
1542
 
                if (priv->video_avg_ptr >= VIDEO_AVG_BUFFER_SIZE) priv->video_avg_ptr = 0;
1543
 
 
1544
 
//              fprintf(stderr, "fps: %lf\n", (double)1e6*VIDEO_AVG_BUFFER_SIZE/priv->video_interval_sum);
1545
 
                
1546
 
                // interpolate the skew in time
1547
 
                pthread_mutex_lock(&priv->skew_mutex);
1548
 
                xskew = priv->audio_skew + (interval - priv->audio_skew_measure_time)*priv->audio_skew_factor;
1549
 
                pthread_mutex_unlock(&priv->skew_mutex);
1550
 
                // correct extreme skew changes to avoid (especially) moving backwards in time
1551
 
                if (xskew - prev_skew > (interval - prev_interval)*MAX_SKEW_DELTA) {
1552
 
                    skew = prev_skew + (interval - prev_interval)*MAX_SKEW_DELTA;
1553
 
                } else if (xskew - prev_skew < -(interval - prev_interval)*MAX_SKEW_DELTA) {
1554
 
                    skew = prev_skew - (interval - prev_interval)*MAX_SKEW_DELTA;
1555
 
                } else {
1556
 
                    skew = xskew;
1557
 
                }
1558
 
            }
1559
 
 
1560
 
            mp_msg(MSGT_TV, MSGL_DBG3, "\nfps = %lf, interval = %lf, a_skew = %f, corr_skew = %f\n",
1561
 
                   (interval != prev_interval) ? (double)1e6/(interval - prev_interval) : -1,
1562
 
                   (double)1e-6*interval, (double)1e-6*xskew, (double)1e-6*skew);
1563
 
            mp_msg(MSGT_TV, MSGL_DBG3, "vcnt = %d, acnt = %d\n", priv->video_cnt, priv->audio_cnt);
1564
 
 
1565
 
            prev_skew = skew;
1566
 
            prev_interval = interval;
1567
 
 
1568
 
            /* allocate a new buffer, if needed */
1569
 
            pthread_mutex_lock(&priv->video_buffer_mutex);
1570
 
            if (priv->video_buffer_size_current < priv->video_buffer_size_max) {
1571
 
                if (priv->video_cnt == priv->video_buffer_size_current) {
1572
 
                    unsigned char *newbuf = (unsigned char*)calloc(priv->bytesperline, priv->height);
1573
 
                    if (newbuf) {
1574
 
                        memmove(priv->video_ringbuffer+priv->video_tail+1, priv->video_ringbuffer+priv->video_tail,
1575
 
                               (priv->video_buffer_size_current-priv->video_tail)*sizeof(unsigned char *));
1576
 
                        memmove(priv->video_timebuffer+priv->video_tail+1, priv->video_timebuffer+priv->video_tail,
1577
 
                               (priv->video_buffer_size_current-priv->video_tail)*sizeof(long long));
1578
 
                        priv->video_ringbuffer[priv->video_tail] = newbuf;
1579
 
                        if ((priv->video_head >= priv->video_tail) && (priv->video_cnt > 0)) priv->video_head++;
1580
 
                        priv->video_buffer_size_current++;
1581
 
                    }
1582
 
                }
1583
 
            }
1584
 
            pthread_mutex_unlock(&priv->video_buffer_mutex);
1585
 
 
1586
 
            if (priv->video_cnt == priv->video_buffer_size_current) {
1587
 
                if (!priv->immediate_mode) {
1588
 
                    mp_msg(MSGT_TV, MSGL_ERR, "\nvideo buffer full - dropping frame\n");
1589
 
                }
1590
 
            } else {
1591
 
                if (priv->immediate_mode) {
1592
 
                    priv->video_timebuffer[priv->video_tail] = interval;
1593
 
                } else {
1594
 
                    // compensate for audio skew
1595
 
                    // negative skew => there are more audio samples, increase interval
1596
 
                    // positive skew => less samples, shorten the interval
1597
 
                    priv->video_timebuffer[priv->video_tail] = interval - skew;
1598
 
                }
1599
 
                
1600
 
                if ( tv_param_mjpeg )
1601
 
                copy_frame(priv, priv->video_ringbuffer[priv->video_tail], 
1602
 
                           priv->mmap+(priv->mjpeg_bufsize)*i);
1603
 
                else
1604
 
                copy_frame(priv, priv->video_ringbuffer[priv->video_tail], priv->mmap+priv->mbuf.offsets[frame]);
1605
 
                priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
1606
 
                priv->video_cnt++;
1607
 
            }
1608
 
 
1609
 
            if ( tv_param_mjpeg )
1610
 
            {
1611
 
              num = frame;
1612
 
              if (ioctl(priv->video_fd, MJPIOC_QBUF_CAPT, &num) < 0)
1613
 
                {
1614
 
                  mp_msg(MSGT_TV, MSGL_ERR, "\n  MJP: ioctl MJPIOC_QBUF_CAPT end failed: %s\n", 
1615
 
                                                    strerror(errno));
1616
 
                  continue;
1617
 
                }
1618
 
            }
1619
 
            else
1620
 
            {
1621
 
            if (ioctl(priv->video_fd, VIDIOCMCAPTURE, &priv->buf[frame]) == -1)
1622
 
            {
1623
 
                mp_msg(MSGT_TV, MSGL_ERR, "\nioctl mcapture failed: %s\n", strerror(errno));
1624
 
                continue;
1625
 
            }
1626
 
            }
1627
 
 
1628
 
        }
1629
 
 
1630
 
    }
1631
 
    mp_msg(MSGT_TV, MSGL_INFO, "  MJP: returning! \n");
1632
 
    return NULL;
1633
 
}
1634
 
 
1635
 
static double grab_video_frame(priv_t *priv, char *buffer, int len)
1636
 
{
1637
 
    double interval;
1638
 
 
1639
 
    if (priv->first) {
1640
 
        pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1641
 
        priv->first = 0;
1642
 
    }
1643
 
 
1644
 
    while (priv->video_cnt == 0) {
1645
 
        usleep(10000);
1646
 
    }
1647
 
 
1648
 
    pthread_mutex_lock(&priv->video_buffer_mutex);
1649
 
    interval = (double)priv->video_timebuffer[priv->video_head]*1e-6;
1650
 
    memcpy(buffer, priv->video_ringbuffer[priv->video_head], len);
1651
 
    priv->video_cnt--;
1652
 
    priv->video_head = (priv->video_head+1)%priv->video_buffer_size_current;
1653
 
    pthread_mutex_unlock(&priv->video_buffer_mutex);
1654
 
 
1655
 
    return interval;
1656
 
}
1657
 
 
1658
 
static int get_video_framesize(priv_t *priv)
1659
 
{
1660
 
    return(priv->bytesperline * priv->height);
1661
 
}
1662
 
 
1663
 
static void *audio_grabber(void *data)
1664
 
{
1665
 
    priv_t *priv = (priv_t*)data;
1666
 
    struct timeval tv;
1667
 
    int i, audio_skew_ptr = 0;
1668
 
    long long current_time, prev_skew = 0;
1669
 
 
1670
 
    pthread_mutex_lock(&priv->audio_starter);
1671
 
 
1672
 
    audio_in_start_capture(&priv->audio_in);
1673
 
    for (i = 0; i < priv->aud_skew_cnt; i++)
1674
 
        priv->audio_skew_buffer[i] = 0;
1675
 
 
1676
 
    for (; !priv->shutdown;)
1677
 
    {
1678
 
        if (audio_in_read_chunk(&priv->audio_in, priv->audio_ringbuffer+priv->audio_tail*priv->audio_in.blocksize) < 0)
1679
 
            continue;
1680
 
 
1681
 
        gettimeofday(&tv, NULL);
1682
 
 
1683
 
        priv->audio_recv_blocks_total++;
1684
 
        current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->starttime;
1685
 
 
1686
 
        priv->audio_skew_total -= priv->audio_skew_buffer[audio_skew_ptr];
1687
 
        priv->audio_skew_buffer[audio_skew_ptr] = current_time
1688
 
            - 1e6*priv->audio_secs_per_block*priv->audio_recv_blocks_total;
1689
 
        priv->audio_skew_total += priv->audio_skew_buffer[audio_skew_ptr];
1690
 
        audio_skew_ptr = (audio_skew_ptr+1) % priv->aud_skew_cnt;
1691
 
 
1692
 
        pthread_mutex_lock(&priv->skew_mutex);
1693
 
        // linear interpolation - here we interpolate current skew value
1694
 
        // from the moving average, which we expect to be in the middle
1695
 
        // of the interval
1696
 
        if (priv->audio_recv_blocks_total > priv->aud_skew_cnt) {
1697
 
            priv->audio_skew = priv->audio_skew_total/priv->aud_skew_cnt;
1698
 
            priv->audio_skew += (priv->audio_skew*priv->aud_skew_cnt)/(2*priv->audio_recv_blocks_total-priv->aud_skew_cnt);
1699
 
        } else {
1700
 
            // this smoothes the evolution of audio_skew at startup a bit
1701
 
            priv->audio_skew = ((priv->aud_skew_cnt+priv->audio_recv_blocks_total)*priv->audio_skew_total)/(priv->aud_skew_cnt*priv->audio_recv_blocks_total);
1702
 
        }
1703
 
        // current skew factor (assuming linearity)
1704
 
        // used for further interpolation in video_grabber
1705
 
        // probably overkill but seems to be necessary for
1706
 
        // stress testing by dropping half of the audio frames ;)
1707
 
        // especially when using ALSA with large block sizes
1708
 
        // where audio_skew remains a long while behind
1709
 
        if ((priv->audio_skew_measure_time != 0) && (current_time - priv->audio_skew_measure_time != 0)) {
1710
 
            priv->audio_skew_factor = (double)(priv->audio_skew-prev_skew)/(current_time - priv->audio_skew_measure_time);
1711
 
        } else {
1712
 
            priv->audio_skew_factor = 0.0;
1713
 
        }
1714
 
        
1715
 
        priv->audio_skew_measure_time = current_time;
1716
 
        prev_skew = priv->audio_skew;
1717
 
        pthread_mutex_unlock(&priv->skew_mutex);
1718
 
        
1719
 
        if ((priv->audio_tail+1) % priv->audio_buffer_size == priv->audio_head) {
1720
 
            mp_msg(MSGT_TV, MSGL_ERR, "\ntoo bad - dropping audio frame !\n");
1721
 
            priv->audio_drop++;
1722
 
        } else {
1723
 
            priv->audio_tail = (priv->audio_tail+1) % priv->audio_buffer_size;
1724
 
            priv->audio_cnt++;
1725
 
        }
1726
 
    }
1727
 
    return NULL;
1728
 
}
1729
 
 
1730
 
static double grab_audio_frame(priv_t *priv, char *buffer, int len)
1731
 
{
1732
 
    mp_dbg(MSGT_TV, MSGL_DBG2, "grab_audio_frame(priv=%p, buffer=%p, len=%d)\n",
1733
 
        priv, buffer, len);
1734
 
 
1735
 
    if (priv->first) {
1736
 
        pthread_create(&priv->video_grabber_thread, NULL, video_grabber, priv);
1737
 
        priv->first = 0;
1738
 
    }
1739
 
 
1740
 
    // compensate for dropped audio frames
1741
 
    if (priv->audio_drop && (priv->audio_head == priv->audio_tail)) {
1742
 
        priv->audio_drop--;
1743
 
        priv->audio_sent_blocks_total++;
1744
 
        memset(buffer, 0, len);
1745
 
        return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
1746
 
    }
1747
 
 
1748
 
    while (priv->audio_head == priv->audio_tail) {
1749
 
        usleep(10000);
1750
 
    }
1751
 
    memcpy(buffer, priv->audio_ringbuffer+priv->audio_head*priv->audio_in.blocksize, len);
1752
 
    priv->audio_head = (priv->audio_head+1) % priv->audio_buffer_size;
1753
 
    priv->audio_cnt--;
1754
 
    priv->audio_sent_blocks_total++;
1755
 
    return (double)priv->audio_sent_blocks_total*priv->audio_secs_per_block;
1756
 
}
1757
 
 
1758
 
static int get_audio_framesize(priv_t *priv)
1759
 
{
1760
 
    return(priv->audio_in.blocksize);
1761
 
}
1762
 
 
1763
 
#endif /* USE_TV */