Commit 9cd81464 authored by Simon Morlat's avatar Simon Morlat

enhance event notification API, so that there can be several listeners, and...

enhance event notification API, so that there can be several listeners, and each listener can decide to receive event synchronously or asynchornously.
Add a new player/resampler/mixer in AudioStream, so that it is possible to play sounds to local speaker, in call or idle.
parent 0e6be4c7
......@@ -190,6 +190,9 @@ struct _AudioStream
MSFilter *plc;
MSFilter *ec;/*echo canceler*/
MSFilter *volsend,*volrecv; /*MSVolumes*/
MSFilter *local_mixer;
MSFilter *local_player;
MSFilter *local_player_resampler;
MSFilter *read_resampler;
MSFilter *write_resampler;
MSFilter *equalizer;
......@@ -282,6 +285,7 @@ MS2_PUBLIC AudioStream *audio_stream_new(int loc_rtp_port, int loc_rtcp_port, bo
#define AUDIO_STREAM_FEATURE_DTMF (1 << 5)
#define AUDIO_STREAM_FEATURE_DTMF_ECHO (1 << 6)
#define AUDIO_STREAM_FEATURE_MIXED_RECORDING (1 << 7)
#define AUDIO_STREAM_FEATURE_LOCAL_PLAYING (1 << 8)
#define AUDIO_STREAM_FEATURE_ALL (\
AUDIO_STREAM_FEATURE_PLC | \
......@@ -291,7 +295,8 @@ MS2_PUBLIC AudioStream *audio_stream_new(int loc_rtp_port, int loc_rtcp_port, bo
AUDIO_STREAM_FEATURE_VOL_RCV | \
AUDIO_STREAM_FEATURE_DTMF | \
AUDIO_STREAM_FEATURE_DTMF_ECHO |\
AUDIO_STREAM_FEATURE_MIXED_RECORDING \
AUDIO_STREAM_FEATURE_MIXED_RECORDING |\
AUDIO_STREAM_FEATURE_LOCAL_PLAYING \
)
......@@ -392,6 +397,8 @@ MS2_PUBLIC void audio_stream_stop (AudioStream * stream);
* */
MS2_PUBLIC int audio_stream_send_dtmf (AudioStream * stream, char dtmf);
MS2_PUBLIC MSFilter *audio_stream_get_local_player(AudioStream *stream);
MS2_PUBLIC int audio_stream_mixed_record_open(AudioStream *st, const char*filename);
MS2_PUBLIC int audio_stream_mixed_record_start(AudioStream *st);
......
......@@ -130,6 +130,7 @@ MS2_PUBLIC MSList * ms_list_append(MSList *elem, void * data);
MS2_PUBLIC MSList *ms_list_append_link(MSList *elem, MSList *new_elem);
MS2_PUBLIC MSList * ms_list_prepend(MSList *elem, void * data);
MS2_PUBLIC MSList * ms_list_free(MSList *elem);
MS2_PUBLIC MSList * ms_list_free_with_data(MSList *elem, void (*freefunc)(void*));
MS2_PUBLIC MSList * ms_list_concat(MSList *first, MSList *second);
MS2_PUBLIC MSList * ms_list_remove(MSList *first, void *data);
MS2_PUBLIC int ms_list_size(const MSList *first);
......
......@@ -178,8 +178,7 @@ struct _MSFilter{
ms_mutex_t lock;
MSQueue **inputs; /**<Table of input queues.*/
MSQueue **outputs;/**<Table of output queues */
MSFilterNotifyFunc notify;
void *notify_ud;
MSList *notify_callbacks;
void *data; /**<Pointer used by the filter for internal state and computations.*/
struct _MSTicker *ticker; /**<Pointer to the ticker object. It is not NULL when being called process()*/
/*private attributes */
......@@ -444,11 +443,37 @@ MS2_PUBLIC bool_t ms_filter_has_method(MSFilter *f, unsigned int id);
* @param f A MSFilter object.
* @param fn A MSFilterNotifyFunc that will be called.
* @param userdata A pointer to private data.
* @deprecated use ms_filter_add_notify_callback()
*
*/
//MS2_PUBLIC void ms_filter_set_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *userdata);
/**
* Set a callback on filter's to be informed of private filter's event.
* This callback is called from the filter's MSTicker, unless a global event queue
* is created to receive all filter's notification or synchronous flag is TRUE.
* See ms_event_queue_new() for details.
*
* @param f A MSFilter object.
* @param fn A MSFilterNotifyFunc that will be called.
* @param userdata A pointer to private data.
* @param synchronous boolean that indicates whether this callback must be called synchronously.
* @deprecated use ms_filter_add_notify_callback()
*
*/
MS2_PUBLIC void ms_filter_set_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *userdata);
MS2_PUBLIC void ms_filter_add_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *userdata, bool_t synchronous);
/**
* Remove a notify callback previously entered with ms_filter_add_notify_callback()
*
* @param f A MSFilter object.
* @param fn A MSFilterNotifyFunc that will be called.
* @param userdata A pointer to private data.
* @param synchronous boolean that indicates whether this callback must be called synchronously.
* @deprecated use ms_filter_add_notify_callback()
*
*/
MS2_PUBLIC void ms_filter_remove_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *userdata);
/**
* Get MSFilterId's filter.
......@@ -655,8 +680,8 @@ MS2_PUBLIC void ms_filter_preprocess(MSFilter *f, struct _MSTicker *t);
MS2_PUBLIC void ms_filter_postprocess(MSFilter *f);
MS2_PUBLIC bool_t ms_filter_inputs_have_data(MSFilter *f);
MS2_PUBLIC void ms_filter_notify(MSFilter *f, unsigned int id, void *arg);
MS2_PUBLIC void ms_filter_notify_synchronous(MSFilter *f, unsigned int id, void *arg);
MS2_PUBLIC void ms_filter_notify_no_arg(MSFilter *f, unsigned int id);
void ms_filter_clear_notify_callback(MSFilter *f);
#define ms_filter_lock(f) ms_mutex_lock(&(f)->lock)
#define ms_filter_unlock(f) ms_mutex_unlock(&(f)->lock)
MS2_PUBLIC void ms_filter_unregister_all(void);
......
......@@ -105,8 +105,16 @@ typedef enum _MSPlayerState MSPlayerState;
#define MS_PLAYER_GET_STATE \
MS_FILTER_METHOD(MSFilterPlayerInterface,5,MSPlayerState)
/**enable loop mode. Argument is a pause interval in milliseconds to be observed between end of play and resuming at start. A value of -1 disables loop mode*/
#define MS_PLAYER_SET_LOOP \
MS_FILTER_METHOD(MSFilterPlayerInterface,6,int)
#define MS_PLAYER_EOF \
MS_FILTER_EVENT_NO_ARG(MSFilterPlayerInterface,0)
#define MS_PLAYER_FORMAT_CHANGED\
MS_FILTER_EVENT_NO_ARG(MSFilterPlayerInterface,1)
/**
* Interface definitions for recorders
......
......@@ -126,7 +126,7 @@ typedef struct MixerState{
static void mixer_init(MSFilter *f){
MixerState *s=ms_new0(MixerState,1);
int i;
s->conf_mode=FALSE; /*this is the default, don't change it*/
s->nchannels=1;
s->rate=44100;
for(i=0;i<MIXER_MAX_CHANNELS;++i){
......
......@@ -204,6 +204,7 @@ static int player_open(MSFilter *f, void *arg){
if (read_wav_header(d)!=0 && strstr(file,".wav")){
ms_warning("File %s has .wav extension but wav header could be found.",file);
}
ms_filter_notify_no_arg(f,MS_PLAYER_FORMAT_CHANGED);
ms_message("%s opened: rate=%i,channel=%i",file,d->rate,d->nchannels);
return 0;
}
......@@ -299,6 +300,7 @@ static void player_process(MSFilter *f){
res = pcap_next_ex(d->pcap, &d->pcap_hdr, &d->pcap_data);
}
if (res == -2) {
ms_filter_notify_no_arg(f,MS_PLAYER_EOF);
ms_filter_notify_no_arg(f, MS_FILE_PLAYER_EOF);
} else if (res > 0) {
const u_char *ethernet_header = &d->pcap_data[0];
......@@ -372,6 +374,8 @@ static void player_process(MSFilter *f){
ms_queue_put(f->outputs[0],om);
}else freemsg(om);
if (err<bytes){
ms_filter_notify_no_arg(f,MS_PLAYER_EOF);
/*for compatibility:*/
ms_filter_notify_no_arg(f,MS_FILE_PLAYER_EOF);
lseek(d->fd,d->hsize,SEEK_SET);
......@@ -446,6 +450,7 @@ static MSFilterMethod player_methods[]={
{ MS_PLAYER_PAUSE, player_pause },
{ MS_PLAYER_CLOSE, player_close },
{ MS_PLAYER_GET_STATE, player_get_state },
{ MS_PLAYER_SET_LOOP, player_loop },
{ 0, NULL }
};
......@@ -457,13 +462,13 @@ MSFilterDesc ms_file_player_desc={
N_("Raw files and wav reader"),
MS_FILTER_OTHER,
NULL,
0,
0,
1,
player_init,
NULL,
player_process,
player_process,
NULL,
player_uninit,
player_uninit,
player_methods
};
......
......@@ -25,6 +25,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MS_EVENT_BUF_SIZE 8192
#endif
typedef enum {
OnlySynchronous,
OnlyAsynchronous,
Both
}InvocationMode;
static void ms_filter_invoke_callbacks(MSFilter *f, unsigned int id, void *arg, InvocationMode synchronous_mode);
struct _MSNotifyContext{
MSFilterNotifyFunc fn;
void *ud;
int synchronous;
};
typedef struct _MSNotifyContext MSNotifyContext;
struct _MSEventQueue{
ms_mutex_t mutex; /*could be replaced by an atomic counter for freeroom*/
uint8_t *rptr;
......@@ -75,8 +91,7 @@ static bool_t read_event(MSEventQueue *q){
argsize=id & 0xff;
evsize=argsize+16;
data=q->rptr+16;
if (f->notify!=NULL)
f->notify(f->notify_ud,f,id,argsize>0 ? data : NULL);
ms_filter_invoke_callbacks(f,id,argsize>0 ? data : NULL, OnlyAsynchronous);
q->rptr+=evsize;
if (q->rptr>=q->endptr){
q->rptr=q->buffer;
......@@ -126,24 +141,73 @@ void ms_event_queue_pump(MSEventQueue *q){
}
}
static MSNotifyContext * ms_notify_context_new(MSFilterNotifyFunc fn, void *ud, bool_t synchronous){
MSNotifyContext *ctx=ms_new0(MSNotifyContext,1);
ctx->fn=fn;
ctx->ud=ud;
ctx->synchronous=synchronous;
return ctx;
}
static void ms_notify_context_destroy(MSNotifyContext *obj){
ms_free(obj);
}
void ms_filter_add_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *ud, bool_t synchronous){
f->notify_callbacks=ms_list_append(f->notify_callbacks,ms_notify_context_new(fn,ud,synchronous));
}
void ms_filter_remove_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *ud){
MSList *elem;
MSList *found=NULL;
for(elem=f->notify_callbacks;elem!=NULL;elem=elem->next){
MSNotifyContext *ctx=(MSNotifyContext*)elem->data;
if (ctx->fn==fn && ctx->ud==ud){
found=elem;
break;
}
}
if (found){
ms_notify_context_destroy((MSNotifyContext*)found->data);
f->notify_callbacks=ms_list_remove_link(f->notify_callbacks,found);
}else ms_warning("ms_filter_remove_notify_callback(filter=%p): no registered callback with fn=%p and ud=%p",f,fn,ud);
}
void ms_filter_clear_notify_callback(MSFilter *f){
f->notify_callbacks=ms_list_free_with_data(f->notify_callbacks,(void (*)(void*))ms_notify_context_destroy);
}
static void ms_filter_invoke_callbacks(MSFilter *f, unsigned int id, void *arg, InvocationMode synchronous_mode){
MSList *elem;
for (elem=f->notify_callbacks;elem!=NULL;elem=elem->next){
MSNotifyContext *ctx=(MSNotifyContext*)elem->data;
if (synchronous_mode==Both || (synchronous_mode==OnlyAsynchronous && !ctx->synchronous)
|| (synchronous_mode==OnlySynchronous && ctx->synchronous))
ctx->fn(ctx->ud,f,id,arg);
}
}
void ms_filter_set_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *ud){
ms_filter_add_notify_callback(f,fn,ud,FALSE);
}
void ms_filter_notify(MSFilter *f, unsigned int id, void *arg){
if (f->notify!=NULL){
if (f->notify_callbacks!=NULL){
if (ms_global_event_queue==NULL){
/* synchronous notification */
f->notify(f->notify_ud,f,id,arg);
ms_filter_invoke_callbacks(f,id,arg,Both);
}else{
ms_filter_invoke_callbacks(f,id,arg,OnlySynchronous);
write_event(ms_global_event_queue,f,id,arg);
}
}
}
void ms_filter_notify_synchronous(MSFilter *f, unsigned int id, void *arg){
if (f->notify){
f->notify(f->notify_ud,f,id,arg);
}
}
void ms_filter_notify_no_arg(MSFilter *f, unsigned int id){
ms_filter_notify(f,id,NULL);
}
......@@ -122,19 +122,23 @@ MSList * ms_list_concat(MSList *first, MSList *second){
return first;
}
MSList * ms_list_free(MSList *list){
MSList *elem = list;
MSList * ms_list_free_with_data(MSList *list, void (*freefunc)(void*)){
MSList *elem;
MSList *tmp;
if (list==NULL) return NULL;
while(elem->next!=NULL) {
tmp = elem;
elem = elem->next;
ms_free(tmp);
for (elem=list;elem!=NULL;){
tmp=elem->next;
if (freefunc) freefunc(elem->data);
ms_free(elem);
elem=tmp;
}
ms_free(elem);
return NULL;
}
MSList * ms_list_free(MSList *elem){
return ms_list_free_with_data(elem,NULL);
}
MSList * ms_list_remove(MSList *first, void *data){
MSList *it;
it=ms_list_find(first,data);
......
......@@ -299,17 +299,13 @@ int ms_filter_call_method_noarg(MSFilter *f, unsigned int id){
return ms_filter_call_method(f,id,NULL);
}
void ms_filter_set_notify_callback(MSFilter *f, MSFilterNotifyFunc fn, void *ud){
f->notify=fn;
f->notify_ud=ud;
}
void ms_filter_destroy(MSFilter *f){
if (f->desc->uninit!=NULL)
f->desc->uninit(f);
if (f->inputs!=NULL) ms_free(f->inputs);
if (f->outputs!=NULL) ms_free(f->outputs);
ms_mutex_destroy(&f->lock);
ms_filter_clear_notify_callback(f);
ms_free(f);
}
......
......@@ -47,7 +47,7 @@ static void ext_display_process(MSFilter *f){
}
}
ms_filter_notify_synchronous(f,MS_EXT_DISPLAY_ON_DRAW,&output);
ms_filter_notify(f,MS_EXT_DISPLAY_ON_DRAW,&output);
if (f->inputs[0]!=NULL)
ms_queue_flush(f->inputs[0]);
......
......@@ -62,6 +62,9 @@ static void audio_stream_free(AudioStream *stream) {
if (stream->send_tee) ms_filter_destroy(stream->send_tee);
if (stream->recorder) ms_filter_destroy(stream->recorder);
if (stream->recorder_mixer) ms_filter_destroy(stream->recorder_mixer);
if (stream->local_mixer) ms_filter_destroy(stream->local_mixer);
if (stream->local_player) ms_filter_destroy(stream->local_player);
if (stream->local_player_resampler) ms_filter_destroy(stream->local_player_resampler);
if (stream->recorder_file) ms_free(stream->recorder_file);
ms_free(stream);
}
......@@ -208,6 +211,42 @@ void audio_stream_unprepare_sound(AudioStream *stream){
}
}
static void player_callback(void *ud, MSFilter *f, unsigned int id, void *arg){
AudioStream *stream=(AudioStream *)ud;
int sr=0;
int channels=0;
switch(id){
case MS_PLAYER_FORMAT_CHANGED:
ms_filter_call_method(f,MS_FILTER_GET_SAMPLE_RATE,&sr);
ms_filter_call_method(f,MS_FILTER_GET_NCHANNELS,&channels);
if (f==stream->local_player){
ms_filter_call_method(stream->local_player_resampler,MS_FILTER_SET_SAMPLE_RATE,&sr);
ms_filter_call_method(stream->local_player_resampler,MS_FILTER_SET_NCHANNELS,&channels);
}
break;
default:
break;
}
}
static void setup_local_player(AudioStream *stream, int samplerate, int channels){
MSConnectionHelper cnx;
stream->local_player=ms_filter_new(MS_FILE_PLAYER_ID);
stream->local_player_resampler=ms_filter_new(MS_RESAMPLE_ID);
ms_connection_helper_start(&cnx);
ms_connection_helper_link(&cnx,stream->local_player,-1,0);
ms_connection_helper_link(&cnx,stream->local_player_resampler,0,0);
ms_connection_helper_link(&cnx,stream->local_mixer,1,-1);
ms_filter_call_method(stream->local_player_resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&samplerate);
ms_filter_call_method(stream->local_player_resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&channels);
ms_filter_call_method(stream->local_mixer,MS_FILTER_SET_SAMPLE_RATE,&samplerate);
ms_filter_call_method(stream->local_mixer,MS_FILTER_SET_NCHANNELS,&channels);
ms_filter_add_notify_callback(stream->local_player,player_callback,stream,TRUE);
}
int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char *rem_rtp_ip,int rem_rtp_port,
const char *rem_rtcp_ip, int rem_rtcp_port, int payload,int jitt_comp, const char *infile, const char *outfile,
MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec)
......@@ -472,6 +511,10 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
} else {
stream->plc = NULL;
}
if (stream->features & AUDIO_STREAM_FEATURE_LOCAL_PLAYING){
stream->local_mixer=ms_filter_new(MS_AUDIO_MIXER_ID);
}
/* create ticker */
if (stream->ms.ticker==NULL) start_ticker(&stream->ms);
......@@ -513,6 +556,10 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
ms_connection_helper_link(&h,stream->recv_tee,0,0);
if (stream->equalizer)
ms_connection_helper_link(&h,stream->equalizer,0,0);
if (stream->local_mixer){
ms_connection_helper_link(&h,stream->local_mixer,0,0);
setup_local_player(stream,sample_rate, pt->channels);
}
if (stream->ec)
ms_connection_helper_link(&h,stream->ec,0,0);
if (stream->write_resampler)
......@@ -773,8 +820,15 @@ void audio_stream_equalizer_set_gain(AudioStream *stream, int frequency, float g
}
}
void audio_stream_stop(AudioStream * stream)
{
static void dismantle_local_player(AudioStream *stream){
MSConnectionHelper cnx;
ms_connection_helper_start(&cnx);
ms_connection_helper_unlink(&cnx,stream->local_player,-1,0);
ms_connection_helper_unlink(&cnx,stream->local_player_resampler,0,0);
ms_connection_helper_unlink(&cnx,stream->local_mixer,1,-1);
}
void audio_stream_stop(AudioStream * stream){
if (stream->ms.ticker){
MSConnectionHelper h;
......@@ -824,6 +878,10 @@ void audio_stream_stop(AudioStream * stream)
ms_connection_helper_unlink(&h,stream->equalizer,0,0);
if (stream->ec!=NULL)
ms_connection_helper_unlink(&h,stream->ec,0,0);
if (stream->local_mixer){
ms_connection_helper_unlink(&h,stream->local_mixer,0,0);
dismantle_local_player(stream);
}
if (stream->write_resampler!=NULL)
ms_connection_helper_unlink(&h,stream->write_resampler,0,0);
ms_connection_helper_unlink(&h,stream->soundwrite,0,-1);
......
......@@ -27,6 +27,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msfileplayer.h"
static void ring_player_event_handler(void *ud, MSFilter *f, unsigned int evid, void *arg){
RingStream *stream=(RingStream*)ud;
int channels,rate;
if (evid==MS_PLAYER_FORMAT_CHANGED){
ms_filter_call_method(stream->source,MS_FILTER_GET_NCHANNELS,&channels);
ms_filter_call_method(stream->source,MS_FILTER_GET_SAMPLE_RATE,&rate);
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_NCHANNELS,&channels);
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_SAMPLE_RATE,&rate);
ms_filter_call_method(stream->gendtmf,MS_FILTER_SET_SAMPLE_RATE,&rate);
ms_filter_call_method(stream->gendtmf,MS_FILTER_SET_NCHANNELS,&channels);
}
}
RingStream * ring_start(const char *file, int interval, MSSndCard *sndcard){
return ring_start_with_cb(file,interval,sndcard,NULL,NULL);
}
......@@ -41,40 +54,32 @@ RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard
stream=(RingStream *)ms_new0(RingStream,1);
stream->source=ms_filter_new(MS_FILE_PLAYER_ID);
if (file)
ms_filter_call_method(stream->source,MS_FILE_PLAYER_OPEN,(void*)file);
ms_filter_call_method(stream->source,MS_FILE_PLAYER_LOOP,&interval);
ms_filter_call_method_noarg(stream->source,MS_FILE_PLAYER_START);
ms_filter_add_notify_callback(stream->source,ring_player_event_handler,stream,TRUE);
if (func!=NULL)
ms_filter_set_notify_callback(stream->source,func,user_data);
ms_filter_add_notify_callback(stream->source,func,user_data,FALSE);
stream->gendtmf=ms_filter_new(MS_DTMF_GEN_ID);
stream->sndwrite=ms_snd_card_create_writer(sndcard);
stream->write_resampler=ms_filter_new(MS_RESAMPLE_ID);
if (file){
ms_filter_call_method(stream->source,MS_FILE_PLAYER_OPEN,(void*)file);
ms_filter_call_method(stream->source,MS_FILE_PLAYER_LOOP,&interval);
ms_filter_call_method_noarg(stream->source,MS_FILE_PLAYER_START);
}
ms_filter_call_method(stream->source,MS_FILTER_GET_SAMPLE_RATE,&srcrate);
ms_filter_call_method(stream->gendtmf,MS_FILTER_SET_SAMPLE_RATE,&srcrate);
ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_SAMPLE_RATE,&srcrate);
ms_filter_call_method(stream->sndwrite,MS_FILTER_GET_SAMPLE_RATE,&dstrate);
if (srcrate!=dstrate){
stream->write_resampler=ms_filter_new(MS_RESAMPLE_ID);
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_SAMPLE_RATE,&srcrate);
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&dstrate);
ms_message("configuring resampler from rate [%i] to rate [%i]", srcrate,dstrate);
}
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_SAMPLE_RATE,&srcrate);
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&dstrate);
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_NCHANNELS,&srcchannels);
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&dstchannels);
ms_message("configuring resampler from rate [%i] to rate [%i], from channels [%i] to channels [%i]",
srcrate,dstrate,srcchannels,dstchannels);
ms_filter_call_method(stream->source,MS_FILTER_GET_NCHANNELS,&srcchannels);
ms_filter_call_method(stream->gendtmf,MS_FILTER_SET_NCHANNELS,&srcchannels);
ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_NCHANNELS,&srcchannels);
ms_filter_call_method(stream->sndwrite,MS_FILTER_GET_NCHANNELS,&dstchannels);
if (srcchannels != dstchannels) {
if (!stream->write_resampler) {
stream->write_resampler=ms_filter_new(MS_RESAMPLE_ID);
}
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_NCHANNELS,&srcchannels);
ms_filter_call_method(stream->write_resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&dstchannels);
ms_message("configuring resampler from channels [%i] to channels [%i]", srcchannels, dstchannels);
}
params.name="Ring MSTicker";
params.prio=MS_TICKER_PRIO_HIGH;
stream->ticker=ms_ticker_new_with_params(&params);
......
......@@ -412,7 +412,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
if (stream->rendercb!=NULL){
stream->output=ms_filter_new(MS_EXT_DISPLAY_ID);
ms_filter_set_notify_callback(stream->output,ext_display_cb,stream);
ms_filter_add_notify_callback(stream->output,ext_display_cb,stream,TRUE);
}else{
stream->output=ms_filter_new_from_name (stream->display_name);
}
......@@ -440,7 +440,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
return -1;
}
}
ms_filter_set_notify_callback(stream->ms.decoder, event_cb, stream);
ms_filter_add_notify_callback(stream->ms.decoder, event_cb, stream,FALSE);
stream->ms.rtprecv = ms_filter_new (MS_RTP_RECV_ID);
ms_filter_call_method(stream->ms.rtprecv,MS_RTP_RECV_SET_SESSION,stream->ms.session);
......
......@@ -202,7 +202,7 @@ static void basic_audio_stream() {
, NULL
, 0),0);
ms_filter_set_notify_callback(marielle->soundread, notify_cb, &marielle_stats);
ms_filter_add_notify_callback(marielle->soundread, notify_cb, &marielle_stats,TRUE);
CU_ASSERT_EQUAL(audio_stream_start_full(margaux
, profile
......
......@@ -62,7 +62,7 @@ static void dtmfgen_tonedet(void) {
ms_filter_reset_statistics();
ms_tester_create_ticker();
ms_tester_create_filters(filter_mask);
ms_filter_set_notify_callback(ms_tester_tonedet, (MSFilterNotifyFunc)tone_detected_cb, NULL);
ms_filter_add_notify_callback(ms_tester_tonedet, (MSFilterNotifyFunc)tone_detected_cb, NULL,TRUE);
ms_connection_helper_start(&h);
ms_connection_helper_link(&h, ms_tester_voidsource, -1, 0);
ms_connection_helper_link(&h, ms_tester_dtmfgen, 0, 0);
......@@ -112,7 +112,7 @@ static void dtmfgen_enc_dec_tonedet(char *mime, int sample_rate, int nchannels)
ms_filter_call_method(ms_tester_voidsink, MS_FILTER_SET_NCHANNELS, &nchannels);
ms_filter_set_notify_callback(ms_tester_tonedet, (MSFilterNotifyFunc)tone_detected_cb, NULL);
ms_filter_add_notify_callback(ms_tester_tonedet, (MSFilterNotifyFunc)tone_detected_cb, NULL,TRUE);
ms_connection_helper_start(&h);
ms_connection_helper_link(&h, ms_tester_voidsource, -1, 0);
ms_connection_helper_link(&h, ms_tester_dtmfgen, 0, 0);
......@@ -164,7 +164,7 @@ static void dtmfgen_enc_rtp_dec_tonedet(void) {
ms_tester_create_ticker();
ms_tester_codec_mime = "pcmu";
ms_tester_create_filters(filter_mask);
ms_filter_set_notify_callback(ms_tester_tonedet, (MSFilterNotifyFunc)tone_detected_cb, NULL);
ms_filter_add_notify_callback(ms_tester_tonedet, (MSFilterNotifyFunc)tone_detected_cb, NULL,TRUE);
rtps = create_duplex_rtpsession(50060, 0, FALSE);
rtp_session_set_remote_addr_full(rtps, "127.0.0.1", 50060, "127.0.0.1", 50061);
rtp_session_set_payload_type(rtps, 8);
......@@ -213,7 +213,7 @@ static void dtmfgen_filerec_fileplay_tonedet(void) {
ms_filter_reset_statistics();
ms_tester_create_ticker();
ms_tester_create_filters(filter_mask);
ms_filter_set_notify_callback(ms_tester_tonedet, (MSFilterNotifyFunc)tone_detected_cb, NULL);
ms_filter_add_notify_callback(ms_tester_tonedet, (MSFilterNotifyFunc)tone_detected_cb, NULL,TRUE);
// Generate tones and save them to a file
ms_filter_call_method_noarg(ms_tester_filerec, MS_FILE_REC_CLOSE);
......
......@@ -136,7 +136,7 @@ static void fileplay_soundwrite(const char *filename) {
ms_filter_reset_statistics();
ms_tester_create_ticker();
ms_tester_create_filters(filter_mask);
ms_filter_set_notify_callback(ms_tester_fileplay, fileplay_eof, &done);
ms_filter_add_notify_callback(ms_tester_fileplay, fileplay_eof, &done,TRUE);
ms_filter_call_method_noarg(ms_tester_fileplay, MS_FILE_PLAYER_CLOSE);
ms_filter_call_method(ms_tester_fileplay, MS_FILE_PLAYER_OPEN, (void *)filename);
ms_filter_call_method(ms_tester_fileplay, MS_FILTER_GET_SAMPLE_RATE, &sample_rate);
......
......@@ -74,8 +74,8 @@ int main(int argc, char *argv[]){
expected_tone.frequency=2000;
expected_tone.min_duration=200;
expected_tone.min_amplitude=0.5;
ms_filter_set_notify_callback(det,(MSFilterNotifyFunc)tone_detected_cb,NULL);
ms_filter_set_notify_callback(gen,(MSFilterNotifyFunc)tone_sent_cb,NULL);
ms_filter_add_notify_callback(det,(MSFilterNotifyFunc)tone_detected_cb,NULL,TRUE);
ms_filter_add_notify_callback(gen,(MSFilterNotifyFunc)tone_sent_cb,NULL,TRUE);
ms_filter_call_method(det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment