static void ecc_play_tones(EcCalibrator *ecc){ MSDtmfGenCustomTone tone; MSToneDetectorDef expected_tone; ms_filter_set_notify_callback(ecc->det,on_tone_received,ecc); expected_tone.frequency=2000; expected_tone.min_duration=40; expected_tone.min_amplitude=0.02; ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); tone.frequency=1300; tone.duration=1000; tone.amplitude=1.0; /*play an initial tone to startup the audio playback/capture*/ ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(2); ms_filter_set_notify_callback(ecc->gen,on_tone_sent,ecc); tone.frequency=2000; tone.duration=100; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(1); ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(1); ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(1); if (ecc->sent_count==3) { if (ecc->recv_count==3){ int delay=ecc->acc/3; if (delay<0){ ms_error("Quite surprising calibration result, delay=%i",delay); ecc->status=LinphoneEcCalibratorFailed; }else{ ms_message("Echo calibration estimated delay to be %i ms",delay); ecc->delay=delay; ecc->status=LinphoneEcCalibratorDone; } } else if (ecc->recv_count == 0) { ms_message("Echo calibration succeeded, no echo has been detected"); ecc->status = LinphoneEcCalibratorDoneNoEcho; } else { ecc->status = LinphoneEcCalibratorFailed; } }else{ ecc->status=LinphoneEcCalibratorFailed; } if (ecc->status == LinphoneEcCalibratorFailed) { ms_error("Echo calibration failed, tones received = %i",ecc->recv_count); } }
RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard, MSFilterNotifyFunc func,void * user_data) { RingStream *stream; int tmp; stream=(RingStream *)ms_new0(RingStream,1); stream->source=ms_filter_new(MS_FILE_PLAYER_ID); if (ms_filter_call_method(stream->source,MS_FILE_PLAYER_OPEN,(void*)file)<0){ ms_filter_destroy(stream->source); ms_free(stream); return NULL; } ms_filter_call_method(stream->source,MS_FILE_PLAYER_LOOP,&interval); ms_filter_call_method_noarg(stream->source,MS_FILE_PLAYER_START); if (func!=NULL) ms_filter_set_notify_callback(stream->source,func,user_data); stream->sndwrite=ms_snd_card_create_writer(sndcard); ms_filter_call_method(stream->source,MS_FILTER_GET_SAMPLE_RATE,&tmp); ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_SAMPLE_RATE,&tmp); ms_filter_call_method(stream->source,MS_FILTER_GET_NCHANNELS,&tmp); ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_NCHANNELS,&tmp); stream->ticker=ms_ticker_new(); ms_ticker_set_name(stream->ticker,"Audio (ring) MSTicker"); ms_filter_link(stream->source,0,stream->sndwrite,0); ms_ticker_attach(stream->ticker,stream->source); return stream; }
static void dtmfgen_tonedet(void) { MSConnectionHelper h; unsigned int filter_mask = FILTER_MASK_VOIDSOURCE | FILTER_MASK_DTMFGEN | FILTER_MASK_TONEDET | FILTER_MASK_VOIDSINK; 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_connection_helper_start(&h); ms_connection_helper_link(&h, ms_tester_voidsource, -1, 0); ms_connection_helper_link(&h, ms_tester_dtmfgen, 0, 0); ms_connection_helper_link(&h, ms_tester_tonedet, 0, 0); ms_connection_helper_link(&h, ms_tester_voidsink, 0, -1); ms_ticker_attach(ms_tester_ticker, ms_tester_voidsource); ms_tester_tone_generation_and_detection_loop(); ms_ticker_detach(ms_tester_ticker, ms_tester_voidsource); ms_connection_helper_start(&h); ms_connection_helper_unlink(&h, ms_tester_voidsource, -1, 0); ms_connection_helper_unlink(&h, ms_tester_dtmfgen, 0, 0); ms_connection_helper_unlink(&h, ms_tester_tonedet, 0, 0); ms_connection_helper_unlink(&h, ms_tester_voidsink, 0, -1); ms_filter_log_statistics(); ms_tester_destroy_filters(filter_mask); ms_tester_destroy_ticker(); }
static void fileplay_soundwrite(const char *filename) { MSConnectionHelper h; bool_t need_resampler = FALSE; unsigned int filter_mask = FILTER_MASK_FILEPLAY | FILTER_MASK_SOUNDWRITE; int sample_rate = 8000; int nchannels = 1; int done = FALSE; 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_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); ms_filter_call_method(ms_tester_fileplay, MS_FILTER_GET_NCHANNELS, &nchannels); if (ms_filter_call_method(ms_tester_soundwrite, MS_FILTER_SET_BITRATE, &sample_rate) != 0) { int soundwrite_sample_rate = 48000; ms_filter_call_method(ms_tester_soundwrite, MS_FILTER_GET_BITRATE, &soundwrite_sample_rate); if (sample_rate != soundwrite_sample_rate) need_resampler = TRUE; } if (ms_filter_call_method(ms_tester_soundwrite, MS_FILTER_SET_NCHANNELS, &nchannels) != 0) { int soundwrite_nchannels = 1; ms_filter_call_method(ms_tester_soundwrite, MS_FILTER_GET_NCHANNELS, &soundwrite_nchannels); if (nchannels != soundwrite_nchannels) need_resampler = TRUE; } if (need_resampler == TRUE) { ms_tester_create_filters(FILTER_MASK_RESAMPLER); configure_resampler(ms_tester_resampler, ms_tester_fileplay, ms_tester_soundwrite); } ms_filter_call_method_noarg(ms_tester_fileplay, MS_FILE_PLAYER_START); ms_connection_helper_start(&h); ms_connection_helper_link(&h, ms_tester_fileplay, -1, 0); if (need_resampler == TRUE) { ms_connection_helper_link(&h, ms_tester_resampler, 0, 0); } ms_connection_helper_link(&h, ms_tester_soundwrite, 0, -1); ms_ticker_attach(ms_tester_ticker, ms_tester_fileplay); while (done != TRUE) { ms_usleep(10000); } ms_filter_call_method_noarg(ms_tester_fileplay, MS_FILE_PLAYER_CLOSE); ms_ticker_detach(ms_tester_ticker, ms_tester_fileplay); ms_connection_helper_start(&h); ms_connection_helper_unlink(&h, ms_tester_fileplay, -1, 0); if (need_resampler == TRUE) { ms_connection_helper_unlink(&h, ms_tester_resampler, 0, 0); } ms_connection_helper_unlink(&h, ms_tester_soundwrite, 0, -1); if (need_resampler == TRUE) { ms_tester_destroy_filters(FILTER_MASK_RESAMPLER); } ms_filter_log_statistics(); ms_tester_destroy_filters(filter_mask); ms_tester_destroy_ticker(); }
RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard, MSFilterNotifyFunc func,void * user_data) { RingStream *stream; int srcchannels, dstchannels; int srcrate,dstrate; MSConnectionHelper h; MSTickerParams params={0}; 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); if (func!=NULL) ms_filter_set_notify_callback(stream->source,func,user_data); stream->gendtmf=ms_filter_new(MS_DTMF_GEN_ID); stream->sndwrite=ms_snd_card_create_writer(sndcard); 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->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(¶ms); ms_connection_helper_start(&h); ms_connection_helper_link(&h,stream->source,-1,0); ms_connection_helper_link(&h,stream->gendtmf,0,0); if (stream->write_resampler) ms_connection_helper_link(&h,stream->write_resampler,0,0); ms_connection_helper_link(&h,stream->sndwrite,0,-1); ms_ticker_attach(stream->ticker,stream->source); return stream; }
static void dtmfgen_enc_dec_tonedet(char *mime, int sample_rate, int nchannels) { MSConnectionHelper h; unsigned int filter_mask = FILTER_MASK_VOIDSOURCE | FILTER_MASK_DTMFGEN | FILTER_MASK_ENCODER | FILTER_MASK_DECODER | FILTER_MASK_TONEDET | FILTER_MASK_VOIDSINK; ms_filter_reset_statistics(); ms_tester_create_ticker(); ms_tester_codec_mime = mime; ms_tester_create_filters(filter_mask); /* set sample rate and channel number to all filters (might need to check the return value to insert a resampler if needed?) */ ms_filter_call_method(ms_tester_voidsource, MS_FILTER_SET_SAMPLE_RATE, &sample_rate); ms_filter_call_method(ms_tester_voidsource, MS_FILTER_SET_NCHANNELS, &nchannels); ms_filter_call_method(ms_tester_dtmfgen, MS_FILTER_SET_SAMPLE_RATE, &sample_rate); ms_filter_call_method(ms_tester_dtmfgen, MS_FILTER_SET_NCHANNELS, &nchannels); ms_filter_call_method(ms_tester_encoder, MS_FILTER_SET_SAMPLE_RATE, &sample_rate); ms_filter_call_method(ms_tester_encoder, MS_FILTER_SET_NCHANNELS, &nchannels); ms_filter_call_method(ms_tester_decoder, MS_FILTER_SET_SAMPLE_RATE, &sample_rate); ms_filter_call_method(ms_tester_decoder, MS_FILTER_SET_NCHANNELS, &nchannels); ms_filter_call_method(ms_tester_tonedet, MS_FILTER_SET_SAMPLE_RATE, &sample_rate); ms_filter_call_method(ms_tester_tonedet, MS_FILTER_SET_NCHANNELS, &nchannels); ms_filter_call_method(ms_tester_voidsink, MS_FILTER_SET_SAMPLE_RATE, &sample_rate); 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_connection_helper_start(&h); ms_connection_helper_link(&h, ms_tester_voidsource, -1, 0); ms_connection_helper_link(&h, ms_tester_dtmfgen, 0, 0); ms_connection_helper_link(&h, ms_tester_encoder, 0, 0); ms_connection_helper_link(&h, ms_tester_decoder, 0, 0); ms_connection_helper_link(&h, ms_tester_tonedet, 0, 0); ms_connection_helper_link(&h, ms_tester_voidsink, 0, -1); ms_ticker_attach(ms_tester_ticker, ms_tester_voidsource); ms_tester_tone_generation_and_detection_loop(); ms_ticker_detach(ms_tester_ticker, ms_tester_voidsource); ms_connection_helper_start(&h); ms_connection_helper_unlink(&h, ms_tester_voidsource, -1, 0); ms_connection_helper_unlink(&h, ms_tester_dtmfgen, 0, 0); ms_connection_helper_unlink(&h, ms_tester_encoder, 0, 0); ms_connection_helper_unlink(&h, ms_tester_decoder, 0, 0); ms_connection_helper_unlink(&h, ms_tester_tonedet, 0, 0); ms_connection_helper_unlink(&h, ms_tester_voidsink, 0, -1); ms_filter_log_statistics(); ms_tester_destroy_filters(filter_mask); ms_tester_destroy_ticker(); }
static void dtmfgen_filerec_fileplay_tonedet(void) { MSConnectionHelper h; unsigned int filter_mask = FILTER_MASK_VOIDSOURCE | FILTER_MASK_DTMFGEN | FILTER_MASK_FILEREC | FILTER_MASK_FILEPLAY | FILTER_MASK_TONEDET | FILTER_MASK_VOIDSINK; 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); // Generate tones and save them to a file ms_filter_call_method_noarg(ms_tester_filerec, MS_FILE_REC_CLOSE); ms_filter_call_method(ms_tester_filerec, MS_FILE_REC_OPEN, DTMFGEN_FILE_NAME); ms_filter_call_method_noarg(ms_tester_filerec, MS_FILE_REC_START); 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); ms_connection_helper_link(&h, ms_tester_filerec, 0, -1); ms_ticker_attach(ms_tester_ticker, ms_tester_voidsource); ms_tester_tone_generation_loop(); ms_filter_call_method_noarg(ms_tester_filerec, MS_FILE_REC_CLOSE); ms_ticker_detach(ms_tester_ticker, ms_tester_voidsource); ms_connection_helper_start(&h); ms_connection_helper_unlink(&h, ms_tester_voidsource, -1, 0); ms_connection_helper_unlink(&h, ms_tester_dtmfgen, 0, 0); ms_connection_helper_unlink(&h, ms_tester_filerec, 0, -1); // Read the previous file and detect the tones ms_filter_call_method_noarg(ms_tester_fileplay, MS_FILE_PLAYER_CLOSE); ms_filter_call_method(ms_tester_fileplay, MS_FILE_PLAYER_OPEN, DTMFGEN_FILE_NAME); ms_filter_call_method_noarg(ms_tester_fileplay, MS_FILE_PLAYER_START); ms_connection_helper_start(&h); ms_connection_helper_link(&h, ms_tester_fileplay, -1, 0); ms_connection_helper_link(&h, ms_tester_tonedet, 0, 0); ms_connection_helper_link(&h, ms_tester_voidsink, 0, -1); ms_ticker_attach(ms_tester_ticker, ms_tester_fileplay); ms_tester_tone_detection_loop(); ms_filter_call_method_noarg(ms_tester_fileplay, MS_FILE_PLAYER_CLOSE); ms_ticker_detach(ms_tester_ticker, ms_tester_fileplay); ms_connection_helper_start(&h); ms_connection_helper_unlink(&h, ms_tester_fileplay, -1, 0); ms_connection_helper_unlink(&h, ms_tester_tonedet, 0, 0); ms_connection_helper_unlink(&h, ms_tester_voidsink, 0, -1); ms_filter_log_statistics(); ms_tester_destroy_filters(filter_mask); ms_tester_destroy_ticker(); unlink(DTMFGEN_FILE_NAME); }
static void dtmfgen_enc_rtp_dec_tonedet(void) { MSConnectionHelper h; RtpSession *rtps; unsigned int filter_mask = FILTER_MASK_VOIDSOURCE | FILTER_MASK_DTMFGEN | FILTER_MASK_ENCODER | FILTER_MASK_RTPSEND | FILTER_MASK_RTPRECV | FILTER_MASK_DECODER | FILTER_MASK_TONEDET | FILTER_MASK_VOIDSINK; ms_filter_reset_statistics(); 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); rtps = create_duplex_rtpsession(50060, 0, FALSE); rtp_session_set_remote_addr_full(rtps, "127.0.0.1", 50060, NULL, 0); rtp_session_set_payload_type(rtps, 8); rtp_session_enable_rtcp(rtps,FALSE); ms_filter_call_method(ms_tester_rtprecv, MS_RTP_RECV_SET_SESSION, rtps); ms_filter_call_method(ms_tester_rtpsend, MS_RTP_SEND_SET_SESSION, rtps); 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); ms_connection_helper_link(&h, ms_tester_encoder, 0, 0); ms_connection_helper_link(&h, ms_tester_rtpsend, 0, -1); ms_connection_helper_start(&h); ms_connection_helper_link(&h, ms_tester_rtprecv, -1, 0); ms_connection_helper_link(&h, ms_tester_decoder, 0, 0); ms_connection_helper_link(&h, ms_tester_tonedet, 0, 0); ms_connection_helper_link(&h, ms_tester_voidsink, 0, -1); ms_ticker_attach_multiple(ms_tester_ticker, ms_tester_voidsource, ms_tester_rtprecv, NULL); ms_tester_tone_generation_and_detection_loop(); ms_ticker_detach(ms_tester_ticker, ms_tester_voidsource); ms_ticker_detach(ms_tester_ticker, ms_tester_rtprecv); ms_connection_helper_start(&h); ms_connection_helper_unlink(&h, ms_tester_voidsource, -1, 0); ms_connection_helper_unlink(&h, ms_tester_dtmfgen, 0, 0); ms_connection_helper_unlink(&h, ms_tester_encoder, 0, 0); ms_connection_helper_unlink(&h, ms_tester_rtpsend, 0, -1); ms_connection_helper_start(&h); ms_connection_helper_unlink(&h, ms_tester_rtprecv, -1, 0); ms_connection_helper_unlink(&h, ms_tester_decoder, 0, 0); ms_connection_helper_unlink(&h, ms_tester_tonedet, 0, 0); ms_connection_helper_unlink(&h, ms_tester_voidsink, 0, -1); ms_filter_log_statistics(); ms_tester_destroy_filters(filter_mask); ms_tester_destroy_ticker(); rtp_session_destroy(rtps); }
int lsd_player_play(LsdPlayer *b, const char *filename ){ int state; ms_filter_call_method(b->player,MS_PLAYER_GET_STATE,&state); if (state!=MSPlayerClosed){ ms_filter_call_method_noarg(b->player,MS_PLAYER_CLOSE); } if (ms_filter_call_method(b->player,MS_PLAYER_OPEN,(void*)filename)!=0){ ms_warning("Could not play %s",filename); return -1; } ms_filter_set_notify_callback (b->player,lsd_player_on_eop,b); lsd_player_configure(b); ms_filter_call_method_noarg (b->player,MS_PLAYER_START); return 0; }
LinphoneSoundDaemon * linphone_sound_daemon_new(const char *cardname, int rate, int nchannels){ int i; MSConnectionPoint mp; LinphoneSoundDaemon *lsd; MSSndCard *card=ms_snd_card_manager_get_card( ms_snd_card_manager_get(), cardname); if (card==NULL){ card=ms_snd_card_manager_get_default_playback_card ( ms_snd_card_manager_get()); if (card==NULL){ ms_error("linphone_sound_daemon_new(): No playback soundcard available"); return NULL; } } lsd=ms_new0(LinphoneSoundDaemon,1); lsd->soundout=ms_snd_card_create_writer(card); lsd->mixer=ms_filter_new(MS_AUDIO_MIXER_ID); lsd->out_rate=rate; lsd->out_nchans=nchannels; ms_filter_call_method(lsd->soundout,MS_FILTER_SET_SAMPLE_RATE,&lsd->out_rate); ms_filter_call_method(lsd->soundout,MS_FILTER_SET_NCHANNELS,&lsd->out_nchans); ms_filter_call_method(lsd->mixer,MS_FILTER_SET_SAMPLE_RATE,&lsd->out_rate); ms_filter_call_method(lsd->mixer,MS_FILTER_SET_NCHANNELS,&lsd->out_nchans); mp.filter=lsd->mixer; mp.pin=0; lsd_player_init(&lsd->branches[0],mp,MS_ITC_SOURCE_ID,lsd); ms_filter_set_notify_callback(lsd->branches[0].player,(MSFilterNotifyFunc)lsd_player_configure,&lsd->branches[0]); ms_filter_enable_synchronous_notifcations (lsd->branches[0].player,TRUE); for(i=1;i<MAX_BRANCHES;++i){ mp.pin=i; lsd_player_init(&lsd->branches[i],mp,MS_FILE_PLAYER_ID,lsd); } ms_filter_link(lsd->mixer,0,lsd->soundout,0); lsd->ticker=ms_ticker_new(); ms_ticker_attach(lsd->ticker,lsd->soundout); lsd->proxycard=ms_snd_card_new(&proxycard); lsd->proxycard->data=lsd; ms_message("LinphoneSoundDaemon started with rate=%i, nchannels=%i",rate,nchannels); return lsd; }
void call_accept(Call *call) { sdp_context_t *ctx; PayloadType *payload; char *hellofile; static int call_count=0; char record_file[250]; osip_message_t *msg=NULL; sprintf(record_file,"/tmp/sipomatic%i.wav",call_count); ctx=call->sdpc; payload=rtp_profile_get_payload(call->profile,call->audio.pt); if (strcmp(payload->mime_type,"telephone-event")==0){ /* telephone-event is not enough to accept a call */ ms_message("Cannot accept call with only telephone-event.\n"); eXosip_call_send_answer(call->did,415,NULL); call->state=CALL_STATE_FINISHED; return; } if (payload->clock_rate==16000){ hellofile=call->root->file_path16000hz; }else hellofile=call->root->file_path8000hz; eXosip_call_build_answer(call->tid,200,&msg); osip_message_set_content_type(msg,"application/sdp"); osip_message_set_body(msg,call->sdpc->answerstr,strlen(call->sdpc->answerstr)); eXosip_call_send_answer(call->tid,200,msg); call->audio_stream=audio_stream_new(call->audio.localport,call->audio.localport+1,call->root->ipv6); audio_stream_start_with_files(call->audio_stream, call->profile, call->audio.remaddr,call->audio.remoteport,call->audio.remoteport+1, call->audio.pt,20,hellofile,record_file); call_count++; #ifdef VIDEO_ENABLED if (call->video.remoteport!=0){ video_stream_send_only_start(call->video_stream,call->profile, call->video.remaddr,call->video.remoteport,call->video.remoteport+1,call->video.pt, 60, ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get())); } #endif call->time=time(NULL); call->state=CALL_STATE_RUNNING; ms_filter_set_notify_callback(call->audio_stream->soundread,endoffile_cb,(void*)call); }
/*this function must be called from the MSTicker thread: it replaces one filter by another one. This is a dirty hack that works anyway. It would be interesting to have something that does the job simplier within the MSTicker api */ void video_stream_change_decoder(VideoStream *stream, int payload){ RtpSession *session=stream->session; RtpProfile *prof=rtp_session_get_profile(session); PayloadType *pt=rtp_profile_get_payload(prof,payload); if (pt!=NULL){ MSFilter *dec; if (stream->decoder!=NULL && stream->decoder->desc->enc_fmt!=NULL && strcasecmp(pt->mime_type,stream->decoder->desc->enc_fmt)==0){ /* same formats behind different numbers, nothing to do */ return; } dec=ms_filter_create_decoder(pt->mime_type); if (dec!=NULL){ ms_filter_unlink(stream->rtprecv, 0, stream->decoder, 0); if (stream->tee2) ms_filter_unlink(stream->decoder,0,stream->tee2,0); else if(stream->output) ms_filter_unlink(stream->decoder,0,stream->output,0); ms_filter_postprocess(stream->decoder); ms_filter_destroy(stream->decoder); stream->decoder=dec; if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp); ms_filter_link (stream->rtprecv, 0, stream->decoder, 0); if (stream->tee2) ms_filter_link(stream->decoder,0,stream->tee2,0); else if(stream->output) ms_filter_link (stream->decoder,0 , stream->output, 0); ms_filter_preprocess(stream->decoder,stream->ticker); ms_filter_set_notify_callback(dec, event_cb, stream); }else{ ms_warning("No decoder found for %s",pt->mime_type); } }else{ ms_warning("No payload defined with number %i",payload); } }
int main(int argc, char *argv[]){ MSFilter *src, *gen, *det, *rec; MSTicker *ticker; ms_base_init(); ortp_set_log_level_mask (ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); src=ms_filter_new(MS_FILE_PLAYER_ID); rec=ms_filter_new(MS_FILE_REC_ID); gen=ms_filter_new(MS_DTMF_GEN_ID); det=ms_filter_new(MS_TONE_DETECTOR_ID); ms_filter_link(src,0,gen,0); ms_filter_link(gen,0,det,0); //ms_filter_link(gen,0,rec,0); ms_filter_link(det,0,rec,0); ticker=ms_ticker_new(); ms_ticker_attach(ticker,src); ms_filter_call_method(rec,MS_FILE_REC_OPEN,"/tmp/output.wav"); ms_filter_call_method_noarg(rec,MS_FILE_REC_START); { /*generate and detect the tones*/ MSDtmfGenCustomTone tone; MSToneDetectorDef expected_tone; char dtmf='*'; tone.frequency=2000; tone.duration=400; tone.amplitude=0.6; 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_call_method(det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); ms_filter_call_method(gen,MS_DTMF_GEN_PLAY,&dtmf); ms_sleep(1); ms_filter_call_method(gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(1); ms_filter_call_method(gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(1); ms_filter_call_method(gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(1); tone.frequency=1500; tone.amplitude=1.0; ms_filter_call_method(gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(1); } ms_filter_call_method_noarg(rec,MS_FILE_REC_CLOSE); ms_ticker_detach(ticker,src); ms_filter_unlink(src,0,gen,0); ms_filter_unlink(gen,0,det,0); //ms_filter_unlink(gen,0,rec,0); ms_filter_unlink(det,0,rec,0); ms_ticker_destroy(ticker); ms_filter_destroy(src); ms_filter_destroy(gen); ms_filter_destroy(det); ms_filter_destroy(rec); ms_base_exit(); return 0; }
int video_stream_start (VideoStream *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, MSWebCam *cam){ PayloadType *pt; RtpSession *rtps=stream->ms.session; MSPixFmt format; MSVideoSize disp_size; int tmp; JBParameters jbp; const int socket_buf_size=2000000; if (cam==NULL){ cam=ms_web_cam_manager_get_default_cam ( ms_web_cam_manager_get()); } pt=rtp_profile_get_payload(profile,payload); if (pt==NULL){ ms_error("videostream.c: undefined payload type."); return -1; } if ((cam != NULL) && (cam->desc->encode_to_mime_type != NULL) && (cam->desc->encode_to_mime_type(cam, pt->mime_type) == TRUE)) { stream->source_performs_encoding = TRUE; } rtp_session_set_profile(rtps,profile); if (rem_rtp_port>0) rtp_session_set_remote_addr_full(rtps,rem_rtp_ip,rem_rtp_port,rem_rtcp_ip,rem_rtcp_port); rtp_session_set_payload_type(rtps,payload); rtp_session_set_jitter_compensation(rtps,jitt_comp); rtp_session_signal_connect(stream->ms.session,"payload_type_changed", (RtpCallback)mediastream_payload_type_changed,(unsigned long)&stream->ms); rtp_session_get_jitter_buffer_params(stream->ms.session,&jbp); jbp.max_packets=1000;//needed for high resolution video rtp_session_set_jitter_buffer_params(stream->ms.session,&jbp); rtp_session_set_rtp_socket_recv_buffer_size(stream->ms.session,socket_buf_size); rtp_session_set_rtp_socket_send_buffer_size(stream->ms.session,socket_buf_size); if (stream->dir==VideoStreamSendRecv || stream->dir==VideoStreamSendOnly){ MSConnectionHelper ch; /*plumb the outgoing stream */ if (rem_rtp_port>0) ms_filter_call_method(stream->ms.rtpsend,MS_RTP_SEND_SET_SESSION,stream->ms.session); if (stream->source_performs_encoding == FALSE) { stream->ms.encoder=ms_filter_create_encoder(pt->mime_type); if ((stream->ms.encoder==NULL) ){ /* big problem: we don't have a registered codec for this payload...*/ ms_error("videostream.c: No encoder available for payload %i:%s.",payload,pt->mime_type); return -1; } } /* creates the filters */ stream->cam=cam; stream->source = ms_web_cam_create_reader(cam); stream->tee = ms_filter_new(MS_TEE_ID); if (stream->source_performs_encoding == TRUE) { stream->ms.encoder = stream->source; /* Consider the encoder is the source */ } if (pt->normal_bitrate>0){ MSVideoConfiguration *vconf_list = NULL; ms_message("Limiting bitrate of video encoder to %i bits/s",pt->normal_bitrate); ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_GET_CONFIGURATION_LIST, &vconf_list); if (vconf_list != NULL) { MSVideoConfiguration vconf = ms_video_find_best_configuration_for_bitrate(vconf_list, pt->normal_bitrate); ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_SET_CONFIGURATION, &vconf); } else { ms_filter_call_method(stream->ms.encoder, MS_FILTER_SET_BITRATE, &pt->normal_bitrate); } } if (pt->send_fmtp){ ms_filter_call_method(stream->ms.encoder,MS_FILTER_ADD_FMTP,pt->send_fmtp); } if (stream->use_preview_window){ if (stream->rendercb==NULL){ stream->output2=ms_filter_new_from_name (stream->display_name); } } configure_video_source (stream); /* and then connect all */ ms_connection_helper_start(&ch); ms_connection_helper_link(&ch, stream->source, -1, 0); if (stream->pixconv) { ms_connection_helper_link(&ch, stream->pixconv, 0, 0); } if (stream->sizeconv) { ms_connection_helper_link(&ch, stream->sizeconv, 0, 0); } ms_connection_helper_link(&ch, stream->tee, 0, 0); if (stream->source_performs_encoding == FALSE) { ms_connection_helper_link(&ch, stream->ms.encoder, 0, 0); } ms_connection_helper_link(&ch, stream->ms.rtpsend, 0, -1); if (stream->output2){ if (stream->preview_window_id!=0){ ms_filter_call_method(stream->output2, MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID,&stream->preview_window_id); } ms_filter_link(stream->tee,1,stream->output2,0); } } if (stream->dir==VideoStreamSendRecv || stream->dir==VideoStreamRecvOnly){ MSConnectionHelper ch; MSVideoDisplayDecodingSupport decoding_support; if (stream->rendercb!=NULL){ stream->output=ms_filter_new(MS_EXT_DISPLAY_ID); ms_filter_set_notify_callback(stream->output,ext_display_cb,stream); }else{ stream->output=ms_filter_new_from_name (stream->display_name); } /* Don't allow null output */ if(stream->output == NULL) { ms_fatal("No video display filter could be instantiated. Please check build-time configuration"); } /* Check if the output filter can perform the decoding process */ decoding_support.mime_type = pt->mime_type; decoding_support.supported = FALSE; ms_filter_call_method(stream->output, MS_VIDEO_DISPLAY_SUPPORT_DECODING, &decoding_support); stream->output_performs_decoding = decoding_support.supported; /*plumb the incoming stream */ if (stream->output_performs_decoding == TRUE) { stream->ms.decoder = stream->output; /* Consider the decoder is the output */ } else { stream->ms.decoder=ms_filter_create_decoder(pt->mime_type); if ((stream->ms.decoder==NULL) ){ /* big problem: we don't have a registered decoderfor this payload...*/ ms_error("videostream.c: No decoder available for payload %i:%s.",payload,pt->mime_type); ms_filter_destroy(stream->output); return -1; } } ms_filter_set_notify_callback(stream->ms.decoder, event_cb, stream); 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); if (stream->output_performs_decoding == FALSE) { stream->jpegwriter=ms_filter_new(MS_JPEG_WRITER_ID); if (stream->jpegwriter) stream->tee2=ms_filter_new(MS_TEE_ID); } /* set parameters to the decoder*/ if (pt->send_fmtp){ ms_filter_call_method(stream->ms.decoder,MS_FILTER_ADD_FMTP,pt->send_fmtp); } if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->ms.decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp); /*force the decoder to output YUV420P */ format=MS_YUV420P; ms_filter_call_method(stream->ms.decoder,MS_FILTER_SET_PIX_FMT,&format); /*configure the display window */ if(stream->output != NULL) { disp_size.width=MS_VIDEO_SIZE_CIF_W; disp_size.height=MS_VIDEO_SIZE_CIF_H; tmp=1; ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&disp_size); ms_filter_call_method(stream->output,MS_VIDEO_DISPLAY_ENABLE_AUTOFIT,&tmp); ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format); ms_filter_call_method(stream->output,MS_VIDEO_DISPLAY_SET_LOCAL_VIEW_MODE,&stream->corner); if (stream->window_id!=0){ ms_filter_call_method(stream->output, MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID,&stream->window_id); } if (stream->display_filter_auto_rotate_enabled) { ms_filter_call_method(stream->output,MS_VIDEO_DISPLAY_SET_DEVICE_ORIENTATION,&stream->device_orientation); } } /* and connect the filters */ ms_connection_helper_start (&ch); ms_connection_helper_link (&ch,stream->ms.rtprecv,-1,0); if (stream->output_performs_decoding == FALSE) { ms_connection_helper_link (&ch,stream->ms.decoder,0,0); } if (stream->tee2){ ms_connection_helper_link (&ch,stream->tee2,0,0); ms_filter_link(stream->tee2,1,stream->jpegwriter,0); } if (stream->output!=NULL) ms_connection_helper_link (&ch,stream->output,0,-1); /* the video source must be send for preview , if it exists*/ if (stream->tee!=NULL && stream->output!=NULL && stream->output2==NULL) ms_filter_link(stream->tee,1,stream->output,1); } if (stream->dir == VideoStreamSendOnly) { 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); stream->ms.voidsink = ms_filter_new(MS_VOID_SINK_ID); ms_filter_link(stream->ms.rtprecv, 0, stream->ms.voidsink, 0); } /* create the ticker */ if (stream->ms.ticker==NULL) start_ticker(&stream->ms); stream->ms.start_time=ms_time(NULL); stream->ms.is_beginning=TRUE; /* attach the graphs */ if (stream->source) ms_ticker_attach (stream->ms.ticker, stream->source); if (stream->ms.rtprecv) ms_ticker_attach (stream->ms.ticker, stream->ms.rtprecv); return 0; }
static void ecc_play_tones(EcCalibrator *ecc) { MSDtmfGenCustomTone tone; MSToneDetectorDef expected_tone; memset(&tone,0,sizeof(tone)); memset(&expected_tone,0,sizeof(expected_tone)); ms_filter_set_notify_callback(ecc->det,on_tone_received,ecc); /* configure the tones to be scanned */ strncpy(expected_tone.tone_name,"freq1",sizeof(expected_tone.tone_name)); expected_tone.frequency=2000; expected_tone.min_duration=40; expected_tone.min_amplitude=0.1; ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); strncpy(expected_tone.tone_name,"freq2",sizeof(expected_tone.tone_name)); expected_tone.frequency=2300; expected_tone.min_duration=40; expected_tone.min_amplitude=0.1; ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); strncpy(expected_tone.tone_name,"freq3",sizeof(expected_tone.tone_name)); expected_tone.frequency=2500; expected_tone.min_duration=40; expected_tone.min_amplitude=0.1; ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); /*play an initial tone to startup the audio playback/capture*/ tone.frequencies[0]=140; tone.duration=1000; tone.amplitude=0.5; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(2); ms_filter_set_notify_callback(ecc->gen,on_tone_sent,ecc); /* play the three tones*/ tone.frequencies[0]=2000; tone.duration=100; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_usleep(300000); tone.frequencies[0]=2300; tone.duration=100; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_usleep(300000); tone.frequencies[0]=2500; tone.duration=100; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(1); if (ecc->freq1 && ecc->freq2 && ecc->freq3) { int delay=ecc->acc/3; if (delay<0) { ms_error("Quite surprising calibration result, delay=%i",delay); ecc->status=LinphoneEcCalibratorFailed; } else { ms_message("Echo calibration estimated delay to be %i ms",delay); ecc->delay=delay; ecc->status=LinphoneEcCalibratorDone; } } else if ((ecc->freq1 || ecc->freq2 || ecc->freq3)==FALSE) { ms_message("Echo calibration succeeded, no echo has been detected"); ecc->status = LinphoneEcCalibratorDoneNoEcho; } else { ecc->status = LinphoneEcCalibratorFailed; } if (ecc->status == LinphoneEcCalibratorFailed) { ms_error("Echo calibration failed."); } }
void playback(char *filename) { MSFilter *f1_w,*play; MSSndCard *card_playback1; MSTicker *ticker1; int i; int done = FALSE; struct msg_st data_w; long int msgtype = 0; int rate = 16000; int nchan=2; int msgid = msgget((key_t)1234, 0666 | IPC_CREAT); if(msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(-1); } ortp_init(); ortp_set_log_level_mask(/*ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|*/ORTP_FATAL); ms_init(); card_playback1 = ms_snd_card_manager_get_default_playback_card(ms_snd_card_manager_get()); if (card_playback1==NULL) { if(card_playback1==NULL) ms_error("No card. card_playback"); } else { ms_warning("card_playback1 %s|%s|%s|%d|%d|%d",card_playback1->name,card_playback1->id,card_playback1->desc->driver_type, card_playback1->capabilities,card_playback1->latency,card_playback1->preferred_sample_rate); } play=ms_filter_new(MS_FILE_PLAYER_ID); if(ms_filter_call_method(play,MS_FILE_PLAYER_OPEN,(void*)filename)!=0) printf("play open file %s failed\n",filename); ms_filter_set_notify_callback(play, fileplay_eof, &done); f1_w=ms_snd_card_create_writer(card_playback1); if(f1_w!=NULL&&play!=NULL) { ms_filter_call_method(play, MS_FILTER_GET_SAMPLE_RATE, &rate); ms_filter_call_method(play, MS_FILTER_GET_NCHANNELS, &nchan); if(ms_filter_call_method(f1_w, MS_FILTER_SET_SAMPLE_RATE, &rate)!=0) printf("set sample rate f1_r failed\n"); if(ms_filter_call_method(f1_w, MS_FILTER_SET_NCHANNELS,&nchan)!=0) printf("set sample rate record failed\n"); ms_filter_call_method_noarg(play,MS_FILE_PLAYER_START); ticker1=ms_ticker_new(); ms_ticker_set_name(ticker1,"card1 to card2"); ms_filter_link(play,0,f1_w,0); ms_ticker_attach(ticker1,play); while (done != TRUE) { ms_usleep(10000); } ms_filter_call_method_noarg(play, MS_FILE_PLAYER_CLOSE); if(ticker1) ms_ticker_detach(ticker1,play); if(f1_w&&play) ms_filter_unlink(play,0,f1_w,0); if(ticker1) ms_ticker_destroy(ticker1); if(f1_w) ms_filter_destroy(f1_w); if(play) ms_filter_destroy(play); data_w.msg_type = 2; //注意2 strcpy(data_w.text, filename); //向队列发送数据 // if(msgsnd(msgid, (void*)&data_w, 512, IPC_NOWAIT) == -1) // { // fprintf(stderr, "msgsnd failed\n"); // exit(1); // } printf("playing finished\n"); } }
int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *remip, int remport, int rem_rtcp_port, int payload, int jitt_comp, MSWebCam *cam){ PayloadType *pt; RtpSession *rtps=stream->session; MSPixFmt format; MSVideoSize disp_size; int tmp; JBParameters jbp; const int socket_buf_size=2000000; if (cam==NULL){ cam=ms_web_cam_manager_get_default_cam ( ms_web_cam_manager_get()); } pt=rtp_profile_get_payload(profile,payload); if (pt==NULL){ ms_error("videostream.c: undefined payload type."); return -1; } rtp_session_set_profile(rtps,profile); if (remport>0) rtp_session_set_remote_addr_full(rtps,remip,remport,rem_rtcp_port); rtp_session_set_payload_type(rtps,payload); rtp_session_set_jitter_compensation(rtps,jitt_comp); rtp_session_signal_connect(stream->session,"payload_type_changed", (RtpCallback)payload_type_changed,(unsigned long)stream); rtp_session_set_recv_buf_size(stream->session,MAX_RTP_SIZE); rtp_session_get_jitter_buffer_params(stream->session,&jbp); jbp.max_packets=1000;//needed for high resolution video rtp_session_set_jitter_buffer_params(stream->session,&jbp); rtp_session_set_rtp_socket_recv_buffer_size(stream->session,socket_buf_size); rtp_session_set_rtp_socket_send_buffer_size(stream->session,socket_buf_size); if (stream->dir==VideoStreamSendRecv || stream->dir==VideoStreamSendOnly){ /*plumb the outgoing stream */ if (remport>0) ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,stream->session); stream->encoder=ms_filter_create_encoder(pt->mime_type); if ((stream->encoder==NULL) ){ /* big problem: we don't have a registered codec for this payload...*/ ms_error("videostream.c: No encoder available for payload %i:%s.",payload,pt->mime_type); return -1; } /* creates the filters */ stream->source = ms_web_cam_create_reader(cam); stream->tee = ms_filter_new(MS_TEE_ID); if (pt->normal_bitrate>0){ ms_message("Limiting bitrate of video encoder to %i bits/s",pt->normal_bitrate); ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&pt->normal_bitrate); } if (pt->send_fmtp){ ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP,pt->send_fmtp); } if (stream->use_preview_window){ if (stream->rendercb==NULL){ stream->output2=ms_filter_new_from_name (stream->display_name); } } configure_video_source (stream); /* and then connect all */ ms_filter_link (stream->source, 0, stream->pixconv, 0); ms_filter_link (stream->pixconv, 0, stream->sizeconv, 0); ms_filter_link (stream->sizeconv, 0, stream->tee, 0); ms_filter_link (stream->tee, 0 ,stream->encoder, 0 ); ms_filter_link (stream->encoder,0, stream->rtpsend,0); if (stream->output2){ if (stream->window_id!=0){ ms_filter_call_method(stream->output2, MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID,&stream->preview_window_id); } ms_filter_link(stream->tee,1,stream->output2,0); } } if (stream->dir==VideoStreamSendRecv || stream->dir==VideoStreamRecvOnly){ MSConnectionHelper ch; /*plumb the incoming stream */ stream->decoder=ms_filter_create_decoder(pt->mime_type); if ((stream->decoder==NULL) ){ /* big problem: we don't have a registered decoderfor this payload...*/ ms_error("videostream.c: No decoder available for payload %i:%s.",payload,pt->mime_type); return -1; } stream->rtprecv = ms_filter_new (MS_RTP_RECV_ID); ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,stream->session); if(stream->conf_mode==FALSE) { stream->tee2=ms_filter_new(MS_TEE_ID); stream->jpegwriter=ms_filter_new(MS_JPEG_WRITER_ID); } if (stream->rendercb!=NULL){ stream->output=ms_filter_new(MS_EXT_DISPLAY_ID); ms_filter_set_notify_callback (stream->output,ext_display_cb,stream); }else{ if(stream->conf_mode) stream->output=ms_filter_new(MS_VOID_SINK_ID); else stream->output=ms_filter_new_from_name (stream->display_name); } /* set parameters to the decoder*/ if (pt->send_fmtp){ ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,pt->send_fmtp); } if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp); /*force the decoder to output YUV420P */ format=MS_YUV420P; ms_filter_call_method(stream->decoder,MS_FILTER_SET_PIX_FMT,&format); /*configure the display window */ disp_size.width=MS_VIDEO_SIZE_CIF_W; disp_size.height=MS_VIDEO_SIZE_CIF_H; tmp=1; ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&disp_size); ms_filter_call_method(stream->output,MS_VIDEO_DISPLAY_ENABLE_AUTOFIT,&tmp); ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format); ms_filter_call_method(stream->output,MS_VIDEO_DISPLAY_SET_LOCAL_VIEW_MODE,&stream->corner); if (stream->window_id!=0){ ms_filter_call_method(stream->output, MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID,&stream->window_id); } /* and connect the filters */ ms_connection_helper_start (&ch); ms_connection_helper_link (&ch,stream->rtprecv,-1,0); ms_connection_helper_link (&ch,stream->decoder,0,0); if (stream->tee2){ ms_connection_helper_link (&ch,stream->tee2,0,0); ms_filter_link(stream->tee2,1,stream->jpegwriter,0); //Êä³öÊÓƵ¼ÖÆÖ¡. if(stream->video_record) ms_filter_link(stream->tee2,2,stream->video_record,0); } ms_connection_helper_link (&ch,stream->output,0,-1); /* the video source must be send for preview , if it exists*/ if (stream->tee!=NULL && stream->output2==NULL) ms_filter_link(stream->tee,1,stream->output,1); } /* create the ticker */ stream->ticker = ms_ticker_new(); ms_ticker_set_name(stream->ticker,"Video MSTicker"); //¼æÈÝPVX Ðëµ÷Õû±àÂë¼ä¸ô //stream->ticker->interval = 3; #ifdef ENABLE_UDT if(stream->enable_udt){ stream->udt = ms_filter_new(MS_UDT_TRANSPORT_ID); ms_filter_call_method(stream->udt,MS_UDT_SET_RTP_SESSION,stream->session); } #endif //ENABLE_UDT /* attach the graphs */ if (stream->source) ms_ticker_attach (stream->ticker, stream->source); if (stream->rtprecv) ms_ticker_attach (stream->ticker, stream->rtprecv); #ifdef ENABLE_UDT //×îºóÔËÐУ¬±ÜÃâ×èÈûUI if (stream->udt) ms_ticker_attach (stream->ticker, stream->udt); #endif // ENABLE_UDT return 0; }