Esempio n. 1
0
gint ms_fifo_get_read_ptr(MSFifo *fifo, gint bsize, void **ret_ptr)
{
	gchar *rnext;
	
	*ret_ptr=NULL;
	/*	//ms_trace("ms_fifo_get_read_ptr: entering.");*/
	g_return_val_if_fail(bsize<=fifo->r_gran,-EINVAL);
	
	if (bsize>fifo->readsize)
	{
		ms_trace("Not enough data: bsize=%i, readsize=%i",bsize,fifo->readsize);
		return (-ENODATA);
	}
	
	rnext=fifo->rd_ptr+bsize;
	if (rnext<=fifo->r_end){
		
		*ret_ptr=fifo->rd_ptr;
		fifo->rd_ptr=rnext;
	}else{
		int unread=fifo->r_end-fifo->rd_ptr;
		*ret_ptr=fifo->begin-unread;
		memcpy(fifo->buffer->buffer,fifo->r_end-fifo->saved_offset,fifo->saved_offset);
		fifo->rd_ptr=(char*)(*ret_ptr) + bsize;
		fifo->r_end=fifo->w_end;	/* this is important ! */
		ms_trace("moving read ptr to %x",fifo->rd_ptr);
		
	}
	/* update write size*/
	fifo->writesize+=bsize;
	fifo->readsize-=bsize;
	return bsize;
}
Esempio n. 2
0
gint ms_fifo_get_write_ptr(MSFifo *fifo, gint bsize, void **ret_ptr)
{
	gchar *wnext;

	*ret_ptr=NULL;
	/*	//ms_trace("ms_fifo_get_write_ptr: Entering.");*/
	g_return_val_if_fail(bsize<=fifo->w_gran,-EINVAL);
	if (bsize>fifo->writesize)
	{
		ms_trace("Not enough space: bsize=%i, writesize=%i",bsize,fifo->writesize);
		*ret_ptr=NULL;
		return(-ENODATA);
	}
	wnext=fifo->wr_ptr+bsize;
	if (wnext<=fifo->w_end){
		*ret_ptr=fifo->wr_ptr;
		fifo->wr_ptr=wnext;
	}else{
		*ret_ptr=fifo->begin;
		fifo->r_end=fifo->wr_ptr;
		fifo->wr_ptr=fifo->begin+bsize;
		ms_trace("moving write ptr to %x",fifo->wr_ptr);
	}
	fifo->prev_wr_ptr=*ret_ptr;
	/* update readsize*/
	fifo->readsize+=bsize;
	fifo->writesize-=bsize;
	/*	//ms_trace("ms_fifo_get_write_ptr: readsize=%i, writesize=%i",fifo->readsize,fifo->writesize);*/
	return bsize;
}
Esempio n. 3
0
void ms_read_process(MSRead *r)
{
	MSFifo *f;
	MSQueue *q;
	MSMessage *msg=NULL;
	int err;
	gint gran=r->gran;
	void *p;
	
	f=r->foutputs[0];
	if ((f!=NULL) && (r->state==MS_READ_STATE_STARTED))
	{
		ms_fifo_get_write_ptr(f,gran,&p);
		if (p!=NULL)
		{
			err=read(r->fd,p,gran);
			if (err<0)
			{
				/* temp: */
				g_warning("ms_read_process: failed to read: %s.\n",strerror(errno));
			}
			else if (err<gran){
				ms_trace("ms_read_process: end of file.");
				ms_filter_notify_event(MS_FILTER(r),MS_READ_EVENT_EOF,NULL);
				r->state=MS_READ_STATE_STOPPED;
				close(r->fd);
				r->fd=-1;
			}
			if (r->need_swap) swap_buffer(p,gran);
		}
	}
	/* process output queues*/
	q=r->qoutputs[0];
	if ((q!=NULL) && (r->fd>0))
	{
		msg=ms_message_new(r->gran);
		err=read(r->fd,msg->data,r->gran);
		if (err>0){
			msg->size=err;
			ms_queue_put(q,msg);
			if (r->need_swap) swap_buffer(msg->data,r->gran);
		}else{
			ms_filter_notify_event(MS_FILTER(r),MS_READ_EVENT_EOF,NULL);
			ms_trace("End of file reached.");
			r->state=MS_READ_STATE_STOPPED;
		}				
	}	
}
Esempio n. 4
0
File: ms.c Progetto: AlekSi/Jabbin
/*execute the processing chain attached to a sync source. It is called as a thread by ms_main()*/
void *ms_thread_run(void *sync_ptr)
{
	MSSync *sync=(MSSync*) sync_ptr;
	GList *filter;
	MSFilter *f;
	
	
	ms_sync_lock(sync);  
	while(sync->run)
	{
		//g_message("sync->run=%i",sync->run);
		if (sync->samples_per_tick==0) ms_sync_suspend(sync);
		if (sync->flags & MS_SYNC_NEED_UPDATE){
			ms_compile(sync);
			ms_sync_setup(sync);
		}
		filter=sync->execution_list;
		ms_sync_unlock(sync);
		//ms_trace("Calling synchronisation");
		ms_sync_synchronize(sync);
		while(filter!=NULL)
		{
			f=(MSFilter*)filter->data;
			if (MS_FILTER_GET_CLASS(f)->attributes & FILTER_IS_SOURCE)
			{
				/* execute it once */
				ms_trace("Running source filter %s.",f->klass->name);
				ms_filter_process(f);
			}
			else
			{
				/* make the filter process its input data until it has no more */
				while ( ms_filter_fifos_have_data(f) || ms_filter_queues_have_data(f) )
				{
					ms_trace("Running filter %s.",f->klass->name);
					ms_filter_process(f);
				}
			}
			filter=g_list_next(filter);
		}
		ms_sync_lock(sync);  
	}
	g_cond_signal(sync->stop_cond);	/* signal that the sync thread has finished */
	ms_sync_unlock(sync);
	g_message("Mediastreamer processing thread is exiting.");
	return NULL;
}
Esempio n. 5
0
MSBuffer * ms_buffer_new(guint32 size)
{
    MSBuffer *buf;
    buf=(MSBuffer*)g_malloc(sizeof(MSBuffer)+size);
    buf->ref_count=0;
    buf->size=size;
    ms_trace("ms_buffer_new: Allocating buffer of %i bytes.",size);
    /* allocate the data buffer: there is a lot of optmisation that can be done by using a pool of cached buffers*/
    buf->buffer=((char*)(buf))+sizeof(MSBuffer); /* to avoid to do two allocations,
					buffer info and buffer are contigous.*/
    buf->flags=MS_BUFFER_CONTIGUOUS;
    return(buf);
}
Esempio n. 6
0
File: ms.c Progetto: AlekSi/Jabbin
/**
 * ms_start:
 * @sync: A synchronisation source to be started.
 *
 * Starts a thread that will shedule all processing chains attached to the synchronisation source @sync.
 *
 *
 */
void ms_start(MSSync *sync)
{
	if (sync->run==1) return; /*already running*/
	ms_compile(sync);  
	ms_sync_setup(sync);
	/* this is to avoid race conditions, for example:
							ms_start(sync);
							ms_oss_write_start(ossw);
							here tge ossw filter need to be compiled to run ms_oss_write_start()
							*/
	ms_trace("ms_start: creating new thread.");
	sync->run=1;
	sync->thread=g_thread_create((GThreadFunc)ms_thread_run,(gpointer)sync,TRUE,NULL);
	if (sync->thread==NULL){
		g_warning("Could not create thread !");
	}
}
Esempio n. 7
0
void ms_rtp_send_process(MSRtpSend *r)
{
	MSFifo *fi;
	MSQueue *qi;
	MSSync *sync= r->sync;
	int gran=ms_sync_get_samples_per_tick(sync);
	guint32 ts;
	void *s;
	guint skip;
	guint32 synctime=sync->time;
	
	g_return_if_fail(gran>0);
	if (r->rtpsession==NULL) return;

	ms_filter_lock(MS_FILTER(r));
	skip=r->delay!=0;
	if (skip) r->delay--;
	/* process output fifo and output queue*/
	fi=r->f_inputs[0];
	if (fi!=NULL)
	{
		ts=get_new_timestamp(r,synctime);
		/* try to read r->packet_size bytes and send them in a rtp packet*/
		ms_fifo_get_read_ptr(fi,r->packet_size,&s);
		if (!skip){
			rtp_session_send_with_ts(r->rtpsession,s,r->packet_size,ts);
			ms_trace("len=%i, ts=%i ",r->packet_size,ts);
		}
	}
	qi=r->q_inputs[0];
	if (qi!=NULL)
	{
		MSMessage *msg;
		/* read a MSMessage and send it through the network*/
		while ( (msg=ms_queue_get(qi))!=NULL){
			ts=get_new_timestamp(r,synctime);
			if (!skip) {
				/*g_message("Sending packet with ts=%u",ts);*/
				rtp_session_send_with_ts(r->rtpsession,msg->data,msg->size,ts);
				
			}
			ms_message_destroy(msg);
		}
	}
	ms_filter_unlock(MS_FILTER(r));
}
Esempio n. 8
0
guint32 get_new_timestamp(MSRtpSend *r,guint32 synctime)
{
	guint32 clockts;
	/* use the sync system time to compute a timestamp */
	PayloadType *pt=rtp_profile_get_payload(r->rtpsession->profile,r->rtpsession->payload_type);
	g_return_val_if_fail(pt!=NULL,0);
	clockts=(guint32)(((double)synctime * (double)pt->clock_rate)/1000.0);
	ms_trace("ms_rtp_send_process: sync->time=%i clock=%i",synctime,clockts);
	if (r->flags & RTPSEND_CONFIGURED){
		if (RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(clockts,r->ts+(2*r->ts_inc) )){
			r->ts=clockts;
		}
		else r->ts+=r->ts_inc;
	}else{
		r->ts=clockts;
	}
	return r->ts;
}
Esempio n. 9
0
File: ms.c Progetto: AlekSi/Jabbin
/* compile graphs attached to a sync source*/
int ms_compile(MSSync *sync)
{
	int i;
	GList *list1=NULL,*list2=NULL,*elem;
	GList *proc_chain=NULL;
	MSFilter *f;
	
	/* first free the old list if we are just updating*/
	if (sync->execution_list!=NULL) g_list_free(sync->execution_list);
	/* get the list of filters attached to this sync*/
	for (i=0;i<sync->filters;i++)
	{
		//printf("found filter !\n");
		list1=g_list_append(list1,sync->attached_filters[i]);
	}
	/* find the processing chain */
	while (list1!=NULL)
	{
		list2=NULL;
		/* sort the list by types of filter*/
		list1=g_list_sort(list1,compare);
		/* save into the processing chain list*/
		//printf("list1 :%i elements\n",g_list_length(list1));
		proc_chain=g_list_concat(proc_chain,list1);
		/* get all following filters. They are appended to list2*/
		elem=list1;
		while (elem!=NULL)
		{
			f=(MSFilter*)(elem->data);
			/* check if filter 's status */
			if (f->klass->attributes & FILTER_CAN_SYNC)
			{
				sync->samples_per_tick=0;
			}
			list2=get_nexts(f,list2);
			elem=g_list_next(elem);
		}
		list1=list2;
	}
	sync->execution_list=proc_chain;
	sync->flags&=~MS_SYNC_NEED_UPDATE;
	ms_trace("%i filters successfully compiled in a processing chain.",g_list_length(sync->execution_list));
	return 0;
}
Esempio n. 10
0
void ms_speex_dec_class_init(MSSpeexDecClass *klass)
{
	gint frame_size=0;
	
	ms_filter_class_init(MS_FILTER_CLASS(klass));
	/* use the largest frame size to configure fifos */
	speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &frame_size);
	MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_speex_dec_process;
	MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_speex_dec_setup;
	MS_FILTER_CLASS(klass)->unsetup=(MSFilterSetupFunc)ms_speex_dec_unsetup;
	MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_speex_dec_destroy;
	MS_FILTER_CLASS(klass)->set_property=(MSFilterPropertyFunc)ms_speex_dec_set_property;
	ms_filter_class_set_name(MS_FILTER_CLASS(klass),"SpeexDecoder");
	MS_FILTER_CLASS(klass)->info=(MSFilterInfo*)&speex_info;
	MS_FILTER_CLASS(klass)->max_foutputs=1;
	MS_FILTER_CLASS(klass)->max_qinputs=1;
	MS_FILTER_CLASS(klass)->w_maxgran=frame_size*2;
	ms_trace("ms_speex_dec_class_init: w_maxgran is %i.",MS_FILTER_CLASS(klass)->w_maxgran);
}
Esempio n. 11
0
MSFifo * ms_fifo_new_with_buffer(gint r_gran, gint w_gran, gint r_offset, gint w_offset,
																 gint min_fifo_size)
{
	MSFifo *fifo;
	MSBuffer *buf;
	gint saved_offset=MAX(r_gran+r_offset,w_offset);
	gint fifo_size;
	gint tmp;
	if (min_fifo_size==0) min_fifo_size=w_gran;
	
	/* we must allocate a fifo with a size multiple of min_fifo_size,
	with a saved_offset */
	if (min_fifo_size>MS_BUFFER_LARGE)
		fifo_size=(min_fifo_size) + saved_offset;
	else fifo_size=(6*min_fifo_size) + saved_offset;
	buf=ms_buffer_new(fifo_size);
	fifo=ms_fifo_new(buf,r_gran,w_gran,r_offset,w_offset);
	ms_trace("fifo_size=%i",fifo_size);
	return(fifo);
}
Esempio n. 12
0
MSFifo * ms_fifo_new(MSBuffer *buf, gint r_gran, gint w_gran, gint r_offset, gint w_offset)
{
	MSFifo *fifo;
	gint saved_offset=MAX(r_gran+r_offset,w_offset);
	
	g_return_val_if_fail(saved_offset<=(buf->size),NULL);
	fifo=g_malloc(sizeof(MSFifo));
	fifo->buffer=buf;
	fifo->r_gran=r_gran;
	fifo->w_gran=w_gran;
	fifo->begin=fifo->wr_ptr=fifo->rd_ptr=buf->buffer+saved_offset;
	fifo->readsize=0;
	fifo->size=fifo->writesize=buf->size-saved_offset;
	fifo->saved_offset= saved_offset;
	fifo->r_end=fifo->w_end=buf->buffer+buf->size;
	fifo->pre_end=fifo->w_end-saved_offset;
	buf->ref_count++;
	fifo->prev_data=NULL;
	fifo->next_data=NULL;
	ms_trace("fifo base=%x, begin=%x, end=%x, saved_offset=%i, size=%i"
			,fifo->buffer->buffer,fifo->begin,fifo->w_end,fifo->saved_offset,fifo->size);
	return(fifo);
}