#include <dshow.h>
#include <d3d9.h>
IBaseFilter* CreateTransformFilter()
{
IBaseFilter* pTransformFilter = NULL;
CoCreateInstance(CLSID_LegacyAmFilterCategory, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pTransformFilter);
return pTransformFilter;
}
void ConfigureTransformFilter(IBaseFilter* pTransformFilter)
{
ITransformFilter* pTransform = NULL;
pTransformFilter->QueryInterface(IID_ITransformFilter, (void**)&pTransform);
// 设置输入和输出格式
AM_MEDIA_TYPE mtInput, mtOutput;
ZeroMemory(&mtInput, sizeof(AM_MEDIA_TYPE));
ZeroMemory(&mtOutput, sizeof(AM_MEDIA_TYPE));
mtInput.majortype = MEDIATYPE_Video;
mtInput.subtype = MEDIASUBTYPE_MJPG;
mtInput.formattype = FORMAT_VideoInfo;
mtInput.bFixedSizeSamples = TRUE;
mtInput.lSampleSize = 0;
mtInput.cbFormat = sizeof(VIDEOINFOHEADER);
VIDEOINFOHEADER* pviInput = (VIDEOINFOHEADER*)CoTaskMemAlloc(sizeof(VIDEOINFOHEADER));
ZeroMemory(pviInput, sizeof(VIDEOINFOHEADER));
pviInput->bmiHeader.biWidth = 1920;
pviInput->bmiHeader.biHeight = 1080;
pviInput->bmiHeader.biPlanes = 1;
pviInput->bmiHeader.biBitCount = 24;
pviInput->bmiHeader.biCompression = MAKEFOURCC('M', 'J', 'P', 'G');
mtInput.pbFormat = (BYTE*)pviInput;
mtOutput.majortype = MEDIATYPE_Video;
mtOutput.subtype = MEDIASUBTYPE_RGB24;
mtOutput.formattype = FORMAT_VideoInfo;
mtOutput.bFixedSizeSamples = TRUE;
mtOutput.lSampleSize = 0;
mtOutput.cbFormat = sizeof(VIDEOINFOHEADER);
VIDEOINFOHEADER* pviOutput = (VIDEOINFOHEADER*)CoTaskMemAlloc(sizeof(VIDEOINFOHEADER));
ZeroMemory(pviOutput, sizeof(VIDEOINFOHEADER));
pviOutput->bmiHeader.biWidth = 320;
pviOutput->bmiHeader.biHeight = 240;
pviOutput->bmiHeader.biPlanes = 1;
pviOutput->bmiHeader.biBitCount = 24;
pviOutput->bmiHeader.biCompression = BI_RGB;
mtOutput.pbFormat = (BYTE*)pviOutput;
pTransform->SetMediaType(0, &mtInput);
pTransform->SetMediaType(1, &mtOutput);
CoTaskMemFree(pviInput);
CoTaskMemFree(pviOutput);
pTransform->Release();
}
void ProcessFrame(IMediaSample* pSample)
{
// 获取原始帧数据
BYTE* ptrBuffer = NULL;
pSample->GetPointer(&ptrBuffer);
DWORD bufferSize = pSample->GetSize();
// 创建Filter Graph实例
IGraphBuilder* pGraphBuilder = NULL;
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraphBuilder);
// 创建摄像头捕获的数据流
IBaseFilter* pCaptureFilter = NULL;
pGraphBuilder->AddFilter(pCaptureFilter, L"Capture Filter");
// 创建缩放滤镜
IBaseFilter* pTransformFilter = CreateTransformFilter();
ConfigureTransformFilter(pTransformFilter);
pGraphBuilder->AddFilter(pTransformFilter, L"Transform Filter");
// 连接滤镜
pGraphBuilder->ConnectDirect(GetPin(pCaptureFilter, PINDIR_OUTPUT), GetPin(pTransformFilter, PINDIR_INPUT), NULL);
// 运行图形
IMediaControl* pMediaControl = NULL;
pGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&pMediaControl);
pMediaControl->Run();
// 等待滤镜处理完帧
Sleep(100);
// 从滤镜的输出端口获取缩放后的数据
IPin* pOutputPin = GetPin(pTransformFilter, PINDIR_OUTPUT);
IMemInputPin* pInputPin = NULL;
pOutputPin->QueryInterface(IID_IMemInputPin, (void**)&pInputPin);
BYTE* pScaledBuffer = NULL;
DWORD scaledBufferSize = 0;
pInputPin->Receive(ptrBuffer, bufferSize);
pInputPin->GetBuffer(&pScaledBuffer, &scaledBufferSize);
// 处理缩放后的数据
// ...
// 释放资源
pInputPin->Release();
pMediaControl->Stop();
pGraphBuilder->Release();
}