Create more than one pj_sock_socket for multicast connection - How to manage memory pool of pjmedia_endpoint

L
Lele
Fri, Jul 14, 2017 7:45 AM

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_endpt),
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

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_endpt), 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
AT
Alain Totouom
Wed, Jul 19, 2017 10:39 AM

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_endpt),
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@gmx.de
PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52

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_endpt), > 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@gmx.de> PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52
L
Lele
Thu, Jul 20, 2017 6:40 AM

Thanks,

It's working.

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?

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@gmx.de]
Inviato: Wednesday, July 19, 2017 12:39
A: pjsip list pjsip@lists.pjsip.org; Lele 86eldnl@gmail.com
Oggetto: Re: *** GMX Spamverdacht *** [pjsip] 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_endpt),
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  mailto:totouom@gmx.de
totouom@gmx.de
PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52

Thanks, It's working. 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? 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@gmx.de] Inviato: Wednesday, July 19, 2017 12:39 A: pjsip list <pjsip@lists.pjsip.org>; Lele <86eldnl@gmail.com> Oggetto: Re: *** GMX Spamverdacht *** [pjsip] 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_endpt), 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 <mailto:totouom@gmx.de> <totouom@gmx.de> PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52
AT
Alain Totouom
Thu, Jul 20, 2017 9:35 AM

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@gmx.de]
Inviato: Wednesday, July 19, 2017 12:39
A: pjsip list pjsip@lists.pjsip.org; Lele 86eldnl@gmail.com
Oggetto: Re: *** GMX Spamverdacht *** [pjsip] 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_endpt),
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@gmx.de
PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52

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@gmx.de] > Inviato: Wednesday, July 19, 2017 12:39 > A: pjsip list <pjsip@lists.pjsip.org>; Lele <86eldnl@gmail.com> > Oggetto: Re: *** GMX Spamverdacht *** [pjsip] 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_endpt), > 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@gmx.de> PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52
L
Lele
Thu, Jul 20, 2017 10:51 AM

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@gmx.de]
Inviato: Thursday, July 20, 2017 11:35
A: Lele 86eldnl@gmail.com; 'Alain Totouom' alain.totouom@gmx.de; 'pjsip list' pjsip@lists.pjsip.org
Oggetto: Re: [pjsip] 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@gmx.de]
Inviato: Wednesday, July 19, 2017 12:39
A: pjsip list pjsip@lists.pjsip.org; Lele 86eldnl@gmail.com
Oggetto: Re: *** GMX Spamverdacht *** [pjsip] 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@gmx.de
PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52

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@gmx.de] Inviato: Thursday, July 20, 2017 11:35 A: Lele <86eldnl@gmail.com>; 'Alain Totouom' <alain.totouom@gmx.de>; 'pjsip list' <pjsip@lists.pjsip.org> Oggetto: Re: [pjsip] 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@gmx.de] > Inviato: Wednesday, July 19, 2017 12:39 > A: pjsip list <pjsip@lists.pjsip.org>; Lele <86eldnl@gmail.com> > Oggetto: Re: *** GMX Spamverdacht *** [pjsip] 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@gmx.de> PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52
AT
Alain Totouom
Thu, Jul 20, 2017 12:01 PM

Hey,

you don't expect us to do your job for you, do you ;o)?

On 20.07.17 12:51, Lele wrote:

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.

Check the callbacks on_rx_rtp and on_rx_rtcp in [1]

Regards,
Alain

[1] http://www.pjsip.org/pjmedia/docs/html/page_pjmedia_samples_siprtp_c.htm

/*
---==================/
/
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@gmx.de]
Inviato: Thursday, July 20, 2017 11:35
A: Lele 86eldnl@gmail.com; 'Alain Totouom' alain.totouom@gmx.de; 'pjsip list' pjsip@lists.pjsip.org
Oggetto: Re: [pjsip] 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@gmx.de]
Inviato: Wednesday, July 19, 2017 12:39
A: pjsip list pjsip@lists.pjsip.org; Lele 86eldnl@gmail.com
Oggetto: Re: *** GMX Spamverdacht *** [pjsip] 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@gmx.de
PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52

Hey, you don't expect us to do your job for you, do you ;o)? On 20.07.17 12:51, Lele wrote: > 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. Check the callbacks *on_rx_rtp* and *on_rx_rtcp* in [1] Regards, Alain [1] http://www.pjsip.org/pjmedia/docs/html/page_pjmedia_samples_siprtp_c.htm > > /*===================================================*/ > /* 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@gmx.de] > Inviato: Thursday, July 20, 2017 11:35 > A: Lele <86eldnl@gmail.com>; 'Alain Totouom' <alain.totouom@gmx.de>; 'pjsip list' <pjsip@lists.pjsip.org> > Oggetto: Re: [pjsip] 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@gmx.de] >> Inviato: Wednesday, July 19, 2017 12:39 >> A: pjsip list <pjsip@lists.pjsip.org>; Lele <86eldnl@gmail.com> >> Oggetto: Re: *** GMX Spamverdacht *** [pjsip] 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@gmx.de> PGP Fingerprint DA18 0DF2 FBD2 5F67 0656 452D E3A2 7531 A9F8 5A52