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

📄 videoout.c

📁 基于osip、eXosip、speex、ffmpeg的VoIP源代码
💻 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.*/#ifdef HAVE_CONFIG_H#include "mediastreamer-config.h"#endif#include "mediastreamer2/msfilter.h"#include "mediastreamer2/msvideo.h"#include "mediastreamer2/msvideoout.h"#include "ffmpeg-priv.h"static int video_out_handle_resize(MSFilter *f, void *arg);bool_t ms_display_poll_event(MSDisplay *d, MSDisplayEvent *ev){	if (d->desc->pollevent)		return d->desc->pollevent(d,ev);	else return FALSE;}#ifndef WIN32#include <SDL/SDL.h>#include <SDL/SDL_video.h>static bool_t sdl_initialized=FALSE;static ms_mutex_t sdl_mutex;static SDL_Surface *sdl_screen=0;#ifdef HAVE_X11_XLIB_H#include <SDL/SDL_syswm.h>static void sdl_show_window(bool_t show){	SDL_SysWMinfo info;	SDL_VERSION(&info.version);	if ( SDL_GetWMInfo(&info) ) {		if ( info.subsystem == SDL_SYSWM_X11 ) {			Display *display;			Window window;					info.info.x11.lock_func();			display = info.info.x11.display;			window = info.info.x11.wmwindow;			if (show)				XMapWindow(display,window);			else				XUnmapWindow(display,window);			info.info.x11.unlock_func();		}	}}#elsestatic void sdl_show_window(bool_t show){	ms_warning("SDL window show/hide not implemented");}#endifstatic SDL_Overlay * sdl_create_window(int w, int h){	SDL_Overlay *lay;	sdl_screen = SDL_SetVideoMode(w,h, 0,SDL_SWSURFACE|SDL_RESIZABLE);	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, MSPicture *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;		ms_mutex_init(&sdl_mutex,NULL);	}	if (obj->data!=NULL)		SDL_FreeYUVOverlay((SDL_Overlay*)obj->data);		lay=sdl_create_window(fbuf->w, fbuf->h);	if (lay){		fbuf->planes[0]=lay->pixels[0];		fbuf->planes[1]=lay->pixels[2];		fbuf->planes[2]=lay->pixels[1];		fbuf->strides[0]=lay->pitches[0];		fbuf->strides[1]=lay->pitches[2];		fbuf->strides[2]=lay->pitches[1];		obj->data=lay;		sdl_show_window(TRUE);		return TRUE;	}	return FALSE;}static void sdl_display_lock(MSDisplay *obj){	ms_mutex_lock(&sdl_mutex);	SDL_LockYUVOverlay((SDL_Overlay*)obj->data);	ms_mutex_unlock(&sdl_mutex);}static void sdl_display_unlock(MSDisplay *obj){	SDL_Overlay *lay=(SDL_Overlay*)obj->data;	ms_mutex_lock(&sdl_mutex);	SDL_UnlockYUVOverlay(lay);	ms_mutex_unlock(&sdl_mutex);}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;	ms_mutex_lock(&sdl_mutex);	SDL_DisplayYUVOverlay(lay,&rect);	ms_mutex_unlock(&sdl_mutex);}static bool_t sdl_poll_event(MSDisplay *obj, MSDisplayEvent *ev){	SDL_Event event;	static MSDisplayEvent last_ev;	static struct timeval tv;	static bool_t got_rs_ev=FALSE;	struct timeval cur;	int elapsed;	bool_t ret=FALSE;	ms_mutex_lock(&sdl_mutex);	if (SDL_PollEvent(&event)){		ms_mutex_unlock(&sdl_mutex);		switch(event.type){			case SDL_VIDEORESIZE:				last_ev.evtype=MS_DISPLAY_RESIZE_EVENT;				last_ev.w=event.resize.w;				last_ev.h=event.resize.h;				got_rs_ev=TRUE;				gettimeofday(&tv,NULL);			break;			default:			break;		}	}else ms_mutex_unlock(&sdl_mutex);	if (got_rs_ev){		gettimeofday(&cur,NULL);		elapsed=((cur.tv_sec-tv.tv_sec)*1000) + ((cur.tv_usec-tv.tv_usec)/1000);		if (elapsed>1000){			got_rs_ev=FALSE;			*ev=last_ev;			ret=TRUE;		}	}	return ret;}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;	}	sdl_show_window(FALSE);}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,	.pollevent=sdl_poll_event};#else#include <Vfw.h>typedef struct _WinDisplay{	HWND window;	HDRAWDIB ddh;	MSPicture fb;	MSDisplayEvent last_rsz;	uint8_t *rgb;	int rgb_len;	bool_t new_ev;}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;		case WM_SIZE:			if (wParam==SIZE_RESTORED){				int h=(lParam>>16) & 0xffff;				int w=lParam & 0xffff;				MSDisplay *obj;				WinDisplay *wd;				ms_message("Resized to %i,%i",w,h);				obj=(MSDisplay*)GetWindowLongPtr(hwnd,GWLP_USERDATA);				if (obj!=NULL){					wd=(WinDisplay*)obj->data;					wd->last_rsz.evtype=MS_DISPLAY_RESIZE_EVENT;					wd->last_rsz.w=w;					wd->last_rsz.h=h;					wd->new_ev=TRUE;				}else{					ms_error("Could not retrieve MSDisplay from window !");				}			}		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_OVERLAPPEDWINDOW|WS_VISIBLE /*WS_CAPTION WS_TILED|WS_BORDER*/,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, MSPicture *fbuf){	WinDisplay *wd=(WinDisplay*)obj->data;	int ysize,usize;	if (wd!=NULL)	{		if (wd->ddh) DrawDibClose(wd->ddh);		wd->ddh=NULL;		if (wd->fb.planes[0]) ms_free(wd->fb.planes[0]);		wd->fb.planes[0]=NULL;		wd->fb.planes[1]=NULL;		wd->fb.planes[2]=NULL;		if (wd->rgb) ms_free(wd->rgb);		wd->rgb=NULL;		wd->rgb_len=0;	}	else		wd=(WinDisplay*)ms_new0(WinDisplay,1);		obj->data=wd;		wd->fb.w=fbuf->w;	wd->fb.h=fbuf->h;		if (wd->window==NULL){		if (obj->window_id!=0){			void *p;			wd->window=(HWND)obj->window_id;			p=(void*)GetWindowLongPtr(wd->window,GWLP_USERDATA);			if (p!=NULL){				ms_error("Gulp: this externally supplied windows seems to "					"already have a userdata ! resizing will crash !");			}else SetWindowLongPtr(wd->window,GWLP_USERDATA,(LONG_PTR)obj);		}else{			wd->window=create_window(wd->fb.w,wd->fb.h);			if (wd->window!=NULL) SetWindowLongPtr(wd->window,GWLP_USERDATA,(LONG_PTR)obj);			else 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.planes[0]) ms_free(wd->fb.planes[0]);	if (wd->rgb) ms_free(wd->rgb);	ysize=wd->fb.w*wd->fb.h;	usize=ysize/4;	fbuf->planes[0]=wd->fb.planes[0]=(uint8_t*)ms_malloc0(ysize+2*usize);	fbuf->planes[1]=wd->fb.planes[1]=wd->fb.planes[0]+ysize;	fbuf->planes[2]=wd->fb.planes[2]=wd->fb.planes[1]+usize;	fbuf->strides[0]=wd->fb.strides[0]=wd->fb.w;	fbuf->strides[1]=wd->fb.strides[1]=wd->fb.w/2;	fbuf->strides[2]=wd->fb.strides[2]=wd->fb.w/2;	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;static void yuv420p_to_rgb(MSPicture *src, uint8_t *rgb){	struct SwsContext *sws;	int rgb_stride=-src->w*3;	uint8_t *p;	p=rgb+(src->w*3*(src->h-1));	sws=sws_getContext(src->w,src->h,PIX_FMT_YUV420P,			src->w,src->h,PIX_FMT_RGB24,			0, NULL, NULL, NULL);	if (sws_scale(sws,src->planes,src->strides, 0,           			0, &p, &rgb_stride)<0){			ms_error("Error in 420->rgb sws_scale().");	}	sws_freeContext(sws);	/*revert colors*/		{		int i,j,stride;		rgb_t pix;		stride=src->w*3;		p=rgb;		for(i=0;i<src->h;++i){			for(j=0;j<stride;j+=3){				pix.r=p[j];				pix.g=p[j+1];				pix.b=p[j+2];				p[j]=pix.b;				p[j+2]=pix.r;			}			p+=stride;		}	}}static void win_display_update(MSDisplay *obj){	WinDisplay *wd=(WinDisplay*)obj->data;	HDC hdc;	BITMAPINFOHEADER bi;	RECT rect;	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, wd->rgb);	memset(&bi,0,sizeof(bi));

⌨️ 快捷键说明

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