]> git.sesse.net Git - vlc/blobdiff - modules/access/dc1394.c
mmdevice: fix crash if several channel volumes change (fixes #12086)
[vlc] / modules / access / dc1394.c
index 853135346ead6c7a0270910db92b306115362022..4d12cf330369a7f48dfa16ac8c52d2429de28060 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * dc1394.c: firewire input module
+ * dc1394.c: IIDC (DCAM) FireWire input module
  *****************************************************************************
  * Copyright (C) 2006-2009 VideoLAN
  *
@@ -8,20 +8,20 @@
  *          Frederic Benoist <fridorik@gmail.com> - updates from Rob's work
  *
  *****************************************************************************
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * 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.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
  *
- * 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
+ * This program 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
 
 #include <vlc_common.h>
 #include <vlc_plugin.h>
-#include <vlc_input.h>
 #include <vlc_demux.h>
-#include <vlc_fs.h>
-#include <vlc_picture.h>
-
-#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>
 #include <dc1394/dc1394.h>
 
 #define MAX_IEEE1394_HOSTS 32
  *****************************************************************************/
 static int  Open ( vlc_object_t * );
 static void Close( vlc_object_t * );
-static int OpenAudioDev( demux_t *p_demux );
-static inline void CloseAudioDev( demux_t *p_demux );
 
 vlc_module_begin()
-    set_description( N_("dc1394 input") )
+    set_shortname( N_("DC1394") )
+    set_description( N_("IIDC Digital Camera (FireWire) input") )
     set_capability( "access_demux", 10 )
-    add_shortcut( "dc1394" )
     set_callbacks( Open, Close )
 vlc_module_end()
 
@@ -80,10 +62,8 @@ struct demux_sys_t
     dc1394camera_t      *camera;
     int                 selected_camera;
     uint64_t            selected_uid;
-    picture_t           pic;
     uint32_t            dma_buffers;
     dc1394featureset_t  features;
-    quadlet_t           supported_framerates;
     bool                reset_bus;
 
     /* video info */
@@ -97,14 +77,6 @@ struct demux_sys_t
     unsigned int        focus;
     es_out_id_t         *p_es_video;
     dc1394video_frame_t *frame;
-
-    /* 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;
 };
 
 /*****************************************************************************
@@ -113,7 +85,6 @@ struct demux_sys_t
 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);
 
 /*****************************************************************************
@@ -156,7 +127,7 @@ static int FindCamera( demux_sys_t *sys, demux_t *p_demux )
         }
         if( !found )
         {
-            msg_Err( p_demux, "Can't find camera with uid : 0x%llx.",
+            msg_Err( p_demux, "Can't find camera with uid : 0x%"PRIx64".",
                      sys->selected_uid );
             goto end;
         }
@@ -194,8 +165,6 @@ static int Open( vlc_object_t *p_this )
     demux_sys_t  *p_sys;
     es_format_t   fmt;
     dc1394error_t res;
-    int           i_width;
-    int           i_height;
 
     if( strncmp(p_demux->psz_access, "dc1394", 6) != 0 )
         return VLC_EGENERIC;
@@ -220,7 +189,6 @@ static int Open( vlc_object_t *p_this )
     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;
@@ -378,49 +346,16 @@ static int Open( vlc_object_t *p_this )
     /* TODO - UYV444 chroma converter is missing, when it will be available
      * fourcc will become variable (and not just a fixed value for UYVY)
      */
-    i_width = p_sys->width;
-    i_height = p_sys->height;
-
-    if( picture_Setup( &p_sys->pic, VLC_CODEC_UYVY,
-                       i_width, i_height, 1, 1 ) )
-    {
-        msg_Err( p_demux ,"unknown chroma" );
-        Close( p_this );
-        return VLC_EGENERIC;
-    }
-
     es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY );
 
-    fmt.video.i_width = i_width;
-    fmt.video.i_height = i_height;
+    fmt.video.i_width = p_sys->width;
+    fmt.video.i_height = p_sys->height;
 
     msg_Dbg( p_demux, "Added new video es %4.4s %dx%d",
              (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 )
-    {
-        if( OpenAudioDev( p_demux ) == VLC_SUCCESS )
-        {
-            es_format_t fmt;
-            es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_S16L ); /* FIXME: hmm, ?? */
-
-            fmt.audio.i_channels = p_sys->channels ? p_sys->channels : 1;
-            fmt.audio.i_rate = p_sys->i_sample_rate;
-            fmt.audio.i_bitspersample = 16;
-            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;
-
-            msg_Dbg( p_demux, "New audio es %d channels %dHz",
-            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 */
     if( dc1394_video_set_transmission( p_sys->camera,
                        DC1394_ON ) != DC1394_SUCCESS )
@@ -435,70 +370,6 @@ static int Open( vlc_object_t *p_this )
     return VLC_SUCCESS;
 }
 
-static int 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;
-
-    p_sys->fd_audio = vlc_open( psz_device, O_RDONLY | O_NONBLOCK );
-    if( p_sys->fd_audio  < 0 )
-    {
-        msg_Err( p_demux, "Cannot open audio device (%s)", psz_device );
-        return VLC_EGENERIC;
-    }
-
-    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) )
-    {
-        msg_Err( p_demux, "Cannot set audio format (16b little endian) "
-                          "(%d)", i_format );
-        goto error;
-    }
-
-    result = ioctl( p_sys->fd_audio, SNDCTL_DSP_CHANNELS, &p_sys->channels );
-    if( result < 0 )
-    {
-        msg_Err( p_demux, "Cannot set audio channels count (%d)",
-                 p_sys->channels );
-        goto error;
-    }
-
-    result = ioctl( p_sys->fd_audio, SNDCTL_DSP_SPEED, &p_sys->i_sample_rate );
-    if( result < 0 )
-    {
-        msg_Err( p_demux, "Cannot set audio sample rate (%d)",
-         p_sys->i_sample_rate );
-        goto error;
-    }
-
-    msg_Dbg( p_demux, "Opened adev=`%s' %s %dHz",
-             psz_device,
-             (p_sys->channels > 1) ? "stereo" : "mono",
-             p_sys->i_sample_rate );
-
-    p_sys->i_audio_max_frame_size = 32 * 1024;
-
-    return VLC_SUCCESS;
-
-error:
-    CloseAudioDev( p_demux );
-    p_sys->fd_audio = -1;
-    return VLC_EGENERIC;
-}
-
-static inline void CloseAudioDev( demux_t *p_demux )
-{
-    demux_sys_t *p_sys = p_demux->p_sys;
-
-    if( p_sys->fd_audio >= 0 )
-        close( p_sys->fd_audio );
-}
-
 /*****************************************************************************
  * Close:
  *****************************************************************************/
@@ -515,13 +386,10 @@ static void Close( vlc_object_t *p_this )
     /* Close camera */
     dc1394_capture_stop( p_sys->camera );
 
-    CloseAudioDev( p_demux );
-
     dc1394_camera_free(p_sys->camera);
     dc1394_free(p_sys->p_dccontext);
 
     free( p_sys->video_device );
-    free( p_sys->audio_device );
     free( p_sys );
 }
 
@@ -575,8 +443,7 @@ static block_t *GrabVideo( demux_t *p_demux )
         return NULL;
     }
 
-    p_block = block_New( p_demux, p_sys->frame->size[0] *
-                                  p_sys->frame->size[1] * 2 );
+    p_block = block_Alloc( p_sys->frame->size[0] * p_sys->frame->size[1] * 2 );
     if( !p_block )
     {
         msg_Err( p_demux, "Can not get block" );
@@ -598,59 +465,15 @@ static block_t *GrabVideo( demux_t *p_demux )
     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 )
-    {
-        msg_Warn( p_demux, "Cannot get buffer" );
-        return NULL;
-    }
-
-    i_read = read( p_sys->fd_audio, p_block->p_buffer,
-                   p_sys->i_audio_max_frame_size );
-
-    if( i_read <= 0 )
-    {
-        block_Release( p_block );
-        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 =
-                        mdate() - INT64_C(1000000) * (mtime_t)i_correct /
-                        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 */
     p_blockv = GrabVideo( p_demux );
 
-    if( !p_blocka && !p_blockv )
+    if( !p_blockv )
     {
         /* Sleep so we do not consume all the cpu, 10ms seems
          * like a good value (100fps)
@@ -659,12 +482,6 @@ static int Demux( demux_t *p_demux )
         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 );
@@ -897,22 +714,6 @@ static int process_options( demux_t *p_demux )
             p_sys->video_device = strdup(token);
             msg_Dbg( p_demux, "Using video device '%s'.", token );
         }
-        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)
         {
             int nr = 0;