]> git.sesse.net Git - vlc/commitdiff
* modules/access/dshow/*: always try to get the video in I420 chroma if supported.
authorGildas Bazin <gbazin@videolan.org>
Sun, 31 Aug 2003 22:06:17 +0000 (22:06 +0000)
committerGildas Bazin <gbazin@videolan.org>
Sun, 31 Aug 2003 22:06:17 +0000 (22:06 +0000)
   Implemented a ":size=" and ":chroma=" option.

modules/access/dshow/dshow.cpp
modules/access/dshow/filter.cpp
modules/access/dshow/filter.h

index f506b4a97d43c0d50cdbbb0d5acbc76d2bd04dbf..c7ba49a20a8dc59d98b806a8439e86a361f4a686 100644 (file)
@@ -2,7 +2,7 @@
  * dshow.c : DirectShow access module for vlc
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: dshow.cpp,v 1.6 2003/08/27 12:59:11 gbazin Exp $
+ * $Id: dshow.cpp,v 1.7 2003/08/31 22:06:17 gbazin Exp $
  *
  * Author: Gildas Bazin <gbazin@netcourrier.com>
  *
 #include <vlc/input.h>
 #include <vlc/vout.h>
 
-#ifndef _MSC_VER
-#   include <wtypes.h>
-#   include <unknwn.h>
-#   include <ole2.h>
-#   include <limits.h>
-#   define _WINGDI_ 1
-#   define AM_NOVTABLE
-#   define _OBJBASE_H_
-#   undef _X86_
-#   define _I64_MAX LONG_LONG_MAX
-#   define LONGLONG long long
-#endif
-
-#include <dshow.h>
-
 #include "filter.h"
 
 /*****************************************************************************
@@ -63,8 +48,9 @@ static int  Demux      ( input_thread_t * );
 static int OpenDevice( input_thread_t *, string, vlc_bool_t );
 static IBaseFilter *FindCaptureDevice( vlc_object_t *, string *,
                                        list<string> *, vlc_bool_t );
-static bool ConnectFilters( IFilterGraph *p_graph, IBaseFilter *p_filter,
-                            IPin *p_input_pin );
+static AM_MEDIA_TYPE EnumDeviceCaps( vlc_object_t *, IBaseFilter *,
+                                     vlc_bool_t, int, int, int );
+static bool ConnectFilters( IFilterGraph *, IBaseFilter *, IPin * );
 
 /*****************************************************************************
  * Module descriptior
@@ -173,6 +159,11 @@ struct access_sys_t
     dshow_stream_t **pp_streams;
     int            i_streams;
     int            i_current_stream;
+
+    /* misc properties */
+    int            i_width;
+    int            i_height;
+    int            i_chroma;
 };
 
 /*****************************************************************************
@@ -188,6 +179,7 @@ static int AccessOpen( vlc_object_t *p_this )
     psz_dup = strdup( p_input->psz_name );
     psz_parser = psz_dup;
     string vdevname, adevname;
+    int i_width = 0, i_height = 0, i_chroma = VLC_FOURCC('I','4','2','0');
 
     while( *psz_parser && *psz_parser != ':' )
     {
@@ -234,6 +226,59 @@ static int AccessOpen( vlc_object_t *p_this )
 
                 psz_parser += i_len;
             }
+            else if( !strncmp( psz_parser, "size=", strlen( "size=" ) ) )
+            {
+                psz_parser += strlen( "size=" );
+                if( !strncmp( psz_parser, "subqcif", strlen( "subqcif" ) ) )
+                {
+                    i_width  = 128;
+                    i_height = 96;
+                }
+                else if( !strncmp( psz_parser, "qsif", strlen( "qsif" ) ) )
+                {
+                    i_width  = 160;
+                    i_height = 120;
+                }
+                else if( !strncmp( psz_parser, "qcif", strlen( "qcif" ) ) )
+                {
+                    i_width  = 176;
+                    i_height = 144;
+                }
+                else if( !strncmp( psz_parser, "sif", strlen( "sif" ) ) )
+                {
+                    i_width  = 320;
+                    i_height = 240;
+                }
+                else if( !strncmp( psz_parser, "cif", strlen( "cif" ) ) )
+                {
+                    i_width  = 352;
+                    i_height = 288;
+                }
+                else if( !strncmp( psz_parser, "vga", strlen( "vga" ) ) )
+                {
+                    i_width  = 640;
+                    i_height = 480;
+                }
+                else
+                {
+                    /* widthxheight */
+                    i_width = strtol( psz_parser, &psz_parser, 0 );
+                    if( *psz_parser == 'x' || *psz_parser == 'X')
+                    {
+                        i_height = strtol( psz_parser + 1, &psz_parser, 0 );
+                    }
+                    msg_Dbg( p_input, "WidthxHeight %dx%d", i_width, i_height );
+                }
+            }
+            else if( !strncmp( psz_parser, "chroma=", strlen( "chroma=" ) ) )
+            {
+                psz_parser += strlen( "chroma=" );
+                if( strlen( psz_parser ) >= 4 )
+                {
+                    i_chroma = VLC_FOURCC( psz_parser[0],psz_parser[1],
+                                           psz_parser[2],psz_parser[3] );
+                }
+            }
             else
             {
                 msg_Warn( p_input, "unknown option" );
@@ -277,6 +322,9 @@ static int AccessOpen( vlc_object_t *p_this )
     /* Initialize some data */
     p_sys->i_streams = 0;
     p_sys->pp_streams = (dshow_stream_t **)malloc( 1 );
+    p_sys->i_width = i_width;
+    p_sys->i_height = i_height;
+    p_sys->i_chroma = i_chroma;
 
     /* Create header */
     p_sys->i_header_size = 8;
@@ -418,8 +466,12 @@ static int OpenDevice( input_thread_t *p_input, string devicename,
         return VLC_EGENERIC;
     }
 
+    AM_MEDIA_TYPE media_type =
+        EnumDeviceCaps( (vlc_object_t *)p_input, p_device_filter, b_audio,
+                        p_sys->i_chroma, p_sys->i_width, p_sys->i_height );
+
     /* Create and add our capture filter */
-    CaptureFilter *p_capture_filter = new CaptureFilter( p_input );
+    CaptureFilter *p_capture_filter = new CaptureFilter( p_input, media_type );
     p_sys->p_graph->AddFilter( p_capture_filter, 0 );
 
     /* Add the device filter to the graph (seems necessary with VfW before
@@ -441,8 +493,13 @@ static int OpenDevice( input_thread_t *p_input, string devicename,
         {
             msg_Dbg( p_input, "MEDIATYPE_Video");
 
+            /* Packed RGB formats */
+            if( dshow_stream.mt.subtype == MEDIASUBTYPE_RGB1 )
+                dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'G', 'B', '1' );
+            if( dshow_stream.mt.subtype == MEDIASUBTYPE_RGB4 )
+                dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'G', 'B', '4' );
             if( dshow_stream.mt.subtype == MEDIASUBTYPE_RGB8 )
-                dshow_stream.i_fourcc = VLC_FOURCC( 'G', 'R', 'E', 'Y' );
+                dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'G', 'B', '8' );
             else if( dshow_stream.mt.subtype == MEDIASUBTYPE_RGB555 )
                 dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'V', '1', '5' );
             else if( dshow_stream.mt.subtype == MEDIASUBTYPE_RGB565 )
@@ -453,21 +510,31 @@ static int OpenDevice( input_thread_t *p_input, string devicename,
                 dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'V', '3', '2' );
             else if( dshow_stream.mt.subtype == MEDIASUBTYPE_ARGB32 )
                 dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'G', 'B', 'A' );
-            
+
+            /* Packed YUV formats */
+            else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YVYU )
+                dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'V', 'Y', 'U' );
             else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YUYV )
                 dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'U', 'Y', 'V' );
             else if( dshow_stream.mt.subtype == MEDIASUBTYPE_Y411 )
                 dshow_stream.i_fourcc = VLC_FOURCC( 'I', '4', '1', 'N' );
+            else if( dshow_stream.mt.subtype == MEDIASUBTYPE_Y211 )
+                dshow_stream.i_fourcc = VLC_FOURCC( 'Y', '2', '1', '1' );
+            else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YUY2 ||
+                     dshow_stream.mt.subtype == MEDIASUBTYPE_UYVY )
+                dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'U', 'Y', '2' );
+
+            /* Planar YUV formats */
+            else if( dshow_stream.mt.subtype == MEDIASUBTYPE_I420 )
+                dshow_stream.i_fourcc = VLC_FOURCC( 'I', '4', '2', '0' );
             else if( dshow_stream.mt.subtype == MEDIASUBTYPE_Y41P )
                 dshow_stream.i_fourcc = VLC_FOURCC( 'I', '4', '1', '1' );
-            else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YUY2 )
-                dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'U', 'Y', '2' );
-            else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YVYU )
-                dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'V', 'Y', 'U' );
-            else if( dshow_stream.mt.subtype == MEDIASUBTYPE_Y411 )
-                dshow_stream.i_fourcc = VLC_FOURCC( 'I', '4', '1', 'N' );
-            else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YV12 )
+            else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YV12 ||
+                     dshow_stream.mt.subtype == MEDIASUBTYPE_IYUV )
                 dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'V', '1', '2' );
+            else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YVU9 )
+                dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'V', 'U', '9' );
+
             else goto fail;
 
             dshow_stream.header.video =
@@ -476,7 +543,10 @@ static int OpenDevice( input_thread_t *p_input, string devicename,
             int i_height = dshow_stream.header.video.bmiHeader.biHeight;
 
             /* Check if the image is inverted (bottom to top) */
-            if( dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
+            if( dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'G', 'B', '1' ) ||
+                dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'G', 'B', '4' ) ||
+                dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'G', 'B', '8' ) ||
+                dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '5' ) ||
                 dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'V', '1', '6' ) ||
                 dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
                 dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
@@ -661,6 +731,90 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,
     return NULL;
 }
 
+static AM_MEDIA_TYPE EnumDeviceCaps( vlc_object_t *p_this,
+                                     IBaseFilter *p_filter, vlc_bool_t b_audio,
+                                     int i_chroma, int i_width, int i_height )
+{
+    IEnumPins *p_enumpins;
+    IPin *p_output_pin;
+    IEnumMediaTypes *p_enummt;
+
+    AM_MEDIA_TYPE media_type;
+    media_type.majortype = GUID_NULL;
+    media_type.subtype = GUID_NULL;
+    media_type.formattype = GUID_NULL;
+    media_type.pUnk = NULL;
+    media_type.cbFormat = 0;
+    media_type.pbFormat = NULL;
+
+    if( S_OK != p_filter->EnumPins( &p_enumpins ) ) return media_type;
+
+    /*while*/if( p_enumpins->Next( 1, &p_output_pin, NULL ) == S_OK )
+    {
+        /* Probe pin */
+        if( !b_audio &&
+            SUCCEEDED( p_output_pin->EnumMediaTypes( &p_enummt ) ) )
+        {
+            AM_MEDIA_TYPE *p_mt;
+            while( p_enummt->Next( 1, &p_mt, NULL ) == S_OK )
+            {
+                int i_fourcc = VLC_FOURCC(' ', ' ', ' ', ' ');
+
+                /* Packed RGB formats */
+                if( p_mt->subtype == MEDIASUBTYPE_RGB1 )
+                    i_fourcc = VLC_FOURCC( 'R', 'G', 'B', '1' );
+                if( p_mt->subtype == MEDIASUBTYPE_RGB4 )
+                    i_fourcc = VLC_FOURCC( 'R', 'G', 'B', '4' );
+                if( p_mt->subtype == MEDIASUBTYPE_RGB8 )
+                    i_fourcc = VLC_FOURCC( 'R', 'G', 'B', '8' );
+                else if( p_mt->subtype == MEDIASUBTYPE_RGB555 )
+                    i_fourcc = VLC_FOURCC( 'R', 'V', '1', '5' );
+                else if( p_mt->subtype == MEDIASUBTYPE_RGB565 )
+                    i_fourcc = VLC_FOURCC( 'R', 'V', '1', '6' );
+                else if( p_mt->subtype == MEDIASUBTYPE_RGB24 )
+                    i_fourcc = VLC_FOURCC( 'R', 'V', '2', '4' );
+                else if( p_mt->subtype == MEDIASUBTYPE_RGB32 )
+                    i_fourcc = VLC_FOURCC( 'R', 'V', '3', '2' );
+                else if( p_mt->subtype == MEDIASUBTYPE_ARGB32 )
+                    i_fourcc = VLC_FOURCC( 'R', 'G', 'B', 'A' );
+                else i_fourcc = *((int *)&p_mt->subtype);
+
+                int i_current_width = p_mt->pbFormat ?
+                  ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biWidth : 0;
+                int i_current_height = p_mt->pbFormat ?
+                  ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biHeight : 0;
+
+                msg_Dbg( p_this, "EnumDeviceCaps: input pin "
+                         "accepts chroma: %4.4s, width:%i, height:%i",
+                         (char *)&i_fourcc, i_current_width,
+                         i_current_height );
+
+                if( i_fourcc == i_chroma )
+                {
+                    media_type.subtype = p_mt->subtype;
+                }
+
+                if( i_fourcc == i_chroma && p_mt->pbFormat &&
+                    i_width && i_height && i_width == i_current_width &&
+                    i_height == i_current_height )
+                {
+                    media_type = *p_mt;
+                }
+                else
+                {
+                    FreeMediaType( *p_mt );
+                }
+                CoTaskMemFree( (PVOID)p_mt );
+            }
+            p_enummt->Release();
+        }
+        p_output_pin->Release();
+    }
+
+    p_enumpins->Release();
+    return media_type;
+}
+
 /*****************************************************************************
  * Read: reads from the device into PES packets.
  *****************************************************************************
index 6c4d0dd949e82c59d056c325c49b8ec09ca7a355..e17fb0d820f59e3cc9264c3e90b3ff253f5cbfc1 100644 (file)
@@ -2,7 +2,7 @@
  * filter.c : DirectShow access module for vlc
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: filter.cpp,v 1.4 2003/08/27 07:31:26 gbazin Exp $
+ * $Id: filter.cpp,v 1.5 2003/08/31 22:06:17 gbazin Exp $
  *
  * Author: Gildas Bazin <gbazin@netcourrier.com>
  *
 #include <vlc/input.h>
 #include <vlc/vout.h>
 
-#ifndef _MSC_VER
-#   include <wtypes.h>
-#   include <unknwn.h>
-#   include <ole2.h>
-#   include <limits.h>
-#   define _WINGDI_ 1
-#   define AM_NOVTABLE
-#   define _OBJBASE_H_
-#   undef _X86_
-#   define _I64_MAX LONG_LONG_MAX
-#   define LONGLONG long long
-#endif
-
-#include <dshow.h>
-
 #include "filter.h"
 
 #define DEBUG_DSHOW 1
@@ -79,6 +64,9 @@ const GUID IID_IEnumMediaTypes = {0x89c31040, 0x846b, 0x11ce, {0x97,0xd3, 0x00,0
  */
 const GUID MEDIATYPE_Video = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
 
+/* Packed RGB formats */
+const GUID MEDIASUBTYPE_RGB1 = {0xe436eb78, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+const GUID MEDIASUBTYPE_RGB4 = {0xe436eb79, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
 const GUID MEDIASUBTYPE_RGB8 = {0xe436eb7a, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
 const GUID MEDIASUBTYPE_RGB565 = {0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
 const GUID MEDIASUBTYPE_RGB555 = {0xe436eb7c, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
@@ -86,19 +74,27 @@ const GUID MEDIASUBTYPE_RGB24 = {0xe436eb7d, 0x524f, 0x11ce, {0x9f, 0x53, 0x00,
 const GUID MEDIASUBTYPE_RGB32 = {0xe436eb7e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
 const GUID MEDIASUBTYPE_ARGB32 = {0x773c9ac0, 0x3274, 0x11d0, {0xb7, 0x24, 0x0, 0xaa, 0x0, 0x6c, 0x1a, 0x1}};
 
+/* Packed YUV formats */
 const GUID MEDIASUBTYPE_YUYV = {0x56595559, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
 const GUID MEDIASUBTYPE_Y411 = {0x31313459, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
-const GUID MEDIASUBTYPE_Y41P = {0x50313459, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+const GUID MEDIASUBTYPE_Y211 = {0x31313259, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
 const GUID MEDIASUBTYPE_YUY2 = {0x32595559, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
 const GUID MEDIASUBTYPE_YVYU = {0x55595659, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
 const GUID MEDIASUBTYPE_UYVY = {0x59565955, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
-const GUID MEDIASUBTYPE_Y211 = {0x31313259, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+
+/* Planar YUV formats */
+const GUID MEDIASUBTYPE_YVU9 = {0x39555659, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
 const GUID MEDIASUBTYPE_YV12 = {0x32315659, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+const GUID MEDIASUBTYPE_IYUV = {0x56555949, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; /* identical to YV12 */
+const GUID MEDIASUBTYPE_Y41P = {0x50313459, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+const GUID MEDIASUBTYPE_I420 = {0x30323449, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
 
 const GUID MEDIATYPE_Audio = {0x73647561, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
 const GUID FORMAT_WaveFormatEx = {0x05589f81, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
 const GUID MEDIASUBTYPE_PCM = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
 
+const GUID GUID_NULL = {0x0000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+
 void WINAPI FreeMediaType( AM_MEDIA_TYPE& mt )
 {
     if( mt.cbFormat != 0 )
@@ -144,9 +140,10 @@ HRESULT WINAPI CopyMediaType( AM_MEDIA_TYPE *pmtTarget,
  * Implementation of our dummy directshow filter pin class
  ****************************************************************************/
 
-CapturePin::CapturePin( input_thread_t * _p_input, CaptureFilter *_p_filter )
+CapturePin::CapturePin( input_thread_t * _p_input, CaptureFilter *_p_filter,
+                        AM_MEDIA_TYPE mt )
   : p_input( _p_input ), p_filter( _p_filter ), p_connected_pin( NULL ),
-    i_ref( 1 )
+    media_type( mt ), i_ref( 1 )
 {
 }
 
@@ -232,8 +229,29 @@ STDMETHODIMP CapturePin::ReceiveConnection( IPin * pConnector,
     msg_Dbg( p_input, "CapturePin::ReceiveConnection" );
 #endif
 
+    if( pmt->majortype == MEDIATYPE_Video )
+    {
+        if( media_type.subtype != GUID_NULL &&
+            media_type.subtype != pmt->subtype )
+            return VFW_E_TYPE_NOT_ACCEPTED;
+
+        if( media_type.pbFormat &&
+            ((VIDEOINFOHEADER *)media_type.pbFormat)->bmiHeader.biHeight &&
+            ((VIDEOINFOHEADER *)media_type.pbFormat)->bmiHeader.biHeight !=
+            ((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biHeight )
+            return VFW_E_TYPE_NOT_ACCEPTED;
+
+        if( media_type.pbFormat &&
+            ((VIDEOINFOHEADER *)media_type.pbFormat)->bmiHeader.biWidth &&
+            ((VIDEOINFOHEADER *)media_type.pbFormat)->bmiHeader.biWidth !=
+            ((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biWidth )
+            return VFW_E_TYPE_NOT_ACCEPTED;
+    }
+
     p_connected_pin = pConnector;
     p_connected_pin->AddRef();
+
+    FreeMediaType( media_type );
     return CopyMediaType( &media_type, pmt );
 }
 STDMETHODIMP CapturePin::Disconnect()
@@ -435,9 +453,9 @@ STDMETHODIMP CapturePin::ReceiveCanBlock( void )
  * Implementation of our dummy directshow filter class
  ****************************************************************************/
 
-CaptureFilter::CaptureFilter( input_thread_t * _p_input )
-  : p_input( _p_input ), p_pin( new CapturePin( _p_input, this ) ),
-    i_ref( 1 )
+CaptureFilter::CaptureFilter( input_thread_t * _p_input, AM_MEDIA_TYPE mt )
+  : p_input( _p_input ), p_pin( new CapturePin( _p_input, this, mt ) ),
+    media_type( mt ), i_ref( 1 )
 {
 }
 
@@ -751,7 +769,6 @@ CaptureEnumMediaTypes::CaptureEnumMediaTypes( input_thread_t * _p_input,
     p_pin->AddRef();
 
     /* Are we creating a new enumerator */
-
     if( pEnumMediaTypes == NULL )
     {
         i_position = 0;
@@ -816,20 +833,7 @@ STDMETHODIMP CaptureEnumMediaTypes::Next( ULONG cMediaTypes,
     msg_Dbg( p_input, "CaptureEnumMediaTypes::Next" );
 #endif
 
-    *pcFetched = 0;
-
-#if 0
-    if( i_position < 1 && cMediaTypes > 0 )
-    {
-        IPin *pPin = p_pin->CustomGetPin();
-        *ppMediaTypes = pPin;
-        pPin->AddRef();
-        *pcFetched = 1;
-        i_position++;
-        return NOERROR;
-    }
-#endif
-
+    if( pcFetched ) *pcFetched = 0;
     return S_FALSE;
 };
 STDMETHODIMP CaptureEnumMediaTypes::Skip( ULONG cMediaTypes )
@@ -838,13 +842,7 @@ STDMETHODIMP CaptureEnumMediaTypes::Skip( ULONG cMediaTypes )
     msg_Dbg( p_input, "CaptureEnumMediaTypes::Skip" );
 #endif
 
-    if( cMediaTypes > 0 )
-    {
-        return S_FALSE;
-    }
-
-    i_position += cMediaTypes;
-    return NOERROR;
+    return S_FALSE;
 };
 STDMETHODIMP CaptureEnumMediaTypes::Reset()
 {
index 1ea95f5f8c9794e56da549292c245fe3cdb0abbc..75c59700d2bdcc781cbc3c2ef2a44bb9109f280c 100644 (file)
@@ -2,7 +2,7 @@
  * filter.h : DirectShow access module for vlc
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: filter.h,v 1.1 2003/08/24 11:17:39 gbazin Exp $
+ * $Id: filter.h,v 1.2 2003/08/31 22:06:17 gbazin Exp $
  *
  * Author: Gildas Bazin <gbazin@netcourrier.com>
  *
 #include <deque>
 using namespace std;
 
+#ifndef _MSC_VER
+#   include <wtypes.h>
+#   include <unknwn.h>
+#   include <ole2.h>
+#   include <limits.h>
+#   define _WINGDI_ 1
+#   define AM_NOVTABLE
+#   define _OBJBASE_H_
+#   undef _X86_
+#   define _I64_MAX LONG_LONG_MAX
+#   define LONGLONG long long
+#endif
+
+#include <dshow.h>
+
+extern const GUID MEDIASUBTYPE_I420;
+
 typedef struct VLCMediaSample
 {
     IMediaSample *p_sample;
@@ -47,9 +64,8 @@ HRESULT WINAPI CopyMediaType( AM_MEDIA_TYPE *pmtTarget,
  ****************************************************************************/
 class CapturePin: public IPin, public IMemInputPin
 {
-    input_thread_t * p_input;
-
-    CaptureFilter *p_filter;
+    input_thread_t *p_input;
+    CaptureFilter  *p_filter;
 
     IPin *p_connected_pin;
     AM_MEDIA_TYPE media_type;
@@ -59,7 +75,8 @@ class CapturePin: public IPin, public IMemInputPin
     int i_ref;
 
   public:
-    CapturePin( input_thread_t * _p_input, CaptureFilter *_p_filter );
+    CapturePin( input_thread_t * _p_input, CaptureFilter *_p_filter,
+                AM_MEDIA_TYPE mt );
     virtual ~CapturePin();
 
     /* IUnknown methods */
@@ -106,14 +123,15 @@ class CapturePin: public IPin, public IMemInputPin
  ****************************************************************************/
 class CaptureFilter : public IBaseFilter
 {
-    input_thread_t * p_input;
-    CapturePin *p_pin;
-    IFilterGraph * p_graph;
+    input_thread_t *p_input;
+    CapturePin     *p_pin;
+    IFilterGraph   *p_graph;
+    AM_MEDIA_TYPE  media_type;
 
     int i_ref;
 
   public:
-    CaptureFilter( input_thread_t * _p_input );
+    CaptureFilter( input_thread_t * _p_input, AM_MEDIA_TYPE mt );
     virtual ~CaptureFilter();
 
     /* IUnknown methods */
@@ -149,9 +167,9 @@ class CaptureFilter : public IBaseFilter
 class CaptureEnumPins : public IEnumPins
 {
     input_thread_t * p_input;
-    int i_position;
-    CaptureFilter *p_filter;
+    CaptureFilter  *p_filter;
 
+    int i_position;
     int i_ref;
 
 public:
@@ -177,9 +195,9 @@ public:
 class CaptureEnumMediaTypes : public IEnumMediaTypes
 {
     input_thread_t * p_input;
-    int i_position;
-    CapturePin *p_pin;
+    CapturePin     *p_pin;
 
+    int i_position;
     int i_ref;
 
 public: