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