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

        前面我们已经使用完美解码这个软件,成功的播放了特殊的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();
     }
};

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值