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

📄 dshow.cpp

📁 VLC Player Source Code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }    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') )        {            free( p_access->psz_demux );            p_access->psz_demux = strdup( "rawdv" );        }        else if( p_stream->i_fourcc == VLC_FOURCC('m','p','2','v') )        {            free( p_access->psz_demux );            p_access->psz_demux = strdup( "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 = 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 );                                // found it                                Found = TRUE;                            }                        }                        pKs->Release();                    }                    pinInfo.pFilter->Release();                }                pP->Release();            }            pins->Release();        }        return true;    }    else    {        IEnumPins *p_enumpins;        IPin *p_pin;        if( S_OK != p_filter->EnumPins( &p_enumpins ) ) return false;        while( S_OK == p_enumpins->Next( 1, &p_pin, NULL ) )        {            PIN_DIRECTION pin_dir;            p_pin->QueryDirection( &pin_dir );            if( pin_dir == PINDIR_OUTPUT &&                p_sys->p_graph->ConnectDirect( p_pin, (IPin *)p_input_pin,                                               0 ) == S_OK )            {                p_pin->Release();                p_enumpins->Release();                return true;            }            p_pin->Release();        }        p_enumpins->Release();        return false;    }}/* * get fourcc priority from arbritary preference, the higher the better */static int GetFourCCPriority( int i_fourcc ){    switch( i_fourcc )    {    case VLC_FOURCC('I','4','2','0'):    case VLC_FOURCC('f','l','3','2'):        return 9;    case VLC_FOURCC('Y','V','1','2'):    case VLC_FOURCC('a','r','a','w'):        return 8;    case VLC_FOURCC('R','V','2','4'):        return 7;    case VLC_FOURCC('Y','U','Y','2'):    case VLC_FOURCC('R','V','3','2'):    case VLC_FOURCC('R','G','B','A'):        return 6;    }    return 0;}#define MAX_MEDIA_TYPES 32static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys,                       string devicename, bool b_audio ){    /* See if device is already opened */    for( int i = 0; i < p_sys->i_streams; i++ )    {        if( devicename.size() &&            p_sys->pp_streams[i]->devicename == devicename )        {            /* Already opened */            return VLC_SUCCESS;        }    }    list<string> list_devices;    /* Enumerate devices and display their names */    FindCaptureDevice( p_this, NULL, &list_devices, b_audio );    if( !list_devices.size() )        return VLC_EGENERIC;    list<string>::iterator iter;    for( iter = list_devices.begin(); iter != list_devices.end(); iter++ )        msg_Dbg( p_this, "found device: %s", iter->c_str() );    /* If no device name was specified, pick the 1st one */    if( devicename.size() == 0 )    {        devicename = *list_devices.begin();    }    // Use the system device enumerator and class enumerator to find    // a capture/preview device, such as a desktop USB video camera.    IBaseFilter *p_device_filter =        FindCaptureDevice( p_this, &devicename, 0, b_audio );    if( p_device_filter )        msg_Dbg( p_this, "using device: %s", devicename.c_str() );    else    {        msg_Err( p_this, "can't use device: %s, unsupported device type",                 devicename.c_str() );        intf_UserFatal( p_this, false, _("Capturing failed"),                        _("VLC cannot use the device \"%s\", because its "                          "type is not supported.") );        return VLC_EGENERIC;    }    // Retreive acceptable media types supported by device    AM_MEDIA_TYPE media_types[MAX_MEDIA_TYPES];    size_t media_count =        EnumDeviceCaps( p_this, p_device_filter, b_audio ? 0 : p_sys->i_chroma,                        p_sys->i_width, p_sys->i_height,      b_audio ? var_CreateGetInteger( p_this, "dshow-audio-channels" ) : 0,      b_audio ? var_CreateGetInteger( p_this, "dshow-audio-samplerate" ) : 0,      b_audio ? var_CreateGetInteger( p_this, "dshow-audio-bitspersample" ) : 0,      media_types, MAX_MEDIA_TYPES );    AM_MEDIA_TYPE *mt = NULL;    if( media_count > 0 )    {        mt = (AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * media_count);        // Order and copy returned media types according to arbitrary        // fourcc priority        for( size_t c = 0; c < media_count; c++ )        {            int slot_priority =                GetFourCCPriority(GetFourCCFromMediaType(media_types[c]));            size_t slot_copy = c;            for( size_t d = c+1; d < media_count; d++ )            {                int priority =                    GetFourCCPriority(GetFourCCFromMediaType(media_types[d]));                if( priority > slot_priority )                {                    slot_priority = priority;                    slot_copy = d;                }            }            if( slot_copy != c )            {                mt[c] = media_types[slot_copy];                media_types[slot_copy] = media_types[c];            }            else            {                mt[c] = media_types[c];            }        }    }    else {        /* capture device */        msg_Err( p_this, "capture device '%s' does not support required parameters !", devicename.c_str() );        intf_UserFatal( p_this, false, _("Capturing failed"),                        _("The capture device \"%s\" does not support the "                          "required parameters."), devicename.c_str() );        p_device_filter->Release();        return VLC_EGENERIC;    }    /* Create and add our capture filter */    CaptureFilter *p_capture_filter =        new CaptureFilter( p_this, p_sys, mt, media_count );    p_sys->p_graph->AddFilter( p_capture_filter, 0 );    /* Add the device filter to the graph (seems necessary with VfW before     * accessing pin attributes). */    p_sys->p_graph->AddFilter( p_device_filter, 0 );    /* Attempt to connect one of this device's capture output pins */    msg_Dbg( p_this, "connecting filters" );    if( ConnectFilters( p_this, p_sys, p_device_filter, p_capture_filter ) )    {        /* Success */        msg_Dbg( p_this, "filters connected successfully !" );        dshow_stream_t dshow_stream;        dshow_stream.b_pts = false;        dshow_stream.p_es = 0;        dshow_stream.mt =            p_capture_filter->CustomGetPin()->CustomGetMediaType();        /* Show Device properties. Done here so the VLC stream is setup with         * the proper parameters. */

⌨️ 快捷键说明

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