📄 wincevideods.c
字号:
/*mediastreamer2 library - modular sound and video processing and streamingCopyright (C) 2006 Simon MORLAT (simon.morlat@linphone.org)This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*///#define AYMERIC_TEST#define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA#include "mediastreamer2/msvideo.h"#include "mediastreamer2/msticker.h"#include "mediastreamer2/msv4l.h"#include <aygshell.h>#include "nowebcam.h"#if 0#include <ffmpeg/avcodec.h>#endif#include <dshow.h>#include <dmodshow.h>#include <dmoreg.h>#include <streams.h>//#include <initguid.h>#include "dxfilter.h"#if 0#include <qedit.h>#endif#include <atlbase.h>#include <atlcom.h>typedef struct V4wState{ char dev[512]; int devidx; CComPtr<IGraphBuilder> m_pGraph; CComPtr<ICaptureGraphBuilder2> m_pBuilder; CComPtr<IMediaControl> m_pControl; CDXFilter *m_pDXFilter; CComPtr<IBaseFilter> m_pIDXFilter; CComPtr<IBaseFilter> m_pNullRenderer; CComPtr<IBaseFilter> m_pDeviceFilter; DWORD rotregvalue; MSVideoSize vsize; int pix_fmt; mblk_t *mire[10]; queue_t rq; ms_mutex_t mutex; int frame_ind; int frame_max; float fps; float start_time; int frame_count; bool_t running; bool_t startwith_yuv_bug; /* avoid bug with USB vimicro cards. */}V4wState;static V4wState *s_callback=NULL;static void dummy(void*p){}HRESULT ( Callback)(IMediaSample* pSample, REFERENCE_TIME* sTime, REFERENCE_TIME* eTime, BOOL changed){ BYTE *byte_buf=NULL; mblk_t *buf; V4wState *s = s_callback; if (s==NULL) return S_OK; HRESULT hr = pSample->GetPointer(&byte_buf); if (FAILED(hr)) { return S_OK; } int size = pSample->GetActualDataLength(); if (size>+1000) { buf=allocb(size,0); memcpy(buf->b_wptr, byte_buf, size); if (s->pix_fmt==MS_RGB24) { /* Conversion from top down bottom up (BGR to RGB and flip) */ unsigned long Index,nPixels; unsigned char *blue; unsigned char tmp; short iPixelSize; blue=buf->b_wptr; nPixels=s->vsize.width*s->vsize.height; iPixelSize=24/8; for(Index=0;Index!=nPixels;Index++) // For each pixel { tmp=*blue; *blue=*(blue+2); *(blue+2)=tmp; blue+=iPixelSize; } unsigned char *pLine1, *pLine2; int iLineLen,iIndex; iLineLen=s->vsize.width*iPixelSize; pLine1=buf->b_wptr; pLine2=&(buf->b_wptr)[iLineLen * (s->vsize.height - 1)]; for( ;pLine1<pLine2;pLine2-=(iLineLen*2)) { for(iIndex=0;iIndex!=iLineLen;pLine1++,pLine2++,iIndex++) { tmp=*pLine1; *pLine1=*pLine2; *pLine2=tmp; } } } buf->b_wptr+=size; ms_mutex_lock(&s->mutex); putq(&s->rq, buf); ms_mutex_unlock(&s->mutex); } return S_OK;}HRESULT GetFirstCameraDriver( WCHAR *pwzName ) { HRESULT hr = S_OK; HANDLE handle = NULL; DEVMGR_DEVICE_INFORMATION di; GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, 0x93, 0x3E, 0x4D, 0x7E, 0x3C, 0x86 }; if( pwzName == NULL ) { return E_POINTER; } di.dwSize = sizeof(di); handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di ); if(( handle == NULL ) || ( di.hDevice == NULL )) { return S_FALSE; } StringCchCopy( pwzName, MAX_PATH, di.szLegacyName ); FindClose( handle ); return hr;}struct VAR_LIST{ VARIANT var; VAR_LIST *pNext; BSTR pBSTRName;};class CPropertyBag : public IPropertyBag{ public: CPropertyBag(); ~CPropertyBag(); HRESULT STDMETHODCALLTYPE Read( LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog ); HRESULT STDMETHODCALLTYPE Write( LPCOLESTR pszPropName, VARIANT *pVar ); ULONG STDMETHODCALLTYPE AddRef(); ULONG STDMETHODCALLTYPE Release(); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv); private: ULONG _refCount; VAR_LIST *pVar;};CPropertyBag::CPropertyBag() : _refCount(1), pVar(0){ }CPropertyBag::~CPropertyBag(){ VAR_LIST *pTemp = pVar; HRESULT hr = S_OK; while(pTemp) { VAR_LIST *pDel = pTemp; VariantClear(&pTemp->var); SysFreeString(pTemp->pBSTRName); pTemp = pTemp->pNext; delete pDel; }}HRESULT STDMETHODCALLTYPECPropertyBag::Read(LPCOLESTR pszPropName, VARIANT *_pVar, IErrorLog *pErrorLog){ VAR_LIST *pTemp = pVar; HRESULT hr = S_OK; while(pTemp) { if(0 == wcscmp(pszPropName, pTemp->pBSTRName)) { hr = VariantCopy(_pVar, &pTemp->var); break; } pTemp = pTemp->pNext; } return hr;}HRESULT STDMETHODCALLTYPECPropertyBag::Write(LPCOLESTR pszPropName, VARIANT *_pVar){ HRESULT hr = S_OK; VAR_LIST *pTemp = new VAR_LIST(); ASSERT(pTemp); if( !pTemp ) { return E_OUTOFMEMORY; } VariantInit(&pTemp->var); pTemp->pBSTRName = SysAllocString(pszPropName); pTemp->pNext = pVar; pVar = pTemp; return VariantCopy(&pTemp->var, _pVar);}ULONG STDMETHODCALLTYPE CPropertyBag::AddRef() { return InterlockedIncrement((LONG *)&_refCount);}ULONG STDMETHODCALLTYPE CPropertyBag::Release() { ASSERT(_refCount != 0xFFFFFFFF); ULONG ret = InterlockedDecrement((LONG *)&_refCount); if(!ret) delete this; return ret;}HRESULT STDMETHODCALLTYPE CPropertyBag::QueryInterface(REFIID riid, void** ppv) { if(!ppv) return E_POINTER; if(riid == IID_IPropertyBag) *ppv = static_cast<IPropertyBag*>(this); else return *ppv = 0, E_NOINTERFACE; return AddRef(), S_OK; }static int v4w_open_videodevice(V4wState *s, int format, MSVideoSize *vsize){ // Initialize COM CoInitialize(NULL); // get a Graph HRESULT hr=s->m_pGraph.CoCreateInstance(CLSID_FilterGraph); if(FAILED(hr)) { return -1; } // get a CaptureGraphBuilder2#if !defined(_WIN32_WCE) hr=s->m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2);#else hr=s->m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder);#endif if(FAILED(hr)) { return -2; } // connect capture graph builder with the graph s->m_pBuilder->SetFiltergraph(s->m_pGraph); // get mediacontrol so we can start and stop the filter graph hr=s->m_pGraph.QueryInterface(&(s->m_pControl)); if(FAILED(hr)) { return -3; } // get DXFilter s->m_pDXFilter = new CDXFilter(NULL, &hr, FALSE); if(s->m_pDXFilter==NULL) { return -4; } s->m_pDXFilter->AddRef(); if(FAILED(hr)) { return -4; } CMediaType mt; mt.SetType(&MEDIATYPE_Video); if (format==MS_YUV420P) { GUID m = (GUID)FOURCCMap(MAKEFOURCC('I','4','2','0')); mt.SetSubtype(&m); mt.SetSubtype(&MEDIASUBTYPE_YV12); } else //if (format==MS_RGB24) { mt.SetSubtype(&MEDIASUBTYPE_RGB24); } //mt.SetSubtype(&MEDIASUBTYPE_IYUV); //mt.SetSubtype(&MEDIASUBTYPE_YUYV); //mt.SetSubtype(&MEDIASUBTYPE_RGB24); //mt.SetSampleSize(); mt.formattype = FORMAT_VideoInfo; mt.SetTemporalCompression(FALSE); VIDEOINFO *pvi = (VIDEOINFO *) mt.AllocFormatBuffer(sizeof(VIDEOINFO)); if (NULL == pvi) return E_OUTOFMEMORY; ZeroMemory(pvi, sizeof(VIDEOINFO)); if (format==MS_YUV420P) { pvi->bmiHeader.biCompression = MAKEFOURCC('I','4','2','0'); pvi->bmiHeader.biCompression = MAKEFOURCC('Y','V','1','2'); pvi->bmiHeader.biBitCount = 12; } else { pvi->bmiHeader.biCompression = BI_RGB; pvi->bmiHeader.biBitCount = 24; } pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pvi->bmiHeader.biWidth = vsize->width; pvi->bmiHeader.biHeight = vsize->height; pvi->bmiHeader.biPlanes = 1; pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); pvi->bmiHeader.biClrImportant = 0; mt.SetSampleSize(pvi->bmiHeader.biSizeImage); mt.SetFormat((BYTE*)pvi, sizeof(VIDEOINFO)); hr = s->m_pDXFilter->SetAcceptedMediaType(&mt); if(FAILED(hr)) { return -5; } hr = s->m_pDXFilter->SetCallback(Callback); if(FAILED(hr)) { return -6; } hr = s->m_pDXFilter->QueryInterface(IID_IBaseFilter, (LPVOID *)&s->m_pIDXFilter); if(FAILED(hr)) { return -7; } hr = s->m_pGraph->AddFilter(s->m_pIDXFilter, L"DXFilter Filter"); if(FAILED(hr)) { return -8; }#ifdef WM6 ICreateDevEnum *pCreateDevEnum = NULL; IEnumMoniker *pEnumMoniker = NULL; IMoniker *pMoniker = NULL; ULONG nFetched = 0; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum); if(FAILED(hr)) { return -9; } hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0); if (FAILED(hr) || pEnumMoniker == NULL) { //printf("no device\n"); return -10; } pEnumMoniker->Reset(); hr = pEnumMoniker->Next(1, &pMoniker, &nFetched); if(FAILED(hr) || pMoniker==NULL) { return -11; } hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&s->m_pDeviceFilter ); if(FAILED(hr)) { return -12; } s->m_pGraph->AddFilter(s->m_pDeviceFilter, L"Device Filter"); pMoniker->Release(); pEnumMoniker->Release(); pCreateDevEnum->Release();#else WCHAR wzDeviceName[ MAX_PATH + 1 ]; CComVariant varCamName; CPropertyBag PropBag; CComPtr<IPersistPropertyBag> pPropertyBag; GetFirstCameraDriver(wzDeviceName); hr = s->m_pDeviceFilter.CoCreateInstance( CLSID_VideoCapture ); if (FAILED(hr)) { return -8; } s->m_pDeviceFilter.QueryInterface( &pPropertyBag ); varCamName = wzDeviceName; if(( varCamName.vt == VT_BSTR ) == NULL ) { return E_OUTOFMEMORY; } PropBag.Write( L"VCapName", &varCamName ); pPropertyBag->Load( &PropBag, NULL ); pPropertyBag.Release(); hr = s->m_pGraph->AddFilter( s->m_pDeviceFilter, L"Video capture source" );#endif if (FAILED(hr)) { return -8; } // get null renderer s->m_pNullRenderer = NULL;#if 0 hr=s->m_pNullRenderer.CoCreateInstance(CLSID_NullRenderer); if(FAILED(hr)) { return -13; }#endif if (s->m_pNullRenderer!=NULL) { s->m_pGraph->AddFilter(s->m_pNullRenderer, L"Null Renderer"); } hr = s->m_pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer); if (FAILED(hr)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -