dc1394.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:31k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * dc1394.c: firewire input module
  3.  *****************************************************************************
  4.  * Copyright (C) 2006 the VideoLAN team
  5.  *
  6.  * Authors: Xant Majere <xant@xant.net>
  7.  *
  8.  *****************************************************************************
  9.  * This library is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU Lesser General Public
  11.  * License as published by the Free Software Foundation;
  12.  * version 2 of the License.
  13.  *
  14.  * This library is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  * Lesser General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU Lesser General Public
  20.  * License along with this library; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  22.  *
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #include <vlc_common.h>
  31. #include <vlc_plugin.h>
  32. #include <vlc_input.h>
  33. #include <vlc_vout.h>
  34. #include <vlc_demux.h>
  35. #ifdef HAVE_FCNTL_H
  36. #   include <fcntl.h>
  37. #endif
  38. #ifdef HAVE_UNISTD_H
  39. #   include <unistd.h>
  40. #elif defined( WIN32 ) && !defined( UNDER_CE )
  41. #   include <io.h>
  42. #endif
  43. #include <sys/ioctl.h>
  44. #include <sys/soundcard.h>
  45. #include <libraw1394/raw1394.h>
  46. #include <libdc1394/dc1394_control.h>
  47. #define MAX_IEEE1394_HOSTS 32
  48. #define MAX_CAMERA_NODES 32
  49. /*****************************************************************************
  50.  * Module descriptor
  51.  *****************************************************************************/
  52. static int  Open ( vlc_object_t * );
  53. static void Close( vlc_object_t * );
  54. static void OpenAudioDev( demux_t *p_demux );
  55. static inline void CloseAudioDev( demux_t *p_demux );
  56. vlc_module_begin ()
  57.     set_description( N_("dc1394 input") )
  58.     set_capability( "access_demux", 10 )
  59.     add_shortcut( "dc1394" )
  60.     set_callbacks( Open, Close )
  61. vlc_module_end ()
  62. typedef struct __dc_camera
  63. {
  64.     int port;
  65.     nodeid_t node;
  66.     u_int64_t uid;
  67. } dc_camera;
  68. typedef struct demux_sys_t
  69. {
  70.     dc1394_cameracapture camera;
  71.     picture_t            pic;
  72.     int                  dma_capture;
  73. #define DMA_OFF 0
  74. #define DMA_ON 1
  75.     int                 num_ports;
  76.     int                 num_cameras;
  77.     int                 selected_camera;
  78.     u_int64_t           selected_uid;
  79.     dc_camera           *camera_nodes;
  80.     dc1394_camerainfo   camera_info;
  81.     dc1394_miscinfo     misc_info;
  82.     raw1394handle_t     fd_video;
  83.     quadlet_t           supported_framerates;
  84.     int                 width;
  85.     int                 height;
  86.     int                 frame_size;
  87.     int                 frame_rate;
  88.     unsigned int        brightness;
  89.     unsigned int        focus;
  90.     char                *dma_device;
  91.     es_out_id_t         *p_es_video;
  92.     /* audio stuff */
  93.     int                 i_sample_rate;
  94.     int                 channels;
  95.     int                 i_audio_max_frame_size;
  96.     int                 fd_audio;
  97.     char                *audio_device;
  98. #define NO_ROTATION 0
  99. #define ROTATION_LEFT 1
  100. #define ROTATION_RIGHT 2
  101.     es_out_id_t         *p_es_audio;
  102. } dc1394_sys;
  103. /*****************************************************************************
  104.  * Local prototypes
  105.  *****************************************************************************/
  106. static int Demux( demux_t *p_demux );
  107. static int Control( demux_t *, int, va_list );
  108. static block_t *GrabVideo( demux_t *p_demux );
  109. static block_t *GrabAudio( demux_t *p_demux );
  110. static int process_options( demux_t *p_demux);
  111. /*****************************************************************************
  112.  * ScanCameras
  113.  *****************************************************************************/
  114. static void ScanCameras( dc1394_sys *sys, demux_t *p_demux )
  115. {
  116.     struct raw1394_portinfo portinfo[MAX_IEEE1394_HOSTS];
  117.     raw1394handle_t tempFd;
  118.     dc1394_camerainfo  info;
  119.     dc_camera *node_list = NULL;
  120.     nodeid_t  *nodes = NULL;
  121.     int num_ports = 0;
  122.     int num_cameras = 0;
  123.     int nodecount;
  124.     int i, n;
  125.     memset( &portinfo, 0, sizeof(portinfo) );
  126.     msg_Dbg( p_demux, "Scanning for ieee1394 ports ..." );
  127.     tempFd = raw1394_new_handle();
  128.     if( !tempFd )
  129.         return VLC_EGENERIC;
  130.     raw1394_get_port_info( tempFd, portinfo, MAX_IEEE1394_HOSTS);
  131.     raw1394_destroy_handle( tempFd );
  132.     for( i=0; i < MAX_IEEE1394_HOSTS; i++ )
  133.     {
  134.         /* check if port exists and has at least one node*/
  135.         if( !portinfo[i].nodes )
  136.             continue;
  137.         nodes = NULL;
  138.         nodecount = 0;
  139.         tempFd = dc1394_create_handle( i );
  140.         /* skip this port if we can't obtain a valid handle */
  141.         if( !tempFd )
  142.             continue;
  143.         msg_Dbg( p_demux, "Found ieee1394 port %d (%s) ... "
  144.                           "checking for camera nodes",
  145.                           i, portinfo[i].name );
  146.         num_ports++;
  147.         nodes = dc1394_get_camera_nodes( tempFd, &nodecount, 0 );
  148.         if( nodecount )
  149.         {
  150.             msg_Dbg( p_demux, "Found %d dc1394 cameras on port %d (%s)",
  151.                      nodecount, i, portinfo[i].name );
  152.             if( node_list )
  153.                 node_list = realloc( node_list, sizeof(dc_camera) * (num_cameras+nodecount) );
  154.             else
  155.                 node_list = malloc( sizeof(dc_camera) * nodecount);
  156.             for( n = 0; n < nodecount; n++ )
  157.             {
  158.                 int result = 0;
  159.                 result = dc1394_get_camera_info( tempFd, nodes[n], &info );
  160.                 if( result == DC1394_SUCCESS )
  161.                 {
  162.                     node_list[num_cameras+n].uid = info.euid_64;
  163.                 }
  164.                 node_list[num_cameras+n].node = nodes[n];
  165.                 node_list[num_cameras+n].port = i;
  166.             }
  167.             num_cameras += nodecount;
  168.         }
  169.         else
  170.             msg_Dbg( p_demux, "no cameras found  on port %d (%s)",
  171.                      i, portinfo[i].name );
  172.         if( tempFd )
  173.             dc1394_destroy_handle( tempFd );
  174.     }
  175.     sys->num_ports = num_ports;
  176.     sys->num_cameras = num_cameras;
  177.     sys->camera_nodes = node_list;
  178. }
  179. /*****************************************************************************
  180.  * Open:
  181.  *****************************************************************************/
  182. static int Open( vlc_object_t *p_this )
  183. {
  184.     demux_t     *p_demux = (demux_t*)p_this;
  185.     demux_sys_t *p_sys;
  186.     es_format_t fmt;
  187.     int i;
  188.     int i_width;
  189.     int i_height;
  190.     int i_aspect;
  191.     int result = 0;
  192.     if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
  193.         return VLC_EGENERIC;
  194.     /* Set up p_demux */
  195.     p_demux->pf_demux = Demux;
  196.     p_demux->pf_control = Control;
  197.     p_demux->info.i_update = 0;
  198.     p_demux->info.i_title = 0;
  199.     p_demux->info.i_seekpoint = 0;
  200.     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
  201.     if( !p_sys )
  202.         return VLC_ENOMEM;
  203.     memset( &fmt, 0, sizeof( es_format_t ) );
  204.     /* DEFAULTS */
  205.     p_sys->frame_size = MODE_640x480_YUV422;
  206.     p_sys->width      = 640;
  207.     p_sys->height     = 480;
  208.     p_sys->frame_rate = FRAMERATE_30;
  209.     p_sys->brightness = 200;
  210.     p_sys->focus      = 0;
  211.     p_sys->dma_capture = DMA_ON; /* defaults to VIDEO1394 capture mode */
  212.     p_sys->fd_audio   = -1;
  213.     p_sys->fd_video   = NULL;
  214.     p_sys->camera_nodes = NULL;
  215.     p_sys->selected_camera = 0;
  216.     p_sys->dma_device = NULL;
  217.     p_sys->selected_uid = 0;
  218.     /* PROCESS INPUT OPTIONS */
  219.     if( process_options(p_demux) != VLC_SUCCESS )
  220.     {
  221.         msg_Err( p_demux, "Bad MRL, please check the option line "
  222.                           "(MRL was: %s)",
  223.                           p_demux->psz_path );
  224.         free( p_sys );
  225.         p_demux->p_sys = NULL;
  226.         return VLC_EGENERIC;
  227.     }
  228.     msg_Dbg( p_demux, "Selected camera %d", p_sys->selected_camera );
  229.     msg_Dbg( p_demux, "Selected uid 0x%llx", p_sys->selected_uid );
  230.     ScanCameras( p_sys, p_demux );
  231.     if( !p_sys->camera_nodes )
  232.     {
  233.         msg_Err( p_demux, "No camera found !!" );
  234.         free( p_sys );
  235.         p_demux->p_sys = NULL;
  236.         return VLC_EGENERIC;
  237.     }
  238.     if( p_sys->selected_uid )
  239.     {
  240.         int found = 0;
  241.         for( i=0; i < p_sys->num_cameras; i++ )
  242.         {
  243.             if( p_sys->camera_nodes[i].uid == p_sys->selected_uid )
  244.             {
  245.                 p_sys->selected_camera = i;
  246.                 found++;
  247.                 break;
  248.             }
  249.         }
  250.         if( !found )
  251.         {
  252.             msg_Err( p_demux, "Can't find camera with uid : 0x%llx.",
  253.                      p_sys->selected_uid );
  254.             Close( p_this );
  255.             return VLC_EGENERIC;
  256.         }
  257.     }
  258.     else if( p_sys->selected_camera >= p_sys->num_cameras )
  259.     {
  260.         msg_Err( p_demux, "there are not this many cameras. (%d/%d)",
  261.                           p_sys->selected_camera, p_sys->num_cameras );
  262.         Close( p_this );
  263.         return VLC_EGENERIC;
  264.     }
  265.     p_sys->fd_video = dc1394_create_handle(
  266.                         p_sys->camera_nodes[p_sys->selected_camera].port );
  267.     if( (int)p_sys->fd_video < 0 )
  268.     {
  269.         msg_Err( p_demux, "Can't init dc1394 handle" );
  270.         Close( p_this );
  271.         return VLC_EGENERIC;
  272.     }
  273.     /* get camera info */
  274.     result = dc1394_get_camera_info( p_sys->fd_video,
  275.                         p_sys->camera_nodes[p_sys->selected_camera].node,
  276.                         &p_sys->camera_info );
  277.     if( result != DC1394_SUCCESS )
  278.     {
  279.         msg_Err( p_demux ,"unable to get camera info" );
  280.         Close( p_this );
  281.         return VLC_EGENERIC;
  282.     }
  283.     dc1394_print_camera_info( &p_sys->camera_info );
  284.     result = dc1394_get_camera_misc_info( p_sys->fd_video,
  285.                         p_sys->camera_nodes[p_sys->selected_camera].node,
  286.                         &p_sys->misc_info );
  287.     if( result != DC1394_SUCCESS )
  288.     {
  289.         msg_Err( p_demux, "unable to get camera misc info" );
  290.         Close( p_this );
  291.         return VLC_EGENERIC;
  292.     }
  293.     /* init camera and set some video options  */
  294.     result = dc1394_init_camera( p_sys->camera_info.handle,
  295.                                  p_sys->camera_info.id );
  296.     if( result != DC1394_SUCCESS )
  297.     {
  298.         msg_Err( p_demux, "unable to get init dc1394 camera" );
  299.         Close( p_this );
  300.         return VLC_EGENERIC;
  301.     }
  302.     if( p_sys->focus )
  303.     {
  304.         result = dc1394_set_focus( p_sys->camera_info.handle,
  305.                         p_sys->camera_nodes[p_sys->selected_camera].node,
  306.                         p_sys->focus );
  307.         if( result != DC1394_SUCCESS )
  308.         {
  309.             msg_Err( p_demux, "unable to set initial focus to %u",
  310.                      p_sys->focus );
  311.         }
  312.         msg_Dbg( p_demux, "Initial focus set to %u", p_sys->focus );
  313.     }
  314.     result = dc1394_set_brightness( p_sys->camera_info.handle,
  315.                         p_sys->camera_nodes[p_sys->selected_camera].node,
  316.                         p_sys->brightness );
  317.     if( result != DC1394_SUCCESS )
  318.     {
  319.         msg_Err( p_demux, "unable to set init brightness to %d",
  320.                  p_sys->brightness);
  321.         Close( p_this );
  322.         return VLC_EGENERIC;
  323.     }
  324.     result = dc1394_set_video_framerate( p_sys->camera_info.handle,
  325.                         p_sys->camera_nodes[p_sys->selected_camera].node,
  326.                         p_sys->frame_rate );
  327.     if( result != DC1394_SUCCESS )
  328.     {
  329.         msg_Err( p_demux, "unable to set framerate to %d",
  330.                  p_sys->frame_rate );
  331.         Close( p_this );
  332.         return VLC_EGENERIC;
  333.     }
  334.     p_sys->misc_info.framerate = p_sys->frame_rate;
  335.     result = dc1394_set_video_format( p_sys->camera_info.handle,
  336.                         p_sys->camera_nodes[p_sys->selected_camera].node,
  337.                         FORMAT_VGA_NONCOMPRESSED );
  338.     if( result != DC1394_SUCCESS )
  339.     {
  340.         msg_Err( p_demux, "unable to set video format to VGA_NONCOMPRESSED" );
  341.         Close( p_this );
  342.         return VLC_EGENERIC;
  343.     }
  344.     p_sys->misc_info.format = FORMAT_VGA_NONCOMPRESSED;
  345.     result = dc1394_set_video_mode( p_sys->camera_info.handle,
  346.                         p_sys->camera_nodes[p_sys->selected_camera].node,
  347.                         p_sys->frame_size );
  348.     if( result != DC1394_SUCCESS )
  349.     {
  350.         msg_Err( p_demux, "unable to set video mode" );
  351.         Close( p_this );
  352.         return VLC_EGENERIC;
  353.     }
  354.     p_sys->misc_info.mode = p_sys->frame_size;
  355.     /* reprobe everything */
  356.     result = dc1394_get_camera_info( p_sys->camera_info.handle,
  357.                                      p_sys->camera_info.id,
  358.                                      &p_sys->camera_info );
  359.     if( result != DC1394_SUCCESS )
  360.     {
  361.         msg_Err( p_demux, "Could not get camera basic information!" );
  362.         Close( p_this );
  363.         return VLC_EGENERIC;
  364.     }
  365.     result = dc1394_get_camera_misc_info( p_sys->camera_info.handle,
  366.                                           p_sys->camera_info.id,
  367.                                           &p_sys->misc_info );
  368.     if( result != DC1394_SUCCESS )
  369.     {
  370.         msg_Err( p_demux, "Could not get camera misc information!" );
  371.         Close( p_this );
  372.         return VLC_EGENERIC;
  373.     }
  374.     /* set iso_channel */
  375.     result = dc1394_set_iso_channel_and_speed( p_sys->camera_info.handle,
  376.                                                p_sys->camera_info.id,
  377.                                                p_sys->selected_camera,
  378.                                                SPEED_400 );
  379.     if( result != DC1394_SUCCESS )
  380.     {
  381.         msg_Err( p_demux, "Could not set iso channel!" );
  382.         Close( p_this );
  383.         return VLC_EGENERIC;
  384.     }
  385.     msg_Dbg( p_demux, "Using ISO channel %d", p_sys->misc_info.iso_channel );
  386.     p_sys->misc_info.iso_channel = p_sys->selected_camera;
  387.     /* and setup capture */
  388.     if( p_sys->dma_capture )
  389.     {
  390.         result = dc1394_dma_setup_capture( p_sys->camera_info.handle,
  391.                         p_sys->camera_info.id,
  392.                         p_sys->misc_info.iso_channel,
  393.                         p_sys->misc_info.format,
  394.                         p_sys->misc_info.mode,
  395.                         SPEED_400,
  396.                         p_sys->misc_info.framerate,
  397.                         10, 0,
  398.                         p_sys->dma_device,
  399.                         &p_sys->camera );
  400.         if( result != DC1394_SUCCESS )
  401.         {
  402.             msg_Err( p_demux ,"unable to setup camera" );
  403.             Close( p_this );
  404.             return VLC_EGENERIC;
  405.         }
  406.     }
  407.     else
  408.     {
  409.         result = dc1394_setup_capture( p_sys->camera_info.handle,
  410.                     p_sys->camera_info.id,
  411.                     p_sys->misc_info.iso_channel,
  412.                     p_sys->misc_info.format,
  413.                     p_sys->misc_info.mode,
  414.                     SPEED_400,
  415.                     p_sys->misc_info.framerate,
  416.                     &p_sys->camera );
  417.         if( result != DC1394_SUCCESS)
  418.         {
  419.             msg_Err( p_demux ,"unable to setup camera" );
  420.             Close( p_this );
  421.             return VLC_EGENERIC;
  422.         }
  423.     }
  424.     /* TODO - UYV444 chroma converter is missing, when it will be available
  425.      * fourcc will become variable (and not just a fixed value for UYVY)
  426.      */
  427.     i_width = p_sys->camera.frame_width;
  428.     i_height = p_sys->camera.frame_height;
  429.     i_aspect = vout_InitPicture( VLC_OBJECT(p_demux), &p_sys->pic,
  430.                     VLC_FOURCC('U', 'Y', 'V', 'Y'),
  431.                     i_width, i_height,
  432.                     i_width * VOUT_ASPECT_FACTOR / i_height );
  433.     es_format_Init( &fmt, VIDEO_ES, VLC_FOURCC('U', 'Y', 'V', 'Y') );
  434.     fmt.video.i_width = i_width;
  435.     fmt.video.i_height = i_height;
  436.     msg_Dbg( p_demux, "added new video es %4.4s %dx%d",
  437.              (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
  438.     p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );
  439.     if( p_sys->audio_device )
  440.     {
  441.         OpenAudioDev( p_demux );
  442.         if( p_sys->fd_audio >= 0 )
  443.         {
  444.             es_format_t fmt;
  445.             es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('a','r','a','w') );
  446.             fmt.audio.i_channels = p_sys->channels ? p_sys->channels : 1;
  447.             fmt.audio.i_rate = p_sys->i_sample_rate;
  448.             fmt.audio.i_bitspersample = 16; /* FIXME: hmm, ?? */
  449.             fmt.audio.i_blockalign = fmt.audio.i_channels *
  450.                                      fmt.audio.i_bitspersample / 8;
  451.             fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate *
  452.                             fmt.audio.i_bitspersample;
  453.             msg_Dbg( p_demux, "new audio es %d channels %dHz",
  454.             fmt.audio.i_channels, fmt.audio.i_rate );
  455.             p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
  456.         }
  457.     }
  458.     /* have the camera start sending us data */
  459.     result = dc1394_start_iso_transmission( p_sys->camera_info.handle,
  460.                                             p_sys->camera_info.id );
  461.     if( result != DC1394_SUCCESS )
  462.     {
  463.         msg_Err( p_demux, "unable to start camera iso transmission" );
  464.         if( p_sys->dma_capture )
  465.         {
  466.             dc1394_dma_release_camera( p_sys->fd_video, &p_sys->camera );
  467.         }
  468.         else
  469.         {
  470.             dc1394_release_camera( p_sys->fd_video, &p_sys->camera );
  471.         }
  472.         Close( p_this );
  473.         return VLC_EGENERIC;
  474.     }
  475.     p_sys->misc_info.is_iso_on = DC1394_TRUE;
  476.     return VLC_SUCCESS;
  477. }
  478. static void OpenAudioDev( demux_t *p_demux )
  479. {
  480.     demux_sys_t *p_sys = p_demux->p_sys;
  481.     char *psz_device = p_sys->audio_device;
  482.     int i_format = AFMT_S16_LE;
  483.     int result;
  484.     p_sys->fd_audio = open( psz_device, O_RDONLY | O_NONBLOCK );
  485.     if( p_sys->fd_audio  < 0 )
  486.     {
  487.         msg_Err( p_demux, "cannot open audio device (%s)", psz_device );
  488.         CloseAudioDev( p_demux );
  489.     }
  490.     if( !p_sys->i_sample_rate )
  491.         p_sys->i_sample_rate = 44100;
  492.     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SETFMT, &i_format );
  493.     if( (result  < 0) || (i_format != AFMT_S16_LE) )
  494.     {
  495.         msg_Err( p_demux, "cannot set audio format (16b little endian) "
  496.                           "(%d)", i_format );
  497.         CloseAudioDev( p_demux );
  498.     }
  499.     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_CHANNELS, &p_sys->channels );
  500.     if( result < 0 )
  501.     {
  502.         msg_Err( p_demux, "cannot set audio channels count (%d)",
  503.                  p_sys->channels );
  504.         CloseAudioDev( p_demux );
  505.     }
  506.     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED, &p_sys->i_sample_rate );
  507.     if( result < 0 )
  508.     {
  509.         msg_Err( p_demux, "cannot set audio sample rate (%s)", p_sys->i_sample_rate );
  510.         CloseAudioDev( p_demux );
  511.     }
  512.     msg_Dbg( p_demux, "opened adev=`%s' %s %dHz",
  513.              psz_device,
  514.              (p_sys->channels > 1) ? "stereo" : "mono",
  515.              p_sys->i_sample_rate );
  516.     p_sys->i_audio_max_frame_size = 32 * 1024;
  517. }
  518. static inline void CloseAudioDev( demux_t *p_demux )
  519. {
  520.     demux_sys_t *p_sys = NULL;
  521.     if( p_demux )
  522.     {
  523.         p_sys = p_demux->p_sys;
  524.         if( p_sys->fd_audio >= 0 )
  525.             close( p_sys->fd_audio );
  526.     }
  527. }
  528. /*****************************************************************************
  529.  * Close:
  530.  *****************************************************************************/
  531. static void Close( vlc_object_t *p_this )
  532. {
  533.     demux_t     *p_demux = (demux_t*)p_this;
  534.     demux_sys_t *p_sys = p_demux->p_sys;
  535.     int result = 0;
  536.     /* Stop data transmission */
  537.     result = dc1394_stop_iso_transmission( p_sys->fd_video,
  538.                                            p_sys->camera.node );
  539.     if( result != DC1394_SUCCESS )
  540.     {
  541.         msg_Err( p_demux, "couldn't stop the camera" );
  542.     }
  543.     /* Close camera */
  544.     if( p_sys->dma_capture )
  545.     {
  546.         dc1394_dma_unlisten( p_sys->fd_video, &p_sys->camera );
  547.         dc1394_dma_release_camera( p_sys->fd_video, &p_sys->camera );
  548.     }
  549.     else
  550.     {
  551.         dc1394_release_camera( p_sys->fd_video, &p_sys->camera );
  552.     }
  553.     if( p_sys->fd_video )
  554.         dc1394_destroy_handle( p_sys->fd_video );
  555.     CloseAudioDev( p_demux );
  556.     free( p_sys->camera_nodes );
  557.     free( p_sys->audio_device );
  558.     free( p_sys );
  559. }
  560. static void MovePixelUYVY( void *src, int spos, void *dst, int dpos )
  561. {
  562.     char u,v,y;
  563.     u_char  *sc;
  564.     u_char  *dc;
  565.     sc = (u_char *)src + (spos*2);
  566.     if( spos % 2 )
  567.     {
  568.         v = sc[0];
  569.         y = sc[1];
  570.         u = *(sc -2);
  571.     }
  572.     else
  573.     {
  574.         u = sc[0];
  575.         y = sc[1];
  576.         v = sc[2];
  577.     }
  578.     dc = (u_char *)dst+(dpos*2);
  579.     if( dpos % 2 )
  580.     {
  581.         dc[0] = v;
  582.         dc[1] = y;
  583.     }
  584.     else
  585.     {
  586.         dc[0] = u;
  587.         dc[1] = y;
  588.     }
  589. }
  590. /*****************************************************************************
  591.  * Demux:
  592.  *****************************************************************************/
  593. static block_t *GrabVideo( demux_t *p_demux )
  594. {
  595.     demux_sys_t *p_sys = p_demux->p_sys;
  596.     block_t     *p_block = NULL;
  597.     int result = 0;
  598.     if( p_sys->dma_capture )
  599.     {
  600.         result = dc1394_dma_single_capture( &p_sys->camera );
  601.         if( result != DC1394_SUCCESS )
  602.         {
  603.             msg_Err( p_demux, "unable to capture a frame" );
  604.             return NULL;
  605.         }
  606.     }
  607.     else
  608.     {
  609.         result = dc1394_single_capture( p_sys->camera_info.handle,
  610.                                         &p_sys->camera );
  611.         if( result != DC1394_SUCCESS )
  612.         {
  613.             msg_Err( p_demux, "unable to capture a frame" );
  614.             return NULL;
  615.         }
  616.     }
  617.     p_block = block_New( p_demux, p_sys->camera.frame_width *
  618.                                   p_sys->camera.frame_height * 2 );
  619.     if( !p_block )
  620.     {
  621.         msg_Err( p_demux, "cannot get block" );
  622.         return NULL;
  623.     }
  624.     if( !p_sys->camera.capture_buffer )
  625.     {
  626.         msg_Err (p_demux, "caputer buffer empty");
  627.         block_Release( p_block );
  628.         return NULL;
  629.     }
  630.     memcpy( p_block->p_buffer, (const char *)p_sys->camera.capture_buffer,
  631.             p_sys->camera.frame_width * p_sys->camera.frame_height * 2 );
  632.     p_block->i_pts = p_block->i_dts = mdate();
  633.     if( p_sys->dma_capture )
  634.         dc1394_dma_done_with_buffer( &p_sys->camera );
  635.     return p_block;
  636. }
  637. static block_t *GrabAudio( demux_t *p_demux )
  638. {
  639.     demux_sys_t *p_sys = p_demux->p_sys;
  640.     struct audio_buf_info buf_info;
  641.     block_t *p_block = NULL;
  642.     int i_read = 0;
  643.     int i_correct = 0;
  644.     int result = 0;
  645.     p_block = block_New( p_demux, p_sys->i_audio_max_frame_size );
  646.     if( !p_block )
  647.     {
  648.         msg_Warn( p_demux, "cannot get buffer" );
  649.         return NULL;
  650.     }
  651.     i_read = read( p_sys->fd_audio, p_block->p_buffer,
  652.                    p_sys->i_audio_max_frame_size );
  653.     if( i_read <= 0 )
  654.         return NULL;
  655.     p_block->i_buffer = i_read;
  656.     /* Correct the date because of kernel buffering */
  657.     i_correct = i_read;
  658.     result = ioctl( p_sys->fd_audio, SNDCTL_DSP_GETISPACE, &buf_info );
  659.     if( result == 0 )
  660.         i_correct += buf_info.bytes;
  661.     p_block->i_pts = p_block->i_dts =
  662.                         mdate() - INT64_C(1000000) * (mtime_t)i_correct /
  663.                         2 / p_sys->channels / p_sys->i_sample_rate;
  664.     return p_block;
  665. }
  666. static int Demux( demux_t *p_demux )
  667. {
  668.     demux_sys_t *p_sys = p_demux->p_sys;
  669.     block_t *p_blocka = NULL;
  670.     block_t *p_blockv = NULL;
  671.     /* Try grabbing audio frames first */
  672.     if( p_sys->fd_audio > 0 )
  673.         p_blocka = GrabAudio( p_demux );
  674.     /* Try grabbing video frame */
  675.     if( (int)p_sys->fd_video > 0 )
  676.         p_blockv = GrabVideo( p_demux );
  677.     if( !p_blocka && !p_blockv )
  678.     {
  679.         /* Sleep so we do not consume all the cpu, 10ms seems
  680.          * like a good value (100fps)
  681.          */
  682.         msleep( 10000 );
  683.         return 1;
  684.     }
  685.     if( p_blocka )
  686.     {
  687.         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blocka->i_pts );
  688.         es_out_Send( p_demux->out, p_sys->p_es_audio, p_blocka );
  689.     }
  690.     if( p_blockv )
  691.     {
  692.         es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_blockv->i_pts );
  693.         es_out_Send( p_demux->out, p_sys->p_es_video, p_blockv );
  694.     }
  695.     return 1;
  696. }
  697. /*****************************************************************************
  698.  * Control:
  699.  *****************************************************************************/
  700. static int Control( demux_t *p_demux, int i_query, va_list args )
  701. {
  702.     bool *pb;
  703.     int64_t    *pi64;
  704.     switch( i_query )
  705.     {
  706.         /* Special for access_demux */
  707.         case DEMUX_CAN_PAUSE:
  708.         case DEMUX_CAN_SEEK:
  709.         case DEMUX_SET_PAUSE_STATE:
  710.         case DEMUX_CAN_CONTROL_PACE:
  711.             pb = (bool*)va_arg( args, bool * );
  712.             *pb = false;
  713.             return VLC_SUCCESS;
  714.         case DEMUX_GET_PTS_DELAY:
  715.             pi64 = (int64_t*)va_arg( args, int64_t * );
  716.             *pi64 = (int64_t)DEFAULT_PTS_DELAY;
  717.             return VLC_SUCCESS;
  718.         case DEMUX_GET_TIME:
  719.             pi64 = (int64_t*)va_arg( args, int64_t * );
  720.             *pi64 = mdate();
  721.             return VLC_SUCCESS;
  722.         /* TODO implement others */
  723.         default:
  724.             return VLC_EGENERIC;
  725.     }
  726.     return VLC_EGENERIC;
  727. }
  728. static int process_options( demux_t *p_demux )
  729. {
  730.     demux_sys_t *p_sys = p_demux->p_sys;
  731.     char *psz_dup;
  732.     char *psz_parser;
  733.     char *token = NULL;
  734.     char *state = NULL;
  735.     float rate_f;
  736.     psz_dup = strdup( p_demux->psz_path );
  737.     psz_parser = psz_dup;
  738.     for( token = strtok_r( psz_parser,":",&state); token;
  739.          token = strtok_r( NULL, ":", &state ) )
  740.     {
  741.         if( strncmp( token, "size=", strlen("size=") ) == 0 )
  742.         {
  743.             token += strlen("size=");
  744.             if( strncmp( token, "160x120", 7 ) == 0 )
  745.             {
  746.                 /* TODO - UYV444 chroma converter is needed ...
  747.                     * video size of 160x120 is temporarily disabled
  748.                     */
  749.                 msg_Err( p_demux,
  750.                     "video size of 160x120 is actually disabled for lack of chroma "
  751.                     "support. It will relased ASAP, until then try an higher size "
  752.                     "(320x240 and 640x480 are fully supported)" );
  753.                 free( psz_dup );
  754.                 return VLC_EGENERIC;
  755. #if 0
  756.                 p_sys->frame_size = MODE_160x120_YUV444;
  757.                 p_sys->width = 160;
  758.                 p_sys->height = 120;
  759. #endif
  760.             }
  761.             else if( strncmp( token, "320x240", 7 ) == 0 )
  762.             {
  763.                 p_sys->frame_size = MODE_320x240_YUV422;
  764.                 p_sys->width = 320;
  765.                 p_sys->height = 240;
  766.             }
  767.             else if( strncmp( token, "640x480", 7 ) == 0 )
  768.             {
  769.                 p_sys->frame_size = MODE_640x480_YUV422;
  770.                 p_sys->width = 640;
  771.                 p_sys->height = 480;
  772.             }
  773.             else
  774.             {
  775.                 msg_Err( p_demux,
  776.                     "This program currently suppots frame sizes of"
  777.                     " 160x120, 320x240, and 640x480. "
  778.                     "Please specify one of them. You have specified %s.",
  779.                     token );
  780.                 free( psz_dup );
  781.                 return VLC_EGENERIC;
  782.             }
  783.             msg_Dbg( p_demux, "Requested video size : %s",token );
  784.         }
  785.         else if( strncmp( token, "fps=", strlen( "fps=" ) ) == 0 )
  786.         {
  787.             token += strlen("fps=");
  788.             sscanf( token, "%g", &rate_f );
  789.             if( rate_f == 1.875 )
  790.                 p_sys->frame_rate = FRAMERATE_1_875;
  791.             else if( rate_f == 3.75 )
  792.                 p_sys->frame_rate = FRAMERATE_3_75;
  793.             else if( rate_f == 7.5 )
  794.                 p_sys->frame_rate = FRAMERATE_7_5;
  795.             else if( rate_f == 15 )
  796.                 p_sys->frame_rate = FRAMERATE_15;
  797.             else if( rate_f == 30 )
  798.                 p_sys->frame_rate = FRAMERATE_30;
  799.             else if( rate_f == 60 )
  800.                 p_sys->frame_rate = FRAMERATE_60;
  801.             else
  802.             {
  803.                 msg_Err( p_demux ,
  804.                     "This program supports framerates of"
  805.                     " 1.875, 3.75, 7.5, 15, 30, 60. "
  806.                     "Please specify one of them. You have specified %s.",
  807.                     token);
  808.                 free( psz_dup );
  809.                 return VLC_EGENERIC;
  810.             }
  811.             msg_Dbg( p_demux, "Requested frame rate : %s",token );
  812.         }
  813.         else if( strncmp( token, "brightness=", strlen( "brightness=" ) ) == 0 )
  814.         {
  815.             int nr = 0;
  816.             token += strlen("brightness=");
  817.             nr = sscanf( token, "%u", &p_sys->brightness);
  818.             if( nr != 1 )
  819.             {
  820.                 msg_Err( p_demux, "Bad brightness value '%s', "
  821.                                   "must be an unsigned integer.",
  822.                                   token );
  823.                 free( psz_dup );
  824.                 return VLC_EGENERIC;
  825.             }
  826.         }
  827. #if 0
  828.         else if( strncmp( token, "controller=", strlen( "controller=" ) ) == 0 )
  829.         {
  830.             int nr = 0;
  831.             token += strlen("controller=");
  832.             nr = sscanf( token, "%u", &p_sys->controller );
  833.             if( nr != 1)
  834.             {
  835.                 msg_Err(p_demux, "Bad controller value '%s', "
  836.                                  "must be an unsigned integer.",
  837.                                  token );
  838.                 return VLC_EGENERIC;
  839.             }
  840.         }
  841. #endif
  842.         else if( strncmp( token, "camera=", strlen( "camera=" ) ) == 0 )
  843.         {
  844.             int nr = 0;
  845.             token += strlen("camera=");
  846.             nr = sscanf(token,"%u",&p_sys->selected_camera);
  847.             if( nr != 1)
  848.             {
  849.                 msg_Err( p_demux, "Bad camera number '%s', "
  850.                                   "must be an unsigned integer.",
  851.                                   token );
  852.                 free( psz_dup );
  853.                 return VLC_EGENERIC;
  854.             }
  855.         }
  856.         else if( strncmp( token, "capture=", strlen( "capture=" ) ) == 0)
  857.         {
  858.             token += strlen("capture=");
  859.             if( strncmp(token, "raw1394",7) == 0 )
  860.             {
  861.                 msg_Dbg( p_demux, "DMA capture disabled!" );
  862.                 p_sys->dma_capture = DMA_OFF;
  863.             }
  864.             else if( strncmp(token,"video1394",9) == 0 )
  865.             {
  866.                 msg_Dbg( p_demux, "DMA capture enabled!" );
  867.                 p_sys->dma_capture = DMA_ON;
  868.             }
  869.             else
  870.             {
  871.                 msg_Err(p_demux, "Bad capture method value '%s', "
  872.                                  "it can be 'raw1394' or 'video1394'.",
  873.                                 token );
  874.                 free( psz_dup );
  875.                 return VLC_EGENERIC;
  876.             }
  877.         }
  878.         else if( strncmp( token, "adev=", strlen( "adev=" ) ) == 0 )
  879.         {
  880.             token += strlen("adev=");
  881.             p_sys->audio_device = strdup(token);
  882.             msg_Dbg( p_demux, "Using audio device '%s'.", token );
  883.         }
  884.         else if( strncmp( token, "samplerate=", strlen( "samplerate=" ) ) == 0 )
  885.         {
  886.             token += strlen("samplerate=");
  887.             sscanf( token, "%d", &p_sys->i_sample_rate );
  888.         }
  889.         else if( strncmp( token, "channels=", strlen("channels=" ) ) == 0 )
  890.         {
  891.             token += strlen("channels=");
  892.             sscanf( token, "%d", &p_sys->channels );
  893.         }
  894.         else if( strncmp( token, "focus=", strlen("focus=" ) ) == 0)
  895.         {
  896.             token += strlen("focus=");
  897.             sscanf( token, "%u", &p_sys->focus );
  898.         }
  899.         else if( strncmp( token, "uid=", strlen("uid=") ) == 0)
  900.         {
  901.             token += strlen("uid=");
  902.             sscanf( token, "0x%llx", &p_sys->selected_uid );
  903.         }
  904.     }
  905.     free( psz_dup );
  906.     return VLC_SUCCESS;
  907. }