void audio_stream_play(AudioStream *st, const char *name){ if (ms_filter_get_id(st->soundread)==MS_FILE_PLAYER_ID){ ms_filter_call_method_noarg(st->soundread,MS_FILE_PLAYER_CLOSE); ms_filter_call_method(st->soundread,MS_FILE_PLAYER_OPEN,(void*)name); ms_filter_call_method_noarg(st->soundread,MS_FILE_PLAYER_START); }else{ ms_error("Cannot play file: the stream hasn't been started with" " audio_stream_start_with_files"); } }
/** * Take a photo of currently received video and write it into a jpeg file. **/ int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file){ #ifdef VIDEO_ENABLED if (call->videostream!=NULL && call->videostream->jpegwriter!=NULL){ return ms_filter_call_method(call->videostream->jpegwriter,MS_JPEG_WRITER_TAKE_SNAPSHOT,(void*)file); } ms_warning("Cannot take snapshot: no currently running video stream on this call."); return -1; #endif return -1; }
void video_stream_prepare_video(VideoStream *stream){ video_stream_unprepare_video(stream); stream->rtprecv=ms_filter_new(MS_RTP_RECV_ID); rtp_session_set_payload_type(stream->session,0); ms_filter_call_method(stream->rtprecv,MS_RTP_RECV_SET_SESSION,stream->session); stream->voidsink=ms_filter_new(MS_VOID_SINK_ID); ms_filter_link(stream->rtprecv,0,stream->voidsink,0); start_ticker(stream); ms_ticker_attach(stream->ticker,stream->rtprecv); }
/** * Returns the measured sound volume recorded locally (sent to remote) * It is expressed in dbm0. **/ float linphone_call_get_record_volume(LinphoneCall *call){ AudioStream *st=call->audiostream; if (st && st->volrecv){ float vol=0; ms_filter_call_method(st->volrecv,MS_VOLUME_GET,&vol); return vol; } return LINPHONE_VOLUME_DB_LOWEST; }
void audio_stream_record(AudioStream *st, const char *name){ if (ms_filter_get_id(st->soundwrite)==MS_FILE_REC_ID){ ms_filter_call_method_noarg(st->soundwrite,MS_FILE_REC_CLOSE); ms_filter_call_method(st->soundwrite,MS_FILE_REC_OPEN,(void*)name); ms_filter_call_method_noarg(st->soundwrite,MS_FILE_REC_START); }else{ ms_error("Cannot record file: the stream hasn't been started with" " audio_stream_start_with_files"); } }
static void fileplay_soundwrite(const char *filename) { MSConnectionHelper h; bool_t need_resampler = FALSE; unsigned int filter_mask = FILTER_MASK_FILEPLAY | FILTER_MASK_SOUNDWRITE; int sample_rate = 8000; int nchannels = 1; int done = FALSE; ms_filter_reset_statistics(); ms_tester_create_ticker(); ms_tester_create_filters(filter_mask); ms_filter_set_notify_callback(ms_tester_fileplay, fileplay_eof, &done); ms_filter_call_method_noarg(ms_tester_fileplay, MS_FILE_PLAYER_CLOSE); ms_filter_call_method(ms_tester_fileplay, MS_FILE_PLAYER_OPEN, (void *)filename); ms_filter_call_method(ms_tester_fileplay, MS_FILTER_GET_SAMPLE_RATE, &sample_rate); ms_filter_call_method(ms_tester_fileplay, MS_FILTER_GET_NCHANNELS, &nchannels); if (ms_filter_call_method(ms_tester_soundwrite, MS_FILTER_SET_SAMPLE_RATE, &sample_rate) != 0) { int soundwrite_sample_rate = 48000; ms_filter_call_method(ms_tester_soundwrite, MS_FILTER_GET_SAMPLE_RATE, &soundwrite_sample_rate); if (sample_rate != soundwrite_sample_rate) need_resampler = TRUE; } if (ms_filter_call_method(ms_tester_soundwrite, MS_FILTER_SET_NCHANNELS, &nchannels) != 0) { int soundwrite_nchannels = 1; ms_filter_call_method(ms_tester_soundwrite, MS_FILTER_GET_NCHANNELS, &soundwrite_nchannels); if (nchannels != soundwrite_nchannels) need_resampler = TRUE; } if (need_resampler == TRUE) { ms_tester_create_filters(FILTER_MASK_RESAMPLER); configure_resampler(ms_tester_resampler, ms_tester_fileplay, ms_tester_soundwrite); } ms_filter_call_method_noarg(ms_tester_fileplay, MS_FILE_PLAYER_START); ms_connection_helper_start(&h); ms_connection_helper_link(&h, ms_tester_fileplay, -1, 0); if (need_resampler == TRUE) { ms_connection_helper_link(&h, ms_tester_resampler, 0, 0); } ms_connection_helper_link(&h, ms_tester_soundwrite, 0, -1); ms_ticker_attach(ms_tester_ticker, ms_tester_fileplay); while (done != TRUE) { ms_usleep(10000); } ms_filter_call_method_noarg(ms_tester_fileplay, MS_FILE_PLAYER_CLOSE); ms_ticker_detach(ms_tester_ticker, ms_tester_fileplay); ms_connection_helper_start(&h); ms_connection_helper_unlink(&h, ms_tester_fileplay, -1, 0); if (need_resampler == TRUE) { ms_connection_helper_unlink(&h, ms_tester_resampler, 0, 0); } ms_connection_helper_unlink(&h, ms_tester_soundwrite, 0, -1); if (need_resampler == TRUE) { ms_tester_destroy_filters(FILTER_MASK_RESAMPLER); } ms_filter_log_statistics(); ms_tester_destroy_filters(filter_mask); ms_tester_destroy_ticker(); }
void audio_stream_enable_equalizer(AudioStream *stream, bool_t enabled){ #ifndef ENABLED_MCU_MEDIA_SERVER stream->eq_active=enabled; if (stream->equalizer){ int tmp=enabled; ms_filter_call_method(stream->equalizer,MS_EQUALIZER_SET_ACTIVE,&tmp); } #endif // ENABLED_MCU_MEDIA_SERVER }
static void ecc_init_filters(EcCalibrator *ecc){ unsigned int rate; MSTickerParams params={0}; params.name="Echo calibrator"; params.prio=MS_TICKER_PRIO_HIGH; ecc->ticker=ms_ticker_new_with_params(¶ms); ecc->sndread=ms_snd_card_create_reader(ecc->play_card); ms_filter_call_method(ecc->sndread,MS_FILTER_SET_SAMPLE_RATE,&ecc->rate); ms_filter_call_method(ecc->sndread,MS_FILTER_GET_SAMPLE_RATE,&rate); ecc->read_resampler=ms_filter_new(MS_RESAMPLE_ID); ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_SAMPLE_RATE,&rate); ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&ecc->rate); ecc->det=ms_filter_new(MS_TONE_DETECTOR_ID); ms_filter_call_method(ecc->det,MS_FILTER_SET_SAMPLE_RATE,&ecc->rate); ecc->rec=ms_filter_new(MS_FILE_REC_ID); ms_filter_link(ecc->sndread,0,ecc->read_resampler,0); ms_filter_link(ecc->read_resampler,0,ecc->det,0); ms_filter_link(ecc->det,0,ecc->rec,0); ecc->play=ms_filter_new(MS_FILE_PLAYER_ID); ecc->gen=ms_filter_new(MS_DTMF_GEN_ID); ms_filter_call_method(ecc->gen,MS_FILTER_SET_SAMPLE_RATE,&ecc->rate); ecc->write_resampler=ms_filter_new(MS_RESAMPLE_ID); ecc->sndwrite=ms_snd_card_create_writer(ecc->capt_card); ms_filter_call_method(ecc->sndwrite,MS_FILTER_SET_SAMPLE_RATE,&ecc->rate); ms_filter_call_method(ecc->sndwrite,MS_FILTER_GET_SAMPLE_RATE,&rate); ms_filter_call_method(ecc->write_resampler,MS_FILTER_SET_SAMPLE_RATE,&ecc->rate); ms_filter_call_method(ecc->write_resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&rate); ms_filter_link(ecc->play,0,ecc->gen,0); ms_filter_link(ecc->gen,0,ecc->write_resampler,0); ms_filter_link(ecc->write_resampler,0,ecc->sndwrite,0); ms_ticker_attach(ecc->ticker,ecc->sndread); ms_ticker_attach(ecc->ticker,ecc->play); }
void video_stream_play_file(VideoStream *st, const char *name) { if (ms_filter_get_id(st->source)==MS_VIDEO_FILE_PLAYER_ID){ ms_filter_call_method_noarg(st->source,MS_VIDEO_FILE_PLAYER_CLOSE); ms_filter_call_method(st->source,MS_VIDEO_FILE_PLAYER_OPEN,(void*)name); ms_filter_call_method_noarg(st->source,MS_VIDEO_FILE_PLAYER_START); }else{ ms_error("Cannot play file: the stream hasn't been started with" " video_stream_play"); } }
void media_stream_set_ice_check_list(MediaStream *stream, IceCheckList *cl) { bool_t stun_enabled = TRUE; stream->ice_check_list = cl; if (stream->ice_check_list != NULL) { ice_check_list_set_rtp_session(stream->ice_check_list, stream->sessions.rtp_session); stun_enabled = FALSE; } if (stream->rtpsend != NULL) { ms_filter_call_method(stream->rtpsend, MS_RTP_SEND_ENABLE_STUN, &stun_enabled); } }
void linphone_conference_set_gain(struct _LinphoneCore *lc, LinphoneConference *conf,float gain) { LinphoneConferenceStream *stream = conf->conf_stream; if(!conf || !conf->conf_stream) return; if(ms_filter_call_method(stream->audio_mixer,MS_FILTER_SET_MAX_GAIN,&gain)!=0) ms_warning("AudioMixer: set MS_FILTER_SET_MAX_GAIN error!"); ms_message("AudioMixer: set GAIN %f !!",gain); }
/** * Returns the sound volume (mic input) of the local participant of the conference. * @param lc the linphone core * @returns the measured input volume expressed in dbm0. **/ float linphone_core_get_conference_local_input_volume(LinphoneCore *lc){ LinphoneConference *conf=&lc->conf_ctx; AudioStream *st=conf->local_participant; if (st && st->volsend && !conf->local_muted){ float vol=0; ms_filter_call_method(st->volsend,MS_VOLUME_GET,&vol); return vol; } return LINPHONE_VOLUME_DB_LOWEST; }
static void qos_analyzer_on_action_suggested(void *user_data, int datac, const char** datav){ reporting_session_report_t *report = (reporting_session_report_t*)user_data; LinphoneCall *call = report->call; char * appendbuf; int i; int ptime = -1; int bitrate[3] = {-1, -1, -1}; int up_bw[3] = {-1, -1, -1}; int down_bw[3] = {-1, -1, -1}; MediaStream *streams[3] = { (MediaStream*) call->audiostream, (MediaStream *) call->videostream, (MediaStream *) call->textstream }; for (i = 0; i < 3; i++){ if (streams[i] != NULL){ if (streams[i]->encoder != NULL){ if (ms_filter_has_method(streams[i]->encoder,MS_FILTER_GET_BITRATE)){ ms_filter_call_method(streams[i]->encoder,MS_FILTER_GET_BITRATE,&bitrate[i]); bitrate[i] /= 1000; } } up_bw[i] = (int)(media_stream_get_up_bw(streams[i])/1000.f); down_bw[i] = (int)(media_stream_get_down_bw(streams[i])/1000.f); } } if (call->audiostream!=NULL){ if (call->audiostream->ms.encoder!=NULL){ if(ms_filter_has_method(call->audiostream->ms.encoder,MS_AUDIO_ENCODER_GET_PTIME)){ ms_filter_call_method(call->audiostream->ms.encoder,MS_AUDIO_ENCODER_GET_PTIME,&ptime); } } } appendbuf=ms_strdup_printf("%s%d;", report->qos_analyzer.timestamp?report->qos_analyzer.timestamp:"", ms_time(0)); STR_REASSIGN(report->qos_analyzer.timestamp,appendbuf); STR_REASSIGN(report->qos_analyzer.input_leg, ms_strdup_printf("%s aenc_ptime aenc_br a_dbw a_ubw venc_br v_dbw v_ubw tenc_br t_dbw t_ubw", datav[0])); appendbuf=ms_strdup_printf("%s%s %d %d %d %d %d %d %d %d %d %d;", report->qos_analyzer.input?report->qos_analyzer.input:"", datav[1], ptime, bitrate[0], down_bw[0], up_bw[0], bitrate[1], down_bw[1], up_bw[1], bitrate[2], down_bw[2], up_bw[2]); STR_REASSIGN(report->qos_analyzer.input,appendbuf); STR_REASSIGN(report->qos_analyzer.output_leg, ms_strdup(datav[2])); appendbuf=ms_strdup_printf("%s%s;", report->qos_analyzer.output?report->qos_analyzer.output:"", datav[3]); STR_REASSIGN(report->qos_analyzer.output, appendbuf); }
void VodWnd::vod(const char *ip, int rtp_port, int rtcp_port) { server_ip_ = ip; server_rtp_port_ = rtp_port; server_rtcp_port_ = rtcp_port; rtp_ = rtp_session_new(RTP_SESSION_RECVONLY); rtp_session_set_payload_type(rtp_, 100); rtp_session_set_local_addr(rtp_, util_get_myip(), 0, 0); rtp_session_set_remote_addr_and_port(rtp_, ip, rtp_port, rtcp_port); JBParameters jb; jb.adaptive = 1; jb.max_packets = 3000; jb.max_size = -1; jb.min_size = jb.nom_size = 300; rtp_session_set_jitter_buffer_params(rtp_, &jb); rtp_session_enable_jitter_buffer(rtp_, 0); evq_ = ortp_ev_queue_new(); rtp_session_register_event_queue(rtp_, evq_); ticker_ = ms_ticker_new(); filter_rtp_ = ms_filter_new(MS_RTP_RECV_ID); ms_filter_call_method(filter_rtp_, MS_RTP_RECV_SET_SESSION, rtp_); filter_decoder_ = ms_filter_new(MS_H264_DEC_ID); ZonekeyYUVSinkCallbackParam cbp; cbp.ctx = this; cbp.push = cb_yuv; filter_sink_ = ms_filter_new_from_name("ZonekeyYUVSink"); ms_filter_call_method(filter_sink_, ZONEKEY_METHOD_YUV_SINK_SET_CALLBACK_PARAM, &cbp); ms_filter_link(filter_rtp_, 0, filter_decoder_, 0); ms_filter_link(filter_decoder_, 0, filter_sink_, 0); ms_ticker_attach(ticker_, filter_rtp_); }
int ms_media_player_get_duration(MSMediaPlayer *obj) { int duration; if(!obj->is_open) { ms_error("Could not get duration. No file is open"); return -1; } if(ms_filter_call_method(obj->player, MS_PLAYER_GET_DURATION, &duration) == -1) { ms_error("Could not get duration"); return -1; } return duration; }
void audio_stream_equalizer_set_gain(AudioStream *stream, int frequency, float gain, int freq_width){ #ifndef ENABLED_MCU_MEDIA_SERVER if (stream->equalizer){ MSEqualizerGain d; d.frequency=frequency; d.gain=gain; d.width=freq_width; ms_filter_call_method(stream->equalizer,MS_EQUALIZER_SET_GAIN,&d); } #endif // ENABLED_MCU_MEDIA_SERVER }
static void parametrize_equalizer(LinphoneCore *lc, AudioStream *st){ if (st->equalizer){ MSFilter *f=st->equalizer; int enabled=lp_config_get_int(lc->config,"sound","eq_active",0); const char *gains=lp_config_get_string(lc->config,"sound","eq_gains",NULL); ms_filter_call_method(f,MS_EQUALIZER_SET_ACTIVE,&enabled); if (enabled){ if (gains){ do{ int bytes; MSEqualizerGain g; if (sscanf(gains,"%f:%f:%f %n",&g.frequency,&g.gain,&g.width,&bytes)==3){ ms_message("Read equalizer gains: %f(~%f) --> %f",g.frequency,g.width,g.gain); ms_filter_call_method(f,MS_EQUALIZER_SET_GAIN,&g); gains+=bytes; }else break; }while(1); } } } }
int ms_media_player_get_current_position(MSMediaPlayer *obj) { int position; if(!obj->is_open) { ms_error("Could not get position. No file is open"); return -1; } if(ms_filter_call_method(obj->player, MS_PLAYER_GET_CURRENT_POSITION, &position) == -1) { ms_error("Could not get position"); return -1; } return position; }
void text_stream_prepare_text(TextStream *stream){ text_stream_unprepare_text(stream); stream->ms.rtprecv = ms_filter_new(MS_RTP_RECV_ID); rtp_session_set_payload_type(stream->ms.sessions.rtp_session, 0); rtp_session_enable_rtcp(stream->ms.sessions.rtp_session, FALSE); ms_filter_call_method(stream->ms.rtprecv, MS_RTP_RECV_SET_SESSION, stream->ms.sessions.rtp_session); stream->ms.voidsink = ms_filter_new(MS_VOID_SINK_ID); ms_filter_link(stream->ms.rtprecv, 0, stream->ms.voidsink, 0); media_stream_start_ticker(&stream->ms); ms_ticker_attach(stream->ms.sessions.ticker, stream->ms.rtprecv); stream->ms.state = MSStreamPreparing; }
MSBitrateDriver *ms_audio_bitrate_driver_new(RtpSession *session, MSFilter *encoder){ MSAudioBitrateDriver *obj=ms_new0(MSAudioBitrateDriver,1); obj->parent.desc=&audio_bitrate_driver; obj->session = session; obj->encoder=encoder; obj->min_ptime=20; obj->cur_ptime=0; obj->cur_bitrate=obj->nom_bitrate=0; if (ms_filter_has_method(obj->encoder, MS_AUDIO_ENCODER_GET_CAPABILITIES)) ms_filter_call_method(obj->encoder, MS_AUDIO_ENCODER_GET_CAPABILITIES, &obj->encoder_caps); return (MSBitrateDriver*)obj; }
void linphone_conference_enable_agc(struct _LinphoneCore *lc, LinphoneConference *conf,float agc_level) { LinphoneConferenceStream *stream = conf->conf_stream; if(!conf || !conf->conf_stream) return; if(ms_filter_call_method(stream->audio_mixer,MS_FILTER_ENABLE_AGC,&agc_level)!=0) ms_warning("AudioMixer: set MS_FILTER_ENABLE_AGC error!"); ms_message("AudioMixer: AGC %f !!",agc_level); }
static void on_dtmf_received(RtpSession *s, int dtmf, void * user_data) { AudioStream *stream=(AudioStream*)user_data; if (dtmf>15){ ms_warning("Unsupported telephone-event type."); return; } ms_message("Receiving dtmf %c.",dtmf_tab[dtmf]); if (stream->dtmfgen!=NULL && stream->play_dtmfs){ ms_filter_call_method(stream->dtmfgen,MS_DTMF_GEN_PUT,&dtmf_tab[dtmf]); } }
static void configure_resampler(MSFilter *resampler, MSFilter *from, MSFilter *to) { int from_rate = 0, to_rate = 0; int from_channels = 0, to_channels = 0; ms_filter_call_method(from, MS_FILTER_GET_SAMPLE_RATE, &from_rate); ms_filter_call_method(to, MS_FILTER_GET_SAMPLE_RATE, &to_rate); ms_filter_call_method(resampler, MS_FILTER_SET_SAMPLE_RATE, &from_rate); ms_filter_call_method(resampler, MS_FILTER_SET_OUTPUT_SAMPLE_RATE, &to_rate); ms_filter_call_method(from, MS_FILTER_GET_NCHANNELS, &from_channels); ms_filter_call_method(to, MS_FILTER_GET_NCHANNELS, &to_channels); if (from_channels == 0) from_channels = 1; if (to_channels == 0) to_channels = 1; ms_filter_call_method(resampler, MS_FILTER_SET_NCHANNELS, &from_channels); ms_filter_call_method(resampler, MS_FILTER_SET_OUTPUT_NCHANNELS, &to_channels); }
int conf_stream_disconnect_video_stream_port(LinphoneConferenceStream *conf_stream, VideoStream *video_stream, int port_index){ if(conf_stream==NULL || video_stream == NULL) return -1; ConfVideoPort *video_port = find_video_slot_at_index(conf_stream,port_index); /*audio_stream <---> audio_port*/ if(video_stream->ticker!=NULL && video_port!=NULL){ ms_message("disconnect: conf_stream [%d] <----> video_stream !!",video_port->index); /*将itc_source itc_sink 链接至 NULL 队列,分离链接*/ video_port->source_connected = FALSE; ms_filter_call_method(video_port->video_itc_source,MS_CONF_ITC_SOURCE_CONNECT,NULL); ms_filter_call_method(video_stream->output,MS_CONF_ITC_SINK_CONNECT,NULL); video_port->sink_connected = FALSE; ms_filter_call_method(video_stream->source,MS_CONF_ITC_SOURCE_CONNECT,NULL); ms_filter_call_method(video_port->video_itc_sink,MS_CONF_ITC_SINK_CONNECT,NULL); int tmp = video_port->index; if(conf_stream->auto_layout){//自动布局模式下只开启 0 号端口的静态图片 if(tmp==0) ms_filter_call_method(conf_stream->video_static_image_tee,MS_TEE_UNMUTE,&tmp); }else{ ms_filter_call_method(conf_stream->video_static_image_tee,MS_TEE_UNMUTE,&tmp); } } return 0; }
int DirectorConference::add_sink(int sid, Sink *s, KVS ¶ms) { // if (sid == -1) { if (s->payload_type() == 100) { ms_filter_call_method(video_publisher_, ZONEKEY_METHOD_PUBLISHER_ADD_REMOTE, s->get_rtp_session()); } else if (s->payload_type() == 102) { ms_filter_call_method(audio_publisher_, ZONEKEY_METHOD_PUBLISHER_ADD_REMOTE, s->get_rtp_session()); } else if (s->payload_type() == 110) { ms_filter_call_method(audio_publisher_, ZONEKEY_METHOD_PUBLISHER_ADD_REMOTE, s->get_rtp_session()); } return 0; } else if (is_source_id(sid)) { assert(find_source(sid) != 0); Graph *g = find_graph(sid); if (!g) { // 没有找到对应的 source return -1; } g->add_sink(s); return 0; } else { // 说明对 Stream 的点播 Stream *stream = find_stream(sid); if (!stream || !stream->support_publisher()) { // 没有找到或者不支持 publisher return -1; } else { stream->add_sink(s); return 0; } } }
RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard, MSFilterNotifyFunc func,void * user_data) { RingStream *stream; int tmp; stream=(RingStream *)ms_new0(RingStream,1); stream->source=ms_filter_new(MS_FILE_PLAYER_ID); if (ms_filter_call_method(stream->source,MS_FILE_PLAYER_OPEN,(void*)file)<0){ ms_filter_destroy(stream->source); ms_free(stream); return NULL; } ms_filter_call_method(stream->source,MS_FILE_PLAYER_LOOP,&interval); ms_filter_call_method_noarg(stream->source,MS_FILE_PLAYER_START); if (func!=NULL) ms_filter_set_notify_callback(stream->source,func,user_data); stream->sndwrite=ms_snd_card_create_writer(sndcard); ms_filter_call_method(stream->source,MS_FILTER_GET_SAMPLE_RATE,&tmp); ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_SAMPLE_RATE,&tmp); ms_filter_call_method(stream->source,MS_FILTER_GET_NCHANNELS,&tmp); ms_filter_call_method(stream->sndwrite,MS_FILTER_SET_NCHANNELS,&tmp); stream->ticker=ms_ticker_new(); ms_ticker_set_name(stream->ticker,"Audio (ring) MSTicker"); ms_filter_link(stream->source,0,stream->sndwrite,0); ms_ticker_attach(stream->ticker,stream->source); return stream; }
// 构造 source --> decoder --> sink static MSFilter *build_simple_chain(ZonekeyYUVSinkCallbackParam *yuvcb) { MSFilter *f_source = ms_filter_new_from_name("ZonekeyH264Source"); MSFilter *f_decoder = ms_filter_new(MS_H264_DEC_ID); MSFilter *f_sink = ms_filter_new_from_name("ZonekeyYUVSink"); ms_filter_call_method(f_sink, ZONEKEY_METHOD_YUV_SINK_SET_CALLBACK_PARAM, yuvcb); ms_filter_link(f_source, 0, f_decoder, 0); ms_filter_link(f_decoder, 0, f_sink, 0); return f_source; }
void video_stream_change_camera(VideoStream *stream, MSWebCam *cam){ bool_t keep_source=(cam==stream->cam); if (stream->ticker && stream->source){ 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 */ if (!keep_source) ms_filter_destroy(stream->source); 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); 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 linphone_conference_record_audio(struct _LinphoneCore *lc, LinphoneConference *conf, const char *filename){ LinphoneConferenceStream *conf_stream = conf->conf_stream; if(conf==NULL && conf_stream==NULL) return; if (conf_stream->audio_filerecorder != NULL && ms_filter_get_id(conf_stream->audio_filerecorder)==MS_FILE_REC_ID){ ms_filter_call_method_noarg(conf_stream->audio_filerecorder,MS_FILE_REC_CLOSE); ms_filter_call_method(conf_stream->audio_filerecorder,MS_FILE_REC_OPEN,(void*)filename); ms_filter_call_method_noarg(conf_stream->audio_filerecorder,MS_FILE_REC_START); }else{ ms_error("Cannot record file: not conf->audio_filerecorder st->filewrite Filter !"); } }
int DirectorConference::del_sink(Sink *s) { // FIXME: 似乎应该提供更好的方式,及早识别 s 的属性 bool found = false; // Source 的点播 do { ost::MutexLock al(cs_graphics_); GRAPHICS::iterator it; for (it = graphics_.begin(); it != graphics_.end(); ++it) { if ((*it)->has_sink(s)) { (*it)->del_sink(s); found = true; break; } } } while (0); // Stream 的点播 do { ost::MutexLock al(cs_streams_); for (STREAMS::iterator it = streams_.begin(); it != streams_.end(); ++it) { (*it)->del_sink(s); } } while (0); // 全局的点播 do { if (s->payload_type() == 100) { ms_filter_call_method(video_publisher_, ZONEKEY_METHOD_PUBLISHER_DEL_REMOTE, s->get_rtp_session()); } else { ms_filter_call_method(audio_publisher_, ZONEKEY_METHOD_PUBLISHER_DEL_REMOTE, s->get_rtp_session()); } } while (0); return 0; }