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

📄 dshow.cpp

📁 video linux conference
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if( !b_audio )        hr = p_dev_enum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory,                                                &p_class_enum, 0 );    else        hr = p_dev_enum->CreateClassEnumerator( CLSID_AudioInputDeviceCategory,                                                &p_class_enum, 0 );    p_dev_enum->Release();    if( FAILED(hr) )    {        msg_Err( p_this, "failed to create the class enumerator (0x%lx)", hr );        return NULL;    }    /* If there are no enumerators for the requested type, then     * CreateClassEnumerator will succeed, but p_class_enum will be NULL */    if( p_class_enum == NULL )    {        msg_Err( p_this, "no capture device was detected" );        return NULL;    }    /* Enumerate the devices */    /* Note that if the Next() call succeeds but there are no monikers,     * it will return S_FALSE (which is not a failure). Therefore, we check     * that the return code is S_OK instead of using SUCCEEDED() macro. */    while( p_class_enum->Next( 1, &p_moniker, &i_fetched ) == S_OK )    {        /* Getting the property page to get the device name */        IPropertyBag *p_bag;        hr = p_moniker->BindToStorage( 0, 0, IID_IPropertyBag,                                       (void **)&p_bag );        if( SUCCEEDED(hr) )        {            VARIANT var;            var.vt = VT_BSTR;            hr = p_bag->Read( L"FriendlyName", &var, NULL );            p_bag->Release();            if( SUCCEEDED(hr) )            {                int i_convert = WideCharToMultiByte(CP_ACP, 0, var.bstrVal,                        SysStringLen(var.bstrVal), NULL, 0, NULL, NULL);                char *p_buf = (char *)alloca( i_convert ); p_buf[0] = 0;                WideCharToMultiByte( CP_ACP, 0, var.bstrVal,                        SysStringLen(var.bstrVal), p_buf, i_convert, NULL, NULL );                SysFreeString(var.bstrVal);                if( p_listdevices ) p_listdevices->push_back( p_buf );                if( p_devicename && *p_devicename == string(p_buf) )                {                    /* Bind Moniker to a filter object */                    hr = p_moniker->BindToObject( 0, 0, IID_IBaseFilter,                                                  (void **)&p_base_filter );                    if( FAILED(hr) )                    {                        msg_Err( p_this, "couldn't bind moniker to filter "                                 "object (0x%lx)", hr );                        p_moniker->Release();                        p_class_enum->Release();                        return NULL;                    }                    p_moniker->Release();                    p_class_enum->Release();                    return p_base_filter;                }            }        }        p_moniker->Release();    }    p_class_enum->Release();    return NULL;}static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,                              int i_fourcc, int i_width, int i_height,                              int i_channels, int i_samplespersec,                              int i_bitspersample, AM_MEDIA_TYPE *mt,                              size_t mt_max ){    IEnumPins *p_enumpins;    IPin *p_output_pin;    IEnumMediaTypes *p_enummt;    size_t mt_count = 0;    LONGLONG i_AvgTimePerFrame = 0;    float r_fps = var_GetFloat( p_this, "dshow-fps" );    if( r_fps )        i_AvgTimePerFrame = 10000000000LL/(LONGLONG)(r_fps*1000.0f);    if( FAILED(p_filter->EnumPins( &p_enumpins )) )    {        msg_Dbg( p_this, "EnumDeviceCaps failed: no pin enumeration !");        return 0;    }    while( S_OK == p_enumpins->Next( 1, &p_output_pin, NULL ) )    {        PIN_INFO info;        if( S_OK == p_output_pin->QueryPinInfo( &info ) )        {            msg_Dbg( p_this, "EnumDeviceCaps: %s pin: %S",                     info.dir == PINDIR_INPUT ? "input" : "output",                     info.achName );            if( info.pFilter ) info.pFilter->Release();        }        p_output_pin->Release();    }    p_enumpins->Reset();    while( !mt_count && p_enumpins->Next( 1, &p_output_pin, NULL ) == S_OK )    {        PIN_INFO info;        if( S_OK == p_output_pin->QueryPinInfo( &info ) )        {            if( info.pFilter ) info.pFilter->Release();            if( info.dir == PINDIR_INPUT )            {                p_output_pin->Release();                continue;            }            msg_Dbg( p_this, "EnumDeviceCaps: trying pin %S", info.achName );        }        AM_MEDIA_TYPE *p_mt;        /*        ** Configure pin with a default compatible media if possible        */        IAMStreamConfig *pSC;        if( SUCCEEDED(p_output_pin->QueryInterface( IID_IAMStreamConfig,                                            (void **)&pSC )) )        {            int piCount, piSize;            if( SUCCEEDED(pSC->GetNumberOfCapabilities(&piCount, &piSize)) )            {                BYTE *pSCC= (BYTE *)CoTaskMemAlloc(piSize);                if( NULL != pSCC )                {                    for( int i=0; i<piCount; ++i )                    {                        if( SUCCEEDED(pSC->GetStreamCaps(i, &p_mt, pSCC)) )                        {                            int i_current_fourcc = GetFourCCFromMediaType( *p_mt );                            if( !i_current_fourcc || (i_fourcc && (i_current_fourcc != i_fourcc)) )                            {                                // incompatible or unrecognized chroma, try next media type                                FreeMediaType( *p_mt );                                CoTaskMemFree( (PVOID)p_mt );                                continue;                            }                            if( MEDIATYPE_Video == p_mt->majortype                                    && FORMAT_VideoInfo == p_mt->formattype )                            {                                VIDEO_STREAM_CONFIG_CAPS *pVSCC = reinterpret_cast<VIDEO_STREAM_CONFIG_CAPS*>(pSCC);                                VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER*>(p_mt->pbFormat);                                if( i_AvgTimePerFrame )                                {                                    if( pVSCC->MinFrameInterval > i_AvgTimePerFrame                                      || i_AvgTimePerFrame > pVSCC->MaxFrameInterval )                                    {                                        // required frame rate not compatible, try next media type                                        FreeMediaType( *p_mt );                                        CoTaskMemFree( (PVOID)p_mt );                                        continue;                                    }                                    pVih->AvgTimePerFrame = i_AvgTimePerFrame;                                }                                if( i_width )                                {                                    if( i_width % pVSCC->OutputGranularityX                                     || pVSCC->MinOutputSize.cx > i_width                                     || i_width > pVSCC->MaxOutputSize.cx )                                    {                                        // required width not compatible, try next media type                                        FreeMediaType( *p_mt );                                        CoTaskMemFree( (PVOID)p_mt );                                        continue;                                    }                                    pVih->bmiHeader.biWidth = i_width;                                }                                if( i_height )                                {                                    if( i_height % pVSCC->OutputGranularityY                                     || pVSCC->MinOutputSize.cy > i_height                                      || i_height > pVSCC->MaxOutputSize.cy )                                    {                                        // required height not compatible, try next media type                                        FreeMediaType( *p_mt );                                        CoTaskMemFree( (PVOID)p_mt );                                        continue;                                    }                                    pVih->bmiHeader.biHeight = i_height;                                }                                // Set the sample size and image size.                                // (Round the image width up to a DWORD boundary.)                                p_mt->lSampleSize = pVih->bmiHeader.biSizeImage =                                     ((pVih->bmiHeader.biWidth + 3) & ~3) *                                    pVih->bmiHeader.biHeight * (pVih->bmiHeader.biBitCount>>3);                                // no cropping, use full video input buffer                                memset(&(pVih->rcSource), 0, sizeof(RECT));                                memset(&(pVih->rcTarget), 0, sizeof(RECT));                                // select this format as default                                if( SUCCEEDED( pSC->SetFormat(p_mt) ) )                                {                                    msg_Dbg( p_this, "EnumDeviceCaps: input pin video format configured");                                    // no need to check any more media types                                     i = piCount;                                }                                else FreeMediaType( *p_mt );                            }                            else if( p_mt->majortype == MEDIATYPE_Audio                                    && p_mt->formattype == FORMAT_WaveFormatEx )                            {                                AUDIO_STREAM_CONFIG_CAPS *pASCC = reinterpret_cast<AUDIO_STREAM_CONFIG_CAPS*>(pSCC);                                WAVEFORMATEX *pWfx = reinterpret_cast<WAVEFORMATEX*>(p_mt->pbFormat);                                if( i_channels )                                {                                    if( i_channels % pASCC->ChannelsGranularity                                     || (unsigned int)i_channels < pASCC->MinimumChannels                                     || (unsigned int)i_channels > pASCC->MaximumChannels )                                    {                                        // required channels not compatible, try next media type                                        FreeMediaType( *p_mt );                                        CoTaskMemFree( (PVOID)p_mt );                                        continue;                                    }                                    pWfx->nChannels = i_channels;                                }                                if( i_samplespersec )                                {                                    if( i_samplespersec % pASCC->BitsPerSampleGranularity                                     || (unsigned int)i_samplespersec < pASCC->MinimumSampleFrequency                                     || (unsigned int)i_samplespersec > pASCC->MaximumSampleFrequency )                                    {                                        // required sampling rate not compatible, try next media type                                        FreeMediaType( *p_mt );                                        CoTaskMemFree( (PVOID)p_mt );                                        continue;                                    }                                    pWfx->nSamplesPerSec = i_samplespersec;                                }                                if( i_bitspersample )                                {                                    if( i_bitspersample % pASCC->BitsPerSampleGranularity                                     || (unsigned int)i_bitspersample < pASCC->MinimumBitsPerSample                                     || (unsigned int)i_bitspersample > pASCC->MaximumBitsPerSample )                                    {                                        // required sample size not compatible, try next media type                                        FreeMediaType( *p_mt );                                        CoTaskMemFree( (PVOID)p_mt );                                        continue;                                    }                                    pWfx->wBitsPerSample = i_bitspersample;                                }                                // select this format as default                                if( SUCCEEDED( pSC->SetFormat(p_mt) ) )                                {                                    msg_Dbg( p_this, "EnumDeviceCaps: input pin default format configured");                                    // no need to check any more media types                                     i = piCount;                                }                            }                            FreeMediaType( *p_mt );                            CoTaskMemFree( (PVOID)p_mt );                        }                    }                    CoTaskMemFree( (LPVOID)pSCC );                }            }            pSC->Release();        }        /*        ** Probe pin for available medias (may be a previously configured one)        */        if( FAILED( p_output_pin->EnumMediaTypes( &p_enummt ) ) )        {            p_output_pin->Release();            continue;        }        while( p_enummt->Next( 1, &p_mt, NULL ) == S_OK )        {            int i_current_fourcc = GetFourCCFromMediaType( *p_mt );            if( i_current_fourcc && p_mt->majortype == MEDIATYPE_Video                && p_mt->formattype == FORMAT_VideoInfo )            {                int i_current_width = ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biWidth;                int i_current_height = ((VIDEOINFOHEADER *)p_mt->pbFormat)->bmiHeader.biHeight;                LONGLONG i_current_atpf = ((VIDEOINFOHEADER *)p_mt->pbFormat)->AvgTimePerFrame;                if( i_current_height < 0 )                    i_current_height = -i_current_height;                 msg_Dbg( p_this, "EnumDeviceCaps: input pin "                         "accepts chroma: %4.4s, width:%i, height:%i, fps:%f",                         (char *)&i_current_fourcc, i_current_width,                         i_current_height, (10000000.0f/((float)i_current_atpf)) );                if( ( !i_fourcc || i_fourcc == i_current_fourcc ) &&                    ( !i_width || i_width == i_current_width ) &&                    ( !i_height || i_height == i_current_height ) &&                    ( !i_AvgTimePerFrame || i_AvgTimePerFrame == i_current_atpf ) &&                    mt_count < mt_max )                {                    /* Pick match */                    mt[mt_count++] = *p_mt;                }                else FreeMediaType( *p_mt );            }            else if( i_current_fourcc && p_mt->majortype == MEDIATYPE_Audio                     && p_mt->formattype == FORMAT_WaveFormatEx)            {                int i_current_channels =                    ((WAVEFORMATEX *)p_mt->pbFormat)->nChannels;                int i_current_samplespersec =                    ((WAVEFORMATEX *)p_mt->pbFormat)->nSamplesPerSec;                int i_current_bitspersample =                    ((WAVEFORMATEX *)p_mt->pbFormat)->wBitsPerSample;                msg_Dbg( p_this, "EnumDeviceCaps: input pin "                         "accepts format: %4.4s, channels:%i, "                         "samples/sec:%i bits/sample:%i",                         (char *)&i_current_fourcc, i_current_channels,                         i_current_samplespersec, i_current_bitspersample);                if( (!i_channels || i_channels == i_current_channels) &&                    (!i_samplespersec ||                     i_samplespersec == i_current_samplespersec) &&                    (!i_bitspersample ||                     i_bitspersample == i_current_bitspersample) &&                    mt_count < mt_max )                {                    /* Pick  match */

⌨️ 快捷键说明

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