Thanks Perfect. The last questions 😊 ... how can trigger when rtp or rtcp packets are received? I'm trying to integrate transport adapter with callbacks but when I call pjmedia_transport_attach application crash on -> /* Must not be "attached" to existing application */ PJ_ASSERT_RETURN(!udp->attached, PJ_EINVALIDOP);. Thanks in advice. /*===================================================*/ /* CREATE TRANSPORT (BASE) */ status = pjmedia_transport_udp_attach(med_endpt, "mcast2", &si, PJMEDIA_UDP_NO_SRC_ADDR_CHECKING, &audio.transport); if (status != PJ_SUCCESS) { return status; } /* CREATE STREAM */ status = pjmedia_stream_create(med_endpt, poolMc, &audio.si, audio.transport, &audio, &stream); if (status != PJ_SUCCESS) { return status; } /* CREATE TRANSPORT ADAPTER */ pjmedia_transport *tp_adp; pjmedia_tp_adapter_create(med_endpt, "ttt", audio.transport, PJ_TRUE, &tp_adp); if (status != PJ_SUCCESS) { return status; } /* ATTACH TRANSPORT ADAPTER */ status = pjmedia_transport_attach(tp_adp, &audio, &audio.si.rem_addr, &audio.si.rem_rtcp, sizeof(pj_sockaddr_in), &on_rx_rtpTest, &on_rx_rtcpTest); if (status != PJ_SUCCESS) { return status; } /*===================================================*/ Best Regards LL -----Messaggio originale----- Da: Alain Totouom [mailto:alain.totouom@xxxxxx] Inviato: Thursday, July 20, 2017 11:35 A: Lele <86eldnl@xxxxxxxxx>; 'Alain Totouom' <alain.totouom@xxxxxx>; 'pjsip list' <pjsip@xxxxxxxxxxxxxxx> Oggetto: Re: Create more than one pj_sock_socket for multicast connection - How to manage memory pool of pjmedia_endpoint Hi, On 20.07.17 08:40, Lele wrote: > Another question, I'm trying to send RTCP BYE packet after I have > started the stream but isn't working. I'm trying to call > "pjmedia_stream_send_rtcp_bye(stream);" function. How can I send RTCP > packets? set the *rtcp_sdes_bye_disabled* field of your *pjmedia_stream_info* to PJ_TRUE, if you wish to _manually_ send the RTCP BYE packet. By default the framework does that for you... Regards, Alain > Thanks in advice. > > > > /* Start streaming */ > > pjmedia_stream_start(stream); > > > > > > /* > > * Time to send RTCP packet. > > */ > > while (true) { > > const pj_str_t content = Utils::toPj_str("Prova invio rtcp > packet app"); > > > > /* Send packet */ > > if (stream) { > > status = pjmedia_stream_send_rtcp_bye(stream); > > if (status != PJ_SUCCESS) { return status; } > > } > > Sleep(2000); > > } > > > > Best Regards > > LL > > > > Da: Alain Totouom [mailto:alain.totouom@xxxxxx] > Inviato: Wednesday, July 19, 2017 12:39 > A: pjsip list <pjsip@xxxxxxxxxxxxxxx>; Lele <86eldnl@xxxxxxxxx> > Oggetto: Re: *** GMX Spamverdacht *** Create more than one > pj_sock_socket for multicast connection - How to manage memory pool of > pjmedia_endpoint > > > > Hi, > > your *pj_caching_pool* object goes out of scope, make it a global variable. > > Regards, > > Alain > > > > On 14.07.17 09:45, Lele wrote: > > Hi guys, > > I should create two pj socket connected with two different multicast Ip. > I'm wrote the following source code but It's only working for the > first multicast connection. When I call multicastConnection2 function > memory pool reference is lost. I don't known why this reference is > lost when I run pj_sock_socket function to instantiate a new sock. > Following, when I create a new transport for the new stream, > application crash. In my application first I call multicastConnection > function that initialize pjsip library and create a media_endpt, and > after I run multicastConnection2 to connect the other stream to the > same sound port. The following source code is wrote starting from > streamutil.c sample. How can I implement this feature in my > application? Thanks in advice > > > > /* Global variables for all opened streams */ > > bool isMcastEnabled = true; > > pjmedia_snd_port *snd_port = NULL; > > pjmedia_port *stream_port; > > bool isMcastEnabled; > > pjmedia_dir dir = PJMEDIA_DIR_DECODING; > > pjmedia_audio_codec_config codec_cfg; > > const pjmedia_codec_info *codec_info; > > pj_pool_t *poolMc; > > pjmedia_endpt *med_endpt; > > > > pj_status_t MainWindow::multicastConnection() { > > if (!isMcastEnabled) { > > pj_bool_t mcast = true; > > pj_caching_pool cp; > > pjmedia_stream *stream = NULL; > > pj_status_t status; > > pjmedia_codec_param codec_param; > > pj_sockaddr_in remote_addr; > > pj_sockaddr_in mcast_addr; > > pj_uint16_t local_port = 4000; > > char *codec_id = new char[4]; > > strcpy(codec_id, "PCMA"); > > > > /* Reset defined remote address */ > > pj_bzero(&remote_addr, sizeof(remote_addr)); > > > > /* Init PJLIB */ > > status = pj_init(); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Set multicast ip */ > > const pj_str_t multicastAddrIpv4 = > Utils::toPj_str("239.0.0.1"); /* Defined multicast IpV4 address */ > > status = pj_sockaddr_in_init(&mcast_addr, &multicastAddrIpv4, > 0); > > > > dir = PJMEDIA_DIR_DECODING; > > /* Must create a pool factory before we can allocate any > memory. */ > > pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0); > > /* > > * Initialize media endpoint. > > * This will implicitly initialize PJMEDIA too. > > */ > > status = pjmedia_endpt_create(&cp.factory, NULL, 1, > &med_endpt); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Create memory pool for application purpose */ > > poolMc = pj_pool_create(&cp.factory, /* pool factory */ > > "app", /* pool factory */ > > 4000, /* init size */ > > 4000, /* increment size */ > > NULL /* callback on error */ > > ); > > > > /* Register all codecs */ > > pjmedia_audio_codec_config_default(&codec_cfg); > > /* Register all supported codecs (register all known audio > codecs implemented in PJMEDA-CODEC library to the specified media > endpoint) */ > > status = pjmedia_codec_register_audio_codecs(med_endpt, > &codec_cfg); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Find which codec to use */ > > if (codec_id) { > > unsigned count = 1; > > pj_str_t str_codec_id = pj_str(codec_id); //PCMA is > configured as codec_id > > pjmedia_codec_mgr *codec_mgr = > pjmedia_endpt_get_codec_mgr(med_endpt); > > > > status = pjmedia_codec_mgr_find_codecs_by_id(codec_mgr, > &str_codec_id, &count, &codec_info, NULL); > > if (status != PJ_SUCCESS) { return status; } > > } > > else { > > /* Default to pcmu */ > > status = > pjmedia_codec_mgr_get_codec_info(pjmedia_endpt_get_codec_mgr(med_endpt > ), 0, &codec_info); > > if (status != PJ_SUCCESS) { return status; } > > } > > > > /* ============ Create stream based on program arguments > ============ */ > > pjmedia_stream_info info; > > pjmedia_transport *transport = NULL; > > > > //Reset stream info > > pj_bzero(&info, sizeof(info)); > > > > /* Initialize stream info formats */ > > info.type = PJMEDIA_TYPE_AUDIO; > > info.dir = dir; > > pj_memcpy(&info.fmt, codec_info, sizeof(pjmedia_codec_info)); > > info.tx_pt = codec_info->pt; > > info.rx_pt = codec_info->pt; > > info.ssrc = pj_rand(); /* each source have different ssrc on > multicast channel */ > > > > /* Copy remote address */ > > pj_memcpy(&info.rem_addr, &remote_addr, > sizeof(pj_sockaddr_in)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* If remote address is not set, set to an arbitrary address > (otherwise stream will assert) */ > > if (info.rem_addr.addr.sa_family == 0) { > > const pj_str_t addr = Utils::toPj_str("127.0.0.1"); > > pj_sockaddr_in_init(&info.rem_addr.ipv4, &addr, 0); > > } > > > > pj_sockaddr_cp(&info.rem_rtcp, &info.rem_addr); /* I think > when rtcp is enabled, this function copy remote_addr ip in rtcp_addr > ip */ > > pj_sockaddr_set_port(&info.rem_rtcp, > pj_sockaddr_get_port(&info.rem_rtcp) + 1); /* I think when rtcp is > enabled, this function assign rtcp port */ > > > > if (mcast) { > > pjmedia_sock_info si; > > int reuse = 1; > > pj_bzero(&si, sizeof(pjmedia_sock_info)); > > si.rtp_sock = si.rtcp_sock = PJ_INVALID_SOCKET; > > > > /* Create RTP socket */ > > status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, > &si.rtp_sock); > > if (status != PJ_SUCCESS) { return status; } > > > > status = pj_sock_setsockopt(si.rtp_sock, > pj_SOL_SOCKET(), pj_SO_REUSEADDR(), &reuse, sizeof(reuse)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Bind RTP socket */ > > status = pj_sockaddr_init(pj_AF_INET(), > &si.rtp_addr_name, NULL, local_port); > > if (status != PJ_SUCCESS) { return status; } > > > > status = pj_sock_bind(si.rtp_sock, &si.rtp_addr_name, > pj_sockaddr_get_len(&si.rtp_addr_name)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Create RTCP socket */ > > status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), > 0, &si.rtcp_sock); > > if (status != PJ_SUCCESS) { return status; } > > > > status = pj_sock_setsockopt(si.rtcp_sock, > pj_SOL_SOCKET(), pj_SO_REUSEADDR(), &reuse, sizeof(reuse)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Bind RTCP socket */ > > status = pj_sockaddr_init(pj_AF_INET(), > &si.rtcp_addr_name, NULL, local_port + 1); > > if (status != PJ_SUCCESS) { return status; } > > > > status = pj_sock_bind(si.rtcp_sock, &si.rtcp_addr_name, > pj_sockaddr_get_len(&si.rtcp_addr_name)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* If have multicast */ > > unsigned char loop; > > struct pj_ip_mreq imr; > > pj_memset(&imr, 0, sizeof(struct pj_ip_mreq)); > > imr.imr_multiaddr.s_addr = mcast_addr.sin_addr.s_addr; > > imr.imr_interface.s_addr = pj_htonl(PJ_INADDR_ANY); > > > > status = pj_sock_setsockopt(si.rtp_sock, pj_SOL_IP(), > pj_IP_ADD_MEMBERSHIP(), &imr, sizeof(struct pj_ip_mreq)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* To manage rtcp */ > > status = pj_sock_setsockopt(si.rtcp_sock, pj_SOL_IP(), > pj_IP_ADD_MEMBERSHIP(), &imr, sizeof(struct pj_ip_mreq)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Disable local reception of local sent packets */ > > loop = 0; > > pj_sock_setsockopt(si.rtp_sock, pj_SOL_IP(), > pj_IP_MULTICAST_LOOP(), &loop, sizeof(loop)); > > pj_sock_setsockopt(si.rtcp_sock, pj_SOL_IP(), > pj_IP_MULTICAST_LOOP(), &loop, sizeof(loop)); > > > > /* Create media transport from existing sockets */ > > status = pjmedia_transport_udp_attach(med_endpt, > "mcast2", &si, PJMEDIA_UDP_NO_SRC_ADDR_CHECKING, &transport); > > if (status != PJ_SUCCESS) { return status; } > > } > > else { > > /* Create media transport from existing sockets */ > > status = pjmedia_transport_udp_create(med_endpt, NULL, > local_port, 0, &transport); > > if (status != PJ_SUCCESS) { return status; } > > } > > > > /* Now that the stream info is initialized, we can create the > stream */ > > status = pjmedia_stream_create(med_endpt, poolMc, &info, > transport, NULL, &stream); > > if (status != PJ_SUCCESS) { > > pjmedia_transport_close(transport); > > return status; > > } > > else { > > /* Get codec default param for info */ > > status = > pjmedia_codec_mgr_get_default_param(pjmedia_endpt_get_codec_mgr(med_en > dpt), > codec_info, &codec_param); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Get the port interface of the stream */ > > status = pjmedia_stream_get_port(stream, &stream_port); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Create sound device port. */ > > if (dir == PJMEDIA_DIR_ENCODING_DECODING) > > status = pjmedia_snd_port_create(poolMc, -1, -1, > PJMEDIA_PIA_SRATE(&stream_port->info), > PJMEDIA_PIA_CCNT(&stream_port->info), > PJMEDIA_PIA_SPF(&stream_port->info), > PJMEDIA_PIA_BITS(&stream_port->info), > 0, &snd_port); > > else if (dir == PJMEDIA_DIR_ENCODING) > > status = pjmedia_snd_port_create_rec(poolMc, -1, > PJMEDIA_PIA_SRATE(&stream_port->info), > PJMEDIA_PIA_CCNT(&stream_port->info), > PJMEDIA_PIA_SPF(&stream_port->info), > PJMEDIA_PIA_BITS(&stream_port->info), > 0, &snd_port); > > else > > status = pjmedia_snd_port_create_player(poolMc, > -1, PJMEDIA_PIA_SRATE(&stream_port->info), > PJMEDIA_PIA_CCNT(&stream_port->info), > PJMEDIA_PIA_SPF(&stream_port->info), > PJMEDIA_PIA_BITS(&stream_port->info), > 0, &snd_port); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Connect sound port to stream */ > > status = pjmedia_snd_port_connect(snd_port, > stream_port); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Start streaming */ > > pjmedia_stream_start(stream); > > } > > } > > return PJ_SUCCESS; > > } > > > > pj_status_t MainWindow::multicastConnection2() { > > > > if (!isMcastEnabled) { > > pj_pool_t *memoryPool; > > pj_bool_t mcast = true; > > pj_sockaddr_in mcast_addr; > > pj_uint16_t local_port = 5000; > > pj_status_t status; > > pjmedia_stream *stream = NULL; > > > > /* Set multicast ip */ > > const pj_str_t multicastAddrIpv4 = > Utils::toPj_str("239.0.0.2"); /* Defined multicast IpV4 address */ > > status = pj_sockaddr_in_init(&mcast_addr, > &multicastAddrIpv4, 0); > > > > /* ============ Create stream based on program > arguments ============ */ > > > > pjmedia_stream_info info; > > pjmedia_transport *transport = NULL; > > > > //Reset stream info > > pj_bzero(&info, sizeof(info)); > > > > /* Initialize stream info formats */ > > info.type = PJMEDIA_TYPE_AUDIO; > > info.dir = dir; > > pj_memcpy(&info.fmt, codec_info, > sizeof(pjmedia_codec_info)); > > info.tx_pt = codec_info->pt; > > info.rx_pt = codec_info->pt; > > info.ssrc = pj_rand(); /* each source have different > ssrc on multicast channel */ > > > > /* If remote address is not set, set to an arbitrary > address (otherwise stream will assert) */ > > if (info.rem_addr.addr.sa_family == 0) { > > const pj_str_t addr = > Utils::toPj_str("127.0.0.1"); > > pj_sockaddr_in_init(&info.rem_addr.ipv4, &addr, > 0); > > } > > > > pj_sockaddr_cp(&info.rem_rtcp, &info.rem_addr); > > pj_sockaddr_set_port(&info.rem_rtcp, > pj_sockaddr_get_port(&info.rem_rtcp) + 1); > > > > if (mcast) { > > pjmedia_sock_info si; > > int reuse = 1; > > > > pj_bzero(&si, sizeof(pjmedia_sock_info)); > > si.rtp_sock = si.rtcp_sock = PJ_INVALID_SOCKET; > > > > /* Create RTP socket */ > > status = pj_sock_socket(pj_AF_INET(), > pj_SOCK_DGRAM(), 0, &si.rtp_sock); > > if (status != PJ_SUCCESS) { return status; } > > > > status = pj_sock_setsockopt(si.rtp_sock, > pj_SOL_SOCKET(), pj_SO_REUSEADDR(), &reuse, sizeof(reuse)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Bind RTP socket */ > > status = pj_sockaddr_init(pj_AF_INET(), > &si.rtp_addr_name, NULL, local_port); > > if (status != PJ_SUCCESS) { return status; } > > > > status = pj_sock_bind(si.rtp_sock, > &si.rtp_addr_name, pj_sockaddr_get_len(&si.rtp_addr_name)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Create RTCP socket */ > > status = pj_sock_socket(pj_AF_INET(), > pj_SOCK_DGRAM(), 0, &si.rtcp_sock); > > if (status != PJ_SUCCESS) { return status; } > > > > status = pj_sock_setsockopt(si.rtcp_sock, > pj_SOL_SOCKET(), pj_SO_REUSEADDR(), &reuse, sizeof(reuse)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Bind RTCP socket */ > > status = pj_sockaddr_init(pj_AF_INET(), > &si.rtcp_addr_name, NULL, local_port + 1); > > if (status != PJ_SUCCESS) { return status; } > > > > status = pj_sock_bind(si.rtcp_sock, > &si.rtcp_addr_name, pj_sockaddr_get_len(&si.rtcp_addr_name)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* If have multicast */ > > unsigned char loop; > > struct pj_ip_mreq imr; > > > > pj_memset(&imr, 0, sizeof(struct pj_ip_mreq)); > > imr.imr_multiaddr.s_addr = > mcast_addr.sin_addr.s_addr; > > imr.imr_interface.s_addr = > pj_htonl(PJ_INADDR_ANY); > > > > status = pj_sock_setsockopt(si.rtp_sock, > pj_SOL_IP(), pj_IP_ADD_MEMBERSHIP(), &imr, sizeof(struct pj_ip_mreq)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* To manage rtcp */ > > status = pj_sock_setsockopt(si.rtcp_sock, > pj_SOL_IP(), pj_IP_ADD_MEMBERSHIP(), &imr, sizeof(struct pj_ip_mreq)); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Disable local reception of local sent packets > */ > > loop = 0; > > pj_sock_setsockopt(si.rtp_sock, pj_SOL_IP(), > pj_IP_MULTICAST_LOOP(), &loop, sizeof(loop)); > > pj_sock_setsockopt(si.rtcp_sock, pj_SOL_IP(), > pj_IP_MULTICAST_LOOP(), &loop, sizeof(loop)); > > > > /* Create media transport from existing sockets > */ > > status = pjmedia_transport_udp_attach(med_endpt, > "mcast2", &si, PJMEDIA_UDP_NO_SRC_ADDR_CHECKING, &transport); > > if (status != PJ_SUCCESS) { return status; } > > } > > > > /* Now that the stream info is initialized, we can > create the stream */ > > status = pjmedia_stream_create(med_endpt, poolMc, > &info, transport, NULL, &stream); > > if (status != PJ_SUCCESS) { > > pjmedia_transport_close(transport); > > return status; > > } > > else > > { > > /* Connect sound port to stream */ > > status = pjmedia_snd_port_connect(snd_port, > stream_port); > > if (status != PJ_SUCCESS) { return status; } > > > > /* Start streaming */ > > pjmedia_stream_start(stream); > > } > > > > } > > return PJ_SUCCESS; > > } > > > > Best Regards > > LL > > > > > > > > This body part will be downloaded on demand. > -- 1024D/A9F85A52 2000-01-18 Alain Totouom <totouom@xxxxxx> PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52 _______________________________________________ Visit our blog: http://blog.pjsip.org pjsip mailing list pjsip@xxxxxxxxxxxxxxx http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org