dc1394.c 29.5 KB
Newer Older
1 2 3
/*****************************************************************************
 * dc1394.c: firewire input module
 *****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
4
 * Copyright (C) 2006-2009 VideoLAN
5 6
 *
 * Authors: Xant Majere <xant@xant.net>
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
7 8
 *          Rob Shortt <rob@tvcentric.com> - libdc1394 V2 API updates
 *          Frederic Benoist <fridorik@gmail.com> - updates from Rob's work
9 10 11 12
 *
 *****************************************************************************
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
13
 * License as published by the Free Software Foundation;
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 * version 2 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/

31 32 33 34
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

35
#include <vlc_common.h>
36
#include <vlc_plugin.h>
37 38
#include <vlc_input.h>
#include <vlc_demux.h>
39
#include <vlc_charset.h>
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
40
#include <vlc_picture.h>
41 42 43 44 45 46 47 48 49 50 51 52 53 54

#ifdef HAVE_FCNTL_H
#   include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#   include <unistd.h>
#elif defined( WIN32 ) && !defined( UNDER_CE )
#   include <io.h>
#endif

#include <sys/ioctl.h>
#include <sys/soundcard.h>

#include <libraw1394/raw1394.h>
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
55
#include <dc1394/dc1394.h>
56 57 58 59 60 61 62 63 64 65 66 67

#define MAX_IEEE1394_HOSTS 32
#define MAX_CAMERA_NODES 32

/*****************************************************************************
 * Module descriptor
 *****************************************************************************/
static int  Open ( vlc_object_t * );
static void Close( vlc_object_t * );
static void OpenAudioDev( demux_t *p_demux );
static inline void CloseAudioDev( demux_t *p_demux );

68
vlc_module_begin()
69 70 71 72
    set_description( N_("dc1394 input") )
    set_capability( "access_demux", 10 )
    add_shortcut( "dc1394" )
    set_callbacks( Open, Close )
73
vlc_module_end()
74

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
75
struct demux_sys_t
76
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
77 78 79 80
    /* camera info */
    dc1394_t            *p_dccontext;
    uint32_t            num_cameras;
    dc1394camera_t      *camera;
81
    int                 selected_camera;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
82 83 84 85
    uint64_t            selected_uid;
    picture_t           pic;
    uint32_t            dma_buffers;
    dc1394featureset_t  features;
86
    quadlet_t           supported_framerates;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
87
    bool                reset_bus;
88

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
89 90 91
    /* video info */
    char                *video_device;
    dc1394video_mode_t  video_mode;
92 93 94 95 96 97 98
    int                 width;
    int                 height;
    int                 frame_size;
    int                 frame_rate;
    unsigned int        brightness;
    unsigned int        focus;
    es_out_id_t         *p_es_video;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
99
    dc1394video_frame_t *frame;
100 101 102 103 104 105 106 107

    /* audio stuff */
    int                 i_sample_rate;
    int                 channels;
    int                 i_audio_max_frame_size;
    int                 fd_audio;
    char                *audio_device;
    es_out_id_t         *p_es_audio;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
108
};
109 110 111 112 113 114 115 116 117 118 119

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
static int Demux( demux_t *p_demux );
static int Control( demux_t *, int, va_list );
static block_t *GrabVideo( demux_t *p_demux );
static block_t *GrabAudio( demux_t *p_demux );
static int process_options( demux_t *p_demux);

/*****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
120
 * FindCameras
121
 *****************************************************************************/
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
122
static int FindCamera( demux_sys_t *sys, demux_t *p_demux )
123
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
124
    dc1394camera_list_t *list;
ivoire's avatar
ivoire committed
125
    int i_ret = VLC_EGENERIC;
126 127 128

    msg_Dbg( p_demux, "Scanning for ieee1394 ports ..." );

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
129 130 131
    if( dc1394_camera_enumerate (sys->p_dccontext, &list) != DC1394_SUCCESS )
    {
        msg_Err(p_demux, "Can not ennumerate cameras");
ivoire's avatar
ivoire committed
132
        goto end;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
133
    }
134

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
135 136 137
    if( list->num == 0 )
    {
        msg_Err(p_demux, "Can not find cameras");
ivoire's avatar
ivoire committed
138
        goto end;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
139 140 141 142
    }

    sys->num_cameras = list->num;
    msg_Dbg( p_demux, "Found %d dc1394 cameras.", list->num);
143

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
144 145 146 147 148 149
    if( sys->selected_uid )
    {
        int found = 0;
        for( unsigned i = 0; i < sys->num_cameras; i++ )
        {
            if( list->ids[i].guid == sys->selected_uid )
150
            {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
151 152 153 154
                sys->camera = dc1394_camera_new(sys->p_dccontext,
                                                list->ids[i].guid);
                found++;
                break;
155 156
            }
        }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
157 158 159 160
        if( !found )
        {
            msg_Err( p_demux, "Can't find camera with uid : 0x%llx.",
                     sys->selected_uid );
ivoire's avatar
ivoire committed
161
            goto end;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
162 163 164 165 166 167
        }
    }
    else if( sys->selected_camera >= (int)list->num )
    {
        msg_Err( p_demux, "There are not this many cameras. (%d/%d)",
                 sys->selected_camera, sys->num_cameras );
ivoire's avatar
ivoire committed
168
        goto end;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
169 170 171 172 173 174 175 176 177 178
    }
    else if( sys->selected_camera >= 0 )
    {
        sys->camera = dc1394_camera_new(sys->p_dccontext,
                    list->ids[sys->selected_camera].guid);
    }
    else
    {
        sys->camera = dc1394_camera_new(sys->p_dccontext,
                                          list->ids[0].guid);
179
    }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
180

ivoire's avatar
ivoire committed
181 182 183
    i_ret = VLC_SUCCESS;

end:
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
184
    dc1394_camera_free_list (list);
ivoire's avatar
ivoire committed
185
    return i_ret;
186 187 188 189 190 191 192
}

/*****************************************************************************
 * Open:
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
193 194 195 196 197 198
    demux_t      *p_demux = (demux_t*)p_this;
    demux_sys_t  *p_sys;
    es_format_t   fmt;
    dc1394error_t res;
    int           i_width;
    int           i_height;
199

200 201 202
    if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
        return VLC_EGENERIC;

203 204 205 206 207 208 209
    /* Set up p_demux */
    p_demux->pf_demux = Demux;
    p_demux->pf_control = Control;
    p_demux->info.i_update = 0;
    p_demux->info.i_title = 0;
    p_demux->info.i_seekpoint = 0;

ivoire's avatar
ivoire committed
210
    p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
211 212
    if( !p_sys )
        return VLC_ENOMEM;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
213

214 215 216
    memset( &fmt, 0, sizeof( es_format_t ) );

    /* DEFAULTS */
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
217 218 219 220 221 222 223 224 225 226 227 228
    p_sys->video_mode      = DC1394_VIDEO_MODE_640x480_YUV422;
    p_sys->width           = 640;
    p_sys->height          = 480;
    p_sys->frame_rate      = DC1394_FRAMERATE_15;
    p_sys->brightness      = 200;
    p_sys->focus           = 0;
    p_sys->fd_audio        = -1;
    p_sys->p_dccontext     = NULL;
    p_sys->camera          = NULL;
    p_sys->selected_camera = -1;
    p_sys->dma_buffers     = 1;
    p_sys->reset_bus       = 0;
229 230 231 232 233 234 235 236 237 238 239

    /* PROCESS INPUT OPTIONS */
    if( process_options(p_demux) != VLC_SUCCESS )
    {
        msg_Err( p_demux, "Bad MRL, please check the option line "
                          "(MRL was: %s)",
                          p_demux->psz_path );
        free( p_sys );
        return VLC_EGENERIC;
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
240 241 242 243
    p_sys->p_dccontext = dc1394_new();
    if( !p_sys->p_dccontext )
    {
        msg_Err( p_demux, "Failed to initialise libdc1394");
244
        free( p_sys );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
245 246 247 248
        return VLC_EGENERIC;
    }

    if( FindCamera( p_sys, p_demux ) != VLC_SUCCESS )
ivoire's avatar
ivoire committed
249 250 251
    {
        dc1394_free( p_sys->p_dccontext );
        free( p_sys );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
252
        return VLC_EGENERIC;
ivoire's avatar
ivoire committed
253
    }
254

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
255
    if( !p_sys->camera )
256 257
    {
        msg_Err( p_demux, "No camera found !!" );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
258
        dc1394_free( p_sys->p_dccontext );
259 260 261 262
        free( p_sys );
        return VLC_EGENERIC;
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
263
    if( p_sys->reset_bus )
264
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
265
        if( dc1394_reset_bus( p_sys->camera ) != DC1394_SUCCESS )
266
        {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
267
            msg_Err( p_demux, "Unable to reset IEEE 1394 bus");
268 269 270
            Close( p_this );
            return VLC_EGENERIC;
        }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
271
        else msg_Dbg( p_demux, "Successfully reset IEEE 1394 bus");
272 273
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
274
    if( dc1394_camera_reset( p_sys->camera ) != DC1394_SUCCESS )
275
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
276
        msg_Err( p_demux, "Unable to reset camera");
277 278 279 280
        Close( p_this );
        return VLC_EGENERIC;
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
281 282
    if( dc1394_camera_print_info( p_sys->camera,
                  stderr ) != DC1394_SUCCESS )
283
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
284
        msg_Err( p_demux, "Unable to print camera info");
285 286 287 288
        Close( p_this );
        return VLC_EGENERIC;
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
289 290
    if( dc1394_feature_get_all( p_sys->camera,
                &p_sys->features ) != DC1394_SUCCESS )
291
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
292
        msg_Err( p_demux, "Unable to get feature set");
293 294 295
        Close( p_this );
        return VLC_EGENERIC;
    }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
296 297
    // TODO: only print features if verbosity increased
    dc1394_feature_print_all(&p_sys->features, stderr);
298

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
299 300
#if 0 //"Note that you need to execute this function only if you use exotic video1394 device names. /dev/video1394, /dev/video1394/* and /dev/video1394-* are automatically recognized." http://damien.douxchamps.net/ieee1394/libdc1394/v2.x/api/capture/
    if( p_sys->video_device )
301
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
302 303 304 305 306 307 308
        if( dc1394_capture_set_device_filename( p_sys->camera,
                        p_sys->video_device ) != DC1394_SUCCESS )
        {
            msg_Err( p_demux, "Unable to set video device");
            Close( p_this );
            return VLC_EGENERIC;
        }
309
    }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
310
#endif
311 312 313

    if( p_sys->focus )
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
314 315 316
        if( dc1394_feature_set_value( p_sys->camera,
                      DC1394_FEATURE_FOCUS,
                      p_sys->focus ) != DC1394_SUCCESS )
317
        {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
318
            msg_Err( p_demux, "Unable to set initial focus to %u",
319 320 321 322 323
                     p_sys->focus );
        }
        msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
324 325 326
    if( dc1394_feature_set_value( p_sys->camera,
                  DC1394_FEATURE_FOCUS,
                  p_sys->brightness ) != DC1394_SUCCESS )
327
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
328 329
        msg_Err( p_demux, "Unable to set initial brightness to %u",
                 p_sys->brightness );
330
    }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
331
    msg_Dbg( p_demux, "Initial brightness set to %u", p_sys->brightness );
332

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
333 334
    if( dc1394_video_set_framerate( p_sys->camera,
                    p_sys->frame_rate ) != DC1394_SUCCESS )
335
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
336
        msg_Err( p_demux, "Unable to set framerate");
337 338 339 340
        Close( p_this );
        return VLC_EGENERIC;
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
341 342
    if( dc1394_video_set_mode( p_sys->camera,
                   p_sys->video_mode ) != DC1394_SUCCESS )
343
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
344
        msg_Err( p_demux, "Unable to set video mode");
345 346 347 348
        Close( p_this );
        return VLC_EGENERIC;
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
349 350
    if( dc1394_video_set_iso_speed( p_sys->camera,
                    DC1394_ISO_SPEED_400 ) != DC1394_SUCCESS )
351
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
352
        msg_Err( p_demux, "Unable to set iso speed");
353 354 355 356 357
        Close( p_this );
        return VLC_EGENERIC;
    }

    /* and setup capture */
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
358 359 360 361 362 363
    res = dc1394_capture_setup( p_sys->camera,
                    p_sys->dma_buffers,
                DC1394_CAPTURE_FLAGS_DEFAULT);
    if( res != DC1394_SUCCESS )
    {
        if( res == DC1394_NO_BANDWIDTH )
364
        {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
365 366
            msg_Err( p_demux ,"No bandwidth: try adding the "
             "\"resetbus\" option" );
367
        }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
368
        else
369
        {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
370
            msg_Err( p_demux ,"Unable to setup capture" );
371
        }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
372 373
        Close( p_this );
        return VLC_EGENERIC;
374 375 376 377 378
    }

    /* TODO - UYV444 chroma converter is missing, when it will be available
     * fourcc will become variable (and not just a fixed value for UYVY)
     */
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
379 380
    i_width = p_sys->width;
    i_height = p_sys->height;
381

382 383 384 385 386 387 388 389
    if( picture_Setup( &p_sys->pic, VLC_CODEC_UYVY,
                       i_width, i_height,
                       i_width * VOUT_ASPECT_FACTOR / i_height ) )
    {
        msg_Err( p_demux ,"unknown chroma" );
        Close( p_this );
        return VLC_EGENERIC;
    }
390

391
    es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY );
392 393 394 395

    fmt.video.i_width = i_width;
    fmt.video.i_height = i_height;

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
396
    msg_Dbg( p_demux, "Added new video es %4.4s %dx%d",
397 398 399 400 401 402 403 404 405 406
             (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );

    p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );

    if( p_sys->audio_device )
    {
        OpenAudioDev( p_demux );
        if( p_sys->fd_audio >= 0 )
        {
            es_format_t fmt;
407
            es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_S16L ); /* FIXME: hmm, ?? */
408 409 410

            fmt.audio.i_channels = p_sys->channels ? p_sys->channels : 1;
            fmt.audio.i_rate = p_sys->i_sample_rate;
411
            fmt.audio.i_bitspersample = 16;
412 413 414 415 416
            fmt.audio.i_blockalign = fmt.audio.i_channels *
                                     fmt.audio.i_bitspersample / 8;
            fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *
                            fmt.audio.i_bitspersample;

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
417
            msg_Dbg( p_demux, "New audio es %d channels %dHz",
418 419 420 421 422 423 424
            fmt.audio.i_channels, fmt.audio.i_rate );

            p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
        }
    }

    /* have the camera start sending us data */
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
425 426
    if( dc1394_video_set_transmission( p_sys->camera,
                       DC1394_ON ) != DC1394_SUCCESS )
427
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
428 429
        msg_Err( p_demux, "Unable to start camera iso transmission" );
        dc1394_capture_stop( p_sys->camera );
430 431 432
        Close( p_this );
        return VLC_EGENERIC;
    }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
433 434
    msg_Dbg( p_demux, "Set iso transmission" );
    // TODO: reread camera
435 436 437 438 439 440 441 442 443 444
    return VLC_SUCCESS;
}

static void OpenAudioDev( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    char *psz_device = p_sys->audio_device;
    int i_format = AFMT_S16_LE;
    int result;

445
    p_sys->fd_audio = utf8_open( psz_device, O_RDONLY | O_NONBLOCK );
446 447
    if( p_sys->fd_audio  < 0 )
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
448
        msg_Err( p_demux, "Cannot open audio device (%s)", psz_device );
449 450 451 452 453 454 455 456 457
        CloseAudioDev( p_demux );
    }

    if( !p_sys->i_sample_rate )
        p_sys->i_sample_rate = 44100;

    result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format );
    if( (result  < 0) || (i_format != AFMT_S16_LE) )
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
458
        msg_Err( p_demux, "Cannot set audio format (16b little endian) "
459 460 461 462 463 464 465
                          "(%d)", i_format );
        CloseAudioDev( p_demux );
    }

    result = ioctl( p_sys->fd_audio, SNDCTL_DSP_CHANNELS, &p_sys->channels );
    if( result < 0 )
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
466
        msg_Err( p_demux, "Cannot set audio channels count (%d)",
467 468 469 470 471 472 473
                 p_sys->channels );
        CloseAudioDev( p_demux );
    }

    result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED, &p_sys->i_sample_rate );
    if( result < 0 )
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
474 475
        msg_Err( p_demux, "Cannot set audio sample rate (%d)",
         p_sys->i_sample_rate );
476 477 478
        CloseAudioDev( p_demux );
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
479
    msg_Dbg( p_demux, "Opened adev=`%s' %s %dHz",
480 481 482 483 484 485 486 487 488
             psz_device,
             (p_sys->channels > 1) ? "stereo" : "mono",
             p_sys->i_sample_rate );

    p_sys->i_audio_max_frame_size = 32 * 1024;
}

static inline void CloseAudioDev( demux_t *p_demux )
{
489
    demux_sys_t *p_sys = p_demux->p_sys;
490

491 492
    if( p_sys->fd_audio >= 0 )
        close( p_sys->fd_audio );
493 494 495 496 497 498 499 500 501 502 503
}

/*****************************************************************************
 * Close:
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys = p_demux->p_sys;

    /* Stop data transmission */
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
504 505 506
    if( dc1394_video_set_transmission( p_sys->camera,
                       DC1394_OFF ) != DC1394_SUCCESS )
        msg_Err( p_demux, "Unable to stop camera iso transmission" );
507 508

    /* Close camera */
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
509
    dc1394_capture_stop( p_sys->camera );
510 511 512

    CloseAudioDev( p_demux );

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
513 514 515
    dc1394_camera_free(p_sys->camera);
    dc1394_free(p_sys->p_dccontext);

516
    free( p_sys->audio_device );
517 518 519
    free( p_sys );
}

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
520
#if 0
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
{
    char u,v,y;
    u_char  *sc;
    u_char  *dc;

    sc = (u_char *)src + (spos*2);
    if( spos % 2 )
    {
        v = sc[0];
        y = sc[1];
        u = *(sc -2);
    }
    else
    {
        u = sc[0];
        y = sc[1];
        v = sc[2];
    }
    dc = (u_char *)dst+(dpos*2);
    if( dpos % 2 )
    {
        dc[0] = v;
        dc[1] = y;
    }
    else
    {
        dc[0] = u;
        dc[1] = y;
    }
}
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
552
#endif
553 554 555 556 557 558 559 560 561

/*****************************************************************************
 * Demux:
 *****************************************************************************/
static block_t *GrabVideo( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    block_t     *p_block = NULL;

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
562 563 564
    if( dc1394_capture_dequeue( p_sys->camera,
                DC1394_CAPTURE_POLICY_WAIT,
                &p_sys->frame ) != DC1394_SUCCESS )
565
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
566 567
        msg_Err( p_demux, "Unable to capture a frame" );
        return NULL;
568 569
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
570 571
    p_block = block_New( p_demux, p_sys->frame->size[0] *
                                  p_sys->frame->size[1] * 2 );
572 573
    if( !p_block )
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
574
        msg_Err( p_demux, "Can not get block" );
575 576 577
        return NULL;
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
578
    if( !p_sys->frame->image )
579
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
580
        msg_Err (p_demux, "Capture buffer empty");
581 582 583 584
        block_Release( p_block );
        return NULL;
    }

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
585 586
    memcpy( p_block->p_buffer, (const char *)p_sys->frame->image,
            p_sys->width * p_sys->height * 2 );
587 588

    p_block->i_pts = p_block->i_dts = mdate();
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
589
    dc1394_capture_enqueue( p_sys->camera, p_sys->frame );
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
    return p_block;
}

static block_t *GrabAudio( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    struct audio_buf_info buf_info;
    block_t *p_block = NULL;
    int i_read = 0;
    int i_correct = 0;
    int result = 0;

    p_block = block_New( p_demux, p_sys->i_audio_max_frame_size );
    if( !p_block )
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
605
        msg_Warn( p_demux, "Cannot get buffer" );
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
        return NULL;
    }

    i_read = read( p_sys->fd_audio, p_block->p_buffer,
                   p_sys->i_audio_max_frame_size );

    if( i_read <= 0 )
        return NULL;

    p_block->i_buffer = i_read;

    /* Correct the date because of kernel buffering */
    i_correct = i_read;
    result = ioctl( p_sys->fd_audio, SNDCTL_DSP_GETISPACE, &buf_info );
    if( result == 0 )
        i_correct += buf_info.bytes;

    p_block->i_pts = p_block->i_dts =
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
624
                        mdate() - INT64_C(1000000) * (mtime_t)i_correct /
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
                        2 / p_sys->channels / p_sys->i_sample_rate;
    return p_block;
}

static int Demux( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    block_t *p_blocka = NULL;
    block_t *p_blockv = NULL;

    /* Try grabbing audio frames first */
    if( p_sys->fd_audio > 0 )
        p_blocka = GrabAudio( p_demux );

    /* Try grabbing video frame */
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
640
    p_blockv = GrabVideo( p_demux );
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669

    if( !p_blocka && !p_blockv )
    {
        /* Sleep so we do not consume all the cpu, 10ms seems
         * like a good value (100fps)
         */
        msleep( 10000 );
        return 1;
    }

    if( p_blocka )
    {
        es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blocka->i_pts );
        es_out_Send( p_demux->out, p_sys->p_es_audio, p_blocka );
    }

    if( p_blockv )
    {
        es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blockv->i_pts );
        es_out_Send( p_demux->out, p_sys->p_es_video, p_blockv );
    }
    return 1;
}

/*****************************************************************************
 * Control:
 *****************************************************************************/
static int Control( demux_t *p_demux, int i_query, va_list args )
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
670
    VLC_UNUSED( p_demux );
671 672 673 674
    switch( i_query )
    {
        /* Special for access_demux */
        case DEMUX_CAN_PAUSE:
675
        case DEMUX_CAN_SEEK:
676 677
        case DEMUX_SET_PAUSE_STATE:
        case DEMUX_CAN_CONTROL_PACE:
678
            *va_arg( args, bool * ) = false;
679 680 681
            return VLC_SUCCESS;

        case DEMUX_GET_PTS_DELAY:
682
            *va_arg( args, int64_t * ) = (int64_t)DEFAULT_PTS_DELAY;
683 684 685
            return VLC_SUCCESS;

        case DEMUX_GET_TIME:
686
            *va_arg( args, int64_t * ) = mdate();
687 688 689 690 691 692 693 694 695 696 697 698
            return VLC_SUCCESS;

        /* TODO implement others */
        default:
            return VLC_EGENERIC;
    }
    return VLC_EGENERIC;
}

static int process_options( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
699
    char *psz_dup;
700 701 702
    char *psz_parser;
    char *token = NULL;
    char *state = NULL;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
703 704
    const char *in_size = NULL;
    const char *in_fmt = NULL;
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
    float rate_f;

    psz_dup = strdup( p_demux->psz_path );
    psz_parser = psz_dup;
    for( token = strtok_r( psz_parser,":",&state); token;
         token = strtok_r( NULL, ":", &state ) )
    {
        if( strncmp( token, "size=", strlen("size=") ) == 0 )
        {
            token += strlen("size=");
            if( strncmp( token, "160x120", 7 ) == 0 )
            {
                /* TODO - UYV444 chroma converter is needed ...
                    * video size of 160x120 is temporarily disabled
                    */
                msg_Err( p_demux,
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
721 722 723 724
                    "video size of 160x120 is actually disabled for lack of"
                    "chroma support. It will relased ASAP, until then try "
                    "an higher size (320x240 and 640x480 are fully supported)" );
                free(psz_dup);
725 726
                return VLC_EGENERIC;
#if 0
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
727
                in_size = "160x120";
728 729 730 731 732 733
                p_sys->width = 160;
                p_sys->height = 120;
#endif
            }
            else if( strncmp( token, "320x240", 7 ) == 0 )
            {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
734
                in_size = "320x240";
735 736 737 738 739
                p_sys->width = 320;
                p_sys->height = 240;
            }
            else if( strncmp( token, "640x480", 7 ) == 0 )
            {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
740
                in_size = "640x480";
741 742 743 744 745 746 747 748 749 750
                p_sys->width = 640;
                p_sys->height = 480;
            }
            else
            {
                msg_Err( p_demux,
                    "This program currently suppots frame sizes of"
                    " 160x120, 320x240, and 640x480. "
                    "Please specify one of them. You have specified %s.",
                    token );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
751
                free(psz_dup);
752 753 754 755
                return VLC_EGENERIC;
            }
            msg_Dbg( p_demux, "Requested video size : %s",token );
        }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
        if( strncmp( token, "format=", strlen("format=") ) == 0 )
        {
            token += strlen("format=");
            if( strncmp( token, "YUV411", 6 ) == 0 )
            {
                in_fmt = "YUV411";
            }
            else if( strncmp( token, "YUV422", 6 ) == 0 )
            {
                in_fmt = "YUV422";
            }
            else if( strncmp( token, "YUV444", 6 ) == 0 )
            {
                in_fmt = "YUV444";
            }
            else if( strncmp( token, "RGB8", 4 ) == 0 )
            {
                in_fmt = "RGB8";
            }
            else if( strncmp( token, "MONO8", 5 ) == 0 )
            {
                in_fmt = "MONO8";
            }
            else if( strncmp( token, "MONO16", 6 ) == 0 )
            {
                in_fmt = "MONO16";
            }
            else
            {
                msg_Err( p_demux, "Invalid format %s.", token );
                free(psz_dup);
                return VLC_EGENERIC;
            }
            msg_Dbg( p_demux, "Requested video format : %s", token );
        }
791 792 793 794 795
        else if( strncmp( token, "fps=", strlen( "fps=" ) ) == 0 )
        {
            token += strlen("fps=");
            sscanf( token, "%g", &rate_f );
            if( rate_f == 1.875 )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
796
                p_sys->frame_rate = DC1394_FRAMERATE_1_875;
797
            else if( rate_f == 3.75 )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
798
                p_sys->frame_rate = DC1394_FRAMERATE_3_75;
799
            else if( rate_f == 7.5 )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
800
                p_sys->frame_rate = DC1394_FRAMERATE_7_5;
801
            else if( rate_f == 15 )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
802
                p_sys->frame_rate = DC1394_FRAMERATE_15;
803
            else if( rate_f == 30 )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
804
                p_sys->frame_rate = DC1394_FRAMERATE_30;
805
            else if( rate_f == 60 )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
806
                p_sys->frame_rate = DC1394_FRAMERATE_60;
807 808 809 810 811 812 813
            else
            {
                msg_Err( p_demux ,
                    "This program supports framerates of"
                    " 1.875, 3.75, 7.5, 15, 30, 60. "
                    "Please specify one of them. You have specified %s.",
                    token);
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
814
                free(psz_dup);
815 816 817 818
                return VLC_EGENERIC;
            }
            msg_Dbg( p_demux, "Requested frame rate : %s",token );
        }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
819 820 821 822 823
        else if( strncmp( token, "resetbus", strlen( "resetbus" ) ) == 0 )
        {
            token += strlen("resetbus");
            p_sys->reset_bus = 1;
        }
824 825 826 827 828 829 830 831 832 833
        else if( strncmp( token, "brightness=", strlen( "brightness=" ) ) == 0 )
        {
            int nr = 0;
            token += strlen("brightness=");
            nr = sscanf( token, "%u", &p_sys->brightness);
            if( nr != 1 )
            {
                msg_Err( p_demux, "Bad brightness value '%s', "
                                  "must be an unsigned integer.",
                                  token );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
834 835 836 837 838 839 840 841 842 843 844 845 846 847
                free(psz_dup);
                return VLC_EGENERIC;
            }
        }
        else if( strncmp( token, "buffers=", strlen( "buffers=" ) ) == 0 )
        {
            int nr = 0;
            int in_buf = 0;
            token += strlen("buffers=");
            nr = sscanf( token, "%d", &in_buf);
            if( nr != 1 || in_buf < 1 )
            {
                msg_Err( p_demux, "DMA buffers must be 1 or greater." );
                free(psz_dup);
848 849
                return VLC_EGENERIC;
            }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
850
            else p_sys->dma_buffers = in_buf;
851 852
        }
#if 0
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
853 854
        // NOTE: If controller support is added back, more logic will needed to be added
        //       after the cameras are scanned.
855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
        else if( strncmp( token, "controller=", strlen( "controller=" ) ) == 0 )
        {
            int nr = 0;
            token += strlen("controller=");
            nr = sscanf( token, "%u", &p_sys->controller );
            if( nr != 1)
            {
                msg_Err(p_demux, "Bad controller value '%s', "
                                 "must be an unsigned integer.",
                                 token );
                return VLC_EGENERIC;
            }
        }
#endif
        else if( strncmp( token, "camera=", strlen( "camera=" ) ) == 0 )
        {
            int nr = 0;
            token += strlen("camera=");
            nr = sscanf(token,"%u",&p_sys->selected_camera);
            if( nr != 1)
            {
                msg_Err( p_demux, "Bad camera number '%s', "
                                  "must be an unsigned integer.",
                                  token );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
879
                free(psz_dup);
880 881 882
                return VLC_EGENERIC;
            }
        }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
883
        else if( strncmp( token, "vdev=", strlen( "vdev=" ) ) == 0)
884
        {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
885 886 887
            token += strlen("vdev=");
            p_sys->video_device = strdup(token);
            msg_Dbg( p_demux, "Using video device '%s'.", token );
888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906
        }
        else if( strncmp( token, "adev=", strlen( "adev=" ) ) == 0 )
        {
            token += strlen("adev=");
            p_sys->audio_device = strdup(token);
            msg_Dbg( p_demux, "Using audio device '%s'.", token );
        }
        else if( strncmp( token, "samplerate=", strlen( "samplerate=" ) ) == 0 )
        {
            token += strlen("samplerate=");
            sscanf( token, "%d", &p_sys->i_sample_rate );
        }
        else if( strncmp( token, "channels=", strlen("channels=" ) ) == 0 )
        {
            token += strlen("channels=");
            sscanf( token, "%d", &p_sys->channels );
        }
        else if( strncmp( token, "focus=", strlen("focus=" ) ) == 0)
        {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
907
            int nr = 0;
908
            token += strlen("focus=");
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
909 910 911 912 913 914 915 916 917
            nr = sscanf( token, "%u", &p_sys->focus );
            if( nr != 1 )
            {
                msg_Err( p_demux, "Bad focus value '%s', "
                                  "must be an unsigned integer.",
                                  token );
                free(psz_dup);
                return VLC_EGENERIC;
            }
918 919 920 921 922 923 924
        }
        else if( strncmp( token, "uid=", strlen("uid=") ) == 0)
        {
            token += strlen("uid=");
            sscanf( token, "0x%llx", &p_sys->selected_uid );
        }
    }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960

    // The mode is a combination of size and format and not every format
    // is supported by every size.
    if( in_size)
    {
        if( strcmp( in_size, "160x120") == 0)
        {
            if( in_fmt && (strcmp( in_fmt, "YUV444") != 0) )
                msg_Err(p_demux, "160x120 only supports YUV444 - forcing");
            p_sys->video_mode = DC1394_VIDEO_MODE_160x120_YUV444;
        }
        else if( strcmp( in_size, "320x240") == 0)
        {
            if( in_fmt && (strcmp( in_fmt, "YUV422") != 0) )
                msg_Err(p_demux, "320x240 only supports YUV422 - forcing");
            p_sys->video_mode = DC1394_VIDEO_MODE_320x240_YUV422;
        }
    }
    else
    { // 640x480 default
        if( in_fmt )
        {
            if( strcmp( in_fmt, "RGB8") == 0)
                p_sys->video_mode = DC1394_VIDEO_MODE_640x480_RGB8;
            else if( strcmp( in_fmt, "MONO8") == 0)
                p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO8;
            else if( strcmp( in_fmt, "MONO16") == 0)
                p_sys->video_mode = DC1394_VIDEO_MODE_640x480_MONO16;
            else if( strcmp( in_fmt, "YUV411") == 0)
                p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV411;
            else // YUV422 default
                p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
        }
        else // YUV422 default
            p_sys->video_mode = DC1394_VIDEO_MODE_640x480_YUV422;
    }
961 962
    return VLC_SUCCESS;
}