📄 dshow.cpp
字号:
p_sys->p_graph = NULL; }}/***************************************************************************** * CommonOpen: open direct show device *****************************************************************************/static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys, bool b_access_demux ){ vlc_value_t val; int i; /* Get/parse options and open device(s) */ string vdevname, adevname; int i_width = 0, i_height = 0, i_chroma = 0; bool b_audio = true; 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 ) vdevname = string( 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 ); 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 }, { "sif", 320, 240 }, { "cif", 352, 288 }, { "d1", 640, 480 }, { 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 ) { for( i = 0; size_table[i].psz_size; i++ ) { if( !strcmp( val.psz_string, size_table[i].psz_size ) ) { i_width = size_table[i].i_width; i_height = size_table[i].i_height; break; } } if( !size_table[i].psz_size ) /* Try to parse "WidthxHeight" */ { char *psz_parser; i_width = strtol( val.psz_string, &psz_parser, 0 ); if( *psz_parser == 'x' || *psz_parser == 'X') { i_height = strtol( psz_parser + 1, &psz_parser, 0 ); } 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 ); if( val.psz_string && strlen( val.psz_string ) >= 4 ) { i_chroma = VLC_FOURCC( val.psz_string[0], val.psz_string[1], val.psz_string[2], val.psz_string[3] ); p_sys->b_chroma = true; } free( val.psz_string ); var_Create( p_this, "dshow-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); var_Create( p_this, "dshow-tuner-channel", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_this, "dshow-tuner-country", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_this, "dshow-tuner-input", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_this, "dshow-amtuner-mode", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_this, "dshow-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_this, "dshow-video-input", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Create( p_this, "dshow-audio-input", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); 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 OLE/COM */ CoInitialize( 0 ); /* Initialize some data */ p_sys->i_streams = 0; p_sys->pp_streams = 0; p_sys->i_width = i_width; p_sys->i_height = i_height; p_sys->i_chroma = i_chroma; p_sys->p_graph = NULL; p_sys->p_capture_graph_builder2 = NULL; p_sys->p_control = NULL; vlc_mutex_init( &p_sys->lock ); vlc_cond_init( p_this, &p_sys->wait ); /* Build directshow graph */ CreateDirectShowGraph( p_sys ); if( OpenDevice( p_this, p_sys, vdevname, 0 ) != VLC_SUCCESS ) { msg_Err( p_this, "can't open video"); } else { /* Check if we can handle the demuxing ourselves or need to spawn * a demuxer module */ dshow_stream_t *p_stream = p_sys->pp_streams[p_sys->i_streams-1]; if( p_stream->mt.majortype == MEDIATYPE_Video ) { if( /* Raw DV stream */ p_stream->i_fourcc == VLC_FOURCC('d','v','s','l') || p_stream->i_fourcc == VLC_FOURCC('d','v','s','d') || p_stream->i_fourcc == VLC_FOURCC('d','v','h','d') || /* Raw MPEG video stream */ p_stream->i_fourcc == VLC_FOURCC('m','p','2','v') ) { b_audio = false; if( b_access_demux ) { /* Let the access (only) take care of that */ return VLC_EGENERIC; } } } if( p_stream->mt.majortype == MEDIATYPE_Stream ) { b_audio = false; if( b_access_demux ) { /* Let the access (only) take care of that */ return VLC_EGENERIC; } var_Get( p_this, "dshow-tuner", &val ); if( val.b_bool ) { /* FIXME: we do MEDIATYPE_Stream here so we don't do * it twice. */ ShowTunerProperties( p_this, p_sys->p_capture_graph_builder2, p_stream->p_device_filter, 0 ); } } } if( b_audio && OpenDevice( p_this, p_sys, adevname, 1 ) != VLC_SUCCESS ) { msg_Err( p_this, "can't open audio"); } 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; IAMCrossbar *pXbar = p_sys->crossbar_routes[i].pXbar; LONG VideoInputIndex = p_sys->crossbar_routes[i].VideoInputIndex; LONG VideoOutputIndex = p_sys->crossbar_routes[i].VideoOutputIndex; LONG AudioInputIndex = p_sys->crossbar_routes[i].AudioInputIndex; LONG AudioOutputIndex = p_sys->crossbar_routes[i].AudioOutputIndex; if( SUCCEEDED(pXbar->Route(VideoOutputIndex, VideoInputIndex)) ) { msg_Dbg( p_this, "crossbar at depth %d, routed video " "output %ld to video input %ld", i, VideoOutputIndex, VideoInputIndex ); if( AudioOutputIndex != -1 && AudioInputIndex != -1 ) { if( SUCCEEDED( pXbar->Route(AudioOutputIndex, AudioInputIndex)) ) { msg_Dbg(p_this, "crossbar at depth %d, routed audio " "output %ld to audio input %ld", i, AudioOutputIndex, AudioInputIndex ); } } } } /* ** Show properties pages from other filters in graph */ var_Get( p_this, "dshow-config", &val ); if( val.b_bool ) { for( i = p_sys->i_crossbar_route_depth-1; i >= 0 ; --i ) { IAMCrossbar *pXbar = p_sys->crossbar_routes[i].pXbar; IBaseFilter *p_XF; if( SUCCEEDED( pXbar->QueryInterface( IID_IBaseFilter, (void **)&p_XF ) ) ) { ShowPropertyPage( p_XF ); p_XF->Release(); } } } /* Initialize some data */ p_sys->i_current_stream = 0; if( !p_sys->i_streams ) return VLC_EGENERIC; return VLC_SUCCESS;}/***************************************************************************** * DemuxOpen: open direct show device as an access_demux module *****************************************************************************/static int DemuxOpen( vlc_object_t *p_this ){ demux_t *p_demux = (demux_t *)p_this; access_sys_t *p_sys; int i; p_sys = (access_sys_t *)malloc( sizeof( access_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; memset( p_sys, 0, sizeof( access_sys_t ) ); p_demux->p_sys = (demux_sys_t *)p_sys; if( CommonOpen( p_this, p_sys, true ) != VLC_SUCCESS ) { CommonClose( p_this, p_sys ); return VLC_EGENERIC; } /* Everything is ready. Let's rock baby */ msg_Dbg( p_this, "Playing..."); p_sys->p_control->Run(); p_demux->pf_demux = Demux; p_demux->pf_control = DemuxControl; p_demux->info.i_update = 0; p_demux->info.i_title = 0; p_demux->info.i_seekpoint = 0; for( i = 0; i < p_sys->i_streams; i++ ) { dshow_stream_t *p_stream = p_sys->pp_streams[i]; es_format_t fmt; if( p_stream->mt.majortype == MEDIATYPE_Video ) { 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( !p_stream->header.video.bmiHeader.biCompression ) { /* RGB DIB are coded from bottom to top */ fmt.video.i_height = (unsigned int)(-(int)fmt.video.i_height); } /* Setup rgb mask for RGB formats */ if( p_stream->i_fourcc == VLC_FOURCC('R','V','2','4') ) { /* This is in BGR format */ fmt.video.i_bmask = 0x00ff0000; fmt.video.i_gmask = 0x0000ff00; fmt.video.i_rmask = 0x000000ff; } if( p_stream->header.video.AvgTimePerFrame ) { fmt.video.i_frame_rate = 10000000; fmt.video.i_frame_rate_base = p_stream->header.video.AvgTimePerFrame; } } else if( p_stream->mt.majortype == MEDIATYPE_Audio ) { es_format_Init( &fmt, AUDIO_ES, p_stream->i_fourcc ); fmt.audio.i_channels = p_stream->header.audio.nChannels; fmt.audio.i_rate = p_stream->header.audio.nSamplesPerSec; fmt.audio.i_bitspersample = p_stream->header.audio.wBitsPerSample; 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; } p_stream->p_es = es_out_Add( p_demux->out, &fmt ); } return VLC_SUCCESS;}/***************************************************************************** * AccessOpen: open direct show device as an access module *****************************************************************************/static int AccessOpen( vlc_object_t *p_this ){ access_t *p_access = (access_t*)p_this; access_sys_t *p_sys; p_access->p_sys = p_sys = (access_sys_t *)malloc( sizeof( access_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; memset( p_sys, 0, sizeof( access_sys_t ) ); if( CommonOpen( p_this, p_sys, false ) != VLC_SUCCESS ) { CommonClose( p_this, p_sys ); return VLC_EGENERIC;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -