myAudioStream::myAudioStream(QString payload) { if (!initialized) { ortp_set_log_level_mask(ORTP_DEBUG|ORTP_ERROR); ms_init(); ortp_init(); initialized = true; } if (!init_card()) { return; } if (!init_stream()) { return; } if (!init_filters(payload)) { return; } if (!link_filters()) { return; } if (!start_ticker()) { return; } }
void myAudioStream::changePayload(const QString & payload) { stop_ticker(); unlink_filters(); destroy_filters(); init_filters(payload); link_filters(); start_ticker(); }
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); }
Bool wait_event (XEvent * event, Window w, int mask, int max_wait) { int tick_count; start_ticker (1); /* now we have to wait for our window to become mapped - waiting for PropertyNotify */ for (tick_count = 0; !XCheckWindowEvent (dpy, w, mask, event) && tick_count < max_wait; tick_count++) { XSync (dpy, False); wait_tick (); } return (tick_count < max_wait); }
/* This function is used either on IOS to workaround the long time to initialize the Audio Unit or for ICE candidates gathering. */ void audio_stream_prepare_sound(AudioStream *stream, MSSndCard *playcard, MSSndCard *captcard){ audio_stream_unprepare_sound(stream); stream->dummy=ms_filter_new(MS_RTP_RECV_ID); rtp_session_set_payload_type(stream->ms.session,0); ms_filter_call_method(stream->dummy,MS_RTP_RECV_SET_SESSION,stream->ms.session); if (captcard && playcard){ #ifdef __ios stream->soundread=ms_snd_card_create_reader(captcard); stream->soundwrite=ms_snd_card_create_writer(playcard); ms_filter_link(stream->dummy,0,stream->soundwrite,0); #else stream->ms.voidsink=ms_filter_new(MS_VOID_SINK_ID); ms_filter_link(stream->dummy,0,stream->ms.voidsink,0); #endif } else { stream->ms.voidsink=ms_filter_new(MS_VOID_SINK_ID); ms_filter_link(stream->dummy,0,stream->ms.voidsink,0); } if (stream->ms.ticker == NULL) start_ticker(&stream->ms); ms_ticker_attach(stream->ms.ticker,stream->dummy); }
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; }
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; }
/* This function is called to trigger a card-reload. */ static void card_reload (GpaCardManager *cardman) { gpg_error_t err, operr; const char *application; char *command_buf = NULL; const char *command; const char *err_desc = NULL; char *err_desc_buffer = NULL; int auto_app; if (!cardman->gpgagent) return; /* No support for GPGME_PROTOCOL_ASSUAN. */ /* Start the ticker if not yet done. */ start_ticker (cardman); if (!cardman->in_card_reload) { cardman->in_card_reload++; update_info_visibility (cardman); cardman->cardtype = G_TYPE_NONE; cardman->cardtypename = "Unknown"; /* The first thing we need to do is to issue the SERIALNO command; this makes sure that scdaemon initalizes the card if that has not yet been done. */ command = "SCD SERIALNO"; if (cardman->app_selector && (gtk_combo_box_get_active (GTK_COMBO_BOX (cardman->app_selector)) > 0) && (application = gtk_combo_box_get_active_text (GTK_COMBO_BOX (cardman->app_selector)))) { command_buf = g_strdup_printf ("%s %s", command, application); command = command_buf; auto_app = 0; } else auto_app = 1; err = gpgme_op_assuan_transact_ext (cardman->gpgagent, command, scd_data_cb, NULL, scd_inq_cb, NULL, scd_status_cb, cardman, &operr); if (!err) { err = operr; if (!auto_app && gpg_err_source (err) == GPG_ERR_SOURCE_SCD && gpg_err_code (err) == GPG_ERR_CONFLICT) { /* Not in auto select mode and the scdaemon told us about a conflicting use. We now do a restart and try again to display an application selection conflict error only if it is not due to our own connection to the scdaemon. */ if (!gpgme_op_assuan_transact_ext (cardman->gpgagent, "SCD RESTART", NULL, NULL, NULL, NULL, NULL, NULL, &operr) && !operr) { err = gpgme_op_assuan_transact_ext (cardman->gpgagent, command, scd_data_cb, NULL, scd_inq_cb, NULL, scd_status_cb, cardman, &operr); if (!err) err = operr; } } } if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT || gpg_err_code (err) == GPG_ERR_CARD_REMOVED) { err_desc = _("No card found."); } else if (gpg_err_source (err) == GPG_ERR_SOURCE_SCD && gpg_err_code (err) == GPG_ERR_CONFLICT) { err_desc = auto_app ? _("The selected card application is currently not available.") : _("Another process is using a different card application " "than the selected one.\n\n" "You may change the application selection mode to " "\"Auto\" to select the active application."); } else if (!auto_app && gpg_err_source (err) == GPG_ERR_SOURCE_SCD && gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED) { err_desc = _("The selected card application is not available."); } else if (err) { g_debug ("assuan command `%s' failed: %s <%s>\n", command, gpg_strerror (err), gpg_strsource (err)); if (!gpgme_op_assuan_transact_ext (cardman->gpgagent, "SCD SERIALNO undefined", NULL, NULL, NULL, NULL, NULL, NULL, &operr) && !operr) err = 0; else { err_desc = _("Error accessing the card."); statusbar_update (cardman, _("Error accessing card")); } } g_free (command_buf); if (!err) { /* Get the event counter to avoid a duplicate reload due to the ticker. */ gpgme_op_assuan_transact_ext (cardman->gpgagent, "GETEVENTCOUNTER", NULL, NULL, NULL, NULL, scd_status_cb, cardman, NULL); /* Now we need to get the APPTYPE of the card so that the correct GpaCM* object can can act on the data. */ command = "SCD GETATTR APPTYPE"; err = gpgme_op_assuan_transact_ext (cardman->gpgagent, command, scd_data_cb, NULL, scd_inq_cb, NULL, scd_status_cb, cardman, &operr); if (!err) err = operr; if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT || gpg_err_code (err) == GPG_ERR_CARD_REMOVED) statusbar_update (cardman, _("No card")); else if (err) { g_debug ("assuan command `%s' failed: %s <%s>\n", command, gpg_strerror (err), gpg_strsource (err)); statusbar_update (cardman, _("Error accessing card")); } } update_card_widget (cardman, err_desc); g_free (err_desc_buffer); err_desc_buffer = NULL; err_desc = NULL; update_title (cardman); update_info_visibility (cardman); /* We decrement our lock using a idle handler with lo priority. This gives us a better chance not to do a reload a second time on behalf of the file watcher or ticker. */ g_object_ref (cardman); g_idle_add_full (G_PRIORITY_LOW, card_reload_finish_idle_cb, cardman, NULL); } }