⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winvideods.c

📁 linphone 网络电话 linphone 网络电话 linphone 网络电话
💻 C
📖 第 1 页 / 共 2 页
字号:
/*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 UNICODE#define AYMERIC_TEST#define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA#include "mediastreamer2/msvideo.h"#include "mediastreamer2/msticker.h"#include "mediastreamer2/msv4l.h"#include "nowebcam.h"#include <ffmpeg/avcodec.h>#include <dshow.h>#include <dmodshow.h>#include <dmoreg.h>#include <streams.h>#include <initguid.h>#include "dxfilter.h"#include <qedit.h>#include <atlbase.h>#include <atlcom.h>HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister);void RemoveGraphFromRot(DWORD pdwRegister);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;}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;}int try_format(V4wState *s, int format){    HRESULT hr=S_OK;    IEnumPins *pEnum=0;    ULONG ulFound;    IPin *pPin;	GUID guid_format;	DWORD biCompression;	DWORD biBitCount;	// Verify input    if (!s->m_pDeviceFilter)        return -1;	if (format == MS_YUV420P)		guid_format = (GUID)FOURCCMap(MAKEFOURCC('I','4','2','0'));	else if (format == MS_YUYV)		guid_format = MEDIASUBTYPE_YUYV;	else if (format == MS_UYVY)		guid_format = MEDIASUBTYPE_UYVY;	else if (format == MS_RGB24)		guid_format = MEDIASUBTYPE_RGB24;	else if (format == MS_YUY2)		guid_format = MEDIASUBTYPE_YUY2;	if (format == MS_YUV420P)		biCompression = MAKEFOURCC('I','4','2','0');	else if (format == MS_YUYV)		biCompression = MAKEFOURCC('Y','U','Y','V');	else if (format == MS_UYVY)		biCompression = MAKEFOURCC('U','Y','V','Y');	else if (format == MS_RGB24)		biCompression = BI_RGB;	else if (format == MS_YUY2)		biCompression = MAKEFOURCC('Y','U','Y','2');		if (format == MS_YUV420P)		biBitCount = 12;	else if (format == MS_YUYV)		biBitCount = 16;	else if (format == MS_UYVY)		biBitCount = 16;	else if (format == MS_RGB24)		biBitCount = 24;	else if (format == MS_YUY2)		biBitCount = 16;	    // Get pin enumerator	hr = s->m_pDeviceFilter->EnumPins(&pEnum);    if(FAILED(hr))         return -1;    pEnum->Reset();    // Count every pin on the filter    while(S_OK == pEnum->Next(1, &pPin, &ulFound))    {        PIN_DIRECTION pindir = (PIN_DIRECTION) 3;        hr = pPin->QueryDirection(&pindir);        if(pindir != PINDIR_INPUT)		{			IEnumMediaTypes *ppEnum;		    ULONG ulFound2;			hr = pPin->EnumMediaTypes(&ppEnum);			if(FAILED(hr)) 				continue;			AM_MEDIA_TYPE *ppMediaTypes;			while(S_OK == ppEnum->Next(1, &ppMediaTypes, &ulFound2))			{				if (ppMediaTypes->formattype != FORMAT_VideoInfo)					continue;				if (ppMediaTypes->majortype != MEDIATYPE_Video)					continue;				if (ppMediaTypes->subtype != guid_format)					continue;				VIDEOINFO *pvi = (VIDEOINFO *)ppMediaTypes->pbFormat;				if (pvi->bmiHeader.biCompression!=biCompression)					continue;				if (pvi->bmiHeader.biBitCount!=biBitCount)					continue;		        pPin->Release();			    pEnum->Release();				return 0;			}		}        pPin->Release();    }    pEnum->Release();    return -1;}int try_format_size(V4wState *s, int format, int width, int height){    HRESULT hr=S_OK;    IEnumPins *pEnum=0;    ULONG ulFound;    IPin *pPin;	GUID guid_format;	DWORD biCompression;	DWORD biBitCount;	// Verify input    if (!s->m_pDeviceFilter)        return -1;	if (format == MS_YUV420P)		guid_format = (GUID)FOURCCMap(MAKEFOURCC('I','4','2','0'));	else if (format == MS_YUYV)		guid_format = MEDIASUBTYPE_YUYV;	else if (format == MS_UYVY)		guid_format = MEDIASUBTYPE_UYVY;	else if (format == MS_RGB24)		guid_format = MEDIASUBTYPE_RGB24;	else if (format == MS_YUY2)		guid_format = MEDIASUBTYPE_YUY2;	if (format == MS_YUV420P)		biCompression = MAKEFOURCC('I','4','2','0');	else if (format == MS_YUYV)		biCompression = MAKEFOURCC('Y','U','Y','V');	else if (format == MS_UYVY)		biCompression = MAKEFOURCC('U','Y','V','Y');	else if (format == MS_RGB24)		biCompression = BI_RGB;	else if (format == MS_YUY2)		biCompression = MAKEFOURCC('Y','U','Y','2');		if (format == MS_YUV420P)		biBitCount = 12;	else if (format == MS_YUYV)		biBitCount = 16;	else if (format == MS_UYVY)		biBitCount = 16;	else if (format == MS_RGB24)		biBitCount = 24;	else if (format == MS_YUY2)		biBitCount = 16;    // Get pin enumerator	hr = s->m_pDeviceFilter->EnumPins(&pEnum);    if(FAILED(hr))         return -1;    pEnum->Reset();    // Count every pin on the filter    while(S_OK == pEnum->Next(1, &pPin, &ulFound))    {        PIN_DIRECTION pindir = (PIN_DIRECTION) 3;        hr = pPin->QueryDirection(&pindir);        if(pindir != PINDIR_INPUT)		{			IEnumMediaTypes *ppEnum;		    ULONG ulFound2;			hr = pPin->EnumMediaTypes(&ppEnum);			if(FAILED(hr)) 				continue;			AM_MEDIA_TYPE *ppMediaTypes;			while(S_OK == ppEnum->Next(1, &ppMediaTypes, &ulFound2))			{				if (ppMediaTypes->formattype != FORMAT_VideoInfo)					continue;				if (ppMediaTypes->majortype != MEDIATYPE_Video)					continue;				if (ppMediaTypes->subtype != guid_format)					continue;				VIDEOINFO *pvi = (VIDEOINFO *)ppMediaTypes->pbFormat;				if (pvi->bmiHeader.biCompression!=biCompression)					continue;				if (pvi->bmiHeader.biBitCount!=biBitCount)					continue;				if (pvi->bmiHeader.biHeight!=height)					continue;				if (pvi->bmiHeader.biWidth!=width)					continue;				s->vsize.width = width;				s->vsize.height = height;				pPin->Release();			    pEnum->Release();				return 0;			}		}        pPin->Release();    }     pEnum->Release();    return -1;}static int v4w_open_videodevice(V4wState *s){	// Initialize COM	CoInitialize(NULL);	// get a Graph	HRESULT hr=s->m_pGraph.CoCreateInstance(CLSID_FilterGraph);	if(FAILED(hr))	{		return -1;	}	// get a CaptureGraphBuilder2	hr=s->m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2);	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;	}#ifdef _DEBUG	HANDLE m_hLogFile=CreateFile(L"DShowGraphLog.txt",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);	if(m_hLogFile!=INVALID_HANDLE_VALUE)	{		hr=s->m_pGraph->SetLogFile((DWORD_PTR)m_hLogFile);		/* ASSERT(SUCCEEDED(hr)); */	}		//AddGraphToRot(s->m_pGraph, &s->rotregvalue);#endif	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 -4;	}	hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,		&pEnumMoniker, 0);	if (FAILED(hr) || pEnumMoniker == NULL) {		//printf("no device\n");		return -5;	}	pEnumMoniker->Reset();	int pos=0;    while(S_OK == pEnumMoniker->Next(1, &pMoniker, &nFetched) )    {		if (pos>=s->devidx)			break;		pos++;		pMoniker->Release();		pMoniker=NULL;	}	if(pMoniker==NULL)	{		return -6;	}	hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&s->m_pDeviceFilter );	if(FAILED(hr))	{		return -7;	}	s->m_pGraph->AddFilter(s->m_pDeviceFilter, L"Device Filter");	pMoniker->Release();	pEnumMoniker->Release();	pCreateDevEnum->Release();	if (try_format(s, s->pix_fmt)==0)		s->pix_fmt = s->pix_fmt;	else if (try_format(s,MS_YUV420P)==0)		s->pix_fmt = MS_YUV420P;	else if (try_format(s,MS_YUY2)==0)		s->pix_fmt = MS_YUY2;	else if (try_format(s,MS_YUYV)==0)		s->pix_fmt = MS_YUYV;	else if (try_format(s,MS_UYVY)==0)		s->pix_fmt = MS_UYVY;	else if (try_format(s,MS_RGB24)==0)		s->pix_fmt = MS_RGB24;	else	{		ms_error("Unsupported video pixel format.");		return -8;	}		if (s->pix_fmt == MS_YUV420P)		ms_message("Driver supports YUV420P, using that format.");	else if (s->pix_fmt == MS_YUY2)		ms_message("Driver supports YUY2 (UYVY), using that format.");	else if (s->pix_fmt == MS_YUYV)		ms_message("Driver supports YUV422, using that format.");	else if (s->pix_fmt == MS_UYVY)		ms_message("Driver supports UYVY, using that format.");	else if (s->pix_fmt == MS_RGB24)		ms_message("Driver supports RGB24, using that format.");	if (try_format_size(s, s->pix_fmt, s->vsize.width, s->vsize.height)==0)		ms_message("Selected Size: %ix%i.", s->vsize.width, s->vsize.height);	else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H)==0)		ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H);	else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H)==0)		ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H);	else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H)==0)		ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H);	else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H)==0)		ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H);	else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H)==0)		ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H);	else	{		ms_error("No supported size found for format.");		/* size not supported? */		return -9;	}	// get DXFilter	s->m_pDXFilter = new CDXFilter(NULL, &hr, FALSE);	if(s->m_pDXFilter==NULL)	{		return -10;	}	s->m_pDXFilter->AddRef();	CMediaType mt;	mt.SetType(&MEDIATYPE_Video);	GUID m = MEDIASUBTYPE_RGB24;	if (s->pix_fmt == MS_YUV420P)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -