Still looking into this - I thought the problem was the call to pjmedia_conf_destroy, but the segfault happens intermittently when I comment that call out. Maybe it's something in the stream/transport/media_port of the rtp stream that's going wrong? Or could it just be that I'm not deinitialising things properly? Any ideas? Here's the code I've been running: #define CHECK_PJ_RETURN(TEXT, INST) \ if ((pj_status = (INST)) != PJ_SUCCESS) \ { \ perror_pj(#INST, TEXT, pj_status); \ return !PJ_SUCCESS; \ } /* * play a .wav file over rtp through a conference bridge */ pj_status_t _test_pj_wav_to_rtp_conf( module_e module, const char *file, const char *ip, unsigned int port) { d_log(info, "starting audio services"); pj_status_t pj_status; /*************************** * * * 1 - initialisation * * * ***************************/ pj_caching_pool cp; pjmedia_endpt *endpt; pj_pool_t *pool; pjmedia_conf *conf; CHECK_PJ_EXCEPTION( "initiating pj library", pj_init() ); pj_caching_pool_init( &cp, &pj_pool_factory_default_policy, 0 /* no max capacity */); CHECK_PJ_EXCEPTION( "creating media endpoint", pjmedia_endpt_create( &cp.factory, NULL, 1, &endpt) ); CHECK_PJ_EXCEPTION( "initiating media codecs", init_all_pj_codecs(endpt)); pool = pj_pool_create( &cp.factory, "pool", 0x10000, 0x10000, NULL /* TODO: add callback */); CHECK_PJ_EXCEPTION( "creating conference bridge", pjmedia_conf_create( pool, DRIP_MAX_CONF_PORTS, CLOCK_SPKR, MONO /* TODO: change to STEREO */, SAMPLES_PER_FRAME(CLOCK_SPKR,MONO), BITS_PER_SAMPLE, PJMEDIA_CONF_SMALL_FILTER | PJMEDIA_CONF_USE_LINEAR, &conf) ); /*************************** * * * 2 - actual "work" * * * ***************************/ /* set up a wav player and stream ports */ pjmedia_stream *stream; pjmedia_port *file_port; pjmedia_port *stream_port; pj_sockaddr_in *sockaddr = get_pj_sockaddr_in(ip, port); CHECK_PJ_RETURN( "creating udp stream", create_pj_udp_stream( pool, endpt, RTP_PT_G711_A, PJMEDIA_DIR_ENCODING, 5004, sockaddr, false, &stream) ); CHECK_PJ_RETURN( "getting udp stream's media port interface", pjmedia_stream_get_port( stream, &stream_port) ); CHECK_PJ_RETURN( "starting stream", pjmedia_stream_start(stream)); CHECK_PJ_RETURN( "creating file port", pjmedia_wav_player_port_create( pool, file, PTIME_NEW(8000,MONO), NO_PJ_OPTIONS, 0, &file_port) ); /* add to conference bridge and connec */ unsigned int stream_slot; unsigned int file_slot; CHECK_PJ_RETURN( "adding stream port to conference bridge", pjmedia_conf_add_port( conf, pool, stream_port, NULL, &stream_slot) ); CHECK_PJ_RETURN( "adding file port to conference bridge", pjmedia_conf_add_port( conf, pool, file_port, NULL, &file_slot) ); CHECK_PJ_RETURN( "connecting ports in conference bridge", pjmedia_conf_connect_port( conf, file_slot, stream_slot, 0 /* future use */) ); /* wait for user input */ cout << "WAITING FOR USER INPUT" << endl; getchar(); /*************************** * * * 3 - deinitialistion * * * ***************************/ //pjmedia_stream_pause(stream, PJMEDIA_DIR_ENCODING_DECODING); pjmedia_conf_remove_port(conf, stream_slot); pjmedia_conf_remove_port(conf, file_slot); cout << "removed" << endl;sleep(1); pjmedia_transport *tp; tp = pjmedia_stream_get_transport(stream); cout << "...1" << endl;cout.flush(); pjmedia_stream_destroy(stream); cout << "...2" << endl;cout.flush(); pjmedia_transport_close(tp); cout << "...3" << endl;cout.flush(); pjmedia_conf_destroy(conf); cout << "...4" << endl;cout.flush(); pj_pool_release(pool); cout << "...5" << endl;cout.flush(); pjmedia_endpt_destroy(endpt); cout << "...6" << endl;cout.flush(); pj_caching_pool_destroy(&cp); cout << "...7" << endl;cout.flush(); pj_shutdown(); return PJ_SUCCESS; } /* * Creates an rtp stream */ pj_status_t _create_pj_udp_stream( module_e module, pj_pool_t *pool, pjmedia_endpt *endpt, unsigned int payload_type, //const pjmedia_codec_info *codec, pjmedia_dir dir, pj_uint16_t local_port, pj_sockaddr_in *sockaddr, bool check_udp_src, pjmedia_stream **stream ) throw (DripException) { pj_status_t pj_status; pjmedia_stream_info stream_info; pjmedia_transport *transport; const pjmedia_codec_info *codec_info; /* initialise info */ CHECK_PJ_RETURN( "getting codec information", pjmedia_codec_mgr_get_codec_info( pjmedia_endpt_get_codec_mgr(endpt), payload_type, &codec_info) ); pj_bzero(&stream_info, sizeof(stream_info)); stream_info.type = PJMEDIA_TYPE_AUDIO; stream_info.dir = dir; pj_memcpy(&stream_info.fmt, codec_info, sizeof(pjmedia_codec_info)); stream_info.tx_pt = codec_info->pt; stream_info.ssrc = pj_rand(); pj_memcpy(&stream_info.rem_addr, sockaddr, sizeof(pj_sockaddr_in)); if (stream_info.rem_addr.addr.sa_family == 0) { char *ad_chars = (char *)"127.0.0.1"; const pj_str_t ad = pj_str(ad_chars); pj_sockaddr_in_init(&stream_info.rem_addr.ipv4, &ad, 0); } /* create transport and stream */ CHECK_PJ_RETURN( "creating udp transport", pjmedia_transport_udp_create( endpt, NULL, // no name local_port, check_udp_src ? NO_PJ_OPTIONS : PJMEDIA_UDP_NO_SRC_ADDR_CHECKING, &transport ) ); CHECK_PJ_RETURN( "creating udp stream", pjmedia_stream_create( endpt, pool, &stream_info, transport, NULL, // no user data stream ) ); /* all ok */ d_log(mundane, "created udp stream ok"); return PJ_SUCCESS; }