您的位置:首页 > 其它

用DirctShow抓取TS流中的视频图片

2008-08-26 11:49 323 查看
前面我们已经使用完美解码这个软件,成功的播放了特殊的TS流。我们的目的是要对视频进行图像处理,那么我们就必须在播放的TS流中,截取视频图像,然后在对图像的像素进行操作。

我使用的是VMR9,这样效率比较高,截图是视频播放不会出现明显的停顿。视频处理类如下:

class SequenceProcessor
{
BYTE *pbuffer;
IGraphBuilder *pGraph;
IMediaControl *pMediaControl;
IMediaEvent *pEvent;
IVideoWindow *pVidWin;

IBaseFilter *g_filter;
IBaseFilter *g_source;
IEnumPins *g_enumpins;
IFilterGraph2 *g_Graph2;
IVMRFilterConfig9 *g_filterConfig;
IVMRWindowlessControl9 *g_VMR;

public:

BOOL PlayVideo;
IplImage frame;

//使用DirctShowVMR9播放TS。

SequenceProcessor(CString filename, HWND hwnd, bool display = true)
{
CoInitialize(NULL);
pGraph = 0;
if (SUCCEEDED(CoCreateInstance(CLSID_FilterGraph, NULL, //处理的目标视频流
CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
(void **)&pGraph)))
{
if (FAILED(CoCreateInstance(CLSID_VideoMixingRenderer9,NULL, //Filter创建
CLSCTX_INPROC_SERVER,IID_IBaseFilter,
(void **)&g_filter)))
{
AfxMessageBox("Failed to Create the VideoMixingRenderer9!");
}
if (FAILED(pGraph->AddFilter(g_filter, L"VMR9"))) //加入VMR9Filter
{
AfxMessageBox("Failed to Add the VideoMixingRenderer9!");
}
g_filter->QueryInterface(IID_IVMRFilterConfig9, reinterpret_cast<void**>(&g_filterConfig));
g_filterConfig->SetRenderingMode(VMR9Mode_Windowless);
g_filter->QueryInterface(IID_IVMRWindowlessControl9, reinterpret_cast<void**>(&g_VMR));
g_VMR->SetVideoClippingWindow(hwnd);
RECT *clientRect = new RECT;
::GetClientRect(hwnd, clientRect );
g_VMR->SetVideoPosition( NULL, clientRect );
WCHAR *MediaFile = new WCHAR[filename.GetLength()+1];
MultiByteToWideChar(CP_ACP, 0, filename, -1,
MediaFile, filename.GetLength()+1);
pGraph->AddSourceFilter(MediaFile, L"source", &g_source);
pGraph->QueryInterface(IID_IFilterGraph2,reinterpret_cast<void**>(&g_Graph2));
g_Graph2->RenderEx(GetPin(g_source,PINDIR_OUTPUT),AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL);

pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
if (display)
{
pMediaControl->Run();
PlayVideo = TRUE;
}
}
}

//截取视频文件为图像

void Catch()

{
pbuffer = NULL;
long buffersize = 0;
BYTE * pByteTemp = NULL;
BYTE * pTemp = NULL;
if(SUCCEEDED(g_VMR->GetCurrentImage(&pByteTemp)))
{
int i = 0;
frame.width = ((LPBITMAPINFOHEADER)pByteTemp)->biWidth;
frame.height = ((LPBITMAPINFOHEADER)pByteTemp)->biHeight;
buffersize = frame.width * frame.height * 4;
pbuffer = new BYTE[buffersize*3/4];
pTemp = pbuffer;
for(i=0; i<buffersize; i++)
{
if((i+1)%4==0)
{
pByteTemp++;
}
else
{
*(pbuffer) = *(pByteTemp);
pbuffer++;
pByteTemp++;
}
}
pbuffer = pTemp;
frame.widthStep = (frame.width * sizeof( RGBTRIPLE ) + 3) & -4;
cvInitImageHeader(&frame, cvSize(frame.width, frame.height), /
IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4);
cvSetData(&frame, pbuffer, frame.widthStep);
}
}
void FreeCatch()

{

CoTaskMemFree(pbuffer); //处理完成后,释放截取图片所分配的内存

}

void execute()

{

/*图片处理函数*/

}

~SequenceProcessor()
{
SAFE_RELEASE(pMediaControl);
SAFE_RELEASE(g_Graph2);
SAFE_RELEASE(g_source);
SAFE_RELEASE(g_VMR);
SAFE_RELEASE(g_filterConfig);
SAFE_RELEASE(g_filter);
SAFE_RELEASE(pGraph);
CoUninitialize();
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: