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

📄 msfileplayer_win.c

📁 linphone 网络电话 linphone 网络电话 linphone 网络电话
💻 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/msfileplayer.h"#include "mediastreamer2/waveheader.h"#include "mediastreamer2/msticker.h"typedef enum {	CLOSED,	STARTED,	STOPPED} PlayerState;struct _PlayerData{	HANDLE fd;	PlayerState state;	int rate;	int nchannels;	int hsize;	int loop_after;	int pause_time;	bool_t swap;	int stat;	int big_buffer; /* ouput less & bigger buffer. (default => no change) */};typedef struct _PlayerData PlayerData;static void player_init(MSFilter *f){	PlayerData *d=(PlayerData *)ms_new(PlayerData,1);	d->fd=INVALID_HANDLE_VALUE;	d->state=CLOSED;	d->swap=FALSE;	d->rate=8000;	d->nchannels=1;	d->hsize=0;	d->loop_after=-1;	d->pause_time=0;	d->stat=-1;	d->big_buffer=1;	f->data=d;	}static int read_wav_header(PlayerData *d){	char header[sizeof(wave_header_t)];	wave_header_t *wav=(wave_header_t*)header;    unsigned long len=0;    BOOL res;        res = ReadFile(d->fd, header, sizeof(header), &len, NULL) ;                if (!res ||  len != sizeof(header)){		ms_warning("Wrong wav header: cannot read file");		return -1;	}	if (0!=strncmp(wav->riff_chunk.riff, "RIFF", 4) || 0!=strncmp(wav->riff_chunk.wave, "WAVE", 4)){			ms_warning("Wrong wav header: (default rate/channel -> %i:%i)", d->rate, d->nchannels);		return -1;	}	d->rate=wave_header_get_rate(wav);	d->nchannels=wave_header_get_channel(wav);	d->hsize=sizeof(header);#ifdef WORDS_BIGENDIAN	d->swap=TRUE;#endif	return 0;}static int player_open(MSFilter *f, void *arg){	PlayerData *d=(PlayerData*)f->data;	HANDLE fd;	const char *file=(const char*)arg;#if defined(_WIN32_WCE)    fd = CreateFile((LPCWSTR)file, GENERIC_READ, FILE_SHARE_READ, NULL,        OPEN_EXISTING, 0, NULL);#else	fd = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL,        OPEN_EXISTING, 0, NULL);#endif	if (fd==INVALID_HANDLE_VALUE){		ms_warning("Failed to open %s",file);		return -1;	}	d->state=STOPPED;	d->fd=fd;	if (strstr(file,".wav")!=NULL) read_wav_header(d);	return 0;}static int player_close(MSFilter *f, void *arg){	PlayerData *d=(PlayerData*)f->data;	if (d->fd!=INVALID_HANDLE_VALUE)	CloseHandle(d->fd);	d->fd=NULL;	d->state=CLOSED;	d->stat=-1;	return 0;}static int player_start(MSFilter *f, void *arg){	PlayerData *d=(PlayerData*)f->data;	if (d->state==STOPPED)		d->state=STARTED;	return 0;}static int player_stop(MSFilter *f, void *arg){	PlayerData *d=(PlayerData*)f->data;	if (d->state==STARTED){		d->state=STOPPED;		d->stat=-1;        SetFilePointer(d->fd, d->hsize, NULL, FILE_BEGIN);	}	return 0;}static void player_uninit(MSFilter *f){	PlayerData *d=(PlayerData*)f->data;	if (d->fd!=INVALID_HANDLE_VALUE) player_close(f,NULL);	ms_free(d);}static void player_process(MSFilter *f){	PlayerData *d=(PlayerData*)f->data;	int bytes =d->big_buffer * 2*(f->ticker->interval*d->rate*d->nchannels)/1000;;	if (d->big_buffer>1)	{		/* when starting reading a file: prepare more data		so that sound card buffer will never remain empty.		*/		d->stat++;		if (d->stat>3)		{			if (d->stat%(d->big_buffer)!=0)				return;		}	}	if (d->state==STARTED){		unsigned long err;		mblk_t *om=allocb(bytes,0);		if (d->pause_time>0){			err=bytes;			memset(om->b_wptr,0,bytes);			d->pause_time-=f->ticker->interval;		}else{            BOOL res;            err=0;            res = ReadFile(d->fd, om->b_wptr, bytes, &err, NULL) ;            		}		if (err>=0){			if (err==bytes){				om->b_wptr+=err;				ms_queue_put(f->outputs[0],om);			}			else if (err>0){				BOOL res;				om->b_wptr+=err;				ms_filter_notify_no_arg(f,MS_FILE_PLAYER_EOF);				SetFilePointer(d->fd, d->hsize, NULL, FILE_BEGIN);				/* special value for playing file only once */				if (d->loop_after==-2)				{					player_close(f,NULL);					return;				}				if (d->loop_after>0)				{					d->stat=-1;					d->pause_time=d->loop_after;				}				else				{					bytes=bytes-err;					err=0;					res = ReadFile(d->fd, om->b_wptr, bytes, &err, NULL);					if (err>0){						om->b_wptr+=err;					}				}				ms_queue_put(f->outputs[0],om);			}			else if (err==0){				BOOL res;				ms_filter_notify_no_arg(f,MS_FILE_PLAYER_EOF);				SetFilePointer(d->fd, d->hsize, NULL, FILE_BEGIN);				if (d->loop_after==-2)				{					player_close(f,NULL);					return;				}				if (d->loop_after>0)				{					d->stat=-1;					d->pause_time=d->loop_after;				}				else				{					bytes=bytes-err;					err=0;					res = ReadFile(d->fd, om->b_wptr, bytes, &err, NULL);					if (err>0){						om->b_wptr+=err;						ms_queue_put(f->outputs[0],om);						return;					}				}				freemsg(om);			}else freemsg(om);		}else{#if !defined(_WIN32_WCE)			ms_warning("Fail to read %i bytes: %s",bytes,strerror(errno));#else			ms_warning("Fail to read %i bytes: %i",bytes,WSAGetLastError());#endif		}	}}static int player_get_sr(MSFilter *f, void*arg){	PlayerData *d=(PlayerData*)f->data;	*((int*)arg)=d->rate;	return 0;}static int player_loop(MSFilter *f, void *arg){	PlayerData *d=(PlayerData*)f->data;	d->loop_after=*((int*)arg);	return 0;}static int player_set_big_buffer(MSFilter *f, void *arg){	PlayerData *d=(PlayerData*)f->data;	d->big_buffer=*((int*)arg);	return 0;}static int player_eof(MSFilter *f, void *arg){	PlayerData *d=(PlayerData*)f->data;	if (d->fd==NULL && d->state==CLOSED)		*((int*)arg) = TRUE; /* 1 */	else		*((int*)arg) = FALSE; /* 0 */	return 0;}static int player_get_nch(MSFilter *f, void *arg){	PlayerData *d=(PlayerData*)f->data;	*((int*)arg)=d->nchannels;	return 0;}static MSFilterMethod player_methods[]={	{	MS_FILE_PLAYER_OPEN,	player_open	},	{	MS_FILE_PLAYER_START,	player_start	},	{	MS_FILE_PLAYER_STOP,	player_stop	},	{	MS_FILE_PLAYER_CLOSE,	player_close	},	{	MS_FILTER_GET_SAMPLE_RATE, player_get_sr},	{	MS_FILTER_GET_NCHANNELS, player_get_nch	},	{	MS_FILE_PLAYER_LOOP,	player_loop	},	{	MS_FILE_PLAYER_DONE,	player_eof	},	{	MS_FILE_PLAYER_BIG_BUFFER,	player_set_big_buffer	},	{	0,			NULL		}};#ifdef _MSC_VERMSFilterDesc ms_file_player_desc={	MS_FILE_PLAYER_ID,	"MSFilePlayer",	"Raw files and wav reader",	MS_FILTER_OTHER,	NULL,    0,	1,	player_init,	NULL,    player_process,	NULL,    player_uninit,	player_methods};#elseMSFilterDesc ms_file_player_desc={	.id=MS_FILE_PLAYER_ID,	.name="MSFilePlayer",	.text="Raw files and wav reader",	.category=MS_FILTER_OTHER,	.ninputs=0,	.noutputs=1,	.init=player_init,	.process=player_process,	.uninit=player_uninit,	.methods=player_methods};#endifMS_FILTER_DESC_EXPORT(ms_file_player_desc)

⌨️ 快捷键说明

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