我用directshow做了个视频采集的程序,因为是初学,东凑西凑终于把预览和采集这块做好了,现在就是差个压缩,用ffdshow进行压缩,编码器已下好,我现在用了一个CSDN上的一个网友给我的压缩FILTER,但是感觉添加上去自己没有添加正确,有点糊,导致现在直接运行程序就报错,代码如下。压缩FilterBOOL CCaptureVideo::MakeEncoder()
{
// if(pEncoderFilter)
// return TRUE; HRESULT hr;
ICreateDevEnum *m_pSysDevEnum = NULL;
IEnumMoniker *pEnumCat = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC,IID_ICreateDevEnum,(void**)&m_pSysDevEnum);
if(FAILED(hr))
{
return FALSE;
}
hr = m_pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory,&pEnumCat,0);
if(FAILED(hr))
{
return FALSE;
}
IMoniker *pMoniker;
ULONG cFetched;
VARIANT varName = {0};
while(pEnumCat->Next(1,&pMoniker,&cFetched) == S_OK)
{
if(!pMoniker)
{
return FALSE;
}
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pPropBag);
if(FAILED(hr))
{
continue;
}
varName.vt = VT_BSTR;
hr = pPropBag->Read(L"FriendlyName",&varName,0);
if(FAILED(hr))
{
continue;
}
CString str(varName.bstrVal);
SysFreeString(varName.bstrVal); if(str == "ffdshow video encoder") //压缩器名称
{
VARIANT varFilterClsid;
varFilterClsid.vt = VT_BSTR;
hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pEncoderFilter);
if(SUCCEEDED(hr))
{
SAFE_RELEASE(pPropBag);
SAFE_RELEASE(pMoniker); hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");
if(hr == NOERROR)
{
return TRUE;
}
}
break;
}
}
return FALSE;
}然后我在Init方法中添加的RenderStream,如下HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd)
{
HRESULT hr;
hr = InitCaptureGraphBuilder();
if (FAILED(hr))
{
AfxMessageBox("Failed to get video interfaces!");
return hr;
}
// Bind Device Filter. We know the device because the id was passed in
if(!BindFilter(iDeviceID, &m_pBF))return S_FALSE;
hr = m_pGB->AddFilter(m_pBF, L"Capture Filter");
// hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, 
// m_pBF, NULL, NULL);
// create a sample grabber// hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );
hr = CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_ISampleGrabber, (void**)&m_pGrabber );
if( !m_pGrabber )
{
AfxMessageBox("Fail to create SampleGrabber, maybe qedit.dll is not registered?");
return hr;
} CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber ); //设置视频格式
AM_MEDIA_TYPE mt; 
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = m_pGrabber->SetMediaType(&mt);
if( FAILED( hr ) )
{
AfxMessageBox("Fail to set media type!");
return hr;
}
hr = m_pGB->AddFilter( pGrabBase, L"Grabber" );
if( FAILED( hr ) )
{
AfxMessageBox("Fail to put sample grabber in graph");
return hr;
}
// try to render preview/capture pin
hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
if( FAILED( hr ) )
{
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
}
if( FAILED( hr ) )
{
AfxMessageBox("Can’t build the graph");
return hr;
}

hr = m_pGrabber->GetConnectedMediaType( &mt );
if ( FAILED( hr) )
{
AfxMessageBox("Failt to read the connected media type");
return hr;
}
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;
mCB.lWidth = vih->bmiHeader.biWidth;
mCB.lHeight = vih->bmiHeader.biHeight;
FreeMediaType(mt);
hr = m_pGrabber->SetBufferSamples( FALSE );
hr = m_pGrabber->SetOneShot( FALSE );
hr = m_pGrabber->SetCallback( &mCB, 1 );
//设置视频捕捉窗口
m_hWnd = hWnd ; 
SetupVideoWindow();
hr = m_pMC->Run();//开始视频捕捉
if(FAILED(hr))
{
AfxMessageBox("Couldn't run the graph!");
return hr;
}
return S_OK;
}我自己原来还有一个枚举设备的EnumDevices,代码如下int CCaptureVideo::EnumDevices(HWND hList)
{
if (!hList)
return -1;
int id = 0;
//枚举视频扑捉设备
ICreateDevEnum *pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (hr != NOERROR)return -1;
CComPtr<IEnumMoniker> pEm;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
if (hr != NOERROR)return -1;
pEm->Reset();
ULONG cFetched;
IMoniker *pM;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
IPropertyBag *pBag;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr)) 
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
if (hr == NOERROR) 
{
TCHAR str[2048]; 
id++;
WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL);
::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str);
SysFreeString(var.bstrVal);
}
pBag->Release();
}
pM->Release();
}
return id;
}然后我现在在OnInitDialog方法中添加
m_cap->MakeEncoder();
m_cap->EnumDevices(pHnd);
m_listCtrl.SetCurSel (0);
int id = m_listCtrl.GetCurSel();          //获取当前选中的视频设备
// m_cap.PreviewImages(id , VideoHnd);     //开始预览视频
m_cap->Init(id,VideoHnd);     //开始预览视频一运行程序就报错,错误定位在
压缩Filter的hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");这句话上面
请大家帮我看看错在哪了,万分感谢

解决方案 »

  1.   


    IBaseFilter* pEncoderFilter;
    IBaseFilter *pMux;//捕获视频为AVI文件

    HWND m_hWnd;
    IGraphBuilder *m_pGB;
    ICaptureGraphBuilder2* m_pCapture;
    IBaseFilter* m_pBF;
    IMediaControl* m_pMC;
    IVideoWindow* m_pVW;
    ISampleGrabber* m_pGrabber;
    int m_IMonikerNum; 
    IMoniker *rgpmVideo[10];
      

  2.   

    call stack中的信息是CCaptureVideo::MakeEncoder() line 481 + 26 bytes
    CTHIRD::OnInitDialog() line 76
    AfxDlgProc(HWND__ * 0x00130736, unsigned int 272, unsigned int 1115950, unsigned int 1115950) line 35 + 14 bytes
    USER32! 77d18734()
    USER32! 77d2413c()
    USER32! 77d23b30()
    USER32! 77d3e599()
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d2a013()
    USER32! 77d2a998()
    CWnd::DefWindowProcA(unsigned int 272, unsigned int 1115950, long 0) line 1011 + 32 bytes
    CWnd::Default() line 258
    CDialog::HandleInitDialog(unsigned int 1115950, unsigned int 1115950) line 624 + 8 bytes
    CWnd::OnWndMsg(unsigned int 272, unsigned int 1115950, long 0, long * 0x0012ea80) line 1826 + 17 bytes
    CWnd::WindowProc(unsigned int 272, unsigned int 1115950, long 0) line 1596 + 30 bytes
    AfxCallWndProc(CWnd * 0x0012fa8c {CTHIRD hWnd=???}, HWND__ * 0x00130736, unsigned int 272, unsigned int 1115950, long 0) line 215 + 26 bytes
    AfxWndProc(HWND__ * 0x00130736, unsigned int 272, unsigned int 1115950, long 0) line 379
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d2a013()
    USER32! 77d2a998()
    SKINPPWTL! 1004140a()
    SKINPPWTL! 1004143d()
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d28ea0()
    USER32! 77d28eec()
    NTDLL! 7c92e473()
    USER32! 77d2651a()
    USER32! 77d2683e()
    USER32! 77d39b43()
    CWnd::CreateDlgIndirect(const DLGTEMPLATE * 0x00185828, CWnd * 0x0012fa30 {CVCCaptureDlg hWnd=???}, HINSTANCE__ * 0x00400000) line 327 + 36 bytes
    CDialog::CreateIndirect(const DLGTEMPLATE * 0x0062f510, CWnd * 0x0012fa30 {CVCCaptureDlg hWnd=???}, void * 0x00000000, HINSTANCE__ * 0x00400000) line 223
    CDialog::CreateIndirect(void * 0x0062f510, CWnd * 0x00000000 {CWnd hWnd=???}, HINSTANCE__ * 0x00400000) line 200 + 22 bytes
    CDialog::Create(const char * 0x00000083, CWnd * 0x00000000 {CWnd hWnd=???}) line 182 + 20 bytes
    CDialog::Create(unsigned int 131, CWnd * 0x00000000 {CWnd hWnd=???}) line 543 + 29 bytes
    CVCCaptureDlg::OnInitDialog() line 131
    AfxDlgProc(HWND__ * 0x000803d4, unsigned int 272, unsigned int 656320, unsigned int 656320) line 35 + 14 bytes
    USER32! 77d18734()
    USER32! 77d2413c()
    USER32! 77d23b30()
    USER32! 77d3e599()
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d2a013()
    USER32! 77d2a998()
    CWnd::DefWindowProcA(unsigned int 272, unsigned int 656320, long 0) line 1011 + 32 bytes
    CWnd::Default() line 258
    CDialog::HandleInitDialog(unsigned int 656320, unsigned int 656320) line 624 + 8 bytes
    CWnd::OnWndMsg(unsigned int 272, unsigned int 656320, long 0, long * 0x0012f440) line 1826 + 17 bytes
    CWnd::WindowProc(unsigned int 272, unsigned int 656320, long 0) line 1596 + 30 bytes
    AfxCallWndProc(CWnd * 0x0012fa30 {CVCCaptureDlg hWnd=???}, HWND__ * 0x000803d4, unsigned int 272, unsigned int 656320, long 0) line 215 + 26 bytes
    AfxWndProc(HWND__ * 0x000803d4, unsigned int 272, unsigned int 656320, long 0) line 379
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d2a013()
    USER32! 77d2a998()
    SKINPPWTL! 1004140a()
    SKINPPWTL! 1004143d()
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d28ea0()
    USER32! 77d28eec()
    NTDLL! 7c92e473()
    USER32! 77d2651a()
    USER32! 77d2683e()
    USER32! 77d39b43()
    CWnd::CreateDlgIndirect(const DLGTEMPLATE * 0x0062ee28, CWnd * 0x00000000 {CWnd hWnd=???}, HINSTANCE__ * 0x00400000) line 327 + 36 bytes
    CDialog::DoModal() line 531 + 32 bytes
    CVCCaptureApp::InitInstance() line 78 + 11 bytes
    AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f1c, int 1) line 39 + 11 bytes
    WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f1c, int 1) line 30
    WinMainCRTStartup() line 198 + 54 bytes
    KERNEL32! 7c817077()
    指向的地方就是 hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");
      

  3.   

    我现在修改了下程序,没有错误了,可是录制不了,每次都是64KB,而且点击录制就卡在那,点停止后释放掉指针什么的,打开录制的视频看就播放不了,我的程序改成了
    在压缩Filter中BOOL CCaptureVideo::MakeEncoder()
    {
    // if(pEncoderFilter)
    // return TRUE; HRESULT hr;
    ICreateDevEnum *m_pSysDevEnum = NULL;
    IEnumMoniker *pEnumCat = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC,IID_ICreateDevEnum,(void**)&m_pSysDevEnum); if(FAILED(hr))
    {
    return FALSE;
    }

    hr = m_pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory,&pEnumCat,0);
    if(FAILED(hr))
    {
    return FALSE;
    }
    IMoniker *pMoniker;
    ULONG cFetched;
    VARIANT varName = {0};
    while(pEnumCat->Next(1,&pMoniker,&cFetched) == S_OK)
    {
    if(!pMoniker)
    {
    return FALSE;
    }
    IPropertyBag *pPropBag;
    hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pPropBag);
    if(FAILED(hr))
    {
    continue;
    }
    varName.vt = VT_BSTR;
    hr = pPropBag->Read(L"FriendlyName",&varName,0);
    if(FAILED(hr))
    {
    continue;
    }
    CString str(varName.bstrVal);
    SysFreeString(varName.bstrVal); if(str == "ffdshow video encoder") //压缩器名称
    {
    VARIANT varFilterClsid;
    varFilterClsid.vt = VT_BSTR;
    hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pEncoderFilter);
    if(SUCCEEDED(hr))
    {
    SAFE_RELEASE(pPropBag);
    SAFE_RELEASE(pMoniker);

    // hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");
    // if(hr == NOERROR)
    // {

    return TRUE;

    // }
    }
    break;
    }
    }
    return FALSE;
    }把这个添加过滤器的话注释掉了
    然后在Init方法中加上HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd)
    {
    HRESULT hr;
    hr = InitCaptureGraphBuilder();
    if (FAILED(hr))
    {
    AfxMessageBox("Failed to get video interfaces!");
    return hr;
    }
    if(MakeEncoder())
    {
    hr = m_pGB->AddFilter(pEncoderFilter, L"EncodeFilter");
    }

    // Bind Device Filter. We know the device because the id was passed in
    if(!BindFilter(iDeviceID, &m_pBF))return S_FALSE;
    hr = m_pGB->AddFilter(m_pBF, L"Capture Filter");
    // hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, 
    // m_pBF, NULL, NULL);
    // create a sample grabber// hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );
    hr = CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_ISampleGrabber, (void**)&m_pGrabber );
    if( !m_pGrabber )
    {
    AfxMessageBox("Fail to create SampleGrabber, maybe qedit.dll is not registered?");
    return hr;
    } CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber ); //设置视频格式
    AM_MEDIA_TYPE mt; 
    ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
    mt.majortype = MEDIATYPE_Video;
    mt.subtype = MEDIASUBTYPE_RGB24;
    hr = m_pGrabber->SetMediaType(&mt);
    if( FAILED( hr ) )
    {
    AfxMessageBox("Fail to set media type!");
    return hr;
    }
    hr = m_pGB->AddFilter( pGrabBase, L"Grabber" );
    if( FAILED( hr ) )
    {
    AfxMessageBox("Fail to put sample grabber in graph");
    return hr;
    }
    // try to render preview/capture pin
    hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
    if( FAILED( hr ) )
    {
    hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
    // hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
    }
    if( FAILED( hr ) )
    {
    AfxMessageBox("Can’t build the graph");
    return hr;
    }

    hr = m_pGrabber->GetConnectedMediaType( &mt );
    if ( FAILED( hr) )
    {
    AfxMessageBox("Failt to read the connected media type");
    return hr;
    }
    VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;
    mCB.lWidth = vih->bmiHeader.biWidth;
    mCB.lHeight = vih->bmiHeader.biHeight;
    FreeMediaType(mt);
    hr = m_pGrabber->SetBufferSamples( FALSE );
    hr = m_pGrabber->SetOneShot( FALSE );
    hr = m_pGrabber->SetCallback( &mCB, 1 );
    //设置视频捕捉窗口
    m_hWnd = hWnd ; 
    SetupVideoWindow();
    hr = m_pMC->Run();//开始视频捕捉
    if(FAILED(hr))
    {
    AfxMessageBox("Couldn't run the graph!");
    return hr;
    }
    return S_OK;
    }
    在这里做个判断然后加上,我在调试的时候会成功的进入if里面。
    然后在压缩方法那里我是这样写的HRESULT CCaptureVideo::CaptureImagesToAVI(CString inFileName)
    {
    HRESULT hr=0;
    m_pMC->Stop();
    //先停止视频//设置文件名,注意第二个参数的类型
    hr = m_pCapture->SetOutputFileName( &MEDIASUBTYPE_Avi,inFileName.AllocSysString(), &pMux, NULL );
    //渲染媒体,链接所有滤波器
    // hr = m_pCapture->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pBF, NULL, pMux );
    hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
    pMux->Release();
    m_pMC->Run();//回复视频
    return hr;
    }我把AddFilter方法写在这里,就不会报错了,可是好像只压缩一帧就不压缩了,诚心的请求各位大大帮帮我,都快急死了呢,谢谢了
      

  4.   

    恩,好的好的,明白,我现在因为对directshow不是很懂,初学者,都是在凑功能,我现在怀疑我是在调用压缩filter时候搞错顺序或是没有写好这块,因为我之前只是先做了预览和采集,写了一个EnumDevices方法,用来遍历设备的,后来我是想临时加压缩功能,已经装好ffdshow,然后网上朋友给了个EncoderFilter的压缩过滤器,但是它那个方法里面也有设备遍历的函数,就是上面的MakeEncoder()代码,里面也有 hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC,IID_ICreateDevEnum,(void**)&m_pSysDevEnum);
        if(FAILED(hr))
        {
            return FALSE;
        }
        hr = m_pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory,&pEnumCat,0);
        if(FAILED(hr))
        {
            return FALSE;
        }
        IMoniker *pMoniker;
        ULONG cFetched;
        VARIANT varName = {0};
        while(pEnumCat->Next(1,&pMoniker,&cFetched) == S_OK)这样的遍历代码,但是我原来的EnumDevice方法里面也有这样类似的int CCaptureVideo::EnumDevices(HWND hList)
    {
    if (!hList)
    return -1;
    int id = 0;
    //枚举视频扑捉设备
    ICreateDevEnum *pCreateDevEnum;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
    if (hr != NOERROR)return -1;
    CComPtr<IEnumMoniker> pEm;
    hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);
    if (hr != NOERROR)return -1;
    pEm->Reset();
    ULONG cFetched;
    IMoniker *pM;
    while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
    {我就不知道该怎么加上这个filter了,我把它这个MakeEncoder()写成了一个方法,然后在Init这个方法里添加AddFilter,
    这样HRESULT CCaptureVideo::Init(int iDeviceID, HWND hWnd)
    {
    HRESULT hr;
    hr = InitCaptureGraphBuilder();
    if (FAILED(hr))
    {
    AfxMessageBox("Failed to get video interfaces!");
    return hr;
    }
    if(MakeEncoder())
    {
    hr = m_pGB->AddFilter(pEncoderFilter, L"EncodeFilter");
    }然后在开始采集的时候,就是点击录制按钮的地方用的是这样的代码HRESULT CCaptureVideo::CaptureImagesToAVI(CString inFileName)
    {
    HRESULT hr=0;
    m_pMC->Stop();
    //先停止视频//设置文件名,注意第二个参数的类型
    hr = m_pCapture->SetOutputFileName( &MEDIASUBTYPE_Avi,inFileName.AllocSysString(), &pMux, NULL );
    //渲染媒体,链接所有滤波器
    // hr = m_pCapture->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pBF, NULL, pMux );
    hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
    pMux->Release();
    m_pMC->Run();//回复视频
    return hr;
    }红色的就是后来添加的,蓝色的就是没有添加压缩的,但是这样添加上去以后,可以预览,然后点击录制,马上影像就卡在那不动,我看存放录制文件的文件夹也生生成了AVI,但是都是64KB,而且不能播放
      

  5.   

    我现在的问题就有点像是在录制方法那里 HRESULT hr=0;
    m_pMC->Stop();
    //先停止视频//设置文件名,注意第二个参数的类型
    hr = m_pCapture->SetOutputFileName( &MEDIASUBTYPE_Avi,inFileName.AllocSysString(), &pMux, NULL );
    //渲染媒体,链接所有滤波器
    // hr = m_pCapture->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pBF, NULL, pMux );
    hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);
    pMux->Release();
    m_pMC->Run();//回复视频
    return hr;点击录制后,它先调用m_pMC->Stop();,然后视频就不动了,本来应该在开始采集的时候会继续调用m_pMC->Run();//回复视频的,但是应该是在hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,m_pBF,pEncoderFilter,pMux);这个地方出了问题,导致没有继续往下走,真的快糊掉了,希望高手能帮帮我
      

  6.   

    我用graphedit弄了个图出来,这样在graphedit中运行是好的,各位能教我如何实现下面这个图的程序么,我是真的ds初学,老板只要我在短时间凑出功能,我快郁闷死了,大家帮帮我吧
      

  7.   

    又有新进展,我的压缩Filter按照msdn上面稍微改了下,现在是这样HRESULT hr;
    ICreateDevEnum *pSysDevEnum = NULL;
    hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
    IID_ICreateDevEnum, (void **)&pSysDevEnum);

    // Obtain a class enumerator for the video compressor category.
    IEnumMoniker *pEnumCat = NULL;
    hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);

    if (hr == S_OK) 
    {
    // Enumerate the monikers.
    IMoniker *pMoniker;
    ULONG cFetched;
    while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
    {
    IPropertyBag *pPropBag;
    pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);

    // To retrieve the friendly name of the filter, do the following:
    VARIANT varName;
    VariantInit(&varName);

    hr = pPropBag->Read(L"FriendlyName", &varName, 0);
    if (SUCCEEDED(hr))
    {
    CString str(varName.bstrVal);
    SysFreeString(varName.bstrVal);
    if(str == "Microsoft MPEG-4 Video Codec V2")
    {
    hr = pMoniker->BindToObject(0,0,IID_IBaseFilter,(void**)&pEncoderFilter);
    if(hr == S_OK)
    {
    hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");
    }
    }

    }
    VariantClear(&varName);

    // To create an instance of the filter, do the following:
    IBaseFilter *pFilter;
    pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter);
    // Now add the filter to the graph. Remember to release pFilter later.

    // Clean up.
    pPropBag->Release();
    pMoniker->Release();
    }
    pEnumCat->Release();
    }
    pSysDevEnum->Release();
    但是每次运行到hr = m_pGB->AddFilter(pEncoderFilter,L"EncodeFilter");这句话的时候就会出错,弹出的错误是
    ‘0x004060614f’指令引用的‘0x00000000’内存,该内存不能为'read'.