织梦CMS - 轻松建站从此开始!

罗索

directshow和vfw采集并转发视频数据的接口(2)

落鹤生 发布于 2011-02-28 15:24 点击:次 
0, // src :left 0, // src :top IMAGE_WIDTH, // src : width IMAGE_HEIGHT, // src : height DDF_SAME_DRAW // use prev params.... ); } // 设置通信接口 void VideoCapture::SetCommClient(CCommClient *p
TAG:

        0,                     // src :left

        0,                     // src :top

        IMAGE_WIDTH,                 // src : width

        IMAGE_HEIGHT,                 // src : height

        DDF_SAME_DRAW             // use prev params....

        );

}

// 设置通信接口

void VideoCapture::SetCommClient(CCommClient *pClient)

{

    m_pCommClient    = pClient;

// 回放远程视频

void VideoCapture::DrawRemoteScreen(char *data, UINT size, HDC hScreenDC)

{

    int            iErrorCode;

    int            iDataSize;

    u_char*        upData;

    iDataSize    = size;

    upData        = (u_char*)data;

    iErrorCode    = DecompressFrame( upData, iDataSize, rgbdata, buffersize );

    if ( iErrorCode == 0 ) return;

    ::DrawDibDraw(

        m_hdib,

        hScreenDC,

        0,        // dest : left pos

        0,        // dest : top pos

        -1,                     // don't zoom x

        -1,                     // don't zoom y

        &m_bmpinfo.bmiHeader,             // bmp header info

        rgbdata,                     // bmp data

        0,                     // src :left

        0,                     // src :top

        IMAGE_WIDTH,                 // src : width

        IMAGE_HEIGHT,                 // src : height

        DDF_SAME_DRAW             // use prev params....

        );

}

/********************此文可以被转发,但请转发者保留作者的署名权
****李浩
****msn:lihao_nx@hotmail.com
****
****email:lihaoyxj@gmail.com
****出处:lihaoyxj.cublog.cn
****from:http://blog.csdn.net/lihao_ningxia
*****************/

 

//DSHOW

 

//head file

 

// CCaptureVideo视频捕捉类头文件

 

/////////////////////////////////////////////////////////////////////

 

#if !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_)

 

#define AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_

 

/////////////////////////////////////////////////////////////////////

 

// CaptureVideo.h : header file

 

/////////////////////////////////////////////////////////////////////

 

#if _MSC_VER > 1000

 

#pragma once

 

#endif // _MSC_VER > 1000

 

#include <atlbase.h>

 

#include <windows.h>

 

#include <dshow.h>

 

#pragma include_alias( "dxtrans.h", "qedit.h" )

 

#define __IDxtCompositor_INTERFACE_DEFINED__

 

#define __IDxtAlphaSetter_INTERFACE_DEFINED__

 

#define __IDxtJpeg_INTERFACE_DEFINED__

 

#define __IDxtKey_INTERFACE_DEFINED__

 

#include <Qedit.h> // ISampleGrabberCB

 

#ifndef SAFE_RELEASE

 

#define SAFE_RELEASE( x ) \

 

if ( NULL != x ) \

 

{ \

 

  x->Release( ); \

 

  x = NULL; \

 

}

 

#endif

 

class CCamFrameHandler {

 

public:

 

    virtual void CamFrameData(double dblSampleTime, BYTE * pBuffer, long lBufferSize) = 0 ;

 

};

 

class CSampleGrabberCB : public ISampleGrabberCB

 

{

 

public:

 

    long                   lWidth ;

 

    long                   lHeight ;

 

    CCamFrameHandler    *  frame_handler ;

 

    BOOL                   bGrabVideo ;

 

public:

 

    CSampleGrabberCB(){

 

        lWidth = 0 ;

 

        lHeight = 0 ;

 

        bGrabVideo = FALSE ;

 

        frame_handler = NULL ;

 

    }

 

    STDMETHODIMP_(ULONG) AddRef() { return 2; }

 

    STDMETHODIMP_(ULONG) Release() { return 1; }

 

    STDMETHODIMP QueryInterface(REFIID riid, void ** ppv) {

 

        if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ){

 

            *ppv = (void *) static_cast<ISampleGrabberCB*> ( this );

 

            return NOERROR;

 

        }

 

        return E_NOINTERFACE;

 

    }

 

    STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )  {

 

        return 0;

 

    }

 

    STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize ){

 

        if (!pBuffer) return E_POINTER;

 

        if(bGrabVideo && frame_handler) frame_handler->CamFrameData(dblSampleTime, pBuffer, lBufferSize) ;

 

        return 0;

 

    }

 

};

 

class CCaptureVideo : public CWnd

 

{

 

    friend class CSampleGrabberCB;

 

  public:

 

    void GrabVideoFrames(BOOL bGrabVideoFrames, CCamFrameHandler * frame_handler);

 

    HRESULT Start(int iDeviceID,HWND hWnd);

 

    HRESULT Stop();

 

    int EnumDevices(HWND hList);

 

    CCaptureVideo();

 

    virtual ~CCaptureVideo();

 

  private:

 

    HWND                    m_hWnd;

 

    IGraphBuilder *            m_pGB;

 

    ICaptureGraphBuilder2*    m_pCapture;

 

    IBaseFilter*            m_pBF;

 

    IMediaControl*            m_pMC;

 

    IVideoWindow*            m_pVW;

 

    ISampleGrabber*            m_pGrabber;

 

  protected:

 

    void FreeMediaType(AM_MEDIA_TYPE& mt);

 

    bool BindFilter(int deviceId, IBaseFilter **pFilter);

 

    void ResizeVideoWindow();

 

    HRESULT SetupVideoWindow();

 

    HRESULT InitCaptureGraphBuilder();

 

};

 

#endif // !defined(AFX_CAPTUREVIDEO_H__F5345AA4_A39F_4B07_B843_3D87C4287AA0__INCLUDED_)

 

//cpp file

 

//-------------------------------------------------------------------

 

// CCaptureVideo视频捕捉类实现文件CaptureVideo.cpp

 

//-------------------------------------------------------------------

 

// CaptureVideo.cpp: implementation of the CCaptureVideo class.

 

//

 

/////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

 

#include "CaptureVideo.h"

 

#ifdef _DEBUG

 

#undef THIS_FILE

 

static char THIS_FILE[]=__FILE__;

 

#define new DEBUG_NEW

 

#endif

 

CSampleGrabberCB mCB;

 

//////////////////////////////////////////////////////////////////////

 

// Construction/Destruction

 

//////////////////////////////////////////////////////////////////////

 

CCaptureVideo::CCaptureVideo()

 

{

 

  //COM Library Intialization

 

  if(FAILED(CoInitialize(NULL))) /*, COINIT_APARTMENTTHREADED)))*/

 

  {

 

    AfxMessageBox("CoInitialize Failed!\r\n");

 

    return;

 

  }

 

  m_hWnd = NULL;

 

  m_pVW = NULL;

 

  m_pMC = NULL;

 

  m_pGB = NULL;

 

  m_pBF = NULL;

 

  m_pGrabber = NULL;

 

  m_pCapture = NULL;

 

}

 

CCaptureVideo::~CCaptureVideo()

 

{

 

  // Stop media playback

 

    // Stop media playback

 

    if(m_pMC)m_pMC->StopWhenReady();

 

    if(m_pVW){

 

        m_pVW->put_Visible(OAFALSE);

 

        m_pVW->put_Owner(NULL);

 

    }

 

    SAFE_RELEASE(m_pMC);

 

    SAFE_RELEASE(m_pVW);

 

    SAFE_RELEASE(m_pGB);

 

    SAFE_RELEASE(m_pBF);

 

    SAFE_RELEASE(m_pGrabber);

 

    SAFE_RELEASE(m_pCapture);

 

    CoUninitialize() ;

 

}

 

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;

 

}

 

HRESULT CCaptureVideo::Stop()

 

{

 

    // Stop media playback

 

    if(m_pMC)m_pMC->StopWhenReady();

 

    if(m_pVW){

 

        m_pVW->put_Visible(OAFALSE);

 

        m_pVW->put_Owner(NULL);

 

    }

 

    SAFE_RELEASE(m_pMC);

 

    SAFE_RELEASE(m_pVW);

 

    SAFE_RELEASE(m_pGB);

 

    SAFE_RELEASE(m_pBF);

 

    SAFE_RELEASE(m_pGrabber);

 

    SAFE_RELEASE(m_pCapture);

 

    return S_OK ;

 

}

 

HRESULT CCaptureVideo::Start(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 = CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_ISampleGrabber, (void**)&m_pGrabber );

 

  if(FAILED(hr)){

 

    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_IYUV;// MEDIASUBTYPE_RGB24; // 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);

 

    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;

 

  mCB.bGrabVideo = FALSE ;

 

  mCB.frame_handler = NULL ;

 

  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;

 

}

 

bool CCaptureVideo::BindFilter(int deviceId, IBaseFilter **pFilter)

 

{

 

  if (deviceId < 0)

 

  return false;

 

  // enumerate all video capture devices

 

  CComPtr<ICreateDevEnum> pCreateDevEnum;

 

  HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,

 

IID_ICreateDevEnum, (void**)&pCreateDevEnum);

 

  if (hr != NOERROR)

 

  {

 

    return false;

 

  }

 

  CComPtr<IEnumMoniker> pEm;

 

  hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);

 

  if (hr != NOERROR)

 

  {

 

    return false;

 

  }

 

  pEm->Reset();

 

  ULONG cFetched;

 

  IMoniker *pM;

 

  int index = 0;

 

  while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId)

 

  {

 

    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)

 

      {

 

        if (index == deviceId)

 

        {

 

          pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);

 

        }

 

        SysFreeString(var.bstrVal);

 

      }

 

      pBag->Release();

 

    }

 

    pM->Release();

 

    index++;

 

  }

 

  return true;

 

}

 

HRESULT CCaptureVideo::InitCaptureGraphBuilder()

 

{

 

  HRESULT hr;

 

  // 创建IGraphBuilder接口

 

  hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB); (lihao_ningxia)

本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201102/10982.html]
本文出处:CSDN博客 作者:lihao_ningxia
顶一下
(0)
0%
踩一下
(1)
100%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容