mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +00:00 
			
		
		
		
	Properly implement using zaptel for timing of file playback
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1137 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -91,7 +91,7 @@ ifeq (${OSARCH},OpenBSD) | ||||
| CFLAGS+=-pthread | ||||
| endif | ||||
|  | ||||
| #CFLAGS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "-DZAPTEL_OPTIMIZATIONS"; fi) | ||||
| CFLAGS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "-DZAPTEL_OPTIMIZATIONS"; fi) | ||||
|  | ||||
| LIBEDIT=editline/libedit.a | ||||
|  | ||||
|   | ||||
							
								
								
									
										30
									
								
								channel.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								channel.c
									
									
									
									
									
								
							| @@ -938,13 +938,19 @@ char ast_waitfordigit(struct ast_channel *c, int ms) | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| int ast_settimeout(struct ast_channel *c, int ms) | ||||
| int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data) | ||||
| { | ||||
| 	int res = -1; | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| 	if (c->timingfd > -1) { | ||||
| 		ms *= 8; | ||||
| 		res = ioctl(c->timingfd, ZT_TIMERCONFIG, &ms); | ||||
| 		if (!func) { | ||||
| 			samples = 0; | ||||
| 			data = 0; | ||||
| 		} | ||||
| 		ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples); | ||||
| 		res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples); | ||||
| 		c->timingfunc = func; | ||||
| 		c->timingdata = data; | ||||
| 	} | ||||
| #endif	 | ||||
| 	return res; | ||||
| @@ -983,6 +989,10 @@ struct ast_frame *ast_read(struct ast_channel *chan) | ||||
| { | ||||
| 	struct ast_frame *f = NULL; | ||||
| 	int blah; | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| 	int (*func)(void *); | ||||
| 	void *data; | ||||
| #endif | ||||
| 	static struct ast_frame null_frame =  | ||||
| 	{ | ||||
| 		AST_FRAME_NULL, | ||||
| @@ -1027,10 +1037,18 @@ struct ast_frame *ast_read(struct ast_channel *chan) | ||||
| 		chan->exception = 0; | ||||
| 		blah = -1; | ||||
| 		ioctl(chan->timingfd, ZT_TIMERACK, &blah); | ||||
| 		blah = 0; | ||||
| 		ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); | ||||
| 		f =  &null_frame; | ||||
| 		func = chan->timingfunc; | ||||
| 		data = chan->timingdata; | ||||
| 		pthread_mutex_unlock(&chan->lock); | ||||
| 		if (func) { | ||||
| 			func(data); | ||||
| 		} else { | ||||
| 			blah = 0; | ||||
| 			pthread_mutex_lock(&chan->lock); | ||||
| 			ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah); | ||||
| 			pthread_mutex_unlock(&chan->lock); | ||||
| 		} | ||||
| 		f =  &null_frame; | ||||
| 		return f; | ||||
| 	} | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										21
									
								
								file.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								file.c
									
									
									
									
									
								
							| @@ -508,16 +508,26 @@ static int ast_readaudio_callback(void *data) | ||||
| 			if (ast_write(s->owner, fr)) { | ||||
| 				ast_log(LOG_WARNING, "Failed to write frame\n"); | ||||
| 				s->owner->streamid = -1; | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| 				ast_settimeout(s->owner, 0, NULL, NULL); | ||||
| #endif			 | ||||
| 				return 0; | ||||
| 			} | ||||
| 		} else { | ||||
| 			/* Stream has finished */ | ||||
| 			s->owner->streamid = -1; | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| 			ast_settimeout(s->owner, 0, NULL, NULL); | ||||
| #endif			 | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 	if (whennext != s->lasttimeout) { | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| 		ast_settimeout(s->owner, whennext, ast_readaudio_callback, s); | ||||
| #else | ||||
| 		s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s); | ||||
| #endif		 | ||||
| 		s->lasttimeout = whennext; | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -606,6 +616,9 @@ int ast_closestream(struct ast_filestream *f) | ||||
| 			if (f->owner->streamid > -1) | ||||
| 				ast_sched_del(f->owner->sched, f->owner->streamid); | ||||
| 			f->owner->streamid = -1; | ||||
| #ifdef ZAPTEL_OPTIMIZATIONS | ||||
| 			ast_settimeout(f->owner, 0, NULL, NULL); | ||||
| #endif			 | ||||
| 		} else { | ||||
| 			f->owner->vstream = NULL; | ||||
| 			if (f->owner->vstreamid > -1) | ||||
| @@ -766,15 +779,15 @@ char ast_waitstream(struct ast_channel *c, char *breakon) | ||||
| 	struct ast_frame *fr; | ||||
| 	while(c->stream) { | ||||
| 		res = ast_sched_wait(c->sched); | ||||
| 		if (res < 0) { | ||||
| 		if ((res < 0) && !c->timingfunc) { | ||||
| 			if (c->stream) | ||||
| 				ast_closestream(c->stream); | ||||
| 			if (c->vstream) | ||||
| 				ast_closestream(c->vstream); | ||||
| 			break; | ||||
| 		} | ||||
| 		/* Setup timeout if supported */ | ||||
| 		ast_settimeout(c, res); | ||||
| 		if (res < 0) | ||||
| 			res = 1000; | ||||
| 		res = ast_waitfor(c, res); | ||||
| 		if (res < 0) { | ||||
| 			ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); | ||||
| @@ -832,7 +845,6 @@ char ast_waitstream_fr(struct ast_channel *c, char *breakon, char *forward, char | ||||
| 				ast_closestream(c->vstream); | ||||
| 			break; | ||||
| 		} | ||||
| 		ast_settimeout(c, res); | ||||
| 		res = ast_waitfor(c, res); | ||||
| 		if (res < 0) { | ||||
| 			ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); | ||||
| @@ -899,7 +911,6 @@ char ast_waitstream_full(struct ast_channel *c, char *breakon, int audiofd, int | ||||
| 				ast_closestream(c->vstream); | ||||
| 			break; | ||||
| 		} | ||||
| 		ast_settimeout(c, ms); | ||||
| 		rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); | ||||
| 		if (!rchan && (outfd < 0) && (ms)) { | ||||
| 			ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); | ||||
|   | ||||
| @@ -48,7 +48,6 @@ struct ast_filestream { | ||||
| }; | ||||
|  | ||||
|  | ||||
| static struct ast_filestream *glist = NULL; | ||||
| static pthread_mutex_t vox_lock = AST_MUTEX_INITIALIZER; | ||||
| static int glistcnt = 0; | ||||
|  | ||||
|   | ||||
| @@ -125,7 +125,8 @@ struct ast_channel { | ||||
| 	 | ||||
| 	/*! Timing fd */ | ||||
| 	int timingfd; | ||||
|  | ||||
| 	int (*timingfunc)(void *data); | ||||
| 	void *timingdata; | ||||
|  | ||||
| 	/*! State of line -- Don't write directly, use ast_setstate */ | ||||
| 	int _state;				 | ||||
| @@ -695,8 +696,8 @@ int ast_autoservice_start(struct ast_channel *chan); | ||||
| int ast_autoservice_stop(struct ast_channel *chan); | ||||
|  | ||||
| /* If built with zaptel optimizations, force a scheduled expiration on the | ||||
|    timer fd */ | ||||
| int ast_settimeout(struct ast_channel *c, int ms); | ||||
|    timer fd, at which point we call the callback function / data */ | ||||
| int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data); | ||||
|  | ||||
| /* Transfer a channel (if supported).  Returns -1 on error, 0 if not supported | ||||
|    and 1 if supported and requested */ | ||||
|   | ||||
| @@ -259,7 +259,7 @@ int ast_stream_rewind(struct ast_filestream *fs, long ms); | ||||
|  */ | ||||
| long ast_tellstream(struct ast_filestream *fs); | ||||
|  | ||||
| #define AST_RESERVED_POINTERS 12 | ||||
| #define AST_RESERVED_POINTERS 20 | ||||
|  | ||||
| #if defined(__cplusplus) || defined(c_plusplus) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user