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

📄 samplecgb.cpp

📁 通用摄像头驱动的应用程序部分
💻 CPP
📖 第 1 页 / 共 3 页
字号:

    return E_FAIL;
}


HRESULT 
ISampleCaptureGraphBuilder::BuildMPEG2Segment(CComPtr<IBaseFilter> pFilter)
{

    if( ! pFilter )
    {
        return E_FAIL;
    }

    
    HRESULT hr = AddMPEG2Demux( );
    if( FAILED( hr ) )
    {
        return hr;
    }

    //
    //  Search a MPEG2 pin on the 
    //  filter
    //
    CComPtr<IPin> pPin;
    hr = FindMPEG2Pin( pFilter, pPin );
    if( SUCCEEDED( hr ) )
    {
        hr = ConnectPin( pPin, pMPEG2Demux_ );
        if( FAILED( hr ) )
        {
            graph_->RemoveFilter( pMPEG2Demux_ );
            return E_FAIL;
        }
        return S_OK;
    }

    //
    //  no pins that streams directly MPEG2 stream
    //
    hr = FindVideoPin( pFilter, pPin );
    if( FAILED( hr ) )
    {
        graph_->RemoveFilter( pMPEG2Demux_ );
        return hr; // no video pin
    }

    hr = RenderToMPEG2Demux( pPin );
    if( FAILED( hr ) )
    {
        graph_->RemoveFilter( pMPEG2Demux_ );
        return hr;
    }

    CComPtr<IPin> pAudioPin;
    hr = FindAudioPin( pFilter, pAudioPin );
    if( FAILED( hr ) )
    {
        //
        //  don't bother with audio
        //
        return S_OK;
    }

    //
    //  try to connect the audio pin directly to encoder
    //  if this is not possible, then try to find an encoder
    //  and connect it to the multiplexer
    //
    ASSERT( pEncoder_ );
    hr = ConnectPin( pAudioPin, pEncoder_ );
    if( FAILED( hr ) )
    {
        hr = ConnectAudioPinToMultiplexer( pAudioPin, pMultiplexer_ );
    }

    return S_OK;
}


HRESULT 
ISampleCaptureGraphBuilder::ConnectAudioPinToMultiplexer( 
                                            CComPtr<IPin> pPin, 
                                            CComPtr<IBaseFilter> pMultiplexer)
{
    if( !pPin || !pMultiplexer )
    {
        return E_INVALIDARG;
    }

    REGPINMEDIUM pinMedium;
    HRESULT hr = GetMedium( pPin, pinMedium );
    if( FAILED( hr ) )
    {
        return hr;
    }

    CComPtr<IBaseFilter> pEncoder;
    CComPtr<IEnumMoniker> pEncoders;

    if( FALSE == ::IsEqualGUID( pinMedium.clsMedium, GUID_NULL ) )
    {
        //
        //  search through encoders category; identify
        //  the encoder using the medium
        //
        hr = GetEncodersByCategory( pEncoders );
        if( FAILED( hr ) )
        {
            return hr;
        }

        hr = FindEncoder( pEncoders, pinMedium, pEncoder );
        if( SUCCEEDED( hr ) )
        {
            hr = graph_->AddFilter( pEncoder, L"Audio Encoder" );
            if( SUCCEEDED( hr ) &&
                SUCCEEDED( ConnectPin( pPin, pEncoder ) ) &&
                SUCCEEDED( ConnectFilters( pEncoder, pMultiplexer ) )
            )
            {
                return S_OK;
            }
        }
        
        
        pEncoders = NULL;
        hr = GetEncodersByEnumerating( pPin, pinMedium, pEncoders );
        if( FAILED( hr ) )
        {
            return hr;
        }

        hr = FindEncoder( pEncoders, pinMedium, pEncoder );
        if( SUCCEEDED( hr ) )
        {
            hr = graph_->AddFilter( pEncoder, L"Audio Encoder" );
            if( SUCCEEDED( hr ) &&
                SUCCEEDED( ConnectPin( pPin, pEncoder ) ) &&
                SUCCEEDED( ConnectFilters( pEncoder, pMultiplexer ) )
            )
            {
                return S_OK;
            }
        }
        return E_FAIL;
    }


    //
    //  Search throgh the codec category 
    //  
    hr = GetEncodersByCategory( pEncoders );
    if( FAILED( hr ) )
    {
        return hr;
    }


    CComPtr<IBaseFilter>    pFilter;
    CComPtr<IMoniker>       pMoniker;
    ULONG                   fetched;
    while( pFilter.Release(), pMoniker.Release(), S_OK == pEncoders->Next( 1, &pMoniker, &fetched ) )
    {
        hr = pMoniker->BindToObject(
            0, 0, IID_IBaseFilter, reinterpret_cast<void **>( &pFilter ) );
        if( FAILED( hr ) )
        {
            continue;
        }

        hr = graph_->AddFilter( pFilter, L"Audio Encoder" );
        if( FAILED( hr ) )
        {
            continue;
        }

        hr = ConnectPin( pPin, pFilter );
        if( FAILED( hr ) )
        {
            graph_->RemoveFilter( pFilter );
            continue;
        }

        hr = ConnectFilters( pFilter, pMultiplexer );
        if( SUCCEEDED( hr ) )
        {
            return S_OK;
        }
        graph_->RemoveFilter( pFilter );
    }

    return E_FAIL;

}


HRESULT 
ISampleCaptureGraphBuilder::CreateVideoPin(
        CComPtr<IMpeg2Demultiplexer> pIMpeg2Demux )
{
    if( !pIMpeg2Demux )
    {
        return E_INVALIDARG;
    }

    AM_MEDIA_TYPE amTypeVideo;
    amTypeVideo.majortype = MEDIATYPE_Video;
    amTypeVideo.subtype = MEDIASUBTYPE_MPEG2_VIDEO;
    amTypeVideo.bFixedSizeSamples = TRUE;
    amTypeVideo.bTemporalCompression = 0;
    amTypeVideo.formattype = FORMAT_MPEG2Video;
    amTypeVideo.pUnk = NULL;
    amTypeVideo.cbFormat = sizeof( Mpeg2ProgramVideo );
    amTypeVideo.pbFormat = Mpeg2ProgramVideo;

    //
    // Create video pin
    //

    CComPtr<IPin> pVideoOutPin;
    HRESULT hr = pIMpeg2Demux->CreateOutputPin( &amTypeVideo, L"MpegVideo", &pVideoOutPin );
    if( FAILED( hr ) )
    {
        return hr;
    }


    CComPtr<IMPEG2StreamIdMap> pIVideoPIDMap;
    hr = pVideoOutPin->QueryInterface( &pIVideoPIDMap );
    if( FAILED( hr ) )
    {
        return hr;
    }

    hr = pIVideoPIDMap->MapStreamId(VidPID_, MPEG2_PROGRAM_ELEMENTARY_STREAM , 0, 0);
    if( FAILED( hr ) )
    {
        return hr;
    }


#ifdef USE_VMR
    //
    //  Get the VMR interface and add it to the graph
    //
    CComPtr<IBaseFilter> pVMR;
    hr = pVMR.CoCreateInstance( CLSID_VideoMixingRenderer );
    if( FAILED( hr ) )
    {
        return hr;
    }

    hr = graph_->AddFilter( pVMR, L"VMR" );
    if( FAILED( hr ) )
    {
        return hr;
    }

    //
    //before rendering the VMR, make the number of streams 1
    //
    CComPtr<IVMRFilterConfig> pConfig;
    hr = pVMR.QueryInterface( &pConfig );
    if( FAILED( hr ) )
    {
        return hr;
    }
    hr = pConfig->SetNumberOfStreams( 1 );
    if( FAILED( hr ) )
    {
        return hr;
    }


    //
    //  Get the input pin from the VMR
    //
    CComPtr<IPin> pInputPin;
    hr = graphBuilder2_->FindPin(
            static_cast<IBaseFilter *>( pVMR ),  
            PINDIR_INPUT, 
            NULL, 
            NULL, 
            TRUE, 
            0, 
            &pInputPin
        );
    if( FAILED( hr ) )
    {

        hr = pIMpeg2Demux->DeleteOutputPin(L"MpegVideo");
        graph_->RemoveFilter( pVMR );
        return hr;
    }

    return graph_->Connect( pVideoOutPin, pInputPin );
#endif

    return hr;
}



HRESULT 
ISampleCaptureGraphBuilder::CreateAudioPin(
            CComPtr<IMpeg2Demultiplexer> pIMpeg2Demux 
    )
{
    if( !pIMpeg2Demux )
    {
        return E_INVALIDARG;
    }

    //
    // for audio: could be Mpeg1, Mpeg2, AC3: if Mpeg1 failed (connect failed) try Mpeg2.if failed tried AC3
    // Audio struct of AC3 can be copied from dev code.
    //
    AM_MEDIA_TYPE amTypeAudio;
    amTypeAudio.majortype   = MEDIATYPE_Audio;
    amTypeAudio.subtype     = MEDIASUBTYPE_MPEG2_AUDIO;
    amTypeAudio.bFixedSizeSamples = TRUE;
    amTypeAudio.bTemporalCompression = 0;
    amTypeAudio.formattype  = FORMAT_WaveFormatEx;
    amTypeAudio.pUnk        = NULL;
    amTypeAudio.cbFormat    = sizeof( MPEG1AudioFormat );
    amTypeAudio.pbFormat    = MPEG1AudioFormat;


    CComPtr<IPin> pAudioOutPin;
    HRESULT hr = pIMpeg2Demux->CreateOutputPin(&amTypeAudio, L"MpegAudio", &pAudioOutPin);
    if( FAILED( hr ) )
    {
        return hr;
    }
    
    CComPtr<IMPEG2StreamIdMap> pIAudioPIDMap;
    hr = pAudioOutPin->QueryInterface( &pIAudioPIDMap );
    if( FAILED( hr ) )
    {
        return hr;
    }

    hr = pIAudioPIDMap->MapStreamId(AudPID_, MPEG2_PROGRAM_ELEMENTARY_STREAM, 0, 0);
    if( FAILED( hr ) )
    {
        return hr;
    }
    
    /*
    //
    //  Get the audio renderer
    //
    CComPtr<IBaseFilter> pAudioRenderer;
    hr = pAudioRenderer.CoCreateInstance( CLSID_AudioRender );
    if( FAILED( hr ) )
    {
        return hr;
    }

    hr = graph_->AddFilter( pAudioRenderer, L"Audio renderer" );
    if( FAILED( hr ) )
    {
        return hr;
    }

    CComPtr<IPin> pInputPin;
    hr = graphBuilder2_->FindPin(
            static_cast<IBaseFilter *>( pAudioRenderer ),  
            PINDIR_INPUT, 
            NULL, 
            NULL, 
            TRUE, 
            0, 
            &pInputPin
        );

    hr = graph_->Connect( pAudioOutPin, pInputPin );
    if(FAILED( hr ))
    {
        hr = pIMpeg2Demux->DeleteOutputPin(L"MpegAudio");
        graph_->RemoveFilter( pAudioRenderer );
    }
*/

    return hr;
}



HRESULT ISampleCaptureGraphBuilder::ConfigureMPEG2Demux( CComPtr<IBaseFilter> pFilter)
{
    
    if( ! pFilter )
    {
        return E_INVALIDARG;
    }

    //
    // Create video pin and render it
    //
    CComPtr<IMpeg2Demultiplexer> pIMpeg2Demux;
    HRESULT hr = pFilter.QueryInterface( &pIMpeg2Demux );
    if( FAILED( hr ) )
    {
        return hr;
    }

    hr = CreateVideoPin( pIMpeg2Demux );
    if( FAILED( hr ) )
    {
        return hr;
    }

    hr = CreateAudioPin( pIMpeg2Demux );
    if( FAILED( hr ) )
    {
        return hr;
    }

    return S_OK;
}


HRESULT 
ISampleCaptureGraphBuilder::ConnectFilters(CComPtr<IBaseFilter> pUpFilter, CComPtr<IBaseFilter> pDownFilter)
{
    if( !pUpFilter || !pDownFilter )
    {
        return E_INVALIDARG;
    }

    // All the need pin & pin enumerator pointers
    CComPtr<IEnumPins>  pEnumUpFilterPins , 
                        pEnumDownFilterPins;

    CComPtr<IPin>   pUpFilterPin , 
                    pDownFilterPin;

    HRESULT hr = S_OK;

    // Get the pin enumerators for both the filtera
    hr = pUpFilter->EnumPins(&pEnumUpFilterPins); 
    if( FAILED( hr ) )
    {
        return hr;
    }

    hr= pDownFilter->EnumPins(&pEnumDownFilterPins); 
    if( FAILED( hr ) )
    {
        return hr;
    }


    // Loop on every pin on the Upstream Filter
    BOOL bConnected = FALSE;
    PIN_DIRECTION pinDir;
    ULONG nFetched = 0;
    while(pUpFilterPin.Release( ), S_OK == pEnumUpFilterPins->Next(1, &pUpFilterPin, &nFetched) )
    {
        // Make sure that we have the output pin of the upstream filter
        hr = pUpFilterPin->QueryDirection( &pinDir );
        if( FAILED( hr ) || PINDIR_INPUT == pinDir )
        {
            continue;
        }

        //
        // I have an output pin; loop on every pin on the Downstream Filter
        //
        while(pDownFilterPin.Release( ), S_OK == pEnumDownFilterPins->Next(1, &pDownFilterPin, &nFetched) )
        {
            hr = pDownFilterPin->QueryDirection( &pinDir );
            if( FAILED( hr ) || PINDIR_OUTPUT == pinDir )
            {
                continue;
            }

            // Try to connect them and exit if u can else loop more until you can
            if(SUCCEEDED(graph_->ConnectDirect(pUpFilterPin, pDownFilterPin, NULL)))
            {
                bConnected = TRUE;
                break;
            }
        }

        hr = pEnumDownFilterPins->Reset();
        if( FAILED( hr ) )
        {
            return hr;
        }
    }

    if( !bConnected )
    {
        return E_FAIL;
    }

    return S_OK;
}


HRESULT 
ISampleCaptureGraphBuilder::ConnectPin( 
                    CComPtr<IPin> pPin, 
                    CComPtr< IBaseFilter > pDownFilter )
{
    if( !pPin || !pDownFilter )
    {
        return E_INVALIDARG;
    }

    PIN_DIRECTION   pinDirection;
    HRESULT hr = pPin->QueryDirection( &pinDirection );
    if( FAILED( hr ) || PINDIR_INPUT == pinDirection )
    {
        return E_FAIL;
    }

    //
    //  Add the filter to the graph
    //
    BOOL bConnected = FALSE;
    ULONG nFetched = 0;
    CComPtr<IPin> pDownFilterPin;

    //
    //  Loop through every input pin from downstream filter
    //  and try to connect the pin
    //  
    CComPtr< IEnumPins > pEnumDownFilterPins;
    hr= pDownFilter->EnumPins( &pEnumDownFilterPins ); 
    if( FAILED( hr ) )
    {
        return hr;
    }

    while(pDownFilterPin.Release( ), S_OK == pEnumDownFilterPins->Next(1, &pDownFilterPin, &nFetched) )
    {
        hr = pDownFilterPin->QueryDirection( &pinDirection );
        if( FAILED( hr ) )
        {
            continue;
        }
        if( PINDIR_OUTPUT == pinDirection )
        {
            continue;
        }

        hr = graph_->ConnectDirect(pPin, pDownFilterPin, NULL);
        if(SUCCEEDED(hr))
        {
            bConnected = TRUE;
            break;
        }
    }

    if( !bConnected )
    {
        graph_->RemoveFilter( pDownFilter );
        return E_FAIL;
    }

    return S_OK;
}

⌨️ 快捷键说明

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