static void iterate_adaptive_stream(stream_manager_t * marielle, stream_manager_t * margaux, int timeout_ms, int* current, int expected){ int retry=0; MediaStream *marielle_ms,*margaux_ms; if (marielle->type == AudioStreamType){ marielle_ms=&marielle->audio_stream->ms; margaux_ms=&margaux->audio_stream->ms; }else{ marielle_ms=&marielle->video_stream->ms; margaux_ms=&margaux->video_stream->ms; } while ((!current||*current<expected) && retry++ <timeout_ms/100) { media_stream_iterate(marielle_ms); media_stream_iterate(margaux_ms); handle_queue_events(marielle); if (retry%10==0) { ms_message("stream [%p] bandwidth usage: [d=%.1f,u=%.1f] kbit/sec" , marielle_ms, media_stream_get_down_bw(marielle_ms)/1000, media_stream_get_up_bw(marielle_ms)/1000); ms_message("stream [%p] bandwidth usage: [d=%.1f,u=%.1f] kbit/sec" , margaux_ms, media_stream_get_down_bw(margaux_ms)/1000, media_stream_get_up_bw(margaux_ms)/1000); } ms_usleep(100000); } }
static bool_t wait_for_eof(bool_t *eof, int *time,int time_refresh, int timeout) { while(*time < timeout && !*eof) { ms_usleep(time_refresh * 1000U); *time += time_refresh; } return *time < timeout; }
void SipClient::shutdown() { qDebug() << __PRETTY_FUNCTION__; if (m_authInfo) { linphone_auth_info_destroy(m_authInfo); // Get default proxy config linphone_core_get_default_proxy(lc, &m_proxyCfg); // start editing proxy configuration linphone_proxy_config_edit(m_proxyCfg); // De-activate registration for this proxy config linphone_proxy_config_enable_register(m_proxyCfg, FALSE); linphone_proxy_config_done(m_proxyCfg); while (linphone_proxy_config_get_state(m_proxyCfg) != LinphoneRegistrationCleared) { //...to make sure we receive call backs before shutting down linphone_core_iterate(lc); ms_usleep(50000); } m_authInfo = 0; } // delete m_loopTimer; if (lc) { linphone_core_destroy(lc); lc = 0; } }
bool_t wait_for_list_with_parse_events(MSList *mss, int *counter, int value, int timeout_ms, MSList *cbs, MSList *ptrs) { MSList *msi; MSList *cbi; MSList *ptri; int retry = 0; while ((*counter < value) && (retry++ < (timeout_ms / 100))) { for (msi = mss, cbi = cbs, ptri = ptrs; msi != NULL; msi = msi->next) { MediaStream *stream = (MediaStream *)msi->data; ms_tester_iterate_cb cb = NULL; media_stream_iterate(stream); if ((retry % 10) == 0) { ms_message("stream [%p] bandwidth usage: [d=%.1f,u=%.1f] kbit/sec", stream, media_stream_get_down_bw(stream) / 1000, media_stream_get_up_bw(stream) / 1000); } if (cbi && ptri) { cb = (ms_tester_iterate_cb)cbi->data; cb(stream, ptri->data); } if (cbi) cbi = cbi->next; if (ptri) ptri = ptri->next; } ms_usleep(100000); } if (*counter < value) return FALSE; return TRUE; }
int main(int argc, char *argv[]){ LinphoneCoreVTable vtable={0}; LinphoneCore *lc; signal(SIGINT,stop); #ifdef DEBUG linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/ #endif /* Fill the LinphoneCoreVTable with application callbacks. All are optional. Here we only use the call_state_changed callbacks in order to get notifications about the progress of the call. */ vtable.call_state_changed=call_state_changed; /*to receive incoming call*/ vtable.message_received=message_received; /*to receive committed messages*/ vtable.is_composing_received=is_composing_received; /*to receive char in real time*/ /* Instanciate a LinphoneCore object given the LinphoneCoreVTable */ lc=linphone_core_new(&vtable,NULL,NULL,NULL); /* main loop for receiving notifications and doing background linphonecore work: */ while(running){ linphone_core_iterate(lc); ms_usleep(50000); } printf("Shutting down...\n"); linphone_core_destroy(lc); printf("Exited\n"); return 0; }
bool_t wait_for_list(MSList* lcs,int* counter,int value,int timeout_ms) { MSList* iterator; MSTimeSpec start; liblinphone_tester_clock_start(&start); while ((counter==NULL || *counter<value) && !liblinphone_tester_clock_elapsed(&start,timeout_ms)) { for (iterator=lcs;iterator!=NULL;iterator=iterator->next) { #ifdef HAVE_GTK gdk_threads_enter(); gtk_main_iteration_do(FALSE); gdk_threads_leave(); #endif linphone_core_iterate((LinphoneCore*)(iterator->data)); } #ifdef WIN32 { MSG msg; while (PeekMessage(&msg, NULL, 0, 0,1)){ TranslateMessage(&msg); DispatchMessage(&msg); } } #endif ms_usleep(20000); } if(counter && *counter<value) return FALSE; else return TRUE; }
int main(int argc, char *argv[]){ LinphoneCoreVTable vtable={0}; LinphoneCore *lc; LinphoneCall *call=NULL; signal(SIGINT,stop); printf("Version: %s\n",linphone_core_get_version()); #ifdef DEBUG linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/ #endif /* Fill the LinphoneCoreVTable with application callbacks. All are optional. Here we only use the call_state_changed callbacksestablished in order to get notifications about the progress of the call. */ vtable.call_state_changed=call_state_changed; //vtable.text_received=text_received; /* Instanciate a LinphoneCore object given the LinphoneCoreVTable */ //linphone_core_disable_logs(); lc=linphone_core_new(&vtable,NULL,NULL,NULL); linphone_core_set_sip_port(lc, 9999); const char** devs = linphone_core_get_sound_devices(lc); printf("DEVICE: %s\n",devs[0]); printf("DEVICE: %s\n",devs[1]); //linphone_core_set_playback_device(lc,devs[1]); //linphone_core_set_capture_device(lc,devs[1]); linphone_core_iterate(lc); //LinphoneChatRoom* chat_room = linphone_core_create_chat_room(lc,"sip:[email protected]:9998"); //linphone_chat_room_send_message(chat_room,"Welcome in room!\n"); /* main loop for receiving notifications and doing background linphonecore work: */ while(running){ linphone_core_iterate(lc); ms_usleep(50000); } if (call && linphone_call_get_state(call)!=LinphoneCallEnd){ /* terminate the call */ printf("Terminating the call...\n"); linphone_core_terminate_call(lc,call); /*at this stage we don't need the call object */ linphone_call_unref(call); } end: printf("Shutting down...\n"); linphone_core_destroy(lc); printf("Exited\n"); return 0; }
static void wait_core(LinphoneCore *core) { int i; for (i = 0; i < 10; i++) { linphone_core_iterate(core); ms_usleep(100000); } }
static void wait_a_bit(LinphoneCore *lc, int seconds){ time_t orig=ms_time(NULL); while(ms_time(NULL)-orig<seconds){ /* we need to call iterate to receive notifications */ linphone_core_iterate(lc); ms_usleep (50000); } }
int main(int argc, char *argv[]){ LinphoneCoreVTable vtable={0}; LinphoneCore *lc; LinphoneCall *call=NULL; const char *dest=NULL; /* take the destination sip uri from the command line arguments */ if (argc>1){ dest=argv[1]; } signal(SIGINT,stop); #ifdef DEBUG linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/ #endif /* Fill the LinphoneCoreVTable with application callbacks. All are optional. Here we only use the call_state_changed callbacks in order to get notifications about the progress of the call. */ vtable.call_state_changed=call_state_changed; /* Instanciate a LinphoneCore object given the LinphoneCoreVTable */ lc=linphone_core_new(&vtable,NULL,NULL,NULL); if (dest){ /* Place an outgoing call */ call=linphone_core_invite(lc,dest); if (call==NULL){ printf("Could not place call to %s\n",dest); goto end; }else printf("Call to %s is in progress...",dest); linphone_call_ref(call); } /* main loop for receiving notifications and doing background linphonecore work: */ while(running){ linphone_core_iterate(lc); ms_usleep(50000); } if (call && linphone_call_get_state(call)!=LinphoneCallEnd){ /* terminate the call */ printf("Terminating the call...\n"); linphone_core_terminate_call(lc,call); /*at this stage we don't need the call object */ linphone_call_unref(call); } end: printf("Shutting down...\n"); linphone_core_destroy(lc); printf("Exited\n"); return 0; }
static void register_with_refresh_base_3(LinphoneCore* lc , bool_t refresh ,const char* domain ,const char* route ,bool_t late_auth_info ,LCSipTransports transport ,LinphoneRegistrationState expected_final_state) { int retry=0; char* addr; LinphoneProxyConfig* proxy_cfg; stats* counters; LinphoneAddress *from; const char* server_addr; LinphoneAuthInfo *info; BC_ASSERT_PTR_NOT_NULL(lc); if (!lc) return; counters = get_stats(lc); reset_counters(counters); linphone_core_set_sip_transports(lc,&transport); proxy_cfg = linphone_proxy_config_new(); from = create_linphone_address(domain); linphone_proxy_config_set_identity(proxy_cfg,addr=linphone_address_as_string(from)); ms_free(addr); server_addr = linphone_address_get_domain(from); linphone_proxy_config_enable_register(proxy_cfg,TRUE); linphone_proxy_config_set_expires(proxy_cfg,1); if (route) { linphone_proxy_config_set_route(proxy_cfg,route); linphone_proxy_config_set_server_addr(proxy_cfg,route); } else { linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); } linphone_address_destroy(from); linphone_core_add_proxy_config(lc,proxy_cfg); linphone_core_set_default_proxy(lc,proxy_cfg); while (counters->number_of_LinphoneRegistrationOk<1+(refresh!=0) && retry++ <(1100 /*only wait 11 s if final state is progress*/+(expected_final_state==LinphoneRegistrationProgress?0:2000))) { linphone_core_iterate(lc); if (counters->number_of_auth_info_requested>0 && linphone_proxy_config_get_state(proxy_cfg) == LinphoneRegistrationFailed && late_auth_info) { if (!linphone_core_get_auth_info_list(lc)) { BC_ASSERT_EQUAL(linphone_proxy_config_get_error(proxy_cfg),LinphoneReasonUnauthorized, int, "%d"); info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain,NULL); /*create authentication structure from identity*/ linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/ } } if (linphone_proxy_config_get_error(proxy_cfg) == LinphoneReasonBadCredentials || (counters->number_of_auth_info_requested>2 &&linphone_proxy_config_get_error(proxy_cfg) == LinphoneReasonUnauthorized)) /*no need to continue if auth cannot be found*/ break; /*no need to continue*/ ms_usleep(10000); }
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_BITRATE, &sample_rate) != 0) { int soundwrite_sample_rate = 48000; ms_filter_call_method(ms_tester_soundwrite, MS_FILTER_GET_BITRATE, &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(); }
static void wait_for_eof(Eof *obj, int refresh_time_ms, int timeout_ms) { ms_mutex_lock(&obj->mutex); while(obj->time_ms < timeout_ms && !obj->eof) { ms_mutex_unlock(&obj->mutex); ms_usleep((useconds_t)(refresh_time_ms) * 1000U); obj->time_ms += refresh_time_ms; ms_mutex_lock(&obj->mutex); } ms_mutex_unlock(&obj->mutex); }
bool_t wait_for_stun_resolution(LinphoneCoreManager *m) { MSTimeSpec start; int timeout_ms = 10000; liblinphone_tester_clock_start(&start); while (m->lc->net_conf.stun_addrinfo == NULL && !liblinphone_tester_clock_elapsed(&start,timeout_ms)) { linphone_core_iterate(m->lc); ms_usleep(20000); } return m->lc->net_conf.stun_addrinfo != NULL; }
static void register_with_refresh_base_2(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route,bool_t late_auth_info,LCSipTransports transport) { int retry=0; char* addr; LinphoneProxyConfig* proxy_cfg; stats* counters; LinphoneAddress *from; const char* server_addr; LinphoneAuthInfo *info; CU_ASSERT_PTR_NOT_NULL(lc); if (!lc) return; counters = get_stats(lc); reset_counters(counters); linphone_core_set_sip_transports(lc,&transport); proxy_cfg = linphone_proxy_config_new(); from = create_linphone_address(domain); linphone_proxy_config_set_identity(proxy_cfg,addr=linphone_address_as_string(from)); ms_free(addr); server_addr = linphone_address_get_domain(from); linphone_proxy_config_enable_register(proxy_cfg,TRUE); linphone_proxy_config_expires(proxy_cfg,1); if (route) { linphone_proxy_config_set_route(proxy_cfg,route); linphone_proxy_config_set_server_addr(proxy_cfg,route); } else { linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); } linphone_address_destroy(from); linphone_core_add_proxy_config(lc,proxy_cfg); linphone_core_set_default_proxy(lc,proxy_cfg); while (counters->number_of_LinphoneRegistrationOk<1+(refresh!=0) && retry++ <310) { linphone_core_iterate(lc); if (counters->number_of_auth_info_requested>0 && late_auth_info) { info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain); /*create authentication structure from identity*/ linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/ } ms_usleep(100000); } CU_ASSERT_TRUE(linphone_proxy_config_is_registered(proxy_cfg)); CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationNone,0); CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationProgress,1); CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationOk,1+(refresh!=0)); CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,late_auth_info?1:0); CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationCleared,0); }
/* * This function returns the addrinfo representation of the stun server address. * It is critical not to block for a long time if it can't be resolved, otherwise this stucks the main thread when making a call. * On the contrary, a fully asynchronous call initiation is complex to develop. * The compromise is then: * - have a cache of the stun server addrinfo * - this cached value is returned when it is non-null * - an asynchronous resolution is asked each time this function is called to ensure frequent refreshes of the cached value. * - if no cached value exists, block for a short time; this case must be unprobable because the resolution will be asked each time the stun server value is * changed. **/ const struct addrinfo *linphone_core_get_stun_server_addrinfo(LinphoneCore *lc){ const char *server=linphone_core_get_stun_server(lc); if (server){ int wait_ms=0; int wait_limit=1000; linphone_core_resolve_stun_server(lc); while (!lc->net_conf.stun_addrinfo && lc->net_conf.stun_res!=NULL && wait_ms<wait_limit){ sal_iterate(lc->sal); ms_usleep(50000); wait_ms+=50; } } return lc->net_conf.stun_addrinfo; }
bool_t wait_for_list(MSList* lcs,int* counter,int value,int timeout_ms) { MSList* iterator; MSTimeSpec start; liblinphone_tester_clock_start(&start); while ((counter==NULL || *counter<value) && !liblinphone_tester_clock_elapsed(&start,timeout_ms)) { for (iterator=lcs;iterator!=NULL;iterator=iterator->next) { linphone_core_iterate((LinphoneCore*)(iterator->data)); } ms_usleep(100000); } if(counter && *counter<value) return FALSE; else return TRUE; }
LinphoneCoreManager* setup(bool_t enable_logs) { LinphoneCoreManager *marie; int timeout_ms = 3000; linphone_core_enable_log_collection(enable_logs); // linphone_core_set_log_collection_size(10); marie = linphone_core_manager_new( "marie_rc"); // wait a few seconds to generate some traffic while (timeout_ms > 0){ linphone_core_iterate(marie->lc); ms_usleep(100000); //100 ms sleep timeout_ms -= 100; // Generate some logs ms_message("Time left: %d", timeout_ms); } return marie; }
static bool_t video_call_with_params(LinphoneCoreManager* caller_mgr, LinphoneCoreManager* callee_mgr, const LinphoneCallParams *caller_params, const LinphoneCallParams *callee_params, bool_t automatically_accept) { int retry = 0; stats initial_caller = caller_mgr->stat; stats initial_callee = callee_mgr->stat; bool_t result = TRUE; bool_t did_received_call; CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(caller_mgr->lc, callee_mgr->identity, caller_params)); did_received_call = wait_for(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallIncomingReceived, initial_callee.number_of_LinphoneCallIncomingReceived + 1); if (!did_received_call) return 0; CU_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress, initial_caller.number_of_LinphoneCallOutgoingProgress + 1); while (caller_mgr->stat.number_of_LinphoneCallOutgoingRinging != (initial_caller.number_of_LinphoneCallOutgoingRinging + 1) && caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia != (initial_caller.number_of_LinphoneCallOutgoingEarlyMedia + 1) && retry++ < 20) { linphone_core_iterate(caller_mgr->lc); linphone_core_iterate(callee_mgr->lc); ms_usleep(100000); } CU_ASSERT_TRUE((caller_mgr->stat.number_of_LinphoneCallOutgoingRinging == initial_caller.number_of_LinphoneCallOutgoingRinging + 1) || (caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia == initial_caller.number_of_LinphoneCallOutgoingEarlyMedia + 1)); CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(callee_mgr->lc)); if(!linphone_core_get_current_call(caller_mgr->lc) || !linphone_core_get_current_call(callee_mgr->lc) || !linphone_core_get_current_call_remote_address(callee_mgr->lc)) { return 0; } if (automatically_accept == TRUE) { linphone_core_accept_call_with_params(callee_mgr->lc, linphone_core_get_current_call(callee_mgr->lc), callee_params); CU_ASSERT_TRUE(wait_for(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallConnected, initial_callee.number_of_LinphoneCallConnected + 1)); CU_ASSERT_TRUE(wait_for(callee_mgr->lc, caller_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallConnected, initial_callee.number_of_LinphoneCallConnected + 1)); result = wait_for(callee_mgr->lc, caller_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallStreamsRunning, initial_caller.number_of_LinphoneCallStreamsRunning + 1) && wait_for(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallStreamsRunning, initial_callee.number_of_LinphoneCallStreamsRunning + 1); } return result; }
static void register_with_refresh_with_send_error() { int retry=0; LinphoneCoreManager* lcm = create_lcm_with_auth(1); stats* counters = &lcm->stat; LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain); /*create authentication structure from identity*/ char route[256]; sprintf(route,"sip:%s",test_route); linphone_core_add_auth_info(lcm->lc,info); /*add authentication info to LinphoneCore*/ register_with_refresh_base(lcm->lc,TRUE,auth_domain,route); /*simultate a network error*/ sal_set_send_error(lcm->lc->sal, -1); while (counters->number_of_LinphoneRegistrationProgress<2 && retry++ <20) { linphone_core_iterate(lcm->lc); ms_usleep(100000); } CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0); CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationProgress,2); CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationCleared,0); linphone_core_manager_destroy(lcm); }
const struct addrinfo * linphone_nat_policy_get_stun_server_addrinfo(LinphoneNatPolicy *policy) { /* * It is critical not to block for a long time if it can't be resolved, otherwise this stucks the main thread when making a call. * On the contrary, a fully asynchronous call initiation is complex to develop. * The compromise is then: * - have a cache of the stun server addrinfo * - this cached value is returned when it is non-null * - an asynchronous resolution is asked each time this function is called to ensure frequent refreshes of the cached value. * - if no cached value exists, block for a short time; this case must be unprobable because the resolution will be asked each * time the stun server value is changed. */ if (linphone_nat_policy_stun_server_activated(policy)) { int wait_ms = 0; int wait_limit = 1000; linphone_nat_policy_resolve_stun_server(policy); while ((policy->stun_addrinfo == NULL) && (policy->stun_resolver_context != NULL) && (wait_ms < wait_limit)) { sal_iterate(policy->lc->sal); ms_usleep(50000); wait_ms += 50; } } return policy->stun_addrinfo; }
// Implementation of the iterate method. void PhpLinphoneCore::iterate() { this->lock(); linphone_core_iterate(this->_core); this->unlock(); ms_usleep(50000); }
int main(int argc, char *argv[]){ LinphoneCoreVTable vtable={0}; LinphoneCore *lc; LinphoneCall *call=NULL; LinphoneChatRoom *chat_room; LinphoneChatMessage *chat_message=NULL; const char *dest=NULL; LCSipTransports tp; tp.udp_port=LC_SIP_TRANSPORT_RANDOM; tp.tcp_port=LC_SIP_TRANSPORT_RANDOM; tp.tls_port=LC_SIP_TRANSPORT_RANDOM; /* take the destination sip uri from the command line arguments */ if (argc>1){ dest=argv[1]; } signal(SIGINT,stop); #ifdef DEBUG linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/ #endif /* Instanciate a LinphoneCore object given the LinphoneCoreVTable */ lc=linphone_core_new(&vtable,NULL,NULL,NULL); linphone_core_set_sip_transports(lc,&tp); /*to avoid port colliding with receiver*/ if (dest){ /* Place an outgoing call with rtt enabled */ LinphoneCallParams *cp = linphone_core_create_call_params(lc, NULL); linphone_call_params_enable_realtime_text(cp,TRUE); /*enable real time text*/ call=linphone_core_invite_with_params(lc,dest,cp); linphone_call_params_destroy(cp); if (call==NULL){ printf("Could not place call to %s\n",dest); goto end; }else printf("Call to %s is in progress...",dest); linphone_call_ref(call); } /*wait for call to be established*/ while (running && (linphone_call_get_state(call) == LinphoneCallOutgoingProgress || linphone_call_get_state(call) == LinphoneCallOutgoingInit)) { linphone_core_iterate(lc); ms_usleep(50000); } /*check if call is established*/ switch (linphone_call_get_state(call)) { case LinphoneCallError: case LinphoneCallReleased: case LinphoneCallEnd: printf("Could not place call to %s\n",dest); goto end; break; default: break; /*continue*/ } chat_room=linphone_call_get_chat_room(call); /*create a chat room associated to this call*/ /* main loop for sending message and doing background linphonecore work: */ while(running){ char character; /*to disable terminal buffering*/ if (system ("/bin/stty raw") == -1){ ms_error("/bin/stty error"); } character = getchar(); if (system("/bin/stty cooked") == -1){ ms_error("/bin/stty error"); } if (character==0x03) {/*CTRL C*/ running=0; break; } if (character != EOF) { /* user has typed something*/ if (chat_message == NULL) { /*create a new message*/ chat_message = linphone_chat_room_create_message(chat_room,""); /*create an empty message*/ } if (character == '\r') { /*new line, committing message*/ linphone_chat_room_send_chat_message(chat_room,chat_message); chat_message = NULL; /*reset message*/ } else { linphone_chat_message_put_char(chat_message,character); /*send char in realtime*/ } } linphone_core_iterate(lc); ms_usleep(50000); } if (call && linphone_call_get_state(call)!=LinphoneCallEnd){ /* terminate the call */ printf("Terminating the call...\n"); linphone_core_terminate_call(lc,call); /*at this stage we don't need the call object */ linphone_call_unref(call); } end: printf("Shutting down...\n"); linphone_core_destroy(lc); printf("Exited\n"); return 0; }
bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state) { LinphoneCall *c1,*c2; bool_t audio_success=FALSE; bool_t video_success=FALSE; bool_t text_success=FALSE; bool_t video_enabled, realtime_text_enabled; MSTimeSpec ts; c1=linphone_core_get_current_call(caller->lc); c2=linphone_core_get_current_call(callee->lc); BC_ASSERT_PTR_NOT_NULL(c1); BC_ASSERT_PTR_NOT_NULL(c2); if (!c1 || !c2) return FALSE; linphone_call_ref(c1); linphone_call_ref(c2); BC_ASSERT_EQUAL(linphone_call_params_video_enabled(linphone_call_get_current_params(c1)),linphone_call_params_video_enabled(linphone_call_get_current_params(c2)), int, "%d"); BC_ASSERT_EQUAL(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c1)),linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c2)), int, "%d"); video_enabled=linphone_call_params_video_enabled(linphone_call_get_current_params(c1)); realtime_text_enabled=linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c1)); liblinphone_tester_clock_start(&ts); do{ if ((c1 != NULL) && (c2 != NULL)) { if (linphone_call_get_audio_stats(c1)->ice_state==state && linphone_call_get_audio_stats(c2)->ice_state==state ){ audio_success=TRUE; check_ice_from_rtp(c1,c2,LinphoneStreamTypeAudio); check_ice_from_rtp(c2,c1,LinphoneStreamTypeAudio); break; } linphone_core_iterate(caller->lc); linphone_core_iterate(callee->lc); } ms_usleep(20000); }while(!liblinphone_tester_clock_elapsed(&ts,10000)); if (video_enabled){ liblinphone_tester_clock_start(&ts); do{ if ((c1 != NULL) && (c2 != NULL)) { if (linphone_call_get_video_stats(c1)->ice_state==state && linphone_call_get_video_stats(c2)->ice_state==state ){ video_success=TRUE; check_ice_from_rtp(c1,c2,LinphoneStreamTypeVideo); check_ice_from_rtp(c2,c1,LinphoneStreamTypeVideo); break; } linphone_core_iterate(caller->lc); linphone_core_iterate(callee->lc); } ms_usleep(20000); }while(!liblinphone_tester_clock_elapsed(&ts,10000)); } if (realtime_text_enabled){ liblinphone_tester_clock_start(&ts); do{ if ((c1 != NULL) && (c2 != NULL)) { if (linphone_call_get_text_stats(c1)->ice_state==state && linphone_call_get_text_stats(c2)->ice_state==state ){ text_success=TRUE; check_ice_from_rtp(c1,c2,LinphoneStreamTypeText); check_ice_from_rtp(c2,c1,LinphoneStreamTypeText); break; } linphone_core_iterate(caller->lc); linphone_core_iterate(callee->lc); } ms_usleep(20000); }while(!liblinphone_tester_clock_elapsed(&ts,10000)); } /*make sure encryption mode are preserved*/ if (c1) { const LinphoneCallParams* call_param = linphone_call_get_current_params(c1); BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller->lc), int, "%d"); } if (c2) { const LinphoneCallParams* call_param = linphone_call_get_current_params(c2); BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(callee->lc), int, "%d"); } linphone_call_unref(c1); linphone_call_unref(c2); return video_enabled ? (realtime_text_enabled ? text_success && audio_success && video_success : audio_success && video_success) : realtime_text_enabled ? text_success && audio_success : audio_success; }
int main(int argc, char *argv[]){ LinphoneCoreVTable vtable={0}; const char* dest_friend=NULL; int i; const char* big_file_content="big file"; LinphoneChatRoom* chat_room; LinphoneContent* content; LinphoneChatMessage* chat_message; LinphoneChatMessageCbs *cbs; /*seting dummy file content to something*/ for (i=0;i<sizeof(big_file);i+=strlen(big_file_content)) memcpy(big_file+i, big_file_content, strlen(big_file_content)); big_file[0]=*"S"; big_file[sizeof(big_file)-1]=*"E"; signal(SIGINT,stop); //#define DEBUG #ifdef DEBUG linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/ #endif vtable.message_received=message_received; /* Instantiate a LinphoneCore object given the LinphoneCoreVTable */ lc=linphone_core_new(&vtable,NULL,NULL,NULL); dest_friend = linphone_core_get_primary_contact(lc); printf("Send message to me : %s\n", dest_friend); /** * Globally configure an http file transfer server. */ //linphone_core_set_file_transfer_server(lc,"http://npasc.al/lft.php"); linphone_core_set_file_transfer_server(lc,"https://www.linphone.org:444/lft.php"); /*Next step is to create a chat room*/ chat_room = linphone_core_get_chat_room_from_uri(lc,dest_friend); content = linphone_core_create_content(lc); linphone_content_set_type(content,"text"); linphone_content_set_subtype(content,"plain"); linphone_content_set_size(content,sizeof(big_file)); /*total size to be transfered*/ linphone_content_set_name(content,"bigfile.txt"); /*now create a chat message with custom content*/ chat_message = linphone_chat_room_create_file_transfer_message(chat_room,content); if (chat_message == NULL) { printf("returned message is null\n"); } /** * Fill the application callbacks. The file_transfer_received callback is used in order to get notifications * about incoming file reception, file_transfer_send to feed file to be transfered and * file_transfer_progress_indication to print progress. */ cbs = linphone_chat_message_get_callbacks(chat_message); linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); linphone_chat_message_cbs_set_file_transfer_send(cbs, file_transfer_send); linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); /*initiating file transfer*/ linphone_chat_room_send_chat_message(chat_room, chat_message); /* main loop for receiving incoming messages and doing background linphone core work: */ while(running){ linphone_core_iterate(lc); ms_usleep(50000); } printf("Shutting down...\n"); linphone_content_unref(content); linphone_core_destroy(lc); printf("Exited\n"); return 0; }
/* this functions runs a simple stun test and return the number of milliseconds to complete the tests, or -1 if the test were failed.*/ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ const char *server=linphone_core_get_stun_server(lc); StunCandidate *ac=&call->ac; StunCandidate *vc=&call->vc; if (lc->sip_conf.ipv6_enabled){ ms_warning("stun support is not implemented for ipv6"); return -1; } if (server!=NULL){ const struct addrinfo *ai=linphone_core_get_stun_server_addrinfo(lc); ortp_socket_t sock1=-1, sock2=-1; int loops=0; bool_t video_enabled=linphone_core_video_enabled(lc); bool_t got_audio,got_video; bool_t cone_audio=FALSE,cone_video=FALSE; struct timeval init,cur; double elapsed; int ret=0; if (ai==NULL){ ms_error("Could not obtain stun server addrinfo."); return -1; } if (lc->vtable.display_status!=NULL) lc->vtable.display_status(lc,_("Stun lookup in progress...")); /*create the two audio and video RTP sockets, and send STUN message to our stun server */ sock1=create_socket(call->audio_port); if (sock1==-1) return -1; if (video_enabled){ sock2=create_socket(call->video_port); if (sock2==-1) return -1; } got_audio=FALSE; got_video=FALSE; ortp_gettimeofday(&init,NULL); do{ int id; if (loops%20==0){ ms_message("Sending stun requests..."); sendStunRequest(sock1,ai->ai_addr,ai->ai_addrlen,11,TRUE); sendStunRequest(sock1,ai->ai_addr,ai->ai_addrlen,1,FALSE); if (sock2!=-1){ sendStunRequest(sock2,ai->ai_addr,ai->ai_addrlen,22,TRUE); sendStunRequest(sock2,ai->ai_addr,ai->ai_addrlen,2,FALSE); } } ms_usleep(10000); if (recvStunResponse(sock1,ac->addr, &ac->port,&id)>0){ ms_message("STUN test result: local audio port maps to %s:%i", ac->addr, ac->port); if (id==11) cone_audio=TRUE; got_audio=TRUE; } if (recvStunResponse(sock2,vc->addr, &vc->port,&id)>0){ ms_message("STUN test result: local video port maps to %s:%i", vc->addr, vc->port); if (id==22) cone_video=TRUE; got_video=TRUE; } ortp_gettimeofday(&cur,NULL); elapsed=((cur.tv_sec-init.tv_sec)*1000.0) + ((cur.tv_usec-init.tv_usec)/1000.0); if (elapsed>2000) { ms_message("Stun responses timeout, going ahead."); ret=-1; break; } loops++; }while(!(got_audio && (got_video||sock2==-1) ) ); if (ret==0) ret=(int)elapsed; if (!got_audio){ ms_error("No stun server response for audio port."); }else{ if (!cone_audio) { ms_message("NAT is symmetric for audio port"); } } if (sock2!=-1){ if (!got_video){ ms_error("No stun server response for video port."); }else{ if (!cone_video) { ms_message("NAT is symmetric for video port."); } } } close_socket(sock1); if (sock2!=-1) close_socket(sock2); return ret; } return -1; }
static void ecc_play_tones(EcCalibrator *ecc) { MSDtmfGenCustomTone tone; MSToneDetectorDef expected_tone; memset(&tone,0,sizeof(tone)); memset(&expected_tone,0,sizeof(expected_tone)); ms_filter_set_notify_callback(ecc->det,on_tone_received,ecc); /* configure the tones to be scanned */ strncpy(expected_tone.tone_name,"freq1",sizeof(expected_tone.tone_name)); expected_tone.frequency=2000; expected_tone.min_duration=40; expected_tone.min_amplitude=0.1; ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); strncpy(expected_tone.tone_name,"freq2",sizeof(expected_tone.tone_name)); expected_tone.frequency=2300; expected_tone.min_duration=40; expected_tone.min_amplitude=0.1; ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); strncpy(expected_tone.tone_name,"freq3",sizeof(expected_tone.tone_name)); expected_tone.frequency=2500; expected_tone.min_duration=40; expected_tone.min_amplitude=0.1; ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); /*play an initial tone to startup the audio playback/capture*/ tone.frequencies[0]=140; tone.duration=1000; tone.amplitude=0.5; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(2); ms_filter_set_notify_callback(ecc->gen,on_tone_sent,ecc); /* play the three tones*/ tone.frequencies[0]=2000; tone.duration=100; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_usleep(300000); tone.frequencies[0]=2300; tone.duration=100; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_usleep(300000); tone.frequencies[0]=2500; tone.duration=100; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(1); if (ecc->freq1 && ecc->freq2 && ecc->freq3) { int delay=ecc->acc/3; if (delay<0) { ms_error("Quite surprising calibration result, delay=%i",delay); ecc->status=LinphoneEcCalibratorFailed; } else { ms_message("Echo calibration estimated delay to be %i ms",delay); ecc->delay=delay; ecc->status=LinphoneEcCalibratorDone; } } else if ((ecc->freq1 || ecc->freq2 || ecc->freq3)==FALSE) { ms_message("Echo calibration succeeded, no echo has been detected"); ecc->status = LinphoneEcCalibratorDoneNoEcho; } else { ecc->status = LinphoneEcCalibratorFailed; } if (ecc->status == LinphoneEcCalibratorFailed) { ms_error("Echo calibration failed."); } }
/* * This small program starts a video stream to either * - read an H264 video track from mkv file and stream it out with RTP to specified destination * - receive H264 RTP packets on a local port and record them into an mkv file */ int main(int argc, char *argv[]){ const char *command; const char *file; const char *ip; int port; VideoStream *stream; RtpProfile *profile; PayloadType *pt; Mode mode = INVALID_MODE; int local_port = 7778; MSFactory *factory ; MSMediaStreamIO io = MS_MEDIA_STREAM_IO_INITIALIZER; int err; /*parse command line arguments*/ if (argc<4) usage(argv[0]); command = argv[1]; if (strcasecmp(command,"play")==0) mode = PLAY_MODE; else if (strcasecmp(command, "record")==0) mode = RECORD_MODE; else usage(argv[0]); file = argv[2]; if (mode == PLAY_MODE){ ip = argv[3]; if (argc<5) usage(argv[0]); port = atoi(argv[4]); }else{ local_port = atoi(argv[3]); ip = "127.0.0.1"; port = 9990; /*dummy destination address, we won't send anything here anyway*/ } /*set a signal handler to interrupt the program cleanly*/ signal(SIGINT,stop_handler); /*initialize mediastreamer2*/ factory = ms_factory_new_with_voip(); /*create the video stream */ stream = video_stream_new(factory, local_port, local_port+1, FALSE); /*define its local input and outputs with the MSMediaStreamIO structure*/ if (mode == PLAY_MODE){ io.input.type = MSResourceFile; io.input.file = file; /*the file we want to stream out via rtp*/ io.output.type = MSResourceFile; io.output.file = NULL; /*we don't set a record file in PLAY_MODE, we just want the received video stream to be ignored, if something is received*/ }else{ io.input.type = MSResourceFile; io.input.file = NULL; /*We don't want to send anything via RTP in RECORD_MODE*/ io.output.type = MSResourceFile; io.output.file = file; /*The file to which we want to record the received video stream*/ } /*define the RTP profile to use: in this case we just want to use H264 codec*/ profile = rtp_profile_new("My RTP profile"); pt = payload_type_clone(&payload_type_h264); rtp_profile_set_payload(profile, payload_type_number, pt); /*we assign H264 to payload type number payload_type_number*/ media_stream_set_target_network_bitrate(&stream->ms, 500000); /*set a target IP bitrate in bits/second */ /*By default, the VideoStream will show up a display window where the received video is played, with a local preview as well. * If you don't need this, assign (void*)-1 as window id, which explicitely disable the display feature.*/ /*video_stream_set_native_window_id(stream, (void*)-1);*/ /*start the video stream, given the RtpProfile and "io" definition */ err = video_stream_start_from_io(stream, profile, ip, port, ip, port+1, payload_type_number, &io); if (err !=0 ){ fprintf(stderr,"Could not start video stream."); goto end; } /*Register an event handler on the player to be notified of end of file*/ ms_filter_add_notify_callback(stream->source, on_end_of_play, NULL, FALSE); /*program's main loop*/ while (active){ /*handle video stream background activity. This is non blocking*/ video_stream_iterate(stream); /*process event callbacks*/ ms_event_queue_pump(ms_factory_get_event_queue(factory)); ms_usleep(50000); /*pause 50ms to avoid busy loop*/ } end: /*stop and destroy the video stream object*/ if (stream) video_stream_stop(stream); /*free the RTP profile and payload type inside*/ if (profile) rtp_profile_destroy(profile); ms_factory_destroy(factory); return err; }
int main(int argc, char *argv[]){ LinphoneCoreVTable vtable={0}; LinphoneCore *lc; LinphoneVideoPolicy policy; int i; LinphoneAddress *addr=NULL; LCSipTransports tp; char * tmp = NULL; LpConfig * lp_config = lp_config_new(NULL); int max_call_duration=3600; static const char *media_file = NULL; policy.automatically_accept=TRUE; signal(SIGINT,stop); #ifndef _WIN32 signal(SIGUSR1,stats); signal(SIGUSR2,dump_call_logs); #endif for(i = 1; i < argc; ++i) { if (strcmp(argv[i], "--verbose") == 0) { linphone_core_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); } else if (strcmp(argv[i], "--max-call-duration") == 0){ max_call_duration = atoi(argv[++i]); } else if (strcmp(argv[i], "--listening-uri") == 0){ addr = linphone_address_new(argv[++i]); if (!addr) { printf("Error, bad sip uri"); helper(argv[0]); } /* switch(linphone_address_get_transport(addr)) { case LinphoneTransportUdp: case LinphoneTransportTcp: break; default: ms_error("Error, bad sip uri [%s] transport, should be udp | tcp",argv[i]); helper(); break; }*/ } else if (strcmp(argv[i], "--media-file") == 0){ i++; if (i<argc){ media_file = argv[i]; }else helper(argv[0]); } else { helper(argv[0]); } } if (!addr) { addr = linphone_address_new("sip:[email protected]:5060"); } lp_config_set_string(lp_config,"sip","bind_address",linphone_address_get_domain(addr)); lp_config_set_string(lp_config,"rtp","bind_address",linphone_address_get_domain(addr)); lp_config_set_int(lp_config,"misc","history_max_size",100000); vtable.call_state_changed=call_state_changed; lc=linphone_core_new_with_config(&vtable,lp_config,NULL); linphone_core_enable_video_capture(lc,TRUE); linphone_core_enable_video_display(lc,FALSE); linphone_core_set_video_policy(lc,&policy); linphone_core_enable_keep_alive(lc,FALSE); /*instead of using sound capture card, a file is played to the calling party*/ linphone_core_set_use_files(lc,TRUE); linphone_core_enable_echo_cancellation(lc, FALSE); /*no need for local echo cancellation when playing files*/ if (!media_file){ linphone_core_set_play_file(lc,PACKAGE_DATA_DIR "/sounds/linphone/hello16000.wav"); linphone_core_set_preferred_framerate(lc,5); }else{ PayloadType *pt = linphone_core_find_payload_type(lc, "opus", 48000, -1); /*if opus is present, give it a bitrate for good quality with music, and stereo enabled*/ if (pt){ linphone_core_set_payload_type_bitrate(lc, pt, 150); payload_type_set_send_fmtp(pt, "stereo=1"); payload_type_set_recv_fmtp(pt, "stereo=1"); } linphone_core_set_play_file(lc, media_file); linphone_core_set_preferred_video_size_by_name(lc, "720p"); } { MSWebCamDesc *desc = ms_mire_webcam_desc_get(); if (desc){ ms_web_cam_manager_add_cam(ms_factory_get_web_cam_manager(linphone_core_get_ms_factory(lc)),ms_web_cam_new(desc)); linphone_core_set_video_device(lc,"Mire: Mire (synthetic moving picture)"); } } memset(&tp,0,sizeof(LCSipTransports)); tp.udp_port = linphone_address_get_port(addr); tp.tcp_port = linphone_address_get_port(addr); linphone_core_set_sip_transports(lc,&tp); linphone_core_set_audio_port_range(lc,1024,65000); linphone_core_set_video_port_range(lc,1024,65000); linphone_core_set_primary_contact(lc,tmp=linphone_address_as_string(addr)); ms_free(tmp); /* main loop for receiving notifications and doing background linphonecore work: */ while(running){ const bctbx_list_t * iterator; linphone_core_iterate(lc); ms_usleep(50000); if (print_stats) { ms_message("*********************************"); ms_message("*Current number of calls [%10u] *", (unsigned int)bctbx_list_size(linphone_core_get_calls(lc))); ms_message("*Number of calls until now [%10u] *", (unsigned int)bctbx_list_size(linphone_core_get_call_logs(lc))); ms_message("*********************************"); print_stats=FALSE; } if (dump_stats) { ms_message("*********************************"); for (iterator=linphone_core_get_call_logs(lc);iterator!=NULL;iterator=iterator->next) { LinphoneCallLog *call_log=(LinphoneCallLog *)iterator->data; char * tmp_str = linphone_call_log_to_str(call_log); ms_message("\n%s",tmp_str); ms_free(tmp_str); } dump_stats=FALSE; ms_message("*********************************"); } for (iterator=linphone_core_get_calls(lc);iterator!=NULL;iterator=iterator->next) { LinphoneCall *call=(LinphoneCall *)iterator->data; if (linphone_call_get_duration(call) > max_call_duration) { ms_message("Terminating call [%p] after [%i] s",call,linphone_call_get_duration(call)); linphone_core_terminate_call(lc,call); break; } } } ms_message("Shutting down...\n"); linphone_core_destroy(lc); ms_message("Exited\n"); return 0; }
void playback(char *filename) { MSFilter *f1_w,*play; MSSndCard *card_playback1; MSTicker *ticker1; int i; int done = FALSE; struct msg_st data_w; long int msgtype = 0; int rate = 16000; int nchan=2; int msgid = msgget((key_t)1234, 0666 | IPC_CREAT); if(msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(-1); } ortp_init(); ortp_set_log_level_mask(/*ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|*/ORTP_FATAL); ms_init(); card_playback1 = ms_snd_card_manager_get_default_playback_card(ms_snd_card_manager_get()); if (card_playback1==NULL) { if(card_playback1==NULL) ms_error("No card. card_playback"); } else { ms_warning("card_playback1 %s|%s|%s|%d|%d|%d",card_playback1->name,card_playback1->id,card_playback1->desc->driver_type, card_playback1->capabilities,card_playback1->latency,card_playback1->preferred_sample_rate); } play=ms_filter_new(MS_FILE_PLAYER_ID); if(ms_filter_call_method(play,MS_FILE_PLAYER_OPEN,(void*)filename)!=0) printf("play open file %s failed\n",filename); ms_filter_set_notify_callback(play, fileplay_eof, &done); f1_w=ms_snd_card_create_writer(card_playback1); if(f1_w!=NULL&&play!=NULL) { ms_filter_call_method(play, MS_FILTER_GET_SAMPLE_RATE, &rate); ms_filter_call_method(play, MS_FILTER_GET_NCHANNELS, &nchan); if(ms_filter_call_method(f1_w, MS_FILTER_SET_SAMPLE_RATE, &rate)!=0) printf("set sample rate f1_r failed\n"); if(ms_filter_call_method(f1_w, MS_FILTER_SET_NCHANNELS,&nchan)!=0) printf("set sample rate record failed\n"); ms_filter_call_method_noarg(play,MS_FILE_PLAYER_START); ticker1=ms_ticker_new(); ms_ticker_set_name(ticker1,"card1 to card2"); ms_filter_link(play,0,f1_w,0); ms_ticker_attach(ticker1,play); while (done != TRUE) { ms_usleep(10000); } ms_filter_call_method_noarg(play, MS_FILE_PLAYER_CLOSE); if(ticker1) ms_ticker_detach(ticker1,play); if(f1_w&&play) ms_filter_unlink(play,0,f1_w,0); if(ticker1) ms_ticker_destroy(ticker1); if(f1_w) ms_filter_destroy(f1_w); if(play) ms_filter_destroy(play); data_w.msg_type = 2; //注意2 strcpy(data_w.text, filename); //向队列发送数据 // if(msgsnd(msgid, (void*)&data_w, 512, IPC_NOWAIT) == -1) // { // fprintf(stderr, "msgsnd failed\n"); // exit(1); // } printf("playing finished\n"); } }