我有这个代码用于流式传输到流缓冲区或从流缓冲区流式传输。我已将所有错误检出,以便让代码更易于阅读并查看我正在做的事情。
ICaptureGraphBuilder2* pCaptureGraphBuilder = nullptr;
IGraphBuilder* pGraphCapture = nullptr;
IMediaControl* pControlCapture = nullptr;
IGraphBuilder* pGraphStream = nullptr;
IMediaControl* pControlStream = nullptr;
IBaseFilter* pFilterVideoIn = nullptr;
IBaseFilter* pFilterDVEncode = nullptr;
IBaseFilter* pFilterBufferCapture = nullptr;
IBaseFilter* pFilterBufferStream = nullptr;
// streams
IStreamBufferSink2* pBufferCapture = nullptr;
IStreamBufferSource* pBufferStream = nullptr;
// This sets up the streaming capture
HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pCaptureGraphBuilder));
hr = CoCreateInstance(CLSID_FilterGraph,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pGraphCapture));
hr = pCaptureGraphBuilder->SetFiltergraph(pGraphCapture);
hr = pGraphCapture->QueryInterface(IID_IMediaControl,(VOID**)&pControlCapture);
hr = EnumClassForFilterName(CLSID_VideoInputDeviceCategory,TEXT_CAPTUREDEVICE,&pFilterVideoIn); // This functions creates an instance of the capture device
hr = pGraphCapture->AddFilter(pFilterVideoIn,L"VideoIn");
hr = CoCreateInstance(CLSID_DVVideoEnc,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pFilterDVEncode));
hr = pGraphCapture->AddFilter(pFilterDVEncode,L"DVEncoder");
hr = CoCreateInstance(CLSID_StreamBufferSink,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pBufferCapture));
hr = pBufferCapture->QueryInterface(IID_PPV_ARGS(&pFilterBufferCapture));
hr = pGraphCapture->AddFilter(pFilterBufferCapture,L"BufferSink");
hr = pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pFilterVideoIn,pFilterDVEncode,pFilterBufferCapture);
hr = pBufferCapture->LockProfile(L"C:\\save.tmp");
// now work on the stream in
hr = CoCreateInstance(CLSID_FilterGraph,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pGraphStream));
hr = pGraphStream->QueryInterface(IID_IMediaControl,(VOID**)&pControlStream);
hr = CoCreateInstance(CLSID_StreamBufferSource,nullptr,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pBufferStream));
hr = pBufferStream->QueryInterface(IID_PPV_ARGS(&pFilterBufferStream));
hr = pGraphStream->AddFilter(pFilterBufferStream,L"StreamBufferSource");
hr = pBufferStream->SetStreamSink(pBufferCapture);
IEnumPins* pEnumPins = nullptr;
IPin* pPin = nullptr;
hr = pFilterBufferStream->EnumPins(&pEnumPins);
while(pEnumPins->Next(1,&pPin,nullptr) == S_OK){
hr = pGraphStream->Render(pPin);
pPin->Release();
}
// Which filters are really in the graph
// capture graph
OutputDebugString(L"-----------------------\n");
OutputDebugString(L"StreamIn Graph Filters\n");
OutputDebugString(L"\n");
IEnumFilters* pFilterEnum = nullptr;
IBaseFilter* pFilter = nullptr;
WCHAR name[256] = {0};
hr = pGraphCapture->EnumFilters(&pFilterEnum);
while(pFilterEnum->Next(1,&pFilter,nullptr) == S_OK){
FILTER_INFO fi={0};
pFilter->QueryFilterInfo(&fi);
StringCchPrintf(name,255,L"%s\n",fi.achName);
OutputDebugString(name);
fi.pGraph->Release();
pFilter->Release();
}
OutputDebugString(L"-----------------------\n");
// stream graph
OutputDebugString(L"-----------------------\n");
OutputDebugString(L"StreamSource Graph Filters\n");
OutputDebugString(L"\n");
pFilterEnum = nullptr;
pFilter = nullptr;
hr = pGraphStream->EnumFilters(&pFilterEnum);
while(pFilterEnum->Next(1,&pFilter,nullptr) == S_OK){
FILTER_INFO fi={0};
pFilter->QueryFilterInfo(&fi);
WCHAR name[256]={0};
StringCchPrintf(name,256,L"%s\n",fi.achName);
OutputDebugString(name);
fi.pGraph->Release();
pFilter->Release();
}
OutputDebugString(L"-----------------------\n");
hr = pControlCapture->Run();
hr = pControlStream->Run();
[SNIP]
一旦第二张图开始以
运行,它就会崩溃First-chance exception at 0x000007fef3ce42e0 (qdv.dll) in StreamBuffer.exe: 0xC0000005: Access violation reading location 0x00000000000001c5.
Unhandled exception at 0x000007fef3ce42e0 (qdv.dll) in StreamBuffer.exe: 0xC0000005: Access violation reading location 0x00000000000001c5.
这告诉我qdv.dll里面有些东西不开心。所以我下载了调试符号,以帮助诊断真正发生的事情。
在调用堆栈中,我得到了
qdv.dll!CDVVideoCodec::Receive() + 0x220 bytes
qdv.dll!CTransformInputPin::Receive() + 0x4c bytes
qdv.dll!CBaseInputPin::ReceiveMultiple() + 0x49 bytes
sbe.dll!COutputQueue::ThreadProc() + 0xca bytes
sbe.dll!COutputQueue::InitialThreadProc() + 0x1c bytes
kernel32.dll!BaseThreadInitThunk() + 0xd bytes
ntdll.dll!RtlUserThreadStart() + 0x21 bytes
这告诉我,也许我还没有在DVEncoder的其中一个图表中提供足够的信息。我已经为编解码器尝试了各种设置,但没有任何效果,我在同一个地方遇到同样的错误。
感谢所有帮助。