]> git.sesse.net Git - vlc/blobdiff - modules/access/dshow/dshow.cpp
Another time "Remove useless test before a free".
[vlc] / modules / access / dshow / dshow.cpp
index f344f7c5ed423fe433b73e8395bd31cadf1e9cec..404d8282a15d70962b2f5ff399fbbe5aa852d8b0 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include <stdio.h>
-#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include <vlc/vlc.h>
 #include <vlc_input.h>
@@ -61,9 +63,9 @@ static int ConfigDevicesCallback( vlc_object_t *, char const *,
                                   vlc_value_t, vlc_value_t, void * );
 
 static void ShowPropertyPage( IUnknown * );
-static void ShowDeviceProperties( vlc_object_t *, ICaptureGraphBuilder2 *, 
+static void ShowDeviceProperties( vlc_object_t *, ICaptureGraphBuilder2 *,
                                   IBaseFilter *, vlc_bool_t );
-static void ShowTunerProperties( vlc_object_t *, ICaptureGraphBuilder2 *, 
+static void ShowTunerProperties( vlc_object_t *, ICaptureGraphBuilder2 *,
                                  IBaseFilter *, vlc_bool_t );
 static void ConfigTuner( vlc_object_t *, ICaptureGraphBuilder2 *,
                          IBaseFilter * );
@@ -331,12 +333,12 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys,
     var_Create( p_this, "dshow-vdev", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
     var_Get( p_this, "dshow-vdev", &val );
     if( val.psz_string ) vdevname = string( val.psz_string );
-    if( val.psz_string ) free( val.psz_string );
+    free( val.psz_string );
 
     var_Create( p_this, "dshow-adev", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
     var_Get( p_this, "dshow-adev", &val );
     if( val.psz_string ) adevname = string( val.psz_string );
-    if( val.psz_string ) free( val.psz_string );
+    free( val.psz_string );
 
     static struct {char *psz_size; int  i_width; int  i_height;} size_table[] =
     { { "subqcif", 128, 96 }, { "qsif", 160, 120 }, { "qcif", 176, 144 },
@@ -368,7 +370,7 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys,
             msg_Dbg( p_this, "width x height %dx%d", i_width, i_height );
         }
     }
-    if( val.psz_string ) free( val.psz_string );
+    free( val.psz_string );
 
     p_sys->b_chroma = VLC_FALSE;
     var_Create( p_this, "dshow-chroma", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
@@ -379,7 +381,7 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys,
                                val.psz_string[2], val.psz_string[3] );
         p_sys->b_chroma = VLC_TRUE;
     }
-    if( val.psz_string ) free( val.psz_string );
+    free( val.psz_string );
 
     var_Create( p_this, "dshow-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
     var_Create( p_this, "dshow-tuner-channel",
@@ -890,8 +892,8 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys,
     {
         msg_Err( p_this, "can't use device: %s, unsupported device type",
                  devicename.c_str() );
-        intf_UserFatal( p_this, VLC_FALSE, _("Capturing failed"), 
-                        _("VLC cannot use the device \"%s\", because its device "
+        intf_UserFatal( p_this, VLC_FALSE, _("Capturing failed"),
+                        _("VLC cannot use the device \"%s\", because its "
                           "type is not supported.") );
         return VLC_EGENERIC;
     }
@@ -940,7 +942,7 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys,
     else {
         /* capture device */
         msg_Err( p_this, "capture device '%s' does not support required parameters !", devicename.c_str() );
-        intf_UserFatal( p_this, VLC_FALSE, _("Capturing failed"), 
+        intf_UserFatal( p_this, VLC_FALSE, _("Capturing failed"),
                         _("The capture device \"%s\" does not support the "
                           "required parameters."), devicename.c_str() );
         p_device_filter->Release();
@@ -1057,6 +1059,7 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,
     IMoniker *p_moniker = NULL;
     ULONG i_fetched;
     HRESULT hr;
+    list<string> devicelist;
 
     /* Create the system device enumerator */
     ICreateDevEnum *p_dev_enum = NULL;
@@ -1120,9 +1123,29 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,
                 SysFreeString(var.bstrVal);
                 p_buf[i_convert] = '\0';
 
-                if( p_listdevices ) p_listdevices->push_back( p_buf );
+        string devname = string(p_buf);
+
+        int dup = 0;
+        /* find out if this name is already used by a previously found device */
+        list<string>::const_iterator iter = devicelist.begin();
+        list<string>::const_iterator end = devicelist.end();
+        while ( iter != end )
+        {
+            if( 0 == (*iter).compare(0, devname.size(), devname) )
+            ++dup;
+            ++iter;
+        }
+        if( dup )
+        {
+            /* we have a duplicate device name, append a sequence number to name
+               to provive a unique list back to the user */
+            char seq[16];
+            sprintf(seq, " #%d", dup);
+            devname.append(seq);
+        }
+        devicelist.push_back( devname );
 
-                if( p_devicename && *p_devicename == string(p_buf) )
+                if( p_devicename && *p_devicename == devname )
                 {
                     /* Bind Moniker to a filter object */
                     hr = p_moniker->BindToObject( 0, 0, IID_IBaseFilter,
@@ -1146,6 +1169,11 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,
     }
 
     p_class_enum->Release();
+
+    if( p_listdevices ) {
+    devicelist.sort();
+    *p_listdevices = devicelist;
+    }
     return NULL;
 }
 
@@ -1272,7 +1300,7 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                                 if( i_height )
                                 {
                                     if( i_height % pVSCC->OutputGranularityY
-                                     || pVSCC->MinOutputSize.cy > i_height 
+                                     || pVSCC->MinOutputSize.cy > i_height
                                      || i_height > pVSCC->MaxOutputSize.cy )
                                     {
                                         // required height not compatible, try next media type
@@ -1285,7 +1313,7 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
 
                                 // Set the sample size and image size.
                                 // (Round the image width up to a DWORD boundary.)
-                                p_mt->lSampleSize = pVih->bmiHeader.biSizeImage = 
+                                p_mt->lSampleSize = pVih->bmiHeader.biSizeImage =
                                     ((pVih->bmiHeader.biWidth + 3) & ~3) *
                                     pVih->bmiHeader.biHeight * (pVih->bmiHeader.biBitCount>>3);
 
@@ -1298,7 +1326,7 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                                 {
                                     i_priority = i_current_priority;
                                     if( i_fourcc )
-                                        // no need to check any more media types 
+                                        // no need to check any more media types
                                         i = piCount;
                                 }
                             }
@@ -1340,7 +1368,7 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                                     }
                                     pWfx->nSamplesPerSec = val;
  
-                                    val = i_bitspersample; 
+                                    val = i_bitspersample;
                                     if( ! val )
                                     {
                                         if( VLC_FOURCC('f', 'l', '3', '2') == i_current_fourcc )
@@ -1403,7 +1431,7 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                 LONGLONG i_current_atpf = ((VIDEOINFOHEADER *)p_mt->pbFormat)->AvgTimePerFrame;
 
                 if( i_current_height < 0 )
-                    i_current_height = -i_current_height; 
+                    i_current_height = -i_current_height;
 
                 msg_Dbg( p_this, "EnumDeviceCaps: input pin "
                          "accepts chroma: %4.4s, width:%i, height:%i, fps:%f",
@@ -1421,7 +1449,7 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                 }
                 else FreeMediaType( *p_mt );
             }
-            else if( i_current_fourcc && p_mt->majortype == MEDIATYPE_Audio 
+            else if( i_current_fourcc && p_mt->majortype == MEDIATYPE_Audio
                     && p_mt->formattype == FORMAT_WaveFormatEx)
             {
                 int i_current_channels =
@@ -1518,33 +1546,33 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                     i_current_fourcc = VLC_FOURCC('I','4','2','0');
                     if( !i_fourcc || i_fourcc == i_current_fourcc )
                     {
-                        // return alternative media type  
-                        AM_MEDIA_TYPE mtr;  
-                        VIDEOINFOHEADER vh;  
-             
-                        mtr.majortype            = MEDIATYPE_Video;  
-                        mtr.subtype              = MEDIASUBTYPE_I420;  
-                        mtr.bFixedSizeSamples    = TRUE;  
-                        mtr.bTemporalCompression = FALSE;  
-                        mtr.pUnk                 = NULL;  
-                        mtr.formattype           = FORMAT_VideoInfo;  
-                        mtr.cbFormat             = sizeof(vh);  
-                        mtr.pbFormat             = (BYTE *)&vh;  
-             
-                        memset(&vh, 0, sizeof(vh));  
-             
-                        vh.bmiHeader.biSize   = sizeof(vh.bmiHeader);  
+                        // return alternative media type
+                        AM_MEDIA_TYPE mtr;
+                        VIDEOINFOHEADER vh;
+                        mtr.majortype            = MEDIATYPE_Video;
+                        mtr.subtype              = MEDIASUBTYPE_I420;
+                        mtr.bFixedSizeSamples    = TRUE;
+                        mtr.bTemporalCompression = FALSE;
+                        mtr.pUnk                 = NULL;
+                        mtr.formattype           = FORMAT_VideoInfo;
+                        mtr.cbFormat             = sizeof(vh);
+                        mtr.pbFormat             = (BYTE *)&vh;
+                        memset(&vh, 0, sizeof(vh));
+                        vh.bmiHeader.biSize   = sizeof(vh.bmiHeader);
                         vh.bmiHeader.biWidth  = i_width > 0 ? i_width :
-                            ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biWidth;  
+                            ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biWidth;
                         vh.bmiHeader.biHeight = i_height > 0 ? i_height :
-                            ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biHeight;  
-                        vh.bmiHeader.biPlanes      = 3; 
-                        vh.bmiHeader.biBitCount    = 12;  
-                        vh.bmiHeader.biCompression = VLC_FOURCC('I','4','2','0');  
-                        vh.bmiHeader.biSizeImage   = vh.bmiHeader.biWidth * 12 *  
-                            vh.bmiHeader.biHeight / 8;  
-                        mtr.lSampleSize            = vh.bmiHeader.biSizeImage;  
-             
+                            ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biHeight;
+                        vh.bmiHeader.biPlanes      = 3;
+                        vh.bmiHeader.biBitCount    = 12;
+                        vh.bmiHeader.biCompression = VLC_FOURCC('I','4','2','0');
+                        vh.bmiHeader.biSizeImage   = vh.bmiHeader.biWidth * 12 *
+                            vh.bmiHeader.biHeight / 8;
+                        mtr.lSampleSize            = vh.bmiHeader.biSizeImage;
                         msg_Dbg( p_this, "EnumDeviceCaps: input pin media: using 'I420' in place of unsupported format 'HCW2'");
 
                         if( SUCCEEDED(CopyMediaType(mt+mt_count, &mtr)) )
@@ -1771,6 +1799,7 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
     {
     /* Special for access_demux */
     case DEMUX_CAN_PAUSE:
+    case DEMUX_CAN_SEEK:
     case DEMUX_SET_PAUSE_STATE:
     case DEMUX_CAN_CONTROL_PACE:
         pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );
@@ -1839,10 +1868,10 @@ static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
     if( !list_devices.size() ) return VLC_SUCCESS;
 
     p_item->ppsz_list =
-        (const char **)realloc( p_item->ppsz_list,
+        (char **)realloc( p_item->ppsz_list,
                           (list_devices.size()+3) * sizeof(char *) );
     p_item->ppsz_list_text =
-        (const char **)realloc( p_item->ppsz_list_text,
+        (char **)realloc( p_item->ppsz_list_text,
                           (list_devices.size()+3) * sizeof(char *) );
 
     list<string>::iterator iter;