X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fdshow%2Fdshow.cpp;h=d2ad8cf4b3d5af05e702c48ca15afb0cc462cfa8;hb=421d5ae77d686b592aaa4fa45ac4a2c1c3629fe0;hp=79c77f642aaba39a94e9363db8a42e3d1455a057;hpb=51bbf793131496c6f31f70953ff434f17be80d63;p=vlc diff --git a/modules/access/dshow/dshow.cpp b/modules/access/dshow/dshow.cpp index 79c77f642a..d2ad8cf4b3 100644 --- a/modules/access/dshow/dshow.cpp +++ b/modules/access/dshow/dshow.cpp @@ -30,6 +30,7 @@ # include "config.h" #endif +#define __STDC_CONSTANT_MACROS 1 #define __STDC_FORMAT_MACROS 1 #include @@ -114,6 +115,8 @@ static const char *const ppsz_amtuner_mode_text[] = { N_("Default"), "Size of the video that will be displayed by the " \ "DirectShow plugin. If you don't specify anything the default size for " \ "your device will be used. You can specify a standard size (cif, d1, ...) or x.") +#define ASPECT_TEXT N_("Picture aspect-ratio n:m") +#define ASPECT_LONGTEXT N_("Define input picture aspect-ratio to use. Default is 4:3" ) #define CHROMA_TEXT N_("Video input chroma format") #define CHROMA_LONGTEXT N_( \ "Force the DirectShow video input to use a specific chroma format " \ @@ -202,6 +205,8 @@ vlc_module_begin () add_string( "dshow-size", NULL, NULL, SIZE_TEXT, SIZE_LONGTEXT, false) + add_string( "dshow-aspect-ratio", "4:3", NULL, ASPECT_TEXT, ASPECT_LONGTEXT, false) + add_string( "dshow-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT, true ) add_float( "dshow-fps", 0.0f, NULL, FPS_TEXT, FPS_LONGTEXT, true ) @@ -343,8 +348,8 @@ static void DeleteDirectShowGraph( access_sys_t *p_sys ) static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys, bool b_access_demux ) { - vlc_value_t val; int i; + char *psz_val; /* Get/parse options and open device(s) */ string vdevname, adevname; @@ -358,31 +363,29 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys, var_Create( p_this, "dshow-config", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_this, "dshow-tuner", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); - var_Create( p_this, "dshow-vdev", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); - var_Get( p_this, "dshow-vdev", &val ); - if( val.psz_string ) + psz_val = var_CreateGetString( p_this, "dshow-vdev" ); + if( psz_val ) { - msg_Dbg( p_this, "dshow-vdev: %s", val.psz_string ) ; + msg_Dbg( p_this, "dshow-vdev: %s", psz_val ) ; /* skip none device */ - if ( strncasecmp( val.psz_string, "none", 4 ) != 0 ) - vdevname = string( val.psz_string ); + if ( strncasecmp( psz_val, "none", 4 ) != 0 ) + vdevname = string( psz_val ); else b_use_video = false ; } - free( val.psz_string ); + free( psz_val ); - var_Create( p_this, "dshow-adev", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); - var_Get( p_this, "dshow-adev", &val ); - if( val.psz_string ) + psz_val = var_CreateGetString( p_this, "dshow-adev" ); + if( psz_val ) { - msg_Dbg( p_this, "dshow-adev: %s", val.psz_string ) ; + msg_Dbg( p_this, "dshow-adev: %s", psz_val ) ; /* skip none device */ - if ( strncasecmp( val.psz_string, "none", 4 ) != 0 ) - adevname = string( val.psz_string ); + if ( strncasecmp( psz_val, "none", 4 ) != 0 ) + adevname = string( psz_val ); else b_use_audio = false ; } - free( val.psz_string ); + free( psz_val ); static struct {const char *psz_size; int i_width; int i_height;} size_table[] = { { "subqcif", 128, 96 }, { "qsif", 160, 120 }, { "qcif", 176, 144 }, @@ -390,13 +393,12 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys, { 0, 0, 0 }, }; - var_Create( p_this, "dshow-size", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); - var_Get( p_this, "dshow-size", &val ); - if( val.psz_string && *val.psz_string ) + psz_val = var_CreateGetString( p_this, "dshow-size" ); + if( !EMPTY_STR(psz_val) ) { for( i = 0; size_table[i].psz_size; i++ ) { - if( !strcmp( val.psz_string, size_table[i].psz_size ) ) + if( !strcmp( psz_val, size_table[i].psz_size ) ) { i_width = size_table[i].i_width; i_height = size_table[i].i_height; @@ -406,7 +408,7 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys, if( !size_table[i].psz_size ) /* Try to parse "WidthxHeight" */ { char *psz_parser; - i_width = strtol( val.psz_string, &psz_parser, 0 ); + i_width = strtol( psz_val, &psz_parser, 0 ); if( *psz_parser == 'x' || *psz_parser == 'X') { i_height = strtol( psz_parser + 1, &psz_parser, 0 ); @@ -414,15 +416,12 @@ 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 ); } } - free( val.psz_string ); - - p_sys->b_chroma = false; - var_Create( p_this, "dshow-chroma", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); - var_Get( p_this, "dshow-chroma", &val ); + free( psz_val ); - i_chroma = vlc_fourcc_GetCodecFromString( UNKNOWN_ES, val.psz_string ); + psz_val = var_CreateGetString( p_this, "dshow-chroma" ); + i_chroma = vlc_fourcc_GetCodecFromString( UNKNOWN_ES, psz_val ); p_sys->b_chroma = i_chroma != 0; - free( val.psz_string ); + free( psz_val ); var_Create( p_this, "dshow-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); var_Create( p_this, "dshow-tuner-channel", @@ -442,6 +441,7 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys, var_Create( p_this, "dshow-video-output", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_this, "dshow-audio-output", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); + /* Initialize some data */ p_sys->i_streams = 0; p_sys->pp_streams = NULL; @@ -509,8 +509,7 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys, return VLC_EGENERIC; } - var_Get( p_this, "dshow-tuner", &val ); - if( val.b_bool ) + if( var_GetBool( p_this, "dshow-tuner" ) ) { /* FIXME: we do MEDIATYPE_Stream here so we don't do * it twice. */ @@ -544,18 +543,18 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys, for( i = p_sys->i_crossbar_route_depth-1; i >= 0 ; --i ) { - var_Get( p_this, "dshow-video-input", &val ); - if( val.i_int >= 0 ) - p_sys->crossbar_routes[i].VideoInputIndex=val.i_int; - var_Get( p_this, "dshow-video-output", &val ); - if( val.i_int >= 0 ) - p_sys->crossbar_routes[i].VideoOutputIndex=val.i_int; - var_Get( p_this, "dshow-audio-input", &val ); - if( val.i_int >= 0 ) - p_sys->crossbar_routes[i].AudioInputIndex=val.i_int; - var_Get( p_this, "dshow-audio-output", &val ); - if( val.i_int >= 0 ) - p_sys->crossbar_routes[i].AudioOutputIndex=val.i_int; + int i_val = var_GetInteger( p_this, "dshow-video-input" ); + if( i_val >= 0 ) + p_sys->crossbar_routes[i].VideoInputIndex = i_val; + i_val = var_GetInteger( p_this, "dshow-video-output" ); + if( i_val >= 0 ) + p_sys->crossbar_routes[i].VideoOutputIndex = i_val; + i_val = var_GetInteger( p_this, "dshow-audio-input" ); + if( i_val >= 0 ) + p_sys->crossbar_routes[i].AudioInputIndex = i_val; + i_val = var_GetInteger( p_this, "dshow-audio-output" ); + if( i_val >= 0 ) + p_sys->crossbar_routes[i].AudioOutputIndex = i_val; IAMCrossbar *pXbar = p_sys->crossbar_routes[i].pXbar; LONG VideoInputIndex = p_sys->crossbar_routes[i].VideoInputIndex; @@ -588,8 +587,7 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys, /* ** Show properties pages from other filters in graph */ - var_Get( p_this, "dshow-config", &val ); - if( val.b_bool ) + if( var_GetBool( p_this, "dshow-config" ) ) { for( i = p_sys->i_crossbar_route_depth-1; i >= 0 ; --i ) { @@ -650,11 +648,25 @@ static int DemuxOpen( vlc_object_t *p_this ) if( p_stream->mt.majortype == MEDIATYPE_Video ) { + char *psz_aspect = var_CreateGetString( p_this, "dshow-aspect-ratio" ); + char *psz_delim = !EMPTY_STR( psz_aspect ) ? strchr( psz_aspect, ':' ) : NULL; + es_format_Init( &fmt, VIDEO_ES, p_stream->i_fourcc ); fmt.video.i_width = p_stream->header.video.bmiHeader.biWidth; fmt.video.i_height = p_stream->header.video.bmiHeader.biHeight; - fmt.video.i_aspect = 4 * VOUT_ASPECT_FACTOR / 3; + + if( psz_delim ) + { + fmt.video.i_sar_num = atoi( psz_aspect ) * fmt.video.i_height; + fmt.video.i_sar_den = atoi( psz_delim + 1 ) * fmt.video.i_width; + } + else + { + fmt.video.i_sar_num = 4 * fmt.video.i_height; + fmt.video.i_sar_den = 3 * fmt.video.i_width; + } + free( psz_aspect ); if( !p_stream->header.video.bmiHeader.biCompression ) { @@ -665,10 +677,12 @@ static int DemuxOpen( vlc_object_t *p_this ) /* Setup rgb mask for RGB formats */ if( p_stream->i_fourcc == VLC_CODEC_RGB24 ) { - /* This is in BGR format */ - fmt.video.i_bmask = 0x00ff0000; + /* This is in RGB format + http://msdn.microsoft.com/en-us/library/dd407253%28VS.85%29.aspx?ppud=4 + */ + fmt.video.i_rmask = 0x00ff0000; fmt.video.i_gmask = 0x0000ff00; - fmt.video.i_rmask = 0x000000ff; + fmt.video.i_bmask = 0x000000ff; } if( p_stream->header.video.AvgTimePerFrame ) @@ -1053,9 +1067,7 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys, /* Show Device properties. Done here so the VLC stream is setup with * the proper parameters. */ - vlc_value_t val; - var_Get( p_this, "dshow-config", &val ); - if( val.b_bool ) + if( var_GetBool( p_this, "dshow-config" ) ) { ShowDeviceProperties( p_this, p_sys->p_capture_graph_builder2, p_device_filter, b_audio ); @@ -1064,8 +1076,8 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys, ConfigTuner( p_this, p_sys->p_capture_graph_builder2, p_device_filter ); - var_Get( p_this, "dshow-tuner", &val ); - if( val.b_bool && dshow_stream.mt.majortype != MEDIATYPE_Stream ) + if( var_GetBool( p_this, "dshow-tuner" ) && + dshow_stream.mt.majortype != MEDIATYPE_Stream ) { /* FIXME: we do MEDIATYPE_Stream later so we don't do it twice. */ ShowTunerProperties( p_this, p_sys->p_capture_graph_builder2, @@ -1110,8 +1122,8 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys, dshow_stream.p_device_filter = p_device_filter; dshow_stream.p_capture_filter = p_capture_filter; - p_sys->pp_streams = (dshow_stream_t **)realloc( p_sys->pp_streams, - sizeof(dshow_stream_t *) * (p_sys->i_streams + 1) ); + p_sys->pp_streams = (dshow_stream_t **)xrealloc( p_sys->pp_streams, + sizeof(dshow_stream_t *) * (p_sys->i_streams + 1) ); p_sys->pp_streams[p_sys->i_streams] = new dshow_stream_t; *p_sys->pp_streams[p_sys->i_streams++] = dshow_stream; @@ -1716,7 +1728,7 @@ static block_t *ReadCompressed( access_t *p_access ) while( 1 ) { - if( !vlc_object_alive (p_access) || p_access->b_error ) return 0; + if( !vlc_object_alive (p_access) ) return NULL; /* Get new sample/frame from the elementary stream (blocking). */ vlc_mutex_lock( &p_sys->lock ); @@ -1855,9 +1867,8 @@ static int Demux( demux_t *p_demux ) *****************************************************************************/ static int AccessControl( access_t *p_access, int i_query, va_list args ) { - bool *pb_bool; - int *pi_int; - int64_t *pi_64; + bool *pb_bool; + int64_t *pi_64; switch( i_query ) { @@ -1873,7 +1884,7 @@ static int AccessControl( access_t *p_access, int i_query, va_list args ) /* */ case ACCESS_GET_PTS_DELAY: pi_64 = (int64_t*)va_arg( args, int64_t * ); - *pi_64 = (int64_t)var_GetInteger( p_access, "dshow-caching" ) * 1000; + *pi_64 = var_GetInteger( p_access, "dshow-caching" ) * 1000; break; /* */ @@ -1897,8 +1908,8 @@ static int AccessControl( access_t *p_access, int i_query, va_list args ) ****************************************************************************/ static int DemuxControl( demux_t *p_demux, int i_query, va_list args ) { - bool *pb; - int64_t *pi64; + bool *pb; + int64_t *pi64; switch( i_query ) { @@ -1913,7 +1924,7 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args ) case DEMUX_GET_PTS_DELAY: pi64 = (int64_t*)va_arg( args, int64_t * ); - *pi64 = (int64_t)var_GetInteger( p_demux, "dshow-caching" ) * 1000; + *pi64 = var_GetInteger( p_demux, "dshow-caching" ) * 1000; return VLC_SUCCESS; case DEMUX_GET_TIME: @@ -1970,13 +1981,11 @@ static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name, /* Uninitialize OLE/COM */ CoUninitialize(); - if( !list_devices.size() ) return VLC_SUCCESS; + if( list_devices.empty() ) return VLC_SUCCESS; - p_item->ppsz_list = - (char **)realloc( p_item->ppsz_list, + p_item->ppsz_list = (char**)xrealloc( p_item->ppsz_list, (list_devices.size()+3) * sizeof(char *) ); - p_item->ppsz_list_text = - (char **)realloc( p_item->ppsz_list_text, + p_item->ppsz_list_text = (char**)xrealloc( p_item->ppsz_list_text, (list_devices.size()+3) * sizeof(char *) ); list::iterator iter; @@ -2001,20 +2010,31 @@ static int ConfigDevicesCallback( vlc_object_t *p_this, char const *psz_name, { module_config_t *p_item; bool b_audio = false; + char *psz_device = NULL; + int i_ret = VLC_SUCCESS; + + if( !EMPTY_STR( newval.psz_string ) ) + psz_device = strdup( newval.psz_string ); /* Initialize OLE/COM */ CoInitialize( 0 ); p_item = config_FindConfig( p_this, psz_name ); - if( !p_item ) return VLC_SUCCESS; + + if( !p_item ) + { + free( psz_device ); + CoUninitialize(); + return VLC_SUCCESS; + } if( !strcmp( psz_name, "dshow-adev" ) ) b_audio = true; string devicename; - if( newval.psz_string && *newval.psz_string ) + if( psz_device ) { - devicename = newval.psz_string; + devicename = psz_device ; } else { @@ -2023,7 +2043,11 @@ static int ConfigDevicesCallback( vlc_object_t *p_this, char const *psz_name, /* Enumerate devices */ FindCaptureDevice( p_this, NULL, &list_devices, b_audio ); - if( !list_devices.size() ) return VLC_EGENERIC; + if( list_devices.empty() ) + { + CoUninitialize(); + return VLC_EGENERIC; + } devicename = *list_devices.begin(); } @@ -2036,17 +2060,15 @@ static int ConfigDevicesCallback( vlc_object_t *p_this, char const *psz_name, } else { - /* Uninitialize OLE/COM */ - CoUninitialize(); - msg_Err( p_this, "didn't find device: %s", devicename.c_str() ); - return VLC_EGENERIC; + i_ret = VLC_EGENERIC; } /* Uninitialize OLE/COM */ CoUninitialize(); - return VLC_SUCCESS; + free( psz_device ); + return i_ret; } /*****************************************************************************