⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dshow.cpp

📁 video linux conference
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    p_sys->p_capture_graph_builder2 = NULL;    p_sys->p_control = NULL;    vlc_mutex_init( p_this, &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 = VLC_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 = VLC_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 )    {        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 "                     "ouput %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 "                            "ouput %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 ) );    memset( p_sys, 0, sizeof( access_sys_t ) );    p_demux->p_sys = (demux_sys_t *)p_sys;    if( CommonOpen( p_this, p_sys, VLC_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 ) );    memset( p_sys, 0, sizeof( access_sys_t ) );    if( CommonOpen( p_this, p_sys, VLC_FALSE ) != VLC_SUCCESS )    {        CommonClose( p_this, p_sys );        return VLC_EGENERIC;    }    dshow_stream_t *p_stream = p_sys->pp_streams[0];    /* Check if we need to force demuxers */    if( !p_access->psz_demux || !*p_access->psz_demux )    {        if( 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') )        {            p_access->psz_demux = strdup( "rawdv" );        }        else if( p_stream->i_fourcc == VLC_FOURCC('m','p','2','v') )        {            p_access->psz_demux = "mpgv";        }    }    /* Setup Access */    p_access->pf_read = NULL;    p_access->pf_block = ReadCompressed;    p_access->pf_control = AccessControl;    p_access->pf_seek = NULL;    p_access->info.i_update = 0;    p_access->info.i_size = 0;    p_access->info.i_pos = 0;    p_access->info.b_eof = VLC_FALSE;    p_access->info.i_title = 0;    p_access->info.i_seekpoint = 0;    p_access->p_sys = p_sys;    /* Everything is ready. Let's rock baby */    msg_Dbg( p_this, "Playing...");    p_sys->p_control->Run();    return VLC_SUCCESS;}/***************************************************************************** * CommonClose: close device *****************************************************************************/static void CommonClose( vlc_object_t *p_this, access_sys_t *p_sys ){    msg_Dbg( p_this, "Releasing DirectShow");    DeleteDirectShowGraph( p_sys );    /* Uninitialize OLE/COM */    CoUninitialize();    for( int i = 0; i < p_sys->i_streams; i++ ) delete p_sys->pp_streams[i];    if( p_sys->i_streams ) free( p_sys->pp_streams );    vlc_mutex_destroy( &p_sys->lock );    vlc_cond_destroy( &p_sys->wait );    free( p_sys );}/***************************************************************************** * AccessClose: close device *****************************************************************************/static void AccessClose( vlc_object_t *p_this ){    access_t     *p_access = (access_t *)p_this;    access_sys_t *p_sys    = p_access->p_sys;    /* Stop capturing stuff */    p_sys->p_control->Stop();    CommonClose( p_this, p_sys );}/***************************************************************************** * DemuxClose: close device *****************************************************************************/static void DemuxClose( vlc_object_t *p_this ){    demux_t      *p_demux = (demux_t *)p_this;    access_sys_t *p_sys   = (access_sys_t *)p_demux->p_sys;    /* Stop capturing stuff */    p_sys->p_control->Stop();    CommonClose( p_this, p_sys );}/**************************************************************************** * ConnectFilters ****************************************************************************/static bool ConnectFilters( vlc_object_t *p_this, access_sys_t *p_sys,                            IBaseFilter *p_filter,                            CaptureFilter *p_capture_filter ){    CapturePin *p_input_pin = p_capture_filter->CustomGetPin();    AM_MEDIA_TYPE mediaType = p_input_pin->CustomGetMediaType();    if( p_sys->p_capture_graph_builder2 )    {        if( FAILED(p_sys->p_capture_graph_builder2->                RenderStream( &PIN_CATEGORY_CAPTURE, &mediaType.majortype,                              p_filter, 0, (IBaseFilter *)p_capture_filter )) )        {            return false;        }        // Sort out all the possible video inputs        // The class needs to be given the capture filters ANALOGVIDEO input pin        IEnumPins *pins = 0;        if( ( mediaType.majortype == MEDIATYPE_Video ||              mediaType.majortype == MEDIATYPE_Stream ) &&            SUCCEEDED(p_filter->EnumPins(&pins)) )        {            IPin        *pP = 0;            ULONG        n;            PIN_INFO     pinInfo;            BOOL         Found = FALSE;            IKsPropertySet *pKs=0;            GUID guid;            DWORD dw;            while( !Found && ( S_OK == pins->Next(1, &pP, &n) ) )            {                if( S_OK == pP->QueryPinInfo(&pinInfo) )                {                    // is this pin an ANALOGVIDEOIN input pin?                    if( pinInfo.dir == PINDIR_INPUT &&                        pP->QueryInterface( IID_IKsPropertySet,                                            (void **)&pKs ) == S_OK )                    {                        if( pKs->Get( AMPROPSETID_Pin,                                      AMPROPERTY_PIN_CATEGORY, NULL, 0,                                      &guid, sizeof(GUID), &dw ) == S_OK )                        {                            if( guid == PIN_CATEGORY_ANALOGVIDEOIN )                            {                                // recursively search crossbar routes                                FindCrossbarRoutes( p_this, p_sys, pP, 0 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -