Пример #1
0
    msandroid_sound_write_data() :audio_track_class(0),audio_track(0),write_chunk_size(0),writtenBytes(0),last_sample_date(0) {
        bufferizer = ms_bufferizer_new();
        ms_cond_init(&cond,0);
        JNIEnv *jni_env = NULL;
        JavaVM *jvm = ms_get_jvm();
        if (jvm->AttachCurrentThread(&jni_env, NULL)!=0) {
            ms_fatal("AttachCurrentThread() failed !");
            return;
        }

        //JNIEnv *jni_env = ms_get_jni_env();
        jclass temp_class = 0;
        temp_class = jni_env->FindClass("android/media/AudioTrack");
        audio_track_class = (jclass)jni_env->NewGlobalRef(temp_class);
        if (audio_track_class == 0) {
            ms_error("cannot find  android/media/AudioTrack\n");
            return;
        }
        jmethodID hwrate_id = jni_env->GetStaticMethodID(audio_track_class,"getNativeOutputSampleRate", "(I)I");
        if (hwrate_id == 0) {
            ms_error("cannot find  int AudioRecord.getNativeOutputSampleRate(int streamType)");
            return;
        }
        rate = jni_env->CallStaticIntMethod(audio_track_class,hwrate_id,0 /*STREAM_VOICE_CALL*/);
        ms_message("Hardware sample rate is %i",rate);
        jvm->DetachCurrentThread();
    };
Пример #2
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);
	}

}