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

📄 videoout.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.*/#include "mediastreamer2/msfilter.h"#include "mediastreamer2/msvideo.h"#include "mediastreamer2/msvideoout.h"#ifndef WIN32#include <SDL/SDL.h>#include <SDL/SDL_video.h>static bool_t sdl_initialized=FALSE;static SDL_Surface *sdl_screen=0;static SDL_Overlay * sdl_create_window(int w, int h){	SDL_Overlay *lay;	sdl_screen = SDL_SetVideoMode(w,h, 0,SDL_SWSURFACE);	if (sdl_screen == NULL ) {		ms_warning("Couldn't set video mode: %s\n",						SDL_GetError());		return NULL;	}	if (sdl_screen->flags & SDL_HWSURFACE) ms_message("SDL surface created in hardware");	SDL_WM_SetCaption("Linphone Video", NULL);	ms_message("Using yuv overlay.");	lay=SDL_CreateYUVOverlay(w,h,SDL_YV12_OVERLAY,sdl_screen);	if (lay==NULL){		ms_warning("Couldn't create yuv overlay: %s\n",						SDL_GetError());		return NULL;	}else{		if (lay->hw_overlay) ms_message("YUV overlay using hardware acceleration.");	}	return lay;}static bool_t sdl_display_init(MSDisplay *obj, MSFrameBuffer *fbuf){	SDL_Overlay *lay;	if (!sdl_initialized){		/* Initialize the SDL library */		if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {			ms_error("Couldn't initialize SDL: %s", SDL_GetError());			return FALSE;		}		/* Clean up on exit */		atexit(SDL_Quit);		sdl_initialized=TRUE;	}	if (obj->data!=NULL)		SDL_FreeYUVOverlay((SDL_Overlay*)obj->data);	lay=sdl_create_window(fbuf->w, fbuf->h);	if (lay){		fbuf->y=lay->pixels[0];		fbuf->u=lay->pixels[2];		fbuf->v=lay->pixels[1];		obj->data=lay;		return TRUE;	}	return FALSE;}static void sdl_display_lock(MSDisplay *obj){	SDL_LockYUVOverlay((SDL_Overlay*)obj->data);}static void sdl_display_unlock(MSDisplay *obj){	SDL_Overlay *lay=(SDL_Overlay*)obj->data;	SDL_UnlockYUVOverlay(lay);}static void sdl_display_update(MSDisplay *obj){	SDL_Rect rect;	SDL_Overlay *lay=(SDL_Overlay*)obj->data;	rect.x=0;	rect.y=0;	rect.w=lay->w;	rect.h=lay->h;	SDL_DisplayYUVOverlay(lay,&rect);}static void sdl_display_uninit(MSDisplay *obj){	SDL_Overlay *lay=(SDL_Overlay*)obj->data;	if (lay==NULL)		return;	if (lay!=NULL)		SDL_FreeYUVOverlay(lay);	if (sdl_screen!=NULL){		SDL_FreeSurface(sdl_screen);		sdl_screen=NULL;	}}MSDisplayDesc ms_sdl_display_desc={	.init=sdl_display_init,	.lock=sdl_display_lock,	.unlock=sdl_display_unlock,	.update=sdl_display_update,	.uninit=sdl_display_uninit};#else#include <Vfw.h>typedef struct _WinDisplay{	HWND window;	HDRAWDIB ddh;	MSFrameBuffer fb;	uint8_t *rgb;	int rgb_len;}WinDisplay;static LRESULT CALLBACK window_proc(    HWND hwnd,        // handle to window    UINT uMsg,        // message identifier    WPARAM wParam,    // first message parameter    LPARAM lParam)    // second message parameter{	switch(uMsg){		case WM_DESTROY:		break;		default:			return DefWindowProc(hwnd, uMsg, wParam, lParam);	}	return 0;}static HWND create_window(int w, int h){	WNDCLASS wc;	HINSTANCE hInstance = GetModuleHandle(NULL);	HWND hwnd;	RECT rect;	wc.style = 0 ;	wc.lpfnWndProc = window_proc;	wc.cbClsExtra = 0;	wc.cbWndExtra = 0;	wc.hInstance = NULL;	wc.hIcon = NULL;	wc.hCursor = LoadCursor(hInstance, IDC_ARROW);	wc.hbrBackground = NULL;	wc.lpszMenuName =  NULL;	wc.lpszClassName = "Video Window";		if(!RegisterClass(&wc))	{		/* already registred! */	}	rect.left=100;	rect.top=100;	rect.right=rect.left+w;	rect.bottom=rect.top+h;	if (!AdjustWindowRect(&rect,WS_CAPTION ,FALSE)){		ms_error("AdjustWindowRect failed.");	}	ms_message("AdjustWindowRect: %li,%li %li,%li",rect.left,rect.top,rect.right,rect.bottom);	hwnd=CreateWindow("Video Window", "Video window", WS_OVERLAPPEDWINDOW|WS_VISIBLE ,						CW_USEDEFAULT, CW_USEDEFAULT, rect.right-rect.left,rect.bottom-rect.top,													NULL, NULL, hInstance, NULL);	if (hwnd==NULL){		ms_error("Fail to create video window");	}	return hwnd;}static bool_t win_display_init(MSDisplay *obj, MSFrameBuffer *fbuf){	WinDisplay *wd=(WinDisplay*)obj->data;	int ysize,usize;	if (wd!=NULL)	{		if (wd->window && !obj->window_id) DestroyWindow(wd->window);		if (wd->ddh) DrawDibClose(wd->ddh);		wd->ddh=NULL;		if (wd->fb.y) ms_free(wd->fb.y);		wd->fb.y=NULL;		wd->fb.u=NULL;		wd->fb.v=NULL;		if (wd->rgb) ms_free(wd->rgb);		wd->rgb=NULL;		wd->rgb_len=0;		wd->window=NULL;	}	else		wd=(WinDisplay*)ms_new0(WinDisplay,1);		obj->data=wd;		wd->fb.w=fbuf->w;	wd->fb.h=fbuf->h;		wd->window=(HWND)obj->window_id;	if (wd->window==NULL) {		wd->window=create_window(wd->fb.w,wd->fb.h);	}	if (wd->window==NULL) return FALSE;	if (wd->ddh==NULL) wd->ddh=DrawDibOpen();	if (wd->ddh==NULL){		ms_error("DrawDibOpen() failed.");		return FALSE;	}	/*allocate yuv and rgb buffers*/	if (wd->fb.y) ms_free(wd->fb.y);	if (wd->rgb) ms_free(wd->rgb);	ysize=wd->fb.w*wd->fb.h;	usize=ysize/4;	fbuf->y=wd->fb.y=(uint8_t*)ms_malloc0(ysize+2*usize);	fbuf->u=wd->fb.u=wd->fb.y+ysize;	fbuf->v=wd->fb.v=wd->fb.u+usize;	wd->rgb_len=ysize*3;	wd->rgb=(uint8_t*)ms_malloc0(wd->rgb_len);	return TRUE;}typedef struct rgb{	uint8_t r,g,b;} rgb_t;typedef struct yuv{	uint8_t y,u,v;} yuv_t;#if 1static inline uint8_t ms_clip_uint8(int a){     if (a&(~255)) return (-a)>>31;     else          return a;}/* R = Y + 1.140V   G = Y - 0.395U - 0.581V   B = Y + 2.032U   or	R = Y + 1.403V'	G = Y - 0.344U' - 0.714V'	B = Y + 1.770U'*/static void yuv_to_rgb_pixel(const yuv_t *yuv, rgb_t *rgb){	int c,d,e;	c=yuv->y-16;	e=yuv->u-128;	d=yuv->v-128;	rgb->r=ms_clip_uint8((float)c + 1.403*e);	rgb->g=ms_clip_uint8((float)c - 0.344*d - 0.714*e );	rgb->b=ms_clip_uint8((float)c + 1.77*d );}static void yuv420p_to_rgb(uint8_t *yuv, uint8_t *rgb, int w, int h){	int i,j,k,l;	yuv_t yuv_pix;	uint8_t *y,*u,*v;	int upos;	int ypos;	y=yuv;	u=yuv + w*h;	v=u + (w*h/4);	for(i=h-1,k=(h/2)-1;i>=0;i-=2,--k){		ypos=i*w;		upos=k*w/2;		for(j=0,l=0;j<w;j+=2,++l){			yuv_pix.y=y[ypos+j];			yuv_pix.u=u[upos+l];			yuv_pix.v=v[upos+l];			yuv_to_rgb_pixel(&yuv_pix,(rgb_t*)rgb);			rgb+=3;			yuv_pix.y=y[ypos+j+1];			yuv_to_rgb_pixel(&yuv_pix,(rgb_t*)rgb);			rgb+=3;		}		ypos=(i-1)*w;		for(j=0,l=0;j<w;j+=2,++l){			yuv_pix.y=y[ypos+j];			yuv_pix.u=u[upos+l];			yuv_pix.v=v[upos+l];			yuv_to_rgb_pixel(&yuv_pix,(rgb_t*)rgb);			rgb+=3;			yuv_pix.y=y[ypos+j+1];			yuv_to_rgb_pixel(&yuv_pix,(rgb_t*)rgb);			rgb+=3;		}	}}#else#include <ffmpeg/avcodec.h>static void yuv420p_to_rgb(uint8_t *yuv, uint8_t *rgb, int w, int h){	AVPicture src,dst;	avpicture_fill(&dst,rgb,PIX_FMT_RGB24,w,h);	avpicture_fill(&src,yuv,PIX_FMT_YUV420P,w,h);	if (img_convert(&dst,PIX_FMT_RGB24,&src,PIX_FMT_YUV420P,w,h)<0){		ms_error("videout.c: img_convert failed !");	}}#endifstatic void win_display_update(MSDisplay *obj){	WinDisplay *wd=(WinDisplay*)obj->data;	HDC hdc;	BITMAPINFOHEADER bi;	bool_t ret;	if (wd->window==NULL) return;	hdc=GetDC(wd->window);	if (hdc==NULL) {		ms_error("Could not get window dc");		return;	}	yuv420p_to_rgb(wd->fb.y, wd->rgb, wd->fb.w, wd->fb.h);	memset(&bi,0,sizeof(bi));	bi.biSize=sizeof(bi);	/*	bi.biWidth=wd->fb.w;	bi.biHeight=wd->fb.h;	bi.biPlanes=3;	bi.biBitCount=12;	bi.biCompression=MAKEFOURCC('I','4','2','0');	bi.biSizeImage=(wd->fb.w*wd->fb.h*3)/2;	*/	bi.biWidth=wd->fb.w;	bi.biHeight=wd->fb.h;	bi.biPlanes=1;	bi.biBitCount=24;	bi.biCompression=BI_RGB;	bi.biSizeImage=wd->rgb_len;	ret=DrawDibDraw(wd->ddh,hdc,0,0,wd->fb.w,wd->fb.h,&bi,wd->rgb,		0,0,wd->fb.w,wd->fb.h,0);  	if (!ret) ms_error("DrawDibDraw failed.");

⌨️ 快捷键说明

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