Exemplo n.º 1
0
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);
	}
}
Exemplo n.º 2
0
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();
}
Exemplo n.º 5
0
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(&params);

	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);
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
/*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);
	}
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
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.");
    }
}
Exemplo n.º 16
0
Arquivo: rec.c Projeto: blueskycoco/hp
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");
	}	
}
Exemplo n.º 17
0
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;
}