static pj_status_t transport_attach(pjmedia_transport *tp, void *user_data, const pj_sockaddr_t *rem_addr, const pj_sockaddr_t *rem_rtcp, unsigned addr_len, void (*rtp_cb) (void*, void*, pj_ssize_t), void (*rtcp_cb)(void*, void*, pj_ssize_t)) { transport_srtp *srtp = (transport_srtp*) tp; pj_status_t status; PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL); /* Save the callbacks */ srtp->rtp_cb = rtp_cb; srtp->rtcp_cb = rtcp_cb; srtp->user_data = user_data; /* Attach itself to transport */ status = pjmedia_transport_attach(srtp->member_tp, srtp, rem_addr, rem_rtcp, addr_len, &srtp_rtp_cb, &srtp_rtcp_cb); if (status != PJ_SUCCESS) { srtp->rtp_cb = NULL; srtp->rtcp_cb = NULL; srtp->user_data = NULL; return status; } return PJ_SUCCESS; }
/* * attach() is called by stream to register callbacks that we should * call on receipt of RTP and RTCP packets. */ static pj_status_t transport_attach(pjmedia_transport *tp, void *user_data, const pj_sockaddr_t *rem_addr, const pj_sockaddr_t *rem_rtcp, unsigned addr_len, void (*rtp_cb)(void*, void*, pj_ssize_t), void (*rtcp_cb)(void*, void*, pj_ssize_t)) { struct tp_zrtp *zrtp = (struct tp_zrtp*)tp; pj_status_t status; PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL); /* In this example, we will save the stream information and callbacks * to our structure, and we will register different RTP/RTCP callbacks * instead. */ pj_assert(zrtp->stream_user_data == NULL); zrtp->stream_user_data = user_data; zrtp->stream_rtp_cb = rtp_cb; zrtp->stream_rtcp_cb = rtcp_cb; status = pjmedia_transport_attach(zrtp->slave_tp, zrtp, rem_addr, rem_rtcp, addr_len, &transport_rtp_cb, &transport_rtcp_cb); if (status != PJ_SUCCESS) { zrtp->stream_user_data = NULL; zrtp->stream_rtp_cb = NULL; zrtp->stream_rtcp_cb = NULL; return status; } return PJ_SUCCESS; }
/* * attach() is called by stream to register callbacks that we should * call on receipt of RTP and RTCP packets. */ static pj_status_t transport_attach(pjmedia_transport *tp, void *user_data, const pj_sockaddr_t *rem_addr, const pj_sockaddr_t *rem_rtcp, unsigned addr_len, void (*rtp_cb)(void*, void*, pj_ssize_t), void (*rtcp_cb)(void*, void*, pj_ssize_t)) { struct tp_adapter *adapter = (struct tp_adapter*)tp; pj_status_t status; /* In this example, we will save the stream information and callbacks * to our structure, and we will register different RTP/RTCP callbacks * instead. */ pj_assert(adapter->stream_user_data == NULL); adapter->stream_user_data = user_data; adapter->stream_rtp_cb = rtp_cb; adapter->stream_rtcp_cb = rtcp_cb; status = pjmedia_transport_attach(adapter->slave_tp, adapter, rem_addr, rem_rtcp, addr_len, &transport_rtp_cb, &transport_rtcp_cb); if (status != PJ_SUCCESS) { adapter->stream_user_data = NULL; adapter->stream_rtp_cb = NULL; adapter->stream_rtcp_cb = NULL; return status; } return PJ_SUCCESS; }
PJ_DEF(pj_status_t) pjmedia_natnl_stream_create(pj_pool_t *pool, pjsua_call *call, pjmedia_stream_info *si, natnl_stream **stream) { pj_status_t status = PJ_SUCCESS; unsigned strm_idx = 0; strm_idx = call->index; /* TODO: * - Create and start your media stream based on the parameters * in si */ PJ_ASSERT_RETURN(pool, PJ_EINVAL); PJ_LOG(4,(THIS_FILE,"natnl audio channel update..strm_idx=%d", strm_idx)); /* Check if no media is active */ if (si->dir != PJMEDIA_DIR_NONE) { /* Create session based on session info. */ #if 0 pool = pj_pool_create(strm_pool->factory, "strm%p", NATNL_STREAM_SIZE, NATNL_STREAM_INC, NULL); PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM); #endif pj_mutex_lock(call->tnl_stream_lock); pj_mutex_lock(call->tnl_stream_lock2); pj_mutex_lock(call->tnl_stream_lock3); // DEAN don't re-create natnl stream if (call->tnl_stream) { *stream = call->tnl_stream; pj_mutex_unlock(call->tnl_stream_lock3); pj_mutex_unlock(call->tnl_stream_lock2); pj_mutex_unlock(call->tnl_stream_lock); return PJ_SUCCESS; } call->tnl_stream = *stream = PJ_POOL_ZALLOC_T(pool, natnl_stream); PJ_ASSERT_RETURN(*stream != NULL, PJ_ENOMEM); (*stream)->call = call; (*stream)->own_pool = pool; (*stream)->med_tp = call->med_tp; pj_memcpy(&(*stream)->rem_addr, &si->rem_addr, sizeof(pj_sockaddr)); pj_list_init(&(*stream)->rbuff); pj_list_init(&(*stream)->gcbuff); pj_get_timestamp(&(*stream)->last_data_or_ka); pj_get_timestamp(&(*stream)->last_data); (*stream)->rbuff_cnt = 0; (*stream)->rx_band = (pj_band_t *)malloc(sizeof(pj_band_t)); (*stream)->tx_band = (pj_band_t *)malloc(sizeof(pj_band_t)); pj_memset((*stream)->rx_band, 0, sizeof(pj_band_t)); pj_memset((*stream)->tx_band, 0, sizeof(pj_band_t)); pj_bandwidthSetLimited((*stream)->rx_band, PJ_FALSE); pj_bandwidthSetLimited((*stream)->tx_band, PJ_FALSE); /* Create mutex to protect jitter buffer: */ status = pj_mutex_create_simple(pool, NULL, &(*stream)->rbuff_mutex); if (status != PJ_SUCCESS) { //pj_pool_t *tmp_pool = (*stream)->own_pool; (*stream)->own_pool = NULL; //pj_pool_release(tmp_pool); goto on_return; } status = pj_mutex_create_simple(pool, NULL, &(*stream)->gcbuff_mutex); if (status != PJ_SUCCESS) { (*stream)->own_pool = NULL; goto on_return; } /* Create semaphore */ status = pj_sem_create(pool, "client", 0, 65535, &(*stream)->rbuff_sem); if (status != PJ_SUCCESS) { (*stream)->own_pool = NULL; goto on_return; } // +Roger - Create Send buffer Mutex status = pj_mutex_create_simple(pool, NULL, &(*stream)->sbuff_mutex); if (status != PJ_SUCCESS) { //pj_pool_t *tmp_pool = (*stream)->own_pool; (*stream)->own_pool = NULL; //pj_pool_release(tmp_pool); goto on_return; } //------------------------------------// #if 0 /* Attach our RTP and RTCP callbacks to the media transport */ status = pjmedia_transport_attach(call_med->tp, stream, //call_med, &si->rem_addr, &si->rem_rtcp, pj_sockaddr_get_len(&si->rem_addr), &aud_rtp_cb, &aud_rtcp_cb); #endif } on_return: pj_mutex_unlock(call->tnl_stream_lock3); pj_mutex_unlock(call->tnl_stream_lock2); pj_mutex_unlock(call->tnl_stream_lock); return status; }