VideoPlay.cpp
资源名称:VC++视频传输.rar [点击查看]
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:8k
源码类别:
VC书籍
开发平台:
Visual C++
- // VideoPlay.cpp: implementation of the CVideoPlay class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "VideoPlay.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CVideoPlay::CVideoPlay(HWND hwnd)
- {
- pigb = NULL;
- pimc = NULL;
- pimex = NULL;
- pivw = NULL;
- pmp = NULL;
- pVCap = NULL;
- CappFg = NULL;
- CapPigb = NULL;
- m_hwnd=hwnd;
- }
- CVideoPlay::~CVideoPlay()
- {
- HELPER_RELEASE(pivw);
- HELPER_RELEASE(pigb);
- HELPER_RELEASE(pimc);
- HELPER_RELEASE(pimex);
- HELPER_RELEASE(pmp);
- HELPER_RELEASE(CapPigb);
- HELPER_RELEASE(CappFg);
- HELPER_RELEASE(pVCap);
- }
- //实时捕捉图像的播放
- void CVideoPlay::RealPlay()
- {
- HRESULT hr;
- //创建捕捉过滤器图表
- CHECK_ERROR(CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder,NULL,
- CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder,(void **)&CapPigb),
- "CoCreateInstance Error");
- //创建过滤器图表
- CHECK_ERROR(hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
- IID_IGraphBuilder, (LPVOID *)&CappFg),"Cannot instantiate filtergraph");
- //将捕捉过滤器图表和过滤器图表进行关联
- hr = CapPigb->SetFiltergraph(CappFg);
- if (hr != NOERROR)
- {
- MessageBox(m_hwnd,"Cannot give graph to builder","Error",MB_OK);
- return;
- }
- int uIndex=0;
- //创建视频设备枚举器
- ICreateDevEnum *pCreateDevEnum;
- hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
- IID_ICreateDevEnum, (void**)&pCreateDevEnum);
- //创建一个类型枚举器,指向系统的视频设备列表
- IEnumMoniker *pEm;
- hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
- &pEm, 0);
- HELPER_RELEASE(pCreateDevEnum);
- pEm->Reset();
- ULONG cFetched;
- IMoniker *pM;
- //枚举每个视频设备
- while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
- {
- //生成并初始化管理该设备的过滤器
- hr = pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&pVCap);
- if(pVCap== NULL)
- {
- MessageBox(m_hwnd,"Cannot get the capture filterr","Error",MB_OK);
- return;
- }
- HELPER_RELEASE(pM);
- uIndex++;
- }
- HELPER_RELEASE(pEm);
- if(pVCap)
- hr = CappFg->AddFilter(pVCap, NULL); //添加过滤器到Filter Graph中
- if (hr != NOERROR)
- {
- MessageBox(m_hwnd,"Cannot add vidcap to filtergraph","Error",MB_OK);
- return;
- }
- //连接源过滤器和提交过滤器
- hr = CapPigb->RenderStream(&PIN_CATEGORY_PREVIEW,pVCap,NULL, NULL);
- if (hr != S_OK)
- {
- MessageBox(m_hwnd,"This graph cannot preview properly","Error",MB_OK);
- return;
- }
- //在过滤器图表中查找一个与捕捉有关的接口
- hr = CapPigb->FindInterface(&PIN_CATEGORY_PREVIEW,pVCap,IID_IVideoWindow,(void **)&pivw);
- if (hr != NOERROR)
- {
- MessageBox(m_hwnd,"cannot find Video Window properly","Error",MB_OK);
- return;
- }
- else
- {
- DisplayVideoWin(); //显示视频播放窗口
- }
- //查询数据流控制接口
- hr =CappFg->QueryInterface(IID_IMediaControl, (void **)&pimc);
- if (SUCCEEDED(hr))
- {
- hr = pimc->Run(); //播放视频
- }
- else
- {
- MessageBox(m_hwnd,"Cannot run preview graph","Error",MB_OK);
- return;
- }
- }
- //显示视频播放窗口
- void CVideoPlay::DisplayVideoWin()
- {
- RECT grc;
- if(pivw)
- {
- //设置窗口所有者
- pivw->put_Owner((OAHWND)m_hwnd);
- //设置窗口尺寸
- pivw->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
- //设置窗口位置
- ::GetClientRect(m_hwnd, &grc);;
- pivw->SetWindowPosition(grc.left, grc.top, grc.right, grc.bottom);
- //显示窗口
- pivw->put_Visible(OATRUE);
- }
- }
- //停止播放视频
- void CVideoPlay::StopPlay()
- {
- if(pimc)
- {
- //停止播放视频
- pimc->Stop();
- HELPER_RELEASE(pimc);
- }
- if (pivw)
- {
- //关闭视频播放窗口
- pivw->put_Visible(OAFALSE);
- pivw->put_Owner(NULL);
- HELPER_RELEASE(pivw);
- }
- HELPER_RELEASE(CapPigb);
- HELPER_RELEASE(CappFg);
- HELPER_RELEASE(pVCap);
- }
- //播放视频文件
- void CVideoPlay::PlayFromFile(CString szFile)
- {
- WCHAR wFile[MAX_PATH];
- HRESULT hr;
- MultiByteToWideChar( CP_ACP, 0, szFile.GetBuffer(_MAX_PATH), -1, wFile, MAX_PATH );
- szFile.ReleaseBuffer();
- //创建过滤器图表生成器接口
- CHECK_ERROR(::CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
- IID_IGraphBuilder, (void **)&pigb),"CoCreateInstance Error") ;
- //查询数据流控制接口
- pigb->QueryInterface(IID_IMediaControl, (void **)&pimc);
- //查询过滤器图表事件接口
- hr=pigb->QueryInterface(IID_IMediaEventEx, (void **)&pimex);
- //查询视频播放窗口接口
- pigb->QueryInterface(IID_IVideoWindow, (void **)&pivw);
- //查询数据流位置接口
- hr=pigb->QueryInterface(IID_IMediaPosition, (void**) &pmp);
- //为指定的多媒体文件创建一个过滤器图表进行处理
- hr = pigb->RenderFile(wFile, NULL);
- //得到视频文件的播放时间
- if (SUCCEEDED(hr))
- hr=pmp->get_Duration(&tLength);
- //显示视频播放窗口
- DisplayVideoWin();
- if (SUCCEEDED(hr))
- pimc->Run(); //播放视频
- pimex->SetNotifyWindow((OAHWND)m_hwnd, WM_PLAYOVER, 0);
- }
- int CVideoPlay::PlayOver()
- {
- long evCode,evParam1,evParam2;
- HRESULT hr;
- if(pimex)
- {
- while (SUCCEEDED(pimex->GetEvent(&evCode, &evParam1, &evParam2, 0)))
- { // Spin through the events
- hr = pimex->FreeEventParams(evCode, evParam1, evParam2);
- if (EC_COMPLETE == evCode)
- { // Finished
- if (pivw)
- { // Relinquish ownership (IMPORTANT!) after hiding
- pivw->put_Visible(OAFALSE);
- pivw->put_Owner(NULL);
- HELPER_RELEASE(pivw);
- } // Relinquish ownership (IMPORTANT!) after hiding
- // HELPER_RELEASE(pif);
- HELPER_RELEASE(pigb);
- HELPER_RELEASE(pimc);
- HELPER_RELEASE(pmp);
- HELPER_RELEASE(pimex);
- return 0;
- break;
- }
- }
- }
- return -1;
- }
- //继续播放
- void CVideoPlay::ResumePlay()
- {
- HRESULT hr;
- //得到当前播放位置
- hr = pmp->get_CurrentPosition(&tCurrent);
- if (SUCCEEDED(hr))
- {
- // 如果已在播放文件的最后(播放时间剩下不到1分钟),当前位置回到文件头
- if ((tRemain=tLength - tCurrent) < 1)
- pmp->put_CurrentPosition(0);
- //不在文件尾,当前位置不变
- else
- pmp->put_CurrentPosition(tCurrent);
- }
- if(pimc)
- pimc->Run(); //继续播放文件
- }
- //暂停播放
- void CVideoPlay::PausePlay()
- {
- if(pimc)
- pimc->Pause();
- }
- //搜索视频设备,并返回视频设备名列表
- void CVideoPlay::FindDevice(CStringList &DevName)
- {
- HRESULT hr;
- int uIndex=0;
- //创建一个系统设备枚举器接口
- ICreateDevEnum *pCreateDevEnum;
- hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
- IID_ICreateDevEnum, (void**)&pCreateDevEnum);
- //创建一个类型枚举器,指向系统的视频设备列表
- IEnumMoniker *pEm;
- hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
- &pEm, 0);
- HELPER_RELEASE(pCreateDevEnum);
- if(pEm)
- {
- 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)
- {
- CString achName;
- WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, achName.GetBuffer(50),80,NULL, NULL);
- achName.ReleaseBuffer();
- //将设备名添加到设备名列表末尾
- DevName.AddTail(achName);
- SysFreeString(var.bstrVal);
- }
- HELPER_RELEASE(pBag);
- }
- HELPER_RELEASE(pM);
- uIndex++;
- }
- HELPER_RELEASE(pEm);
- }
- }
- CVideoPlay::CVideoPlay()
- {
- pigb = NULL;
- pimc = NULL;
- pimex = NULL;
- pivw = NULL;
- pmp = NULL;
- pVCap = NULL;
- CappFg = NULL;
- CapPigb = NULL;
- }