static void test_filterdesc_enable_disable_base(const char* mime, const char* filtername,bool_t is_enc) {
	MSFilter *filter;

	ms_init();

	if (is_enc)
			filter = ms_filter_create_encoder(mime);
		else
			filter = ms_filter_create_decoder(mime);

	BC_ASSERT_PTR_NOT_NULL(filter);
	ms_filter_destroy(filter);

	BC_ASSERT_FALSE(ms_factory_enable_filter_from_name(ms_factory_get_fallback(),filtername,FALSE));
	BC_ASSERT_FALSE(ms_factory_filter_from_name_enabled(ms_factory_get_fallback(),filtername));
	if (is_enc)
			filter = ms_filter_create_encoder(mime);
		else
			filter = ms_filter_create_decoder(mime);
	BC_ASSERT_PTR_NULL(filter);

	BC_ASSERT_FALSE(ms_factory_enable_filter_from_name(ms_factory_get_fallback(),filtername,TRUE));
	BC_ASSERT_TRUE(ms_factory_filter_from_name_enabled(ms_factory_get_fallback(),filtername));
	if (is_enc)
		filter = ms_filter_create_encoder(mime);
	else
		filter = ms_filter_create_decoder(mime);
	BC_ASSERT_PTR_NOT_NULL(filter);

	ms_filter_destroy(filter);
	ms_exit();
}
void ms_tester_create_filters(unsigned int filter_mask) {
	MSSndCardManager *snd_manager;
	MSWebCamManager *cam_manager;
	MSSndCard *playcard;
	MSSndCard *captcard;
	MSWebCam *camera;

	CREATE_FILTER(FILTER_MASK_FILEPLAY, ms_tester_fileplay, MS_FILE_PLAYER_ID);
	CREATE_FILTER(FILTER_MASK_FILEREC, ms_tester_filerec, MS_FILE_REC_ID);
	CREATE_FILTER(FILTER_MASK_DTMFGEN, ms_tester_dtmfgen, MS_DTMF_GEN_ID);
	CREATE_FILTER(FILTER_MASK_TONEDET, ms_tester_tonedet, MS_TONE_DETECTOR_ID);
	CREATE_FILTER(FILTER_MASK_VOIDSOURCE, ms_tester_voidsource, MS_VOID_SOURCE_ID);
	CREATE_FILTER(FILTER_MASK_VOIDSINK, ms_tester_voidsink, MS_VOID_SINK_ID);
	if (filter_mask & FILTER_MASK_ENCODER) {
		CU_ASSERT_PTR_NULL(ms_tester_encoder);
		ms_tester_encoder = ms_filter_create_encoder(ms_tester_codec_mime);
		CU_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_encoder);
	}
	if (filter_mask & FILTER_MASK_DECODER) {
		CU_ASSERT_PTR_NULL(ms_tester_decoder);
		ms_tester_decoder = ms_filter_create_decoder(ms_tester_codec_mime);
		CU_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_decoder);
	}
	CREATE_FILTER(FILTER_MASK_RTPRECV, ms_tester_rtprecv, MS_RTP_RECV_ID);
	CREATE_FILTER(FILTER_MASK_RTPSEND, ms_tester_rtpsend, MS_RTP_SEND_ID);
	CREATE_FILTER(FILTER_MASK_RESAMPLER, ms_tester_resampler, MS_RESAMPLE_ID);
	if (filter_mask & FILTER_MASK_SOUNDWRITE) {
		CU_ASSERT_PTR_NULL(ms_tester_soundwrite);
		snd_manager = ms_snd_card_manager_get();
		playcard = ms_snd_card_manager_get_default_playback_card(snd_manager);
		CU_ASSERT_PTR_NOT_NULL_FATAL(playcard);
		ms_tester_soundwrite = ms_snd_card_create_writer(playcard);
		CU_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_soundwrite);
	}
	if (filter_mask & FILTER_MASK_SOUNDREAD) {
		CU_ASSERT_PTR_NULL(ms_tester_soundread);
		snd_manager = ms_snd_card_manager_get();
		captcard = ms_snd_card_manager_get_default_capture_card(snd_manager);
		CU_ASSERT_PTR_NOT_NULL_FATAL(captcard);
		ms_tester_soundread = ms_snd_card_create_reader(captcard);
		CU_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_soundread);
	}
	if (filter_mask & FILTER_MASK_VIDEOCAPTURE) {
		CU_ASSERT_PTR_NULL(ms_tester_videocapture);
		cam_manager = ms_web_cam_manager_get();
		camera = ms_web_cam_manager_get_default_cam(cam_manager);
		CU_ASSERT_PTR_NOT_NULL_FATAL(camera);
		ms_tester_videocapture = ms_web_cam_create_reader(camera);
		CU_ASSERT_PTR_NOT_NULL_FATAL(ms_tester_videocapture);
	}
}
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)
{
	RtpSession *rtps=stream->ms.session;
	PayloadType *pt,*tel_ev;
	int tmp;
	MSConnectionHelper h;
	int sample_rate;
	MSRtpPayloadPickerContext picker_context;
	bool_t has_builtin_ec=FALSE;

	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);
	if (rem_rtcp_port<=0){
		rtp_session_enable_rtcp(rtps,FALSE);
	}
	rtp_session_set_payload_type(rtps,payload);
	rtp_session_set_jitter_compensation(rtps,jitt_comp);

	if (rem_rtp_port>0)
		ms_filter_call_method(stream->ms.rtpsend,MS_RTP_SEND_SET_SESSION,rtps);
	stream->ms.rtprecv=ms_filter_new(MS_RTP_RECV_ID);
	ms_filter_call_method(stream->ms.rtprecv,MS_RTP_RECV_SET_SESSION,rtps);
	stream->ms.session=rtps;

	if((stream->features & AUDIO_STREAM_FEATURE_DTMF) != 0)
		stream->dtmfgen=ms_filter_new(MS_DTMF_GEN_ID);
	else
		stream->dtmfgen=NULL;
	rtp_session_signal_connect(rtps,"telephone-event",(RtpCallback)on_dtmf_received,(unsigned long)stream);
	rtp_session_signal_connect(rtps,"payload_type_changed",(RtpCallback)mediastream_payload_type_changed,(unsigned long)&stream->ms);
	/* creates the local part */
	if (captcard!=NULL){
		if (stream->soundread==NULL)
			stream->soundread=ms_snd_card_create_reader(captcard);
		has_builtin_ec=!!(ms_snd_card_get_capabilities(captcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER);
	}else {
		stream->soundread=ms_filter_new(MS_FILE_PLAYER_ID);
		stream->read_resampler=ms_filter_new(MS_RESAMPLE_ID);
		if (infile!=NULL) audio_stream_play(stream,infile);
	}
	if (playcard!=NULL) {
		if (stream->soundwrite==NULL)
			stream->soundwrite=ms_snd_card_create_writer(playcard);
	}else {
		stream->soundwrite=ms_filter_new(MS_FILE_REC_ID);
		if (outfile!=NULL) audio_stream_record(stream,outfile);
	}

	/* creates the couple of encoder/decoder */
	pt=rtp_profile_get_payload(profile,payload);
	if (pt==NULL){
		ms_error("audiostream.c: undefined payload type.");
		return -1;
	}
	tel_ev=rtp_profile_get_payload_from_mime (profile,"telephone-event");

	if ((stream->features & AUDIO_STREAM_FEATURE_DTMF_ECHO) != 0 && (tel_ev==NULL || ( (tel_ev->flags & PAYLOAD_TYPE_FLAG_CAN_RECV) && !(tel_ev->flags & PAYLOAD_TYPE_FLAG_CAN_SEND)))
	    && ( strcasecmp(pt->mime_type,"pcmu")==0 || strcasecmp(pt->mime_type,"pcma")==0)){
		/*if no telephone-event payload is usable and pcma or pcmu is used, we will generate
		  inband dtmf*/
		stream->dtmfgen_rtp=ms_filter_new (MS_DTMF_GEN_ID);
	} else {
		stream->dtmfgen_rtp=NULL;
	}
	
	if (ms_filter_call_method(stream->ms.rtpsend,MS_FILTER_GET_SAMPLE_RATE,&sample_rate)!=0){
		ms_error("Sample rate is unknown for RTP side !");
		return -1;
	}
	
	stream->ms.encoder=ms_filter_create_encoder(pt->mime_type);
	stream->ms.decoder=ms_filter_create_decoder(pt->mime_type);
	if ((stream->ms.encoder==NULL) || (stream->ms.decoder==NULL)){
		/* big problem: we have not a registered codec for this payload...*/
		ms_error("audio_stream_start_full: No decoder or encoder available for payload %s.",pt->mime_type);
		return -1;
	}
	if (ms_filter_has_method(stream->ms.decoder, MS_FILTER_SET_RTP_PAYLOAD_PICKER)) {
		ms_message(" decoder has FEC capabilities");
		picker_context.filter_graph_manager=stream;
		picker_context.picker=&audio_stream_payload_picker;
		ms_filter_call_method(stream->ms.decoder,MS_FILTER_SET_RTP_PAYLOAD_PICKER, &picker_context);
	}
	if((stream->features & AUDIO_STREAM_FEATURE_VOL_SND) != 0)
		stream->volsend=ms_filter_new(MS_VOLUME_ID);
	else
		stream->volsend=NULL;
	if((stream->features & AUDIO_STREAM_FEATURE_VOL_RCV) != 0)
		stream->volrecv=ms_filter_new(MS_VOLUME_ID);
	else
		stream->volrecv=NULL;
	audio_stream_enable_echo_limiter(stream,stream->el_type);
	audio_stream_enable_noise_gate(stream,stream->use_ng);

	if (stream->use_agc){
		int tmp=1;
		if (stream->volsend==NULL)
			stream->volsend=ms_filter_new(MS_VOLUME_ID);
		ms_filter_call_method(stream->volsend,MS_VOLUME_ENABLE_AGC,&tmp);
	}

	if (stream->dtmfgen) {
		ms_filter_call_method(stream->dtmfgen,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
		ms_filter_call_method(stream->dtmfgen,MS_FILTER_SET_NCHANNELS,&pt->channels);
	}
	if (stream->dtmfgen_rtp) {
		ms_filter_call_method(stream->dtmfgen_rtp,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
		ms_filter_call_method(stream->dtmfgen_rtp,MS_FILTER_SET_NCHANNELS,&pt->channels);
	}
	/* give the sound filters some properties */
	if (ms_filter_call_method(stream->soundread,MS_FILTER_SET_SAMPLE_RATE,&sample_rate) != 0) {
		/* need to add resampler*/
		if (stream->read_resampler == NULL) stream->read_resampler=ms_filter_new(MS_RESAMPLE_ID);
	}
	ms_filter_call_method(stream->soundread,MS_FILTER_SET_NCHANNELS,&pt->channels);

	if (ms_filter_call_method(stream->soundwrite,MS_FILTER_SET_SAMPLE_RATE,&sample_rate) != 0) {
		/* need to add resampler*/
		if (stream->write_resampler == NULL) stream->write_resampler=ms_filter_new(MS_RESAMPLE_ID);
	}
	ms_filter_call_method(stream->soundwrite,MS_FILTER_SET_NCHANNELS,&pt->channels);

	// Override feature
	if ( ((stream->features & AUDIO_STREAM_FEATURE_EC) && !use_ec) || has_builtin_ec )
		stream->features &=~AUDIO_STREAM_FEATURE_EC;

	/*configure the echo canceller if required */
	if ((stream->features & AUDIO_STREAM_FEATURE_EC) == 0 && stream->ec != NULL) {
		ms_filter_destroy(stream->ec);
		stream->ec=NULL;
	}
	if (stream->ec){
		if (!stream->is_ec_delay_set){
			int delay_ms=ms_snd_card_get_minimal_latency(captcard);
			if (delay_ms!=0){
				ms_message("Setting echo canceller delay with value provided by soundcard: %i ms",delay_ms);
				ms_filter_call_method(stream->ec,MS_ECHO_CANCELLER_SET_DELAY,&delay_ms);
			}
		}
		ms_filter_call_method(stream->ec,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
	}
	
	if (stream->features & AUDIO_STREAM_FEATURE_MIXED_RECORDING){
		int val=0;
		int pin=1;
		stream->recorder=ms_filter_new(MS_FILE_REC_ID);
		stream->recorder_mixer=ms_filter_new(MS_AUDIO_MIXER_ID);
		stream->recv_tee=ms_filter_new(MS_TEE_ID);
		stream->send_tee=ms_filter_new(MS_TEE_ID);
		ms_filter_call_method(stream->recorder_mixer,MS_AUDIO_MIXER_ENABLE_CONFERENCE_MODE,&val);
		ms_filter_call_method(stream->recorder_mixer,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
		ms_filter_call_method(stream->recorder_mixer,MS_FILTER_SET_NCHANNELS,&pt->channels);
		ms_filter_call_method(stream->recv_tee,MS_TEE_MUTE,&pin);
		ms_filter_call_method(stream->send_tee,MS_TEE_MUTE,&pin);
		ms_filter_call_method(stream->recorder,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
		ms_filter_call_method(stream->recorder,MS_FILTER_SET_NCHANNELS,&pt->channels);
		
	}

	/* give the encoder/decoder some parameters*/
	ms_filter_call_method(stream->ms.encoder,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
	ms_message("Payload's bitrate is %i",pt->normal_bitrate);
	if (pt->normal_bitrate>0){
		ms_message("Setting audio encoder network bitrate to %i",pt->normal_bitrate);
		ms_filter_call_method(stream->ms.encoder,MS_FILTER_SET_BITRATE,&pt->normal_bitrate);
	}
	ms_filter_call_method(stream->ms.encoder,MS_FILTER_SET_NCHANNELS,&pt->channels);
	ms_filter_call_method(stream->ms.decoder,MS_FILTER_SET_SAMPLE_RATE,&sample_rate);
	ms_filter_call_method(stream->ms.decoder,MS_FILTER_SET_NCHANNELS,&pt->channels);

	if (pt->send_fmtp!=NULL) {
		char value[16]={0};
		int ptime;
		if (ms_filter_has_method(stream->ms.encoder,MS_AUDIO_ENCODER_SET_PTIME)){
			if (fmtp_get_value(pt->send_fmtp,"ptime",value,sizeof(value)-1)){
				ptime=atoi(value);
				ms_filter_call_method(stream->ms.encoder,MS_AUDIO_ENCODER_SET_PTIME,&ptime);
			}
		}
		ms_filter_call_method(stream->ms.encoder,MS_FILTER_ADD_FMTP, (void*)pt->send_fmtp);
	}
	if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->ms.decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp);

	/*create the equalizer*/
	if ((stream->features & AUDIO_STREAM_FEATURE_EQUALIZER) != 0){
		stream->equalizer=ms_filter_new(MS_EQUALIZER_ID);
		if(stream->equalizer) {
			tmp=stream->eq_active;
			ms_filter_call_method(stream->equalizer,MS_EQUALIZER_SET_ACTIVE,&tmp);
		}
	}else
		stream->equalizer=NULL;
	

	/*configure resampler if needed*/
	ms_filter_call_method(stream->ms.rtpsend, MS_FILTER_SET_NCHANNELS, &pt->channels);
	ms_filter_call_method(stream->ms.rtprecv, MS_FILTER_SET_NCHANNELS, &pt->channels);
	if (stream->read_resampler){
		audio_stream_configure_resampler(stream->read_resampler,stream->soundread,stream->ms.rtpsend);
	}

	if (stream->write_resampler){
		audio_stream_configure_resampler(stream->write_resampler,stream->ms.rtprecv,stream->soundwrite);
	}

	if (stream->ms.use_rc){
		stream->ms.rc=ms_audio_bitrate_controller_new(stream->ms.session,stream->ms.encoder,0);
	}
	
	/* Create PLC */
	if ((stream->features & AUDIO_STREAM_FEATURE_PLC) != 0) {
		int decoder_have_plc = 0;
		if (ms_filter_has_method(stream->ms.decoder, MS_AUDIO_DECODER_HAVE_PLC)) {
			if (ms_filter_call_method(stream->ms.decoder, MS_AUDIO_DECODER_HAVE_PLC, &decoder_have_plc) != 0) {
				ms_warning("MS_AUDIO_DECODER_HAVE_PLC function error: enable default plc");
			}
		} else {
			ms_warning("MS_DECODER_HAVE_PLC function not implemented by the decoder: enable default plc");
		}
		if (decoder_have_plc == 0) {
			stream->plc = ms_filter_new(MS_GENERIC_PLC_ID);
		}

		if (stream->plc) {
			ms_filter_call_method(stream->plc, MS_FILTER_SET_NCHANNELS, &pt->channels);
			ms_filter_call_method(stream->plc, MS_FILTER_SET_SAMPLE_RATE, &sample_rate);
		}
	} else {
		stream->plc = NULL;
	}

	/* create ticker */
	if (stream->ms.ticker==NULL) start_ticker(&stream->ms);
	else{
		/*we were using the dummy preload graph, destroy it*/
		if (stream->dummy) stop_preload_graph(stream);
	}
	
	/* and then connect all */
	/* tip: draw yourself the picture if you don't understand */

	/*sending graph*/
	ms_connection_helper_start(&h);
	ms_connection_helper_link(&h,stream->soundread,-1,0);
	if (stream->read_resampler)
		ms_connection_helper_link(&h,stream->read_resampler,0,0);
	if (stream->ec)
		ms_connection_helper_link(&h,stream->ec,1,1);
	if (stream->volsend)
		ms_connection_helper_link(&h,stream->volsend,0,0);
	if (stream->dtmfgen_rtp)
		ms_connection_helper_link(&h,stream->dtmfgen_rtp,0,0);
	if (stream->send_tee)
		ms_connection_helper_link(&h,stream->send_tee,0,0);
	ms_connection_helper_link(&h,stream->ms.encoder,0,0);
	ms_connection_helper_link(&h,stream->ms.rtpsend,0,-1);

	/*receiving graph*/
	ms_connection_helper_start(&h);
	ms_connection_helper_link(&h,stream->ms.rtprecv,-1,0);
	ms_connection_helper_link(&h,stream->ms.decoder,0,0);
	if (stream->plc)
		ms_connection_helper_link(&h,stream->plc,0,0);
	if (stream->dtmfgen)
		ms_connection_helper_link(&h,stream->dtmfgen,0,0);
	if (stream->volrecv)
		ms_connection_helper_link(&h,stream->volrecv,0,0);
	if (stream->recv_tee)
		ms_connection_helper_link(&h,stream->recv_tee,0,0);
	if (stream->equalizer)
		ms_connection_helper_link(&h,stream->equalizer,0,0);
	if (stream->ec)
		ms_connection_helper_link(&h,stream->ec,0,0);
	if (stream->write_resampler)
		ms_connection_helper_link(&h,stream->write_resampler,0,0);
	ms_connection_helper_link(&h,stream->soundwrite,0,-1);

	/*call recording part, attached to both outgoing and incoming graphs*/
	if (stream->recorder){
		ms_filter_link(stream->send_tee,1,stream->recorder_mixer,0);
		ms_filter_link(stream->recv_tee,1,stream->recorder_mixer,1);
		ms_filter_link(stream->recorder_mixer,0,stream->recorder,0);
	}
	
	/*to make sure all preprocess are done before befre processing audio*/
	ms_ticker_attach_multiple(stream->ms.ticker
				,stream->soundread
				,stream->ms.rtprecv
				,NULL);

	stream->ms.start_time=ms_time(NULL);
	stream->ms.is_beginning=TRUE;

	return 0;
}
Example #4
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;
}
Example #5
0
int video_stream_send_only_start(VideoStream* stream, RtpProfile *profile, const char *remip, int remport,
	int rem_rtcp_port, int payload, int jitt_comp, MSWebCam *device){
	PayloadType *pt;
	MSPixFmt format;
	MSVideoSize vsize;
	RtpSession *rtps=stream->session;
	float fps=15;
	
	vsize.width=MS_VIDEO_SIZE_CIF_W;
	vsize.height=MS_VIDEO_SIZE_CIF_H;

	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);
	
	/* creates rtp filter to send streams (remote part) */
	rtp_session_set_recv_buf_size(rtps,MAX_RTP_SIZE);
	stream->rtpsend =ms_filter_new(MS_RTP_SEND_ID);
	if (remport>0) ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,stream->session);

	/* creates the filters */
	pt=rtp_profile_get_payload(profile,payload);
	if (pt==NULL){
		video_stream_free(stream);
		ms_error("videostream.c: undefined payload type.");
		return -1;
	}
	stream->encoder=ms_filter_create_encoder(pt->mime_type);
	if ((stream->encoder==NULL)){
		/* big problem: we have not a registered codec for this payload...*/
		video_stream_free(stream);
		ms_error("videostream.c: No codecs available for payload %i.",payload);
		return -1;
	}

	/* creates the filters */
	stream->source = ms_web_cam_create_reader(device);
	stream->sizeconv=ms_filter_new(MS_SIZE_CONV_ID);

	/* configure the filters */
	if (pt->send_fmtp)
		ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP,pt->send_fmtp);
	ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&pt->normal_bitrate);
	ms_filter_call_method(stream->encoder,MS_FILTER_GET_FPS,&fps);
	ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);

	ms_filter_call_method(stream->source,MS_FILTER_SET_FPS,&fps);
	ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	
	/* get the output format for webcam reader */
	ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);
	/*set it to the pixconv */

	/* bug fix from AMD: What about MJPEG mode???*/
	if (format==MS_MJPEG){
		stream->pixconv=ms_filter_new(MS_MJPEG_DEC_ID);
	}else{
		stream->pixconv=ms_filter_new(MS_PIX_CONV_ID);
		ms_filter_call_method(stream->pixconv,MS_FILTER_SET_PIX_FMT,&format);

		ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&vsize);
		ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	}

	ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);
	ms_filter_call_method(stream->sizeconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	
	ms_message("vsize=%ix%i, fps=%f, send format: %s, capture format: %d, bitrate: %d",
			vsize.width,vsize.height,fps,pt->send_fmtp,format, pt->normal_bitrate);

	/* 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->encoder, 0);
	ms_filter_link (stream->encoder,0, stream->rtpsend,0);

	/* create the ticker */
	stream->ticker = ms_ticker_new(); 
	/* attach it the graph */
	ms_ticker_attach (stream->ticker, stream->source);
	return 0;
}
Example #6
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 vsize;
	float fps=15;

	vsize.height=MS_VIDEO_SIZE_CIF_H;
	vsize.width=MS_VIDEO_SIZE_CIF_W;

	pt=rtp_profile_get_payload(profile,payload);
	if (pt==NULL){
		ms_error("videostream.c: undefined payload type.");
		return -1;
	}
	stream->encoder=ms_filter_create_encoder(pt->mime_type);
	stream->decoder=ms_filter_create_decoder(pt->mime_type);
	if ((stream->encoder==NULL) || (stream->decoder==NULL)){
		/* big problem: we have not a registered codec for this payload...*/
		ms_error("videostream.c: No codecs available for payload %i:%s.",payload,pt->mime_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);

	/* creates two rtp filters to recv send streams (remote part) */
	if (remport>0) ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,stream->session);
	
	stream->rtprecv = ms_filter_new (MS_RTP_RECV_ID);
	ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,stream->session);

	/* creates the filters */
	stream->source = ms_web_cam_create_reader(cam);
	stream->tee = ms_filter_new(MS_TEE_ID);
	stream->output=ms_filter_new(MS_VIDEO_OUT_ID);
	stream->sizeconv=ms_filter_new(MS_SIZE_CONV_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);
	}
	/* set parameters to the encoder and decoder*/
	if (pt->send_fmtp){
		ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP,pt->send_fmtp);
		ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,pt->send_fmtp);
	}
	ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);
	ms_filter_call_method(stream->encoder,MS_FILTER_GET_FPS,&fps);
	ms_message("Setting vsize=%ix%i, fps=%f",vsize.width,vsize.height,fps);
	/* configure the filters */
	ms_filter_call_method(stream->source,MS_FILTER_SET_FPS,&fps);
	ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize);

	/* get the output format for webcam reader */
	ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);
	if (format==MS_MJPEG){
		stream->pixconv=ms_filter_new(MS_MJPEG_DEC_ID);
	}else{
		stream->pixconv = ms_filter_new(MS_PIX_CONV_ID);
		/*set it to the pixconv */
		ms_filter_call_method(stream->pixconv,MS_FILTER_SET_PIX_FMT,&format);

		ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&vsize);
	
		ms_filter_call_method(stream->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
		  
	}

	ms_filter_call_method(stream->encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);
	ms_filter_call_method(stream->sizeconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);

	/*force the decoder to output YUV420P */
	format=MS_YUV420P;
	ms_filter_call_method(stream->decoder,MS_FILTER_SET_PIX_FMT,&format);


	/*ask the video display to always output CIF */
	vsize.height=MS_VIDEO_SIZE_CIF_H;
	vsize.width=MS_VIDEO_SIZE_CIF_W;

	ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format);

	if (pt->recv_fmtp!=NULL)
		ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp);

	/* 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);
	
	ms_filter_link (stream->rtprecv, 0, stream->decoder, 0);
	ms_filter_link (stream->decoder,0 , stream->output, 0);
	/* the source video must be send for preview */
	ms_filter_link(stream->tee,1,stream->output,1);

	/* create the ticker */
	stream->ticker = ms_ticker_new(); 
	/* attach it the graph */
	ms_ticker_attach (stream->ticker, stream->source);
	return 0;
}
Example #7
0
int main(int argc, char* argv[]){
  ms_init();
  ortp_init();
  RtpSession* temp_session;
  temp_session=rtp_session_new(1);

  MSSndCard *sndcard;
  sndcard=ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());

  /*define sample audio capture filter */
  MSFilter *soundread=ms_snd_card_create_reader(sndcard);
  MSFilter *soundwrite=ms_snd_card_create_writer(sndcard);

  MSFilter *encoder=ms_filter_create_encoder("PCMU");
  MSFilter *decoder=ms_filter_create_decoder("PCMU");

  MSFilter *rtpsend=ms_filter_new(MS_RTP_SEND_ID);
  MSFilter *rtprecv=ms_filter_new(MS_RTP_RECV_ID);

  RtpSession *rtp_session = temp_session ;

  ms_filter_call_method(rtpsend,MS_RTP_SEND_SET_SESSION,rtp_session);
  ms_filter_call_method(rtprecv,MS_RTP_RECV_SET_SESSION,rtp_session);

/*define capture rate and initialize filters*/
  MSFilter *dtmfgen=ms_filter_new(MS_DTMF_GEN_ID);
  int sr = 8000;
  int chan=1;
  ms_filter_call_method(soundread,MS_FILTER_SET_SAMPLE_RATE,&sr);
  ms_filter_call_method(soundwrite,MS_FILTER_SET_SAMPLE_RATE,&sr);
  ms_filter_call_method(encoder,MS_FILTER_SET_SAMPLE_RATE,&sr);
  ms_filter_call_method(decoder,MS_FILTER_SET_SAMPLE_RATE,&sr);

  ms_filter_call_method(soundwrite,MS_FILTER_SET_NCHANNELS, &chan);

 




  /*link the filters and run the graph*/
  ms_filter_link(soundread,0, encoder,0);
  ms_filter_link( encoder,0, rtpsend,0);

  ms_filter_link( rtprecv,0, decoder,0);
  ms_filter_link( decoder,0, dtmfgen,0);
  ms_filter_link( dtmfgen,0, soundwrite,0); 

  /*create tiker*/
  MSTicker *ticker=ms_ticker_new();

  ms_ticker_attach(ticker,soundread);
  ms_ticker_attach(ticker,rtprecv);
  ms_ticker_detach(ticker,soundread);
  ms_ticker_detach(ticker,rtprecv);

/*unlink filters and destroy the MS objects*/
  ms_filter_unlink( soundread,0, encoder,0);
  ms_filter_unlink( encoder,0, rtpsend,0);

  ms_filter_unlink( rtprecv,0, decoder,0);
  ms_filter_unlink( decoder,0, dtmfgen,0);
  ms_filter_unlink( dtmfgen,0, soundwrite,0);
  

  if (rtp_session!=NULL) rtp_session_destroy(rtp_session);
  if (rtpsend!=NULL) ms_filter_destroy(rtpsend);
  if (rtprecv!=NULL) ms_filter_destroy(rtprecv);
  if (soundread!=NULL) ms_filter_destroy(soundread);
  if (soundwrite!=NULL) ms_filter_destroy(soundwrite);
  if (encoder!=NULL) ms_filter_destroy(encoder);
  if (decoder!=NULL) ms_filter_destroy(decoder);
  if (dtmfgen!=NULL) ms_filter_destroy(dtmfgen);
  if (ticker!=NULL) ms_ticker_destroy(ticker);

}
int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char *remip,int remport,
	int rem_rtcp_port, int payload,int jitt_comp, const char *infile, const char *outfile,
	MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec)
{
	RtpSession *rtps=stream->session;
	PayloadType *pt;
	int tmp;
	MSConnectionHelper h;

	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);

	if (remport>0)
		ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,rtps);
	stream->rtprecv=ms_filter_new(MS_RTP_RECV_ID);
	ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,rtps);
	stream->session=rtps;

	stream->dtmfgen=ms_filter_new(MS_DTMF_GEN_ID);
	rtp_session_signal_connect(rtps,"telephone-event",(RtpCallback)on_dtmf_received,(unsigned long)stream);
	rtp_session_signal_connect(rtps,"payload_type_changed",(RtpCallback)payload_type_changed,(unsigned long)stream);

	/* creates the local part */
	if (captcard!=NULL) stream->soundread=ms_snd_card_create_reader(captcard);
	else {
		stream->soundread=ms_filter_new(MS_FILE_PLAYER_ID);
		stream->read_resampler=ms_filter_new(MS_RESAMPLE_ID);
		if (infile!=NULL) audio_stream_play(stream,infile);
	}
	if (playcard!=NULL) stream->soundwrite=ms_snd_card_create_writer(playcard);
	else {
		stream->soundwrite=ms_filter_new(MS_FILE_REC_ID);
		if (outfile!=NULL) audio_stream_record(stream,outfile);
	}

	/* creates the couple of encoder/decoder */
	pt=rtp_profile_get_payload(profile,payload);
	if (pt==NULL){
		ms_error("audiostream.c: undefined payload type.");
		return -1;
	}
	stream->encoder=ms_filter_create_encoder(pt->mime_type);
	stream->decoder=ms_filter_create_decoder(pt->mime_type);
	if ((stream->encoder==NULL) || (stream->decoder==NULL)){
		/* big problem: we have not a registered codec for this payload...*/
		ms_error("mediastream.c: No decoder available for payload %i.",payload);
		return -1;
	}

	if (stream->el_type!=ELInactive || stream->use_gc || stream->use_ng){
		stream->volsend=ms_filter_new(MS_VOLUME_ID);
		stream->volrecv=ms_filter_new(MS_VOLUME_ID);
		if (stream->el_type!=ELInactive){
			if (stream->el_type==ELControlFull) {
				/* also reduce speaker gain when no signal - same parameters as std. noise gate */
				int tmp=1;
				ms_filter_call_method(stream->volrecv,MS_VOLUME_ENABLE_NOISE_GATE,&tmp);
			}
			ms_filter_call_method(stream->volsend,MS_VOLUME_SET_PEER,stream->volrecv);
		}
		if (stream->use_ng){
			int tmp=1;
			ms_filter_call_method(stream->volsend,MS_VOLUME_ENABLE_NOISE_GATE,&tmp);
		}
	}

	if (stream->use_agc || stream->use_nr){
		int tmp=1;
		if (stream->volsend==NULL)
			stream->volsend=ms_filter_new(MS_VOLUME_ID);

		if(stream->use_agc) ms_filter_call_method(stream->volsend,MS_VOLUME_ENABLE_AGC,&tmp);
		/*Noise Reduction*/
		if(stream->use_nr) ms_filter_call_method(stream->volsend,MS_VOLUME_ENABLE_NR,&tmp);
	}

	/* give the sound filters some properties */
	if (ms_filter_call_method(stream->soundread,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate) != 0) {
		/* need to add resampler*/
		if (stream->read_resampler == NULL) stream->read_resampler=ms_filter_new(MS_RESAMPLE_ID);
	}

	if (ms_filter_call_method(stream->soundwrite,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate) != 0) {
		/* need to add resampler*/
		if (stream->write_resampler == NULL) stream->write_resampler=ms_filter_new(MS_RESAMPLE_ID);
	}

	tmp=1;
	ms_filter_call_method(stream->soundwrite,MS_FILTER_SET_NCHANNELS, &tmp);

	if(stream->record_enabled)
	{
		stream->filewriter = ms_filter_new(MS_FILE_REC_ID);
		stream->recordmixer= ms_filter_new(MS_AUDIO_MIXER_ID);
		stream->mic_tee = ms_filter_new(MS_TEE_ID);
		stream->spk_tee = ms_filter_new(MS_TEE_ID);
		ms_filter_call_method(stream->filewriter,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
		ms_filter_call_method(stream->recordmixer,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
		tmp=1;
		ms_filter_call_method(stream->recordmixer,MS_FILTER_SET_NCHANNELS,&tmp);
	}

	/*configure the echo canceller if required */
	if (use_ec) {
		stream->ec=ms_filter_new(MS_SPEEX_EC_ID);
		ms_filter_call_method(stream->ec,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
		if (stream->ec_tail_len!=0)
			ms_filter_call_method(stream->ec,MS_ECHO_CANCELLER_SET_TAIL_LENGTH,&stream->ec_tail_len);
		if (stream->ec_delay!=0){
			ms_filter_call_method(stream->ec,MS_ECHO_CANCELLER_SET_DELAY,&stream->ec_delay);
		}else{
			/*configure from latency of sound card in case it is availlable */
			int latency=0;
			ms_filter_call_method(stream->soundread,MS_FILTER_GET_LATENCY,&latency);
			latency-=30; /*keep 30 milliseconds security margin*/
			if (latency<0) latency=0;
			ms_filter_call_method(stream->ec,MS_ECHO_CANCELLER_SET_DELAY,&latency);
		}
		if (stream->ec_framesize!=0)
			ms_filter_call_method(stream->ec,MS_ECHO_CANCELLER_SET_FRAMESIZE,&stream->ec_framesize);
	}

	/* give the encoder/decoder some parameters*/
	ms_filter_call_method(stream->encoder,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
	ms_message("Payload's bitrate is %i",pt->normal_bitrate);
	if (pt->normal_bitrate>0){
		ms_message("Setting audio encoder network bitrate to %i",pt->normal_bitrate);
		ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&pt->normal_bitrate);
	}
	ms_filter_call_method(stream->decoder,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);

	if (pt->send_fmtp!=NULL) ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP, (void*)pt->send_fmtp);
	if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp);

	/*create the equalizer*/
	stream->equalizer=ms_filter_new(MS_EQUALIZER_ID);
	tmp=stream->eq_active;
	ms_filter_call_method(stream->equalizer,MS_EQUALIZER_SET_ACTIVE,&tmp);
	/*configure resampler if needed*/
	if (stream->read_resampler){
		audio_stream_configure_resampler(stream->read_resampler,stream->soundread,stream->rtpsend);
	}

	if (stream->write_resampler){
		audio_stream_configure_resampler(stream->write_resampler,stream->rtprecv,stream->soundwrite);
	}
	/* and then connect all */
	/* tip: draw yourself the picture if you don't understand */

	/*sending graph*/
	ms_connection_helper_start(&h);
	ms_connection_helper_link(&h,stream->soundread,-1,0);
	if (stream->read_resampler)
		ms_connection_helper_link(&h,stream->read_resampler,0,0);
	if (stream->ec)
		ms_connection_helper_link(&h,stream->ec,1,1);
	if (stream->volsend)
		ms_connection_helper_link(&h,stream->volsend,0,0);
	if(stream->mic_tee)
		ms_connection_helper_link(&h,stream->mic_tee,0,0);
	if(stream->mic_tee && stream->recordmixer)
		ms_filter_link(stream->mic_tee,1,stream->recordmixer,0);

	ms_connection_helper_link(&h,stream->encoder,0,0);
	ms_connection_helper_link(&h,stream->rtpsend,0,-1);

	/*receiving graph*/
	ms_connection_helper_start(&h);
	ms_connection_helper_link(&h,stream->rtprecv,-1,0);
	ms_connection_helper_link(&h,stream->decoder,0,0);
	ms_connection_helper_link(&h,stream->dtmfgen,0,0);
	if (stream->equalizer)
		ms_connection_helper_link(&h,stream->equalizer,0,0);
	if (stream->volrecv)
		ms_connection_helper_link(&h,stream->volrecv,0,0);
	if (stream->ec)
		ms_connection_helper_link(&h,stream->ec,0,0);
	if (stream->write_resampler)
		ms_connection_helper_link(&h,stream->write_resampler,0,0);
	if(stream->spk_tee)
		ms_connection_helper_link(&h,stream->spk_tee,0,0);
	if(stream->mic_tee && stream->recordmixer)
		ms_filter_link(stream->spk_tee,1,stream->recordmixer,1);
	ms_connection_helper_link(&h,stream->soundwrite,0,-1);

	if (stream->filewriter && stream->spk_tee && stream->mic_tee && stream->recordmixer){
		ms_filter_link(stream->recordmixer,0,stream->filewriter,0);
	}
	/* create ticker */
	stream->ticker=ms_ticker_new();
	ms_ticker_set_name(stream->ticker,"Audio MSTicker");
	ms_ticker_attach(stream->ticker,stream->soundread);
	ms_ticker_attach(stream->ticker,stream->rtprecv);

	return 0;
}
Example #9
0
int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char *remip,int remport,
	int rem_rtcp_port, int payload,int jitt_comp, const char *infile, const char *outfile,
	MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec)
{
	RtpSession *rtps=stream->session;
	PayloadType *pt;
	int tmp;	

	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);
	
	if (remport>0)
		ms_filter_call_method(stream->rtpsend,MS_RTP_SEND_SET_SESSION,rtps);
	stream->rtprecv=ms_filter_new(MS_RTP_RECV_ID);
	ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,rtps);
	stream->session=rtps;
	
	stream->dtmfgen=ms_filter_new(MS_DTMF_GEN_ID);
	rtp_session_signal_connect(rtps,"telephone-event",(RtpCallback)on_dtmf_received,(unsigned long)stream);
	rtp_session_signal_connect(rtps,"payload_type_changed",(RtpCallback)payload_type_changed,(unsigned long)stream);
	
	/* creates the local part */
	if (captcard!=NULL) stream->soundread=ms_snd_card_create_reader(captcard);
	else {
		stream->soundread=ms_filter_new(MS_FILE_PLAYER_ID);
		if (infile!=NULL) audio_stream_play(stream,infile);
	}
	if (playcard!=NULL) stream->soundwrite=ms_snd_card_create_writer(playcard);
	else {
		stream->soundwrite=ms_filter_new(MS_FILE_REC_ID);
		if (outfile!=NULL) audio_stream_record(stream,outfile);
	}
	
	/* creates the couple of encoder/decoder */
	pt=rtp_profile_get_payload(profile,payload);
	if (pt==NULL){
		ms_error("audiostream.c: undefined payload type.");
		return -1;
	}
	stream->encoder=ms_filter_create_encoder(pt->mime_type);
	stream->decoder=ms_filter_create_decoder(pt->mime_type);
	if ((stream->encoder==NULL) || (stream->decoder==NULL)){
		/* big problem: we have not a registered codec for this payload...*/
		ms_error("mediastream.c: No decoder available for payload %i.",payload);
		return -1;
	}
	
	if (use_ec) {
		stream->ec=ms_filter_new(MS_SPEEX_EC_ID);
		ms_filter_call_method(stream->ec,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
	}	

	/* give the sound filters some properties */
	ms_filter_call_method(stream->soundread,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
	ms_filter_call_method(stream->soundwrite,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
	tmp=1;
	ms_filter_call_method(stream->soundwrite,MS_FILTER_SET_NCHANNELS, &tmp);
	
	/* give the encoder/decoder some parameters*/
	ms_filter_call_method(stream->encoder,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
	ms_message("Payload's bitrate is %i",pt->normal_bitrate);
	if (pt->normal_bitrate>0){
		ms_message("Setting audio encoder network bitrate to %i",pt->normal_bitrate);
		ms_filter_call_method(stream->encoder,MS_FILTER_SET_BITRATE,&pt->normal_bitrate);
	}
	ms_filter_call_method(stream->decoder,MS_FILTER_SET_SAMPLE_RATE,&pt->clock_rate);
	
	if (pt->send_fmtp!=NULL) ms_filter_call_method(stream->encoder,MS_FILTER_ADD_FMTP, (void*)pt->send_fmtp);
	if (pt->recv_fmtp!=NULL) ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp);
	
	/* and then connect all */
	/* tip: draw yourself the picture if you don't understand */
	if (stream->ec){
		ms_filter_link(stream->soundread,0,stream->ec,1);
		ms_filter_link(stream->ec,1,stream->encoder,0);
		ms_filter_link(stream->dtmfgen,0,stream->ec,0);
		ms_filter_link(stream->ec,0,stream->soundwrite,0);
	}else{
		ms_filter_link(stream->soundread,0,stream->encoder,0);
		ms_filter_link(stream->dtmfgen,0,stream->soundwrite,0);
	}
	
	ms_filter_link(stream->encoder,0,stream->rtpsend,0);
	ms_filter_link(stream->rtprecv,0,stream->decoder,0);
	ms_filter_link(stream->decoder,0,stream->dtmfgen,0);
	
	/* create ticker */
	stream->ticker=ms_ticker_new();
	ms_ticker_set_name(stream->ticker,"Audio MSTicker");
	ms_ticker_attach(stream->ticker,stream->soundread);
	ms_ticker_attach(stream->ticker,stream->rtprecv);
	
	return 0;
}
Example #10
0
int init_bench(struct bench_config *bench)
{
	PayloadType *pt;
	int pos;
	int val;
	int count;
	bench->ticker=ms_ticker_new();

	count = 0;
	/* creates the couple of encoder/decoder */
	pt=rtp_profile_get_payload(&av_profile,bench->payload);
	if (pt==NULL){
		ms_error("audiostream.c: undefined payload type.");
		return count;
	}
	if (pt->clock_rate!=8000 && pt->clock_rate!=16000 && pt->clock_rate!=32000){
		ms_error("audiostream.c: wrong rate.");
		return count;
	}
	for (pos=0;pos<bench->num_session;pos++)
		{
			struct test_session *ts = (struct test_session *)ortp_malloc(sizeof(struct test_session));
			memset(ts, 0, sizeof(struct test_session));

			ts->rtps = create_duplex_rtpsession(bench->port_origin+pos*2);
			if (ts->rtps==NULL)
				{
					ms_error("bench.c: cannot create rtp_session!");
					ortp_free(ts);
					return count;
				}

			rtp_session_set_payload_type(ts->rtps,bench->payload);
			rtp_session_set_remote_addr_full(ts->rtps,
											 bench->ip_destination,
											 bench->port_destination+pos*2,
											 bench->ip_destination,
											 bench->port_destination+1+pos*2);

			ts->fplayer = ms_filter_new(MS_FILE_PLAYER_ID);
			if (strstr(bench->wavfile, ".au")==NULL)
				ts->encoder = ms_filter_create_encoder(pt->mime_type);
			ts->rtpsend = ms_filter_new(MS_RTP_SEND_ID);

			ts->rtprecv = ms_filter_new(MS_RTP_RECV_ID);
			ts->decoder = ms_filter_create_decoder(pt->mime_type);
			ts->frecorder = ms_filter_new(MS_FILE_REC_ID);

			if ((ts->encoder==NULL && strstr(bench->wavfile, ".au")==NULL)
				|| (ts->decoder==NULL )){
				ms_error("bench.c: No decoder available for payload %i.",bench->payload);
				if (ts->fplayer) ms_filter_destroy(ts->fplayer);
				if (ts->encoder) ms_filter_destroy(ts->encoder);
				if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
				if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
				if (ts->decoder) ms_filter_destroy(ts->decoder);
				if (ts->frecorder) ms_filter_destroy(ts->frecorder);
				ortp_free(ts);
				return count;
			}
			if (ts->fplayer==NULL){
				ms_error("bench.c: missing player filter.");
				if (ts->fplayer) ms_filter_destroy(ts->fplayer);
				if (ts->encoder) ms_filter_destroy(ts->encoder);
				if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
				if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
				if (ts->decoder) ms_filter_destroy(ts->decoder);
				if (ts->frecorder) ms_filter_destroy(ts->frecorder);
				ortp_free(ts);
				return count;
			}
			if (ts->frecorder==NULL){
				ms_error("bench.c: missing recorder filter.");
				if (ts->fplayer) ms_filter_destroy(ts->fplayer);
				if (ts->encoder) ms_filter_destroy(ts->encoder);
				if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
				if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
				if (ts->decoder) ms_filter_destroy(ts->decoder);
				if (ts->frecorder) ms_filter_destroy(ts->frecorder);
				ortp_free(ts);
				return count;
			}
			if (ts->rtpsend==NULL){
				ms_error("bench.c: missing rtpsend filter.");
				if (ts->fplayer) ms_filter_destroy(ts->fplayer);
				if (ts->encoder) ms_filter_destroy(ts->encoder);
				if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
				if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
				if (ts->decoder) ms_filter_destroy(ts->decoder);
				if (ts->frecorder) ms_filter_destroy(ts->frecorder);
				ortp_free(ts);
				return count;
			}
			if (ts->rtprecv==NULL){
				ms_error("bench.c: missing rtprecv filter.");
				if (ts->fplayer) ms_filter_destroy(ts->fplayer);
				if (ts->encoder) ms_filter_destroy(ts->encoder);
				if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
				if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
				if (ts->decoder) ms_filter_destroy(ts->decoder);
				if (ts->frecorder) ms_filter_destroy(ts->frecorder);
				ortp_free(ts);
				return count;
			}

			ms_filter_call_method(ts->rtpsend,MS_RTP_SEND_SET_SESSION,ts->rtps);
			ms_filter_call_method(ts->rtprecv,MS_RTP_RECV_SET_SESSION,ts->rtps);

			ms_filter_call_method (ts->rtprecv, MS_FILTER_SET_SAMPLE_RATE,
								   &pt->clock_rate);

			ms_filter_call_method (ts->frecorder, MS_FILTER_SET_SAMPLE_RATE,
								   &pt->clock_rate);

			val = ms_filter_call_method(ts->fplayer,MS_FILE_PLAYER_OPEN,(void*)bench->wavfile);
			if (val!=0)
				{
					ms_error("bench.c: Cannot open wav file (%s)", bench->wavfile);
					if (ts->fplayer) ms_filter_destroy(ts->fplayer);
					if (ts->encoder) ms_filter_destroy(ts->encoder);
					if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
					if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
					if (ts->decoder) ms_filter_destroy(ts->decoder);
					if (ts->frecorder) ms_filter_destroy(ts->frecorder);
					ortp_free(ts);
					return count;
				}

			val=0;
			ms_filter_call_method (ts->fplayer, MS_FILTER_GET_SAMPLE_RATE,
								   &val);
			if (val!=pt->clock_rate)
				{
					ms_error("bench.c: unsupported rate for wav file: codec=%i / file=%i",
							 pt->clock_rate, val);
					if (ts->fplayer) ms_filter_destroy(ts->fplayer);
					if (ts->encoder) ms_filter_destroy(ts->encoder);
					if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
					if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
					if (ts->decoder) ms_filter_destroy(ts->decoder);
					if (ts->frecorder) ms_filter_destroy(ts->frecorder);
					ortp_free(ts);
					return count;
				}
			ms_filter_call_method (ts->fplayer, MS_FILTER_GET_NCHANNELS,
								   &val);

			if (val!=1)
				{
					ms_error("bench.c: unsupported number of channel for wav file: codec=1 / file=%i",
							 val);
					if (ts->fplayer) ms_filter_destroy(ts->fplayer);
					if (ts->encoder) ms_filter_destroy(ts->encoder);
					if (ts->rtpsend) ms_filter_destroy(ts->rtpsend);
					if (ts->rtprecv) ms_filter_destroy(ts->rtprecv);
					if (ts->decoder) ms_filter_destroy(ts->decoder);
					if (ts->frecorder) ms_filter_destroy(ts->frecorder);
					ortp_free(ts);
					return count;
				}
			ms_filter_call_method_noarg(ts->fplayer,MS_FILE_PLAYER_START);

			if (strstr(bench->wavfile, ".au")==NULL)
				{
					ms_filter_link(ts->fplayer,0,ts->encoder,0);
					ms_filter_link(ts->encoder,0,ts->rtpsend,0);
				}
			else
				{
					ms_filter_link(ts->fplayer,0,ts->rtpsend,0);
				}

			ms_filter_link(ts->rtprecv,0,ts->decoder,0);
			ms_filter_link(ts->decoder,0,ts->frecorder,0);

			ms_ticker_attach(bench->ticker,ts->fplayer);
			ms_ticker_attach(bench->ticker,ts->rtprecv);

			if (pos < bench->num_session_record)
			{
				char rec_file[128];
				snprintf(rec_file, sizeof(rec_file), "rec_%s_%i.wav",
						 bench->ip_destination,
						 bench->port_destination+pos*2);
				ms_filter_call_method(ts->frecorder,MS_FILE_REC_OPEN,(void*)rec_file);
				ms_filter_call_method_noarg(ts->frecorder,MS_FILE_REC_START);
			}

			bench->tsessions = ms_list_append(bench->tsessions, (void*)ts);
			count++;
		}

	return count;
}
Example #11
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;
}