Commit 1b88d65c authored by Gildas Bazin's avatar Gildas Bazin

* modules/access/dshow/*: always try to get the video in I420 chroma if supported.
   Implemented a ":size=" and ":chroma=" option.
parent 5dfa0cff
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dshow.c : DirectShow access module for vlc * dshow.c : DirectShow access module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Author: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -32,21 +32,6 @@ ...@@ -32,21 +32,6 @@
#include <vlc/input.h> #include <vlc/input.h>
#include <vlc/vout.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" #include "filter.h"
/***************************************************************************** /*****************************************************************************
...@@ -63,8 +48,9 @@ static int Demux ( input_thread_t * ); ...@@ -63,8 +48,9 @@ static int Demux ( input_thread_t * );
static int OpenDevice( input_thread_t *, string, vlc_bool_t ); static int OpenDevice( input_thread_t *, string, vlc_bool_t );
static IBaseFilter *FindCaptureDevice( vlc_object_t *, string *, static IBaseFilter *FindCaptureDevice( vlc_object_t *, string *,
list<string> *, vlc_bool_t ); list<string> *, vlc_bool_t );
static bool ConnectFilters( IFilterGraph *p_graph, IBaseFilter *p_filter, static AM_MEDIA_TYPE EnumDeviceCaps( vlc_object_t *, IBaseFilter *,
IPin *p_input_pin ); vlc_bool_t, int, int, int );
static bool ConnectFilters( IFilterGraph *, IBaseFilter *, IPin * );
/***************************************************************************** /*****************************************************************************
* Module descriptior * Module descriptior
...@@ -173,6 +159,11 @@ struct access_sys_t ...@@ -173,6 +159,11 @@ struct access_sys_t
dshow_stream_t **pp_streams; dshow_stream_t **pp_streams;
int i_streams; int i_streams;
int i_current_stream; 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 ) ...@@ -188,6 +179,7 @@ static int AccessOpen( vlc_object_t *p_this )
psz_dup = strdup( p_input->psz_name ); psz_dup = strdup( p_input->psz_name );
psz_parser = psz_dup; psz_parser = psz_dup;
string vdevname, adevname; string vdevname, adevname;
int i_width = 0, i_height = 0, i_chroma = VLC_FOURCC('I','4','2','0');
while( *psz_parser && *psz_parser != ':' ) while( *psz_parser && *psz_parser != ':' )
{ {
...@@ -234,6 +226,59 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -234,6 +226,59 @@ static int AccessOpen( vlc_object_t *p_this )
psz_parser += i_len; 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 else
{ {
msg_Warn( p_input, "unknown option" ); msg_Warn( p_input, "unknown option" );
...@@ -277,6 +322,9 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -277,6 +322,9 @@ static int AccessOpen( vlc_object_t *p_this )
/* Initialize some data */ /* Initialize some data */
p_sys->i_streams = 0; p_sys->i_streams = 0;
p_sys->pp_streams = (dshow_stream_t **)malloc( 1 ); 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 */ /* Create header */
p_sys->i_header_size = 8; p_sys->i_header_size = 8;
...@@ -418,8 +466,12 @@ static int OpenDevice( input_thread_t *p_input, string devicename, ...@@ -418,8 +466,12 @@ static int OpenDevice( input_thread_t *p_input, string devicename,
return VLC_EGENERIC; 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 */ /* 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 ); p_sys->p_graph->AddFilter( p_capture_filter, 0 );
/* Add the device filter to the graph (seems necessary with VfW before /* 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, ...@@ -441,8 +493,13 @@ static int OpenDevice( input_thread_t *p_input, string devicename,
{ {
msg_Dbg( p_input, "MEDIATYPE_Video"); 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 ) 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 ) else if( dshow_stream.mt.subtype == MEDIASUBTYPE_RGB555 )
dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'V', '1', '5' ); dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'V', '1', '5' );
else if( dshow_stream.mt.subtype == MEDIASUBTYPE_RGB565 ) else if( dshow_stream.mt.subtype == MEDIASUBTYPE_RGB565 )
...@@ -453,21 +510,31 @@ static int OpenDevice( input_thread_t *p_input, string devicename, ...@@ -453,21 +510,31 @@ static int OpenDevice( input_thread_t *p_input, string devicename,
dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'V', '3', '2' ); dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'V', '3', '2' );
else if( dshow_stream.mt.subtype == MEDIASUBTYPE_ARGB32 ) else if( dshow_stream.mt.subtype == MEDIASUBTYPE_ARGB32 )
dshow_stream.i_fourcc = VLC_FOURCC( 'R', 'G', 'B', 'A' ); 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 ) else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YUYV )
dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'U', 'Y', 'V' ); dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'U', 'Y', 'V' );
else if( dshow_stream.mt.subtype == MEDIASUBTYPE_Y411 ) else if( dshow_stream.mt.subtype == MEDIASUBTYPE_Y411 )
dshow_stream.i_fourcc = VLC_FOURCC( 'I', '4', '1', 'N' ); 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 ) else if( dshow_stream.mt.subtype == MEDIASUBTYPE_Y41P )
dshow_stream.i_fourcc = VLC_FOURCC( 'I', '4', '1', '1' ); dshow_stream.i_fourcc = VLC_FOURCC( 'I', '4', '1', '1' );
else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YUY2 ) else if( dshow_stream.mt.subtype == MEDIASUBTYPE_YV12 ||
dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'U', 'Y', '2' ); dshow_stream.mt.subtype == MEDIASUBTYPE_IYUV )
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 )
dshow_stream.i_fourcc = VLC_FOURCC( 'Y', 'V', '1', '2' ); 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; else goto fail;
dshow_stream.header.video = dshow_stream.header.video =
...@@ -476,7 +543,10 @@ static int OpenDevice( input_thread_t *p_input, string devicename, ...@@ -476,7 +543,10 @@ static int OpenDevice( input_thread_t *p_input, string devicename,
int i_height = dshow_stream.header.video.bmiHeader.biHeight; int i_height = dshow_stream.header.video.bmiHeader.biHeight;
/* Check if the image is inverted (bottom to top) */ /* 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', '1', '6' ) ||
dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) || dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) ||
dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'V', '3', '2' ) || dshow_stream.i_fourcc == VLC_FOURCC( 'R', 'V', '3', '2' ) ||
...@@ -661,6 +731,90 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename, ...@@ -661,6 +731,90 @@ FindCaptureDevice( vlc_object_t *p_this, string *p_devicename,
return NULL; 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. * Read: reads from the device into PES packets.
***************************************************************************** *****************************************************************************
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* filter.c : DirectShow access module for vlc * filter.c : DirectShow access module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Author: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -32,21 +32,6 @@ ...@@ -32,21 +32,6 @@
#include <vlc/input.h> #include <vlc/input.h>
#include <vlc/vout.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" #include "filter.h"
#define DEBUG_DSHOW 1 #define DEBUG_DSHOW 1
...@@ -79,6 +64,9 @@ const GUID IID_IEnumMediaTypes = {0x89c31040, 0x846b, 0x11ce, {0x97,0xd3, 0x00,0 ...@@ -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}}; 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_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_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}}; 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, ...@@ -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_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}}; 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_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_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_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_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_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_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 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 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 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 ) void WINAPI FreeMediaType( AM_MEDIA_TYPE& mt )
{ {
if( mt.cbFormat != 0 ) if( mt.cbFormat != 0 )
...@@ -144,9 +140,10 @@ HRESULT WINAPI CopyMediaType( AM_MEDIA_TYPE *pmtTarget, ...@@ -144,9 +140,10 @@ HRESULT WINAPI CopyMediaType( AM_MEDIA_TYPE *pmtTarget,
* Implementation of our dummy directshow filter pin class * 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 ), : 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, ...@@ -232,8 +229,29 @@ STDMETHODIMP CapturePin::ReceiveConnection( IPin * pConnector,
msg_Dbg( p_input, "CapturePin::ReceiveConnection" ); msg_Dbg( p_input, "CapturePin::ReceiveConnection" );
#endif #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 = pConnector;
p_connected_pin->AddRef(); p_connected_pin->AddRef();
FreeMediaType( media_type );
return CopyMediaType( &media_type, pmt ); return CopyMediaType( &media_type, pmt );
} }
STDMETHODIMP CapturePin::Disconnect() STDMETHODIMP CapturePin::Disconnect()
...@@ -435,9 +453,9 @@ STDMETHODIMP CapturePin::ReceiveCanBlock( void ) ...@@ -435,9 +453,9 @@ STDMETHODIMP CapturePin::ReceiveCanBlock( void )
* Implementation of our dummy directshow filter class * Implementation of our dummy directshow filter class
****************************************************************************/ ****************************************************************************/
CaptureFilter::CaptureFilter( input_thread_t * _p_input ) CaptureFilter::CaptureFilter( input_thread_t * _p_input, AM_MEDIA_TYPE mt )
: p_input( _p_input ), p_pin( new CapturePin( _p_input, this ) ), : p_input( _p_input ), p_pin( new CapturePin( _p_input, this, mt ) ),
i_ref( 1 ) media_type( mt ), i_ref( 1 )
{ {
} }
...@@ -751,7 +769,6 @@ CaptureEnumMediaTypes::CaptureEnumMediaTypes( input_thread_t * _p_input, ...@@ -751,7 +769,6 @@ CaptureEnumMediaTypes::CaptureEnumMediaTypes( input_thread_t * _p_input,
p_pin->AddRef(); p_pin->AddRef();
/* Are we creating a new enumerator */ /* Are we creating a new enumerator */
if( pEnumMediaTypes == NULL ) if( pEnumMediaTypes == NULL )
{ {
i_position = 0; i_position = 0;
...@@ -816,20 +833,7 @@ STDMETHODIMP CaptureEnumMediaTypes::Next( ULONG cMediaTypes, ...@@ -816,20 +833,7 @@ STDMETHODIMP CaptureEnumMediaTypes::Next( ULONG cMediaTypes,
msg_Dbg( p_input, "CaptureEnumMediaTypes::Next" ); msg_Dbg( p_input, "CaptureEnumMediaTypes::Next" );
#endif #endif
*pcFetched = 0; if( pcFetched ) *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
return S_FALSE; return S_FALSE;
}; };
STDMETHODIMP CaptureEnumMediaTypes::Skip( ULONG cMediaTypes ) STDMETHODIMP CaptureEnumMediaTypes::Skip( ULONG cMediaTypes )
...@@ -838,13 +842,7 @@ STDMETHODIMP CaptureEnumMediaTypes::Skip( ULONG cMediaTypes ) ...@@ -838,13 +842,7 @@ STDMETHODIMP CaptureEnumMediaTypes::Skip( ULONG cMediaTypes )
msg_Dbg( p_input, "CaptureEnumMediaTypes::Skip" ); msg_Dbg( p_input, "CaptureEnumMediaTypes::Skip" );
#endif #endif
if( cMediaTypes > 0 ) return S_FALSE;
{
return S_FALSE;
}
i_position += cMediaTypes;
return NOERROR;
}; };
STDMETHODIMP CaptureEnumMediaTypes::Reset() STDMETHODIMP CaptureEnumMediaTypes::Reset()
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* filter.h : DirectShow access module for vlc * filter.h : DirectShow access module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * 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> * Author: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -29,6 +29,23 @@ ...@@ -29,6 +29,23 @@
#include <deque> #include <deque>
using namespace std; 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 typedef struct VLCMediaSample
{ {
IMediaSample *p_sample; IMediaSample *p_sample;
...@@ -47,9 +64,8 @@ HRESULT WINAPI CopyMediaType( AM_MEDIA_TYPE *pmtTarget, ...@@ -47,9 +64,8 @@ HRESULT WINAPI CopyMediaType( AM_MEDIA_TYPE *pmtTarget,
****************************************************************************/ ****************************************************************************/
class CapturePin: public IPin, public IMemInputPin class CapturePin: public IPin, public IMemInputPin
{ {
input_thread_t * p_input; input_thread_t *p_input;
CaptureFilter *p_filter;
CaptureFilter *p_filter;
IPin *p_connected_pin; IPin *p_connected_pin;
AM_MEDIA_TYPE media_type; AM_MEDIA_TYPE media_type;
...@@ -59,7 +75,8 @@ class CapturePin: public IPin, public IMemInputPin ...@@ -59,7 +75,8 @@ class CapturePin: public IPin, public IMemInputPin
int i_ref; int i_ref;
public: 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(); virtual ~CapturePin();
/* IUnknown methods */ /* IUnknown methods */
...@@ -106,14 +123,15 @@ class CapturePin: public IPin, public IMemInputPin ...@@ -106,14 +123,15 @@ class CapturePin: public IPin, public IMemInputPin
****************************************************************************/ ****************************************************************************/
class CaptureFilter : public IBaseFilter class CaptureFilter : public IBaseFilter
{ {
input_thread_t * p_input; input_thread_t *p_input;
CapturePin *p_pin; CapturePin *p_pin;
IFilterGraph * p_graph; IFilterGraph *p_graph;
AM_MEDIA_TYPE media_type;
int i_ref; int i_ref;
public: public:
CaptureFilter( input_thread_t * _p_input ); CaptureFilter( input_thread_t * _p_input, AM_MEDIA_TYPE mt );
virtual ~CaptureFilter(); virtual ~CaptureFilter();
/* IUnknown methods */ /* IUnknown methods */
...@@ -149,9 +167,9 @@ class CaptureFilter : public IBaseFilter ...@@ -149,9 +167,9 @@ class CaptureFilter : public IBaseFilter
class CaptureEnumPins : public IEnumPins class CaptureEnumPins : public IEnumPins
{ {
input_thread_t * p_input; input_thread_t * p_input;
int i_position; CaptureFilter *p_filter;
CaptureFilter *p_filter;
int i_position;
int i_ref; int i_ref;
public: public:
...@@ -177,9 +195,9 @@ public: ...@@ -177,9 +195,9 @@ public:
class CaptureEnumMediaTypes : public IEnumMediaTypes class CaptureEnumMediaTypes : public IEnumMediaTypes
{ {
input_thread_t * p_input; input_thread_t * p_input;
int i_position; CapturePin *p_pin;
CapturePin *p_pin;
int i_position;
int i_ref; int i_ref;
public: public:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment