Пример #1
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);
}
Пример #2
0
static void configure_video_source(VideoStream *stream){
	MSVideoSize vsize,cam_vsize;
	float fps=15;
	MSPixFmt format;
	bool_t encoder_has_builtin_converter = FALSE;

	/* transmit orientation to source filter */
	ms_filter_call_method(stream->source,MS_VIDEO_CAPTURE_SET_DEVICE_ORIENTATION,&stream->device_orientation);
	
    /* transmit its preview window id if any to source filter*/
	if (stream->preview_window_id!=0){
		video_stream_set_native_preview_window_id(stream, stream->preview_window_id);
	}

	ms_filter_call_method(stream->ms.encoder, MS_VIDEO_ENCODER_HAS_BUILTIN_CONVERTER, &encoder_has_builtin_converter);
	ms_filter_call_method(stream->ms.encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);
	vsize=get_compatible_size(vsize,stream->sent_vsize);
	ms_filter_call_method(stream->source,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	/*the camera may not support the target size and suggest a one close to the target */
	ms_filter_call_method(stream->source,MS_FILTER_GET_VIDEO_SIZE,&cam_vsize);
	if (cam_vsize.width*cam_vsize.height<=vsize.width*vsize.height &&
			cam_vsize.width != vsize.width){
		vsize=cam_vsize;
		ms_message("Output video size adjusted to match camera resolution (%ix%i)\n",vsize.width,vsize.height);
	} else if (cam_vsize.width*cam_vsize.height>vsize.width*vsize.height){
#if TARGET_IPHONE_SIMULATOR || defined(__arm__)
		ms_error("Camera is proposing a size bigger than encoder's suggested size (%ix%i > %ix%i) "
		           "Using the camera size as fallback because cropping or resizing is not implemented for arm.",
		           cam_vsize.width,cam_vsize.height,vsize.width,vsize.height);
		vsize=cam_vsize;
#else
		vsize=get_with_same_orientation(vsize,cam_vsize);
		ms_warning("Camera video size greater than encoder one. A scaling filter will be used!\n");
#endif
	}
	ms_filter_call_method(stream->ms.encoder,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	ms_filter_call_method(stream->ms.encoder,MS_FILTER_GET_FPS,&fps);
	ms_message("Setting sent vsize=%ix%i, fps=%f",vsize.width,vsize.height,fps);
	/* configure the filters */
	if (ms_filter_get_id(stream->source)!=MS_STATIC_IMAGE_ID) {
		ms_filter_call_method(stream->source,MS_FILTER_SET_FPS,&fps);
	}
	/* get the output format for webcam reader */
	ms_filter_call_method(stream->source,MS_FILTER_GET_PIX_FMT,&format);

	if ((encoder_has_builtin_converter == TRUE) || (stream->source_performs_encoding == TRUE)) {
		ms_filter_call_method(stream->ms.encoder, MS_FILTER_SET_PIX_FMT, &format);
	} else {
		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->pixconv,MS_FILTER_SET_VIDEO_SIZE,&cam_vsize);
		}
		stream->sizeconv=ms_filter_new(MS_SIZE_CONV_ID);
		ms_filter_call_method(stream->sizeconv,MS_FILTER_SET_VIDEO_SIZE,&vsize);
	}
	if (stream->ms.rc){
		ms_bitrate_controller_destroy(stream->ms.rc);
		stream->ms.rc=NULL;
	}
	if (stream->ms.use_rc){
		stream->ms.rc=ms_av_bitrate_controller_new(NULL,NULL,stream->ms.session,stream->ms.encoder);
	}
}
Пример #3
0
void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone){
	LinphoneCore *lc=call->core;
	LinphoneAddress *me=linphone_core_get_primary_contact_parsed(lc);
	const char *tool="linphone-" LINPHONE_VERSION;
	char *cname;
	int used_pt=-1;
#ifdef VIDEO_ENABLED
	const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc,
		    					SalProtoRtpAvp,SalVideo);
#endif
	bool_t use_arc=linphone_core_adaptive_rate_control_enabled(lc);
	
	if(call->audiostream == NULL)
	{
		ms_fatal("start_media_stream() called without prior init !");
		return;
	}
	call->current_params = call->params;
	/* adjust rtp jitter compensation. It must be at least the latency of the sound card */
	int jitt_comp=MAX(lc->sound_conf.latency,lc->rtp_conf.audio_jitt_comp);

	if (call->media_start_time==0) call->media_start_time=time(NULL);

	cname=linphone_address_as_string_uri_only(me);
	{
		const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
		    					SalProtoRtpAvp,SalAudio);
		if (stream && stream->dir!=SalStreamInactive && stream->port!=0){
			MSSndCard *playcard=lc->sound_conf.lsd_card ? 
				lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
			MSSndCard *captcard=lc->sound_conf.capt_sndcard;
			const char *playfile=lc->play_file;
			const char *recfile=lc->rec_file;
			call->audio_profile=make_profile(call,call->resultdesc,stream,&used_pt);
			bool_t use_ec,use_arc_audio=use_arc;

			if (used_pt!=-1){
				if (playcard==NULL) {
					ms_warning("No card defined for playback !");
				}
				if (captcard==NULL) {
					ms_warning("No card defined for capture !");
				}
				/*Replace soundcard filters by inactive file players or recorders
				 when placed in recvonly or sendonly mode*/
				if (stream->port==0 || stream->dir==SalStreamRecvOnly){
					captcard=NULL;
					playfile=NULL;
				}else if (stream->dir==SalStreamSendOnly){
					playcard=NULL;
					captcard=NULL;
					recfile=NULL;
					/*And we will eventually play "playfile" if set by the user*/
					/*playfile=NULL;*/
				}
				if (send_ringbacktone){
					captcard=NULL;
					playfile=NULL;/* it is setup later*/
				}
				/*if playfile are supplied don't use soundcards*/
				if (lc->use_files) {
					captcard=NULL;
					playcard=NULL;
				}
				use_ec=captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc);
#if defined(VIDEO_ENABLED)
				if (vstream && vstream->dir!=SalStreamInactive && vstream->payloads!=NULL){
					/*when video is used, do not make adaptive rate control on audio, it is stupid.*/
					use_arc_audio=FALSE;
	#if defined(ANDROID)
					/*On android we have to disable the echo canceller to preserve CPU for video codecs */
					use_ec=FALSE;
	#endif
				}
#endif
				audio_stream_enable_adaptive_bitrate_control(call->audiostream,use_arc_audio);
				audio_stream_start_full(
					call->audiostream,
					call->audio_profile,
					stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr,
					stream->port,
					stream->port+1,
					used_pt,
					jitt_comp,
					playfile,
					recfile,
					playcard,
					captcard,
					use_ec
					);
				post_configure_audio_streams(call);
				if (all_inputs_muted && !send_ringbacktone){
					audio_stream_set_mic_gain(call->audiostream,0);
				}
				if (stream->dir==SalStreamSendOnly && playfile!=NULL){
					int pause_time=500;
					ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time);
				}
				if (send_ringbacktone){
					setup_ring_player(lc,call);
				}
				audio_stream_set_rtcp_information(call->audiostream, cname, tool);
			}else ms_warning("No audio stream accepted ?");
		}
	}
#ifdef VIDEO_ENABLED
	{
		
		used_pt=-1;
		/* shutdown preview */
		if (lc->previewstream!=NULL) {
			video_preview_stop(lc->previewstream);
			lc->previewstream=NULL;
		}
		call->current_params.has_video=FALSE;
		if (vstream && vstream->dir!=SalStreamInactive && vstream->port!=0) {
			const char *addr=vstream->addr[0]!='\0' ? vstream->addr : call->resultdesc->addr;
			call->video_profile=make_profile(call,call->resultdesc,vstream,&used_pt);
			if (used_pt!=-1){
				VideoStreamDir dir=VideoStreamSendRecv;
				MSWebCam *cam=lc->video_conf.device;
				bool_t is_inactive=FALSE;

				call->current_params.has_video=TRUE;
				
				video_stream_set_sent_video_size(call->videostream,linphone_core_get_preferred_video_size(lc));
				video_stream_enable_self_view(call->videostream,lc->video_conf.selfview);
				if (lc->video_window_id!=0)
					video_stream_set_native_window_id(call->videostream,lc->video_window_id);
				if (lc->preview_window_id!=0)
					video_stream_set_native_preview_window_id (call->videostream,lc->preview_window_id);
				video_stream_use_preview_video_window (call->videostream,lc->use_preview_window);
				
				if (vstream->dir==SalStreamSendOnly && lc->video_conf.capture ){
					cam=get_nowebcam_device();
					dir=VideoStreamSendOnly;
				}else if (vstream->dir==SalStreamRecvOnly && lc->video_conf.display ){
					dir=VideoStreamRecvOnly;
				}else if (vstream->dir==SalStreamSendRecv){
					if (lc->video_conf.display && lc->video_conf.capture)
						dir=VideoStreamSendRecv;
					else if (lc->video_conf.display)
						dir=VideoStreamRecvOnly;
					else
						dir=VideoStreamSendOnly;
				}else{
					ms_warning("video stream is inactive.");
					/*either inactive or incompatible with local capabilities*/
					is_inactive=TRUE;
				}
				if (call->camera_active==FALSE || all_inputs_muted){
					cam=get_nowebcam_device();
				}
				if (!is_inactive){
					video_stream_set_direction (call->videostream, dir);
					video_stream_start(call->videostream,
						call->video_profile, addr, vstream->port,
						vstream->port+1,
						used_pt, jitt_comp, cam);
					video_stream_set_rtcp_information(call->videostream, cname,tool);
				}
			}else ms_warning("No video stream accepted.");
		}else{
			ms_warning("No valid video stream defined.");
		}
	}
#endif
	call->all_muted=all_inputs_muted;
	call->playing_ringbacktone=send_ringbacktone;
	call->up_bw=linphone_core_get_upload_bandwidth(lc);
	
	if (ortp_zrtp_available()) {
		OrtpZrtpParams params;
		params.zid=get_hexa_zrtp_identifier(lc);
		params.zid_file=lc->zrtp_secrets_cache;
		audio_stream_enable_zrtp(call->audiostream,&params);
	}

	goto end;
	end:
		ms_free(cname);
		linphone_address_destroy(me);
}