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

📄 sdlout.c

📁 基于osip、eXosip、speex、ffmpeg的VoIP源代码
💻 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.*/#include "mediastreamer2/msfilter.h"#include "mediastreamer2/msvideo.h"#include <SDL/SDL.h>#include <SDL/SDL_video.h>typedef struct SdlOut{	MSVideoSize size;	MSVideoSize local_size; /*size of local preview */	MSPixFmt format;	SDL_Surface *screen;	SDL_Overlay *overlay;	mblk_t *smallb;	int scale_factor;	bool_t lsize_init;} SdlOut;#define SCALE_FACTOR 6static bool_t sdl_initialized=FALSE;static void sdl_out_init(MSFilter  *f){	SdlOut *obj=ms_new(SdlOut,1);	obj->size.width = MS_VIDEO_SIZE_CIF_W;	obj->size.height = MS_VIDEO_SIZE_CIF_H;	obj->local_size.width = MS_VIDEO_SIZE_CIF_W;	obj->local_size.height = MS_VIDEO_SIZE_CIF_H;	obj->lsize_init=FALSE;	obj->scale_factor=SCALE_FACTOR;	obj->format=MS_RGB24;	obj->screen=NULL;	obj->overlay=NULL;	obj->smallb=NULL;#if !defined(WIN32) && !defined(__APPLE__)	if (!sdl_initialized){		/* Initialize the SDL library */		if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {			ms_error("Couldn't initialize SDL: %s", SDL_GetError());			return;		}		/* Clean up on exit */		atexit(SDL_Quit);		sdl_initialized=TRUE;	}#endif	f->data=obj;}static void sdl_destroy_window(SdlOut *obj){	if (obj->overlay!=NULL){		SDL_FreeYUVOverlay(obj->overlay);		obj->overlay=NULL;	}	if (obj->screen!=NULL){		SDL_FreeSurface(obj->screen);		obj->screen=NULL;	}}static void sdl_out_uninit(MSFilter *f){	SdlOut *s=(SdlOut*)f->data;	sdl_destroy_window(s);	if (s->smallb!=NULL) freemsg(s->smallb);	ms_free(s);}static void sdl_create_window(SdlOut *obj){	obj->screen = SDL_SetVideoMode(obj->size.width, obj->size.height, 0,SDL_SWSURFACE);	if ( obj->screen == NULL ) {		ms_warning("Couldn't set video mode: %s\n",						SDL_GetError());		return ;	}	if (obj->screen->flags & SDL_HWSURFACE) ms_message("SDL surface created in hardware");	SDL_WM_SetCaption("Linphone Video", NULL);		if (obj->format==MS_YUV420P){		ms_message("Using yuv overlay.");		obj->overlay=SDL_CreateYUVOverlay(obj->size.width,obj->size.height,SDL_YV12_OVERLAY,obj->screen);		if (obj->overlay==NULL){			ms_warning("Couldn't create yuv overlay: %s\n",							SDL_GetError());			return;		}else{			if (obj->overlay->hw_overlay) ms_message("YUV overlay using hardware acceleration.");		}	}}mblk_t * resize_yuv_small(unsigned char *pict, int w, int h, int scale){	int i,j,id,jd;	int nh,nw;	unsigned char *smallpict;	int ysize,usize,ydsize,udsize;	int smallpict_sz;	unsigned char *dptr,*sptr;	mblk_t *smallb;	nw=w/scale;	nh=h/scale;	ysize=w*h;	usize=ysize/4;	ydsize=nw*nh;	udsize=ydsize/4;	smallpict_sz=(ydsize*3)/2;	smallb=allocb(smallpict_sz,0);	smallpict=smallb->b_wptr;	smallb->b_wptr+=smallpict_sz;		dptr=smallpict;	sptr=pict;	for (j=0,jd=0;j<nh;j++,jd+=scale){		for (i=0,id=0;i<nw;i++,id+=scale){			dptr[(j*nw) + i]=sptr[(jd*w)+id];		}	}		nh=nh/2;	nw=nw/2;	w=w/2;	h=h/2;	dptr+=ydsize;	sptr+=ysize;	for (j=0,jd=0;j<nh;j++,jd+=scale){		for (i=0,id=0;i<nw;i++,id+=scale){			dptr[(j*nw) + i]=sptr[(jd*w)+id];		}	}	dptr+=udsize;	sptr+=usize;	for (j=0,jd=0;j<nh;j++,jd+=scale){		for (i=0,id=0;i<nw;i++,id+=scale){			dptr[(j*nw) + i]=sptr[(jd*w)+id];		}	}		return smallb;}static void fill_overlay_at_pos(SDL_Overlay *lay, mblk_t *m, int x, int y, int w, int h){	unsigned char *data=m->b_rptr;	int i,j;	int jlim,ilim;	int off;	unsigned char *dptr;		ilim=MIN(x+w,lay->w);	jlim=MIN(y+h,lay->h);	SDL_LockYUVOverlay(lay);	/* set Y */	dptr=lay->pixels[0];	for (j=y;j<jlim;j++){		off=j*lay->w;		for (i=x;i<ilim;i++){			dptr[off + i]=*data;			data++;		}	}	/*set U and V*/	ilim=ilim/2;	jlim=jlim/2;	dptr=lay->pixels[2];	for (j=y/2;j<jlim;j++){		off=j*(lay->w/2);		for (i=x/2;i<ilim;i++){			dptr[off + i]=*data;			data++;		}	}	dptr=lay->pixels[1];	for (j=y/2;j<jlim;j++){		off=j*(lay->w/2);		for (i=x/2;i<ilim;i++){			dptr[off + i]=*data;			data++;		}	}	SDL_UnlockYUVOverlay(lay);}static void fill_overlay(SDL_Overlay *lay,mblk_t *m){		int w2,h2;	char *data=(char*)m->b_rptr;	int ysize=lay->pitches[0]*lay->h;	int usize;	w2=lay->w/2;	h2=lay->h/2;	usize=w2*h2;	SDL_LockYUVOverlay(lay);	memcpy(lay->pixels[0],data,ysize);	memcpy(lay->pixels[2],data+ysize,usize);	memcpy(lay->pixels[1],data+ysize+usize,usize);	SDL_UnlockYUVOverlay(lay);}static void sdl_out_process(MSFilter *f){	SdlOut *obj=(SdlOut*)f->data;	mblk_t *inm0=NULL;	mblk_t *inm1=NULL;	int err;	SDL_Rect smallrect;	SDL_Rect rect;	bool_t got_preview=FALSE;	#if defined(WIN32) || defined(__APPLE__)	if (!sdl_initialized){		/* Initialize the SDL library */		if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {			ms_error("Couldn't initialize SDL: %s", SDL_GetError());			return;		}		/* Clean up on exit */		atexit(SDL_Quit);		sdl_initialized=TRUE;	}#endif	if (obj->screen==NULL){		sdl_create_window(obj);	}	rect.w=obj->size.width;	rect.h=obj->size.height;	rect.x=0;	rect.y=0;	smallrect.w=obj->size.width/SCALE_FACTOR;	smallrect.h=obj->size.height/SCALE_FACTOR;	smallrect.x=obj->size.width - smallrect.w ;	smallrect.y=obj->size.height -smallrect.h;			while (f->inputs[0]!=NULL && (inm0=ms_queue_get(f->inputs[0]))!=NULL){		SDL_Surface *surf;		if  (obj->format==MS_YUV420P){			fill_overlay(obj->overlay,inm0);		}else {			surf=SDL_CreateRGBSurfaceFrom(inm0->b_rptr,obj->size.width,obj->size.height,24,obj->size.width*3,0,0,0,0);			err=SDL_BlitSurface(surf,NULL,obj->screen,NULL);			if (err<0) ms_warning("Fail to blit surface: %s",SDL_GetError());			SDL_FreeSurface(surf);		}		freemsg(inm0);	}	while (f->inputs[1]!=NULL && (inm1=ms_queue_get(f->inputs[1]))!=NULL){		/* this message is blitted on the right,bottom corner of the screen */		SDL_Surface *surf;		got_preview=TRUE;		if (!obj->lsize_init){			/*attempt to guess the video size of the local preview buffer*/			int bsize=msgdsize(inm1);			if (bsize<(MS_VIDEO_SIZE_CIF_W*MS_VIDEO_SIZE_CIF_H*3/2)){				/*surely qcif ?*/				obj->local_size.width=MS_VIDEO_SIZE_QCIF_W;				obj->local_size.height=MS_VIDEO_SIZE_QCIF_H;				ms_message("preview is in QCIF.");				obj->scale_factor=SCALE_FACTOR/2;			}			obj->lsize_init=TRUE;		}		if  (obj->format==MS_YUV420P){			if (obj->smallb!=NULL) {				freemsg(obj->smallb);			}			obj->smallb=resize_yuv_small(inm1->b_rptr,obj->local_size.width,obj->local_size.height,obj->scale_factor);			fill_overlay_at_pos(obj->overlay,obj->smallb,smallrect.x, smallrect.y, smallrect.w, smallrect.h);			freemsg(inm1);		}else {			surf=SDL_CreateRGBSurfaceFrom(inm1->b_rptr,obj->size.width,obj->size.height,24,obj->size.width*3,0,0,0,0);			err=SDL_BlitSurface(surf,NULL,obj->screen,&smallrect);			if (err<0) ms_warning("Fail to blit surface: %s",SDL_GetError());			SDL_FreeSurface(surf);		}	}	if (!got_preview){		/* this is the case were we have only inm0, we have to redisplay inm1 */		if  (obj->format==MS_YUV420P){			if (obj->smallb!=NULL){				fill_overlay_at_pos(obj->overlay,obj->smallb,smallrect.x, smallrect.y, smallrect.w, smallrect.h);			}		}	}		if (obj->format==MS_YUV420P) SDL_DisplayYUVOverlay(obj->overlay,&rect);	else SDL_UpdateRect(obj->screen,0,0,obj->size.width,obj->size.height);	#if defined(WIN32) || defined(__APPLE__)	{		SDL_Event event;		SDL_PollEvent(&event);	}#endif}static int sdl_out_set_pix_fmt(MSFilter *f,void *arg){	SdlOut *s=(SdlOut*)f->data;	s->format=*(MSPixFmt*)arg;	return 0;}static int sdl_out_set_vsize(MSFilter *f,void *arg){	SdlOut *s=(SdlOut*)f->data;	s->size=*(MSVideoSize*)arg;	s->local_size=*(MSVideoSize*)arg;	return 0;}static MSFilterMethod methods[]={	{	MS_FILTER_SET_PIX_FMT	,	sdl_out_set_pix_fmt},	{	MS_FILTER_SET_VIDEO_SIZE	,	sdl_out_set_vsize },	{	0	,NULL}};#ifdef _MSC_VERMSFilterDesc ms_sdl_out_desc={	MS_SDL_OUT_ID,	"MSSdlOut",	"A video display window using SDL",	MS_FILTER_OTHER,	NULL,	2,	0,	sdl_out_init,	NULL,	sdl_out_process,	NULL,	sdl_out_uninit,	methods};#elseMSFilterDesc ms_sdl_out_desc={	.id=MS_SDL_OUT_ID,	.name="MSSdlOut",	.text="A video display window using SDL",	.category=MS_FILTER_OTHER,	.ninputs=2,	.noutputs=0,	.init=sdl_out_init,	.process=sdl_out_process,	.uninit=sdl_out_uninit,	.methods=methods};#endifMS_FILTER_DESC_EXPORT(ms_sdl_out_desc)

⌨️ 快捷键说明

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