Esempio n. 1
0
static MSFilter *get_source()
{
	MSWebCamManager *wcm = ms_web_cam_manager_get();
	const MSList *list = ms_web_cam_manager_get_list(wcm);

	const MSList *next = list->next;
	while (next) {
		MSWebCam *cam = (MSWebCam*)next->data;

		dump_webcam(cam->desc);

		next = next->next;
	}

	MSWebCam *cam = ms_web_cam_manager_get_default_cam(wcm);
	if (!cam) {
		fprintf(stderr, "ERR: NO cams!!!\n");
		return 0;
	}

	MSFilter *source = ms_web_cam_create_reader(cam);
	if (!source) {
		fprintf(stderr, "ERR: can't create Filter for %s\n", cam->desc->driver_type);
		ms_web_cam_destroy(cam);
		return 0;
	}

	return source;
}
Esempio n. 2
0
void video_stream_change_camera(VideoStream *stream, MSWebCam *cam){
	if (stream->ticker && stream->source){
#ifdef ENABLE_UDT
		if (stream->udt) ms_ticker_detach (stream->ticker, stream->udt);
#endif // ENABLE_UDT
		ms_ticker_detach(stream->ticker,stream->source);
		/*unlink source filters and subsequent post processin filters */
		ms_filter_unlink (stream->source, 0, stream->pixconv, 0);
		ms_filter_unlink (stream->pixconv, 0, stream->sizeconv, 0);
		ms_filter_unlink (stream->sizeconv, 0, stream->tee, 0);
		/*destroy the filters */
		ms_filter_destroy(stream->source);
		ms_filter_destroy(stream->pixconv);
		ms_filter_destroy(stream->sizeconv);

		/*re create new ones and configure them*/
		stream->source = ms_web_cam_create_reader(cam);
		configure_video_source(stream);
		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_ticker_attach(stream->ticker,stream->source);
	}
}
void ms_tester_create_filters(unsigned int filter_mask, MSFactory * f) {
	MSSndCardManager *snd_manager;
	MSWebCamManager *cam_manager;
	MSSndCard *playcard;
	MSSndCard *captcard;
	MSWebCam *camera;



	CREATE_FILTER(FILTER_MASK_FILEPLAY, ms_tester_fileplay,f, MS_FILE_PLAYER_ID);
	CREATE_FILTER(FILTER_MASK_FILEREC, ms_tester_filerec,f, MS_FILE_REC_ID);
	CREATE_FILTER(FILTER_MASK_DTMFGEN, ms_tester_dtmfgen, f,  MS_DTMF_GEN_ID);
	CREATE_FILTER(FILTER_MASK_TONEDET, ms_tester_tonedet, f, MS_TONE_DETECTOR_ID);
	CREATE_FILTER(FILTER_MASK_VOIDSOURCE, ms_tester_voidsource, f, MS_VOID_SOURCE_ID);
	CREATE_FILTER(FILTER_MASK_VOIDSINK, ms_tester_voidsink, f, MS_VOID_SINK_ID);
	if (filter_mask & FILTER_MASK_ENCODER) {
		BC_ASSERT_PTR_NULL(ms_tester_encoder);
		ms_tester_encoder = ms_factory_create_encoder(f, ms_tester_codec_mime);
		BC_ASSERT_PTR_NOT_NULL(ms_tester_encoder);
	}
	if (filter_mask & FILTER_MASK_DECODER) {
		BC_ASSERT_PTR_NULL(ms_tester_decoder);
		ms_tester_decoder = ms_factory_create_decoder(f, ms_tester_codec_mime);
		BC_ASSERT_PTR_NOT_NULL(ms_tester_decoder);
	}
	CREATE_FILTER(FILTER_MASK_RTPRECV, ms_tester_rtprecv, f, MS_RTP_RECV_ID);
	CREATE_FILTER(FILTER_MASK_RTPSEND, ms_tester_rtpsend, f ,MS_RTP_SEND_ID);
	CREATE_FILTER(FILTER_MASK_RESAMPLER, ms_tester_resampler, f, MS_RESAMPLE_ID);
	if (filter_mask & FILTER_MASK_SOUNDWRITE) {
		BC_ASSERT_PTR_NULL(ms_tester_soundwrite);
		snd_manager = ms_factory_get_snd_card_manager(f);
		playcard = ms_snd_card_manager_get_default_playback_card(snd_manager);
		BC_ASSERT_PTR_NOT_NULL(playcard);
		ms_tester_soundwrite = ms_snd_card_create_writer(playcard);
		BC_ASSERT_PTR_NOT_NULL(ms_tester_soundwrite);
	}
	if (filter_mask & FILTER_MASK_SOUNDREAD) {
		BC_ASSERT_PTR_NULL(ms_tester_soundread);
		snd_manager = ms_factory_get_snd_card_manager(f);
		captcard = ms_snd_card_manager_get_default_capture_card(snd_manager);
		BC_ASSERT_PTR_NOT_NULL(captcard);
		ms_tester_soundread = ms_snd_card_create_reader(captcard);
		BC_ASSERT_PTR_NOT_NULL(ms_tester_soundread);
	}
	if (filter_mask & FILTER_MASK_VIDEOCAPTURE) {
		BC_ASSERT_PTR_NULL(ms_tester_videocapture);
		cam_manager = ms_factory_get_web_cam_manager(f);
		camera = ms_web_cam_manager_get_default_cam(cam_manager);
		BC_ASSERT_PTR_NOT_NULL(camera);
		ms_tester_videocapture = ms_web_cam_create_reader(camera);
		BC_ASSERT_PTR_NOT_NULL(ms_tester_videocapture);
	}
}
Esempio n. 4
0
int local_webcam_start(ConfWebCam *localcam,MSWebCam *device,MSVideoSize vsize,float fps){

	MSPixFmt format=MS_YUV420P;

	if(!device) return -1;

	if(fps<=0)
		fps=15;

	if (device==NULL){
		device=ms_web_cam_manager_get_default_cam (
			ms_web_cam_manager_get());                                
	}

	localcam->webcam = ms_web_cam_create_reader(device);

	ms_message("Setting sent vsize=%ix%i, fps=%f",vsize.width,vsize.height,fps);
	/* configure the filters */
	if (ms_filter_get_id(localcam->webcam)!=MS_STATIC_IMAGE_ID) {
		ms_filter_call_method(localcam->webcam,MS_FILTER_SET_FPS,&fps);
	}
	ms_filter_call_method(localcam->webcam,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	/* get the output format for webcam reader */
	ms_filter_call_method(localcam->webcam,MS_FILTER_GET_PIX_FMT,&format);
	if (format==MS_MJPEG){
		localcam->pixconv=ms_filter_new(MS_MJPEG_DEC_ID);
	}else{
		localcam->pixconv = ms_filter_new(MS_PIX_CONV_ID);
		/*set it to the pixconv */
		ms_filter_call_method(localcam->pixconv,MS_FILTER_SET_PIX_FMT,&format);
		ms_filter_call_method(localcam->webcam,MS_FILTER_GET_VIDEO_SIZE,&vsize);
		ms_filter_call_method(localcam->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	}
	localcam->sizeconv=ms_filter_new(MS_SIZE_CONV_ID);
	ms_filter_call_method(localcam->sizeconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);

	localcam->itc_sink = ms_filter_new(MS_CONF_ITC_SINK_ID);

	ms_filter_link(localcam->webcam,0,localcam->pixconv,0);
	ms_filter_link(localcam->pixconv,0,localcam->sizeconv,0);
	ms_filter_link(localcam->sizeconv,0,localcam->itc_sink,0);


	localcam->ticker = ms_ticker_new();
	ms_ticker_set_name(localcam->ticker,"Local Camera MSTicker");

	ms_ticker_attach(localcam->ticker,localcam->webcam);

	return 0;
}
Esempio n. 5
0
void video_stream_change_camera(VideoStream *stream, MSWebCam *cam){
	bool_t keep_source=(cam==stream->cam);
	bool_t encoder_has_builtin_converter = (!stream->pixconv && !stream->sizeconv);

	if (stream->ms.ticker && stream->source){
		ms_ticker_detach(stream->ms.ticker,stream->source);
		/*unlink source filters and subsequent post processin filters */
		if (encoder_has_builtin_converter || (stream->source_performs_encoding == TRUE)) {
			ms_filter_unlink(stream->source, 0, stream->tee, 0);
		} else {
			ms_filter_unlink (stream->source, 0, stream->pixconv, 0);
			ms_filter_unlink (stream->pixconv, 0, stream->sizeconv, 0);
			ms_filter_unlink (stream->sizeconv, 0, stream->tee, 0);
		}
		/*destroy the filters */
		if (!keep_source) ms_filter_destroy(stream->source);
		if (!encoder_has_builtin_converter && (stream->source_performs_encoding == FALSE)) {
			ms_filter_destroy(stream->pixconv);
			ms_filter_destroy(stream->sizeconv);
		}

		/*re create new ones and configure them*/
		if (!keep_source) stream->source = ms_web_cam_create_reader(cam);
		stream->cam=cam;

		/* update orientation */
		if (stream->source){
			ms_filter_call_method(stream->source,MS_VIDEO_CAPTURE_SET_DEVICE_ORIENTATION,&stream->device_orientation);
			if (!stream->display_filter_auto_rotate_enabled)
				ms_filter_call_method(stream->source,MS_VIDEO_DISPLAY_SET_DEVICE_ORIENTATION,&stream->device_orientation);
		}
		if (stream->output && stream->display_filter_auto_rotate_enabled) {
			ms_filter_call_method(stream->output,MS_VIDEO_DISPLAY_SET_DEVICE_ORIENTATION,&stream->device_orientation);
		}

		configure_video_source(stream);

		if (encoder_has_builtin_converter || (stream->source_performs_encoding == TRUE)) {
			ms_filter_link (stream->source, 0, stream->tee, 0);
		}
		else {
			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_ticker_attach(stream->ms.ticker,stream->source);
	}
}
Esempio n. 6
0
void video_preview_start(VideoPreview *stream, MSWebCam *device){
	MSPixFmt format;
	float fps=(float)29.97;
	int mirroring=1;
	int corner=-1;
	MSVideoSize disp_size=stream->sent_vsize;
	MSVideoSize vsize=disp_size;
	const char *displaytype=stream->display_name;

	stream->source = ms_web_cam_create_reader(device);


	/* configure the filters */
	ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	if (ms_filter_get_id(stream->source)!=MS_STATIC_IMAGE_ID)
		ms_filter_call_method(stream->source,MS_FILTER_SET_FPS,&fps);
	ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);
	ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&vsize);
	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->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	}

	format=MS_YUV420P;

	stream->output2=ms_filter_new_from_name (displaytype);
	ms_filter_call_method(stream->output2,MS_FILTER_SET_PIX_FMT,&format);
	ms_filter_call_method(stream->output2,MS_FILTER_SET_VIDEO_SIZE,&disp_size);
	ms_filter_call_method(stream->output2,MS_VIDEO_DISPLAY_ENABLE_MIRRORING,&mirroring);
	ms_filter_call_method(stream->output2,MS_VIDEO_DISPLAY_SET_LOCAL_VIEW_MODE,&corner);
	/* and then connect all */

	ms_filter_link(stream->source,0, stream->pixconv,0);
	ms_filter_link(stream->pixconv, 0, stream->output2, 0);

	if (stream->preview_window_id!=0){
		video_stream_set_native_preview_window_id(stream, stream->preview_window_id);
	}
	/* create the ticker */
	stream->ms.ticker = ms_ticker_new();
	ms_ticker_set_name(stream->ms.ticker,"Video MSTicker");
	ms_ticker_attach (stream->ms.ticker, stream->source);
}
Esempio n. 7
0
VideoStream * video_preview_start(MSWebCam *device){
	VideoStream *stream = (VideoStream *)ms_new0 (VideoStream, 1);
	MSPixFmt format;
	MSVideoSize vsize;
	vsize.width=MS_VIDEO_SIZE_CIF_W;
	vsize.height=MS_VIDEO_SIZE_CIF_H;

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


	/* configure the filters */
	ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);
	ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&vsize);
	
	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->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	}

	format=MS_YUV420P;
	ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format);
	ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	/* and then connect all */

	ms_filter_link(stream->source,0, stream->pixconv,0);
	ms_filter_link(stream->pixconv, 0, stream->output, 0);

	/* create the ticker */
	stream->ticker = ms_ticker_new(); 
	ms_ticker_attach (stream->ticker, stream->source);
	return stream;
}
Esempio n. 8
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;
}
int  video_mail_record_start(VideoMailRecord *vp, MSSndCard *sndcard,MSWebCam *webcam,unsigned long video_window_id,const char *filename){
	MSConnectionHelper h;
	MSPixFmt format=MS_YUV420P;

	{
		strcpy(vp->filename, filename);

		vp->os = video_recoder_new();
		video_recoder_init(vp->os);
		video_recoder_set_vsize(vp->os,vp->vsize);
		video_recoder_set_rate(vp->os,vp->rate);
		video_recoder_set_audio_bit_rate(vp->os,  get_bit_rate_by_samples_rate(vp->rate));
		video_recoder_set_video_bit_rate(vp->os, vp->bit_rate - get_bit_rate_by_samples_rate(vp->rate));
		video_recoder_set_nbchannels(vp->os,vp->nchannels);

		if(video_recoder_open_file(vp->os,vp->filename)<0){

			video_recoder_destory(vp->os);
			vp->os=NULL;
			return -1;
		}

		video_mail_record_set_audio_sink(vp,video_recoder_create_audio_filter(vp->os));
		video_mail_record_set_video_sink(vp,video_recoder_create_video_filter(vp->os));

		video_recoder_start(vp->os);
	}


	{
		if (sndcard!=NULL) vp->snd_read=ms_snd_card_create_reader(sndcard);

		if(vp->snd_read){
			ms_filter_call_method(vp->snd_read,MS_FILTER_SET_NCHANNELS,&vp->nchannels);
			ms_filter_call_method(vp->snd_read,MS_FILTER_SET_SAMPLE_RATE,&vp->rate);
		}
	}

	{
		if (webcam==NULL){
			webcam=ms_web_cam_manager_get_default_cam (
				ms_web_cam_manager_get());                                
		}

		vp->video_source = ms_web_cam_create_reader(webcam);

		vp->video_tee = ms_filter_new(MS_TEE_ID);


		ms_message("Setting sent vsize=%ix%i, fps=%f",vp->vsize.width,vp->vsize.height,vp->fps);
		/* configure the filters */
		if (ms_filter_get_id(vp->video_source)!=MS_STATIC_IMAGE_ID) {
			ms_filter_call_method(vp->video_source,MS_FILTER_SET_FPS,&vp->fps);
		}
		ms_filter_call_method(vp->video_source,MS_FILTER_SET_VIDEO_SIZE,&vp->vsize);

		ms_filter_call_method(vp->video_source,MS_FILTER_GET_PIX_FMT,&format);

		if (format==MS_MJPEG){
			vp->pixconv=ms_filter_new(MS_MJPEG_DEC_ID);
		}else{
			vp->pixconv = ms_filter_new(MS_PIX_CONV_ID);
			/*set it to the pixconv */
			ms_filter_call_method(vp->pixconv,MS_FILTER_SET_PIX_FMT,&format);
			ms_filter_call_method(vp->video_source,MS_FILTER_GET_VIDEO_SIZE,&vp->vsize);
			ms_filter_call_method(vp->pixconv,MS_FILTER_SET_VIDEO_SIZE,&vp->vsize);
		}
		vp->sizeconv=ms_filter_new(MS_SIZE_CONV_ID);
		ms_filter_call_method(vp->sizeconv,MS_FILTER_SET_VIDEO_SIZE,&vp->vsize);

		choose_display_name(vp);
		vp->video_output=ms_filter_new_from_name (vp->display_name);

		if (video_window_id!=0)
			ms_filter_call_method(vp->video_output, MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID,&video_window_id);
	}

	if(vp->snd_read!=NULL && vp->snd_sink!=NULL){

		ms_filter_link(vp->snd_read,0,vp->snd_sink,0);
	}

	if(vp->video_source!=NULL && vp->video_output!=NULL)
	{
		ms_connection_helper_start(&h);
		ms_connection_helper_link(&h,vp->video_source,-1,0);
		ms_connection_helper_link(&h,vp->pixconv,0,0);
		ms_connection_helper_link(&h,vp->sizeconv,0,0);
		ms_connection_helper_link(&h,vp->video_tee,0,0);

		ms_filter_link(vp->video_tee,1,vp->video_output,0);

		ms_connection_helper_link(&h,vp->video_sink,0,-1);

	}

	vp->ticker = ms_ticker_new();
	ms_ticker_set_name(vp->ticker,"VideoMailRecord");

	if(vp->snd_read!=NULL && vp->snd_sink!=NULL)
		ms_ticker_attach(vp->ticker,vp->snd_read);

	if(vp->video_source!=NULL && vp->video_output!=NULL)
		ms_ticker_attach(vp->ticker,vp->video_source);


	return 0;
}
Esempio n. 10
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;
}
Esempio n. 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 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;
}
Esempio n. 12
0
void conf_stream_start(LinphoneConferenceStream *stream,bool_t video_monitor)
{
	bool_t ptt = stream->ptt_mode;
	int tmp;

	{
		stream->audio_ticker = ms_ticker_new();
		ms_cond_init(&stream->audio_ticker->cond,NULL);
		ms_ticker_set_name(stream->audio_ticker,"Audio Mixer MSTicker");

		stream->audio_mixer = ms_filter_new(MS_CONF_ID);
		stream->audio_filerecorder = ms_filter_new(MS_FILE_REC_ID);
		stream->audio_fileplayer = ms_filter_new(MS_FILE_PLAYER_ID);


		ms_filter_call_method(stream->audio_mixer,MS_FILTER_SET_SAMPLE_RATE,&stream->sample_rate);
		ms_filter_call_method (stream->audio_fileplayer , MS_FILTER_SET_SAMPLE_RATE,&stream->sample_rate);
		tmp = 1; /*默认采用单声道会议*/
		ms_filter_call_method (stream->audio_fileplayer , MS_FILTER_SET_NCHANNELS,&tmp);
		/*设置会议音频采样率,8k,16k,32k*/
		ms_filter_call_method(stream->audio_filerecorder,MS_FILTER_SET_SAMPLE_RATE,&stream->sample_rate);

		ms_message("Link audio filter list!!!");

		/*创建录制端口*/
		{
			int audio_mixer_pin = NB_AUDIO_MAX_OUPUT_PINS-2;
			stream->audio_record_sink = ms_filter_new(MS_CONF_ITC_SINK_ID);

			ms_filter_link(stream->audio_mixer,audio_mixer_pin,stream->audio_record_sink,0); 
		}

		{/*创建音频对接端口*/
			int max_ports = stream->max_ports;
			for(int i=0; i< max_ports; i++)
			{
				ConfAudioPort *port = audio_slot_new();
				audio_slot_init(port,i);

				stream->audio_ports = ms_list_append(stream->audio_ports, port);

				/*顺序连接音频对接端口*/
				ms_filter_link(port->audio_itc_source,0,stream->audio_mixer,i);// <--- call[i].sink <--- call[i].decode <--- call[i].rtp_recv
				ms_filter_link(stream->audio_mixer,i,port->audio_itc_sink,0);  // ---> call[i].itc_source --->call[i].encode --->call[i].rtp_send

			}

			/*将音频播放,及录制连接至最末端端口*/
			ms_filter_link(stream->audio_fileplayer,0,stream->audio_mixer,stream->max_ports);
			ms_filter_link(stream->audio_mixer,stream->max_ports,stream->audio_filerecorder,0);
		}

		/*启动音频mixer线程*/
		ms_ticker_attach(stream->audio_ticker,stream->audio_mixer);
	}


	if(stream->has_video)
	{
		ms_message("Link video filter list!!!");

		MSPixFmt format=MS_YUV420P;
		MSVideoSize vsize,cam_vsize,disp_size;
		stream->video_mixer=ms_filter_new_from_name("MSVideoMixer");

		if(stream->video_mixer==NULL){
			ms_error("Not have MSVideoStitcher, Can't to Video Conference!!!");
			return;
		}

		stream->video_ticker = ms_ticker_new();
		ms_cond_init(&stream->video_ticker->cond,NULL);
		
		ms_ticker_set_name(stream->video_ticker,"Video Mixer MSTicker");
		/*设置视频会议的输出尺寸*/
		ms_filter_call_method(stream->video_mixer,MS_FILTER_SET_VIDEO_SIZE,&stream->sent_vsize);
		/*添加服务器端视频监视,可添加jpeg画面截取filer,用于web端实时会议的画面截取*/
		if(video_monitor) stream->video_output=ms_filter_new_from_name (stream->display_name);

		/*配置监视器*/
		if(stream->video_output!=NULL){
			disp_size = stream->sent_vsize;
			tmp=1;
			ms_filter_call_method(stream->video_output,MS_FILTER_SET_VIDEO_SIZE,&disp_size);
			ms_filter_call_method(stream->video_output,MS_VIDEO_DISPLAY_ENABLE_AUTOFIT,&tmp);
			ms_filter_call_method(stream->video_output,MS_FILTER_SET_PIX_FMT,&format);

			/*在已有窗口上绘图,或创建新window*/
			if (stream->video_window_id!=0)
				ms_filter_call_method(stream->video_output, MS_VIDEO_DISPLAY_SET_NATIVE_WINDOW_ID,&stream->video_window_id);
		
			/*设置服务器端 视频监视filter,将其连接至视频Mixer输出最后的端口上*/
			ms_filter_link (stream->video_mixer,VIDEO_MIXER_MAX_OUTPUTS-1, stream->video_output, 0);
		}

		/*输出录制端口*/
		{
			int video_mixer_pin = VIDEO_MIXER_MAX_OUTPUTS-2;
			stream->video_record_sink = ms_filter_new(MS_CONF_ITC_SINK_ID);
			ms_filter_link(stream->video_mixer,video_mixer_pin,stream->video_record_sink,0); 
		}

		/*创建无信号输出时,显示的图片*/
		stream->video_static_image = ms_web_cam_create_reader(get_image_webcam_device());
		
		if(stream->static_image_path!=NULL)
			ms_filter_call_method(stream->video_static_image, MS_STATIC_IMAGE_SET_IMAGE,(void *)stream->static_image_path);

		ms_filter_call_method(stream->video_static_image, MS_FILTER_SET_FPS,&stream->fps);
		ms_filter_call_method(stream->video_static_image,MS_FILTER_SET_VIDEO_SIZE,&stream->sent_vsize);

		/*并行输出至所有视频端口*/
		stream->video_static_image_tee = ms_filter_new(MS_TEE_ID);

		ms_filter_link (stream->video_static_image, 0, stream->video_static_image_tee, 0);

		/*最大视频端口,需小于视频Mixer最大布局数,当前最大为 9 画面*/
		int max_ports = (stream->max_ports > NB_MAX_VIDEO_LAYOUT)? NB_MAX_VIDEO_LAYOUT:stream->max_ports;
		int static_pic_index=0;

		/*创建端口连接插座*/
		for(int i=0; i<max_ports; i++)
		{
			ConfVideoPort *port = video_slot_new();
			video_slot_init(port,i);
			stream->video_ports = ms_list_append(stream->video_ports, port);

			/**
			* 视频采集输入源 和 静态图片 同时 join 至mixer的输入端口,
			* 当视频流有效时需MUTE 静态图片的输入,反之则输入静态图片
			*
			* video_input -------> join ------> mixer ----> video_output
			*                       |  
			* static_pic  ----------+
			*
			**/

			ms_filter_link (port->video_itc_source, 0, port->video_input_join,0);
			ms_filter_link (stream->video_static_image_tee, static_pic_index++, port->video_input_join,1);

			/*自动布局模式下除了0号端口外,均不输出静态图片*/
			if(stream->auto_layout && (static_pic_index > 0)){
				ms_filter_call_method(stream->video_static_image_tee,MS_TEE_MUTE,&static_pic_index);
			}

			ms_filter_link (port->video_input_join, 0, stream->video_mixer,i);
			ms_filter_link (stream->video_mixer,i, port->video_itc_sink,0);
		}

		ms_ticker_attach(stream->video_ticker,stream->video_mixer);
	}

}
Esempio n. 13
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;
}