pj_status_t pjmedia_format_id_to_PixelFormat(pjmedia_format_id fmt_id, enum AVPixelFormat *pixel_format) { unsigned i; for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_fmt_table); ++i) { const struct ffmpeg_fmt_table_t *t = &ffmpeg_fmt_table[i]; if (t->id==fmt_id && t->pf != AV(PIX_FMT_NONE)) { *pixel_format = t->pf; return PJ_SUCCESS; } } *pixel_format = AV(PIX_FMT_NONE); return PJ_ENOTFOUND; }
pj_status_t pjmedia_format_id_to_CodecID(pjmedia_format_id fmt_id, unsigned *codec_id) { unsigned i; for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_codec_table); ++i) { const struct ffmpeg_codec_table_t *t = &ffmpeg_codec_table[i]; if (t->id==fmt_id && t->codec_id != AV(PIX_FMT_NONE)) { *codec_id = t->codec_id; return PJ_SUCCESS; } } *codec_id = (unsigned)AV(PIX_FMT_NONE); return PJ_ENOTFOUND; }
/* * Set the user data associated with the buddy object. */ PJ_DEF(pj_status_t) pjsua_buddy_set_user_data( pjsua_buddy_id buddy_id, void *user_data) { PJ_ASSERT_RETURN(buddy_id>=0 && buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), PJ_EINVAL); PJSUA_LOCK(); pjsua_var.buddy[buddy_id].user_data = user_data; PJSUA_UNLOCK(); return PJ_SUCCESS; }
PJ_END_DECL const char* get_libsrtp_errstr(int err) { #if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0) static char *liberr[] = { "ok", /* err_status_ok = 0 */ "unspecified failure", /* err_status_fail = 1 */ "unsupported parameter", /* err_status_bad_param = 2 */ "couldn't allocate memory", /* err_status_alloc_fail = 3 */ "couldn't deallocate properly", /* err_status_dealloc_fail = 4 */ "couldn't initialize", /* err_status_init_fail = 5 */ "can't process as much data as requested", /* err_status_terminus = 6 */ "authentication failure", /* err_status_auth_fail = 7 */ "cipher failure", /* err_status_cipher_fail = 8 */ "replay check failed (bad index)", /* err_status_replay_fail = 9 */ "replay check failed (index too old)", /* err_status_replay_old = 10 */ "algorithm failed test routine", /* err_status_algo_fail = 11 */ "unsupported operation", /* err_status_no_such_op = 12 */ "no appropriate context found", /* err_status_no_ctx = 13 */ "unable to perform desired validation", /* err_status_cant_check = 14 */ "can't use key any more", /* err_status_key_expired = 15 */ "error in use of socket", /* err_status_socket_err = 16 */ "error in use POSIX signals", /* err_status_signal_err = 17 */ "nonce check failed", /* err_status_nonce_bad = 18 */ "couldn't read data", /* err_status_read_fail = 19 */ "couldn't write data", /* err_status_write_fail = 20 */ "error pasring data", /* err_status_parse_err = 21 */ "error encoding data", /* err_status_encode_err = 22 */ "error while using semaphores", /* err_status_semaphore_err = 23 */ "error while using pfkey" /* err_status_pfkey_err = 24 */ }; if (err >= 0 && err < (int)PJ_ARRAY_SIZE(liberr)) { return liberr[err]; } else { static char msg[32]; pj_ansi_snprintf(msg, sizeof(msg), "Unknown libsrtp error %d", err); return msg; } #else static char msg[32]; pj_ansi_snprintf(msg, sizeof(msg), "libsrtp error %d", err); return msg; #endif }
/* * Get the user data associated with the budy object. */ PJ_DEF(void*) pjsua_buddy_get_user_data(pjsua_buddy_id buddy_id) { void *user_data; PJ_ASSERT_RETURN(buddy_id>=0 && buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), NULL); PJSUA_LOCK(); user_data = pjsua_var.buddy[buddy_id].user_data; PJSUA_UNLOCK(); return user_data; }
static const struct alt_codec_desc* find_codec_desc_by_info(const pjmedia_vid_codec_info *info) { unsigned i; for (i=0; i<PJ_ARRAY_SIZE(alt_vid_codecs); ++i) { struct alt_codec_desc *desc = &alt_vid_codecs[i]; if ((desc->info.fmt_id == info->fmt_id) && ((desc->info.dir & info->dir) == info->dir) && (desc->info.pt == info->pt) && (desc->info.packings & info->packings)) { return desc; } } return NULL; }
/* Called when pjsua is started */ void PjsuaOnStarted(pj_status_t status, const char* title) { wchar_t wtitle[128]; char err_msg[128]; if (status != PJ_SUCCESS || title == NULL) { char err_str[PJ_ERR_MSG_SIZE]; pj_strerror(status, err_str, sizeof(err_str)); pj_ansi_snprintf(err_msg, sizeof(err_msg), "%s: %s", (title?title:"App start error"), err_str); title = err_msg; } pj_ansi_to_unicode(title, strlen(title), wtitle, PJ_ARRAY_SIZE(wtitle)); SetWindowText(g_hWndLbl, wtitle); }
static unsigned max_common_substr_len(const pj_str_t* str1, const pj_str_t* str2) { unsigned max_len = 0; /* We compare only on first MAX_COMPARE_LEN char */ unsigned tree[MAX_COMPARE_LEN][MAX_COMPARE_LEN]; unsigned m1=0, m2=0; int i=0, j=0; if(str1->slen == 0 || str2->slen == 0) { return 0; } /* Init tree */ for(i=0;i < MAX_COMPARE_LEN;i++) { pj_bzero(tree[i], PJ_ARRAY_SIZE( tree[i] )); } m1 = PJ_MIN(str1->slen, MAX_COMPARE_LEN); m2 = PJ_MIN(str2->slen, MAX_COMPARE_LEN); for (i = 0; i < m1; i++) { for (j = 0; j < m2; j++) { if (str1->ptr[i] != str2->ptr[j]) { tree[i][j] = 0; } else { if ((i == 0) || (j == 0)) { tree[i][j] = 1; } else { tree[i][j] = 1 + tree[i - 1][j - 1]; } if (tree[i][j] > max_len) { max_len = tree[i][j]; } } } } return max_len; }
static int vidport_test(void) { int i, j, k, l; int cap_id, rend_id; pjmedia_format_id test_fmts[] = { PJMEDIA_FORMAT_RGBA, PJMEDIA_FORMAT_I420 }; PJ_LOG(3, (THIS_FILE, " Video port tests:")); /* Capturer's role: active/passive. */ for (i = 1; i >= 0; i--) { /* Capturer's device has_callback: TRUE/FALSE. */ for (j = 1; j >= 0; j--) { cap_id = find_device(PJMEDIA_DIR_CAPTURE, j); if (cap_id < 0) continue; /* Renderer's device has callback: TRUE/FALSE. */ for (k = 1; k >= 0; k--) { rend_id = find_device(PJMEDIA_DIR_RENDER, k); if (rend_id < 0) continue; /* Check various formats to test format conversion. */ for (l = 0; l < PJ_ARRAY_SIZE(test_fmts); ++l) { pjmedia_format fmt; PJ_LOG(3,(THIS_FILE, "capturer %s (stream: %s) ===> " "renderer %s (stream: %s)", (i? "active": "passive"), (j? "active": "passive"), (i? "passive": "active"), (k? "active": "passive"))); pjmedia_format_init_video(&fmt, test_fmts[l], 640, 480, 25, 1); capture_render_loopback(i, cap_id, rend_id, &fmt); } } } } return 0; }
/* Register customized SDP format negotiation callback function. */ PJ_DEF(pj_status_t) pjmedia_sdp_neg_register_fmt_match_cb( const pj_str_t *fmt_name, pjmedia_sdp_neg_fmt_match_cb cb) { struct fmt_match_cb_t *f = NULL; unsigned i; PJ_ASSERT_RETURN(fmt_name, PJ_EINVAL); /* Check if the callback for the format name has been registered */ for (i = 0; i < fmt_match_cb_cnt; ++i) { if (pj_stricmp(fmt_name, &fmt_match_cb[i].fmt_name) == 0) break; } /* Unregistration */ if (cb == NULL) { if (i == fmt_match_cb_cnt) return PJ_ENOTFOUND; pj_array_erase(fmt_match_cb, sizeof(fmt_match_cb[0]), fmt_match_cb_cnt, i); fmt_match_cb_cnt--; return PJ_SUCCESS; } /* Registration */ if (i < fmt_match_cb_cnt) { /* The same format name has been registered before */ if (cb != fmt_match_cb[i].cb) return PJ_EEXISTS; else return PJ_SUCCESS; } if (fmt_match_cb_cnt >= PJ_ARRAY_SIZE(fmt_match_cb)) return PJ_ETOOMANY; f = &fmt_match_cb[fmt_match_cb_cnt++]; f->fmt_name = *fmt_name; f->cb = cb; return PJ_SUCCESS; }
/* * Init media stack. */ static pj_status_t init_media() { unsigned i; pj_uint16_t rtp_port; pj_status_t status; /* Initialize media endpoint so that at least error subsystem is properly * initialized. */ status = pjmedia_endpt_create(&app.cp.factory, pjsip_endpt_get_ioqueue(app.sip_endpt), 0, &app.med_endpt); PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); /* Must register all codecs to be supported */ pjmedia_codec_register_audio_codecs(app.med_endpt, NULL); /* Init dummy socket addresses */ app.skinfo_cnt = 0; for (i=0, rtp_port=4000; i<PJ_ARRAY_SIZE(app.skinfo); ++i, rtp_port+=2) { pjmedia_sock_info *skinfo; skinfo = &app.skinfo[i]; pj_sockaddr_in_init(&skinfo->rtp_addr_name.ipv4, &app.local_addr, (pj_uint16_t)rtp_port); pj_sockaddr_in_init(&skinfo->rtp_addr_name.ipv4, &app.local_addr, (pj_uint16_t)(rtp_port+1)); app.skinfo_cnt++; } /* Generate dummy SDP */ dummy_sdp_str.slen = pj_ansi_strlen(dummy_sdp_str.ptr); status = pjmedia_sdp_parse(app.pool, dummy_sdp_str.ptr, dummy_sdp_str.slen, &app.dummy_sdp); if (status != PJ_SUCCESS) { app_perror(THIS_FILE, "Error parsing dummy SDP", status); return status; } /* Done */ return PJ_SUCCESS; }
/* * Init presence */ pj_status_t pjsua_pres_init() { unsigned i; pj_status_t status; status = pjsip_endpt_register_module( pjsua_var.endpt, &mod_pjsua_pres); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to register pjsua presence module", status); } for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { reset_buddy(i); } return status; }
/* * Get transport type from name. */ PJ_DEF(pjsip_transport_type_e) pjsip_transport_get_type_from_name(const pj_str_t *name) { unsigned i; if (name->slen == 0) return PJSIP_TRANSPORT_UNSPECIFIED; /* Get transport type from name. */ for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { if (pj_stricmp(name, &transport_names[i].name) == 0) { return transport_names[i].type; } } pj_assert(!"Invalid transport name"); return PJSIP_TRANSPORT_UNSPECIFIED; }
std::vector<std::string> ip_utils::getAllIpInterface() { pj_sockaddr addrList[16]; unsigned addrCnt = PJ_ARRAY_SIZE(addrList); std::vector<std::string> ifaceList; if (pj_enum_ip_interface(pj_AF_UNSPEC(), &addrCnt, addrList) == PJ_SUCCESS) { for (unsigned i = 0; i < addrCnt; i++) { char addr[PJ_INET6_ADDRSTRLEN]; pj_sockaddr_print(&addrList[i], addr, sizeof(addr), 0); ifaceList.push_back(std::string(addr)); } } return ifaceList; }
static pj_status_t alt_vid_codec_enum_codecs( pjmedia_vid_codec_factory *factory, unsigned *count, pjmedia_vid_codec_info codecs[]) { unsigned i, max_cnt; PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL); max_cnt = PJ_MIN(*count, PJ_ARRAY_SIZE(alt_vid_codecs)); *count = 0; for (i=0; i<max_cnt; ++i) { pj_memcpy(&codecs[*count], &alt_vid_codecs[i].info, sizeof(pjmedia_vid_codec_info)); (*count)++; } return PJ_SUCCESS; }
PJ_DEF(const pjmedia_snd_dev_info*) pjmedia_snd_get_dev_info(unsigned index) { pjmedia_snd_dev_info *oi = &g_sys.info[g_sys.info_counter]; pjmedia_aud_dev_info di; g_sys.info_counter = (g_sys.info_counter+1) % PJ_ARRAY_SIZE(g_sys.info); if (pjmedia_aud_dev_get_info(index, &di) != PJ_SUCCESS) return NULL; pj_bzero(oi, sizeof(*oi)); pj_ansi_strncpy(oi->name, di.name, sizeof(oi->name)); oi->name[sizeof(oi->name)-1] = '\0'; oi->input_count = di.input_count; oi->output_count = di.output_count; oi->default_samples_per_sec = di.default_samples_per_sec; return oi; }
/* Register strerror handle. */ PJ_DEF(pj_status_t) pj_register_strerror( pj_status_t start, pj_status_t space, pj_error_callback f) { unsigned i; /* Check arguments. */ PJ_ASSERT_RETURN(start && space && f, PJ_EINVAL); /* Check if there aren't too many handlers registered. */ PJ_ASSERT_RETURN(err_msg_hnd_cnt < PJ_ARRAY_SIZE(err_msg_hnd), PJ_ETOOMANY); /* Start error must be greater than PJ_ERRNO_START_USER */ PJ_ASSERT_RETURN(start >= PJ_ERRNO_START_USER, PJ_EEXISTS); /* Check that no existing handler has covered the specified range. */ for (i=0; i<err_msg_hnd_cnt; ++i) { if (IN_RANGE(start, err_msg_hnd[i].begin, err_msg_hnd[i].end) || IN_RANGE(start+space-1, err_msg_hnd[i].begin, err_msg_hnd[i].end)) { if (err_msg_hnd[i].begin == start && err_msg_hnd[i].end == (start+space) && err_msg_hnd[i].strerror == f) { /* The same range and handler has already been registered */ return PJ_SUCCESS; } return PJ_EEXISTS; } } /* Register the handler. */ err_msg_hnd[err_msg_hnd_cnt].begin = start; err_msg_hnd[err_msg_hnd_cnt].end = start + space; err_msg_hnd[err_msg_hnd_cnt].strerror = f; ++err_msg_hnd_cnt; return PJ_SUCCESS; }
static int simple_uri_test(void) { unsigned i; pj_pool_t *pool; pj_status_t status; PJ_LOG(3,(THIS_FILE, " simple test")); for (i=0; i<PJ_ARRAY_SIZE(uri_test_array); ++i) { pool = pjsip_endpt_create_pool(endpt, "", POOL_SIZE, POOL_SIZE); status = do_uri_test(pool, &uri_test_array[i]); pjsip_endpt_release_pool(endpt, pool); if (status != PJ_SUCCESS) { PJ_LOG(3,(THIS_FILE, " error %d when testing entry %d", status, i)); return status; } } return 0; }
static pj_status_t alt_codec_enum_codecs(pjmedia_codec_factory *factory, unsigned *count, pjmedia_codec_info codecs[]) { unsigned i; for (i=0; i<*count && i<PJ_ARRAY_SIZE(codec_list); ++i) { struct alt_codec *ac = &codec_list[i]; pj_bzero(&codecs[i], sizeof(pjmedia_codec_info)); codecs[i].encoding_name = ac->encoding_name; codecs[i].pt = ac->payload_type; codecs[i].type = PJMEDIA_TYPE_AUDIO; codecs[i].clock_rate = ac->clock_rate; codecs[i].channel_cnt = ac->channel_cnt; } *count = i; return PJ_SUCCESS; }
static const openh264_codec_desc* find_codec_desc_by_info( const pjmedia_vid_codec_info *info) { int i; for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) { openh264_codec_desc *desc = &codec_desc[i]; if (desc->enabled && (desc->info.fmt_id == info->fmt_id) && ((desc->info.dir & info->dir) == info->dir) && (desc->info.pt == info->pt) && (desc->info.packings & info->packings)) { return desc; } } return NULL; }
/* * Enable/disable buddy's presence monitoring. */ PJ_DEF(pj_status_t) pjsua_buddy_subscribe_pres( pjsua_buddy_id buddy_id, pj_bool_t subscribe) { pjsua_buddy *buddy; PJ_ASSERT_RETURN(buddy_id>=0 && buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), PJ_EINVAL); PJSUA_LOCK(); buddy = &pjsua_var.buddy[buddy_id]; buddy->monitor = subscribe; PJSUA_UNLOCK(); pjsua_pres_refresh(); return PJ_SUCCESS; }
static void on_media_update(pjsip_inv_session *inv_ses, pj_status_t status) { PJ_UNUSED_ARG(status); if (inv_ses == inv_test.uas) { inv_test.uas_update_cnt++; pj_assert(inv_test.uas_update_cnt - inv_test.uac_update_cnt <= 1); TRACE_((THIS_FILE, " Callee media is established")); } else if (inv_ses == inv_test.uac) { inv_test.uac_update_cnt++; pj_assert(inv_test.uac_update_cnt - inv_test.uas_update_cnt <= 1); TRACE_((THIS_FILE, " Caller media is established")); } else { pj_assert(!"Unknown session!"); } if (inv_test.uac_update_cnt == inv_test.uas_update_cnt) { inv_test.oa_index++; if (inv_test.oa_index < inv_test.param.count) { switch (inv_test.param.oa[inv_test.oa_index]) { case OFFERER_UAC: jobs[job_cnt].type = SEND_OFFER; jobs[job_cnt].who = PJSIP_ROLE_UAC; job_cnt++; break; case OFFERER_UAS: jobs[job_cnt].type = SEND_OFFER; jobs[job_cnt].who = PJSIP_ROLE_UAS; job_cnt++; break; default: pj_assert(!"Invalid oa"); } } pj_assert(job_cnt <= PJ_ARRAY_SIZE(jobs)); } }
/* API: get capability name/info */ PJ_DEF(const char*) pjmedia_aud_dev_cap_name(pjmedia_aud_dev_cap cap, const char **p_desc) { const char *desc; unsigned i; if (p_desc==NULL) p_desc = &desc; for (i=0; i<PJ_ARRAY_SIZE(cap_infos); ++i) { if ((1 << i)==cap) break; } if (i==32) { *p_desc = "??"; return "??"; } *p_desc = cap_infos[i].info; return cap_infos[i].name; }
/* Timer callback to re-create client subscription */ static void pres_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry) { unsigned i; pj_time_val delay = { PJSUA_PRES_TIMER, 0 }; /* Retry failed PUBLISH requests */ for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) { pjsua_acc *acc = &pjsua_var.acc[i]; if (acc->cfg.publish_enabled && acc->publish_sess==NULL) pjsua_pres_init_publish_acc(acc->index); } entry->id = PJ_FALSE; refresh_client_subscriptions(); pjsip_endpt_schedule_timer(pjsua_var.endpt, entry, &delay); entry->id = PJ_TRUE; PJ_UNUSED_ARG(th); }
/* Called by application to initialize the transport */ static pj_status_t transport_attach( pjmedia_transport *tp, void *user_data, const pj_sockaddr_t *rem_addr, const pj_sockaddr_t *rem_rtcp, unsigned addr_len, void (*rtp_cb)(void*, void*, pj_ssize_t), void (*rtcp_cb)(void*, void*, pj_ssize_t)) { struct transport_loop *loop = (struct transport_loop*) tp; unsigned i; const pj_sockaddr *rtcp_addr; /* Validate arguments */ PJ_ASSERT_RETURN(tp && rem_addr && addr_len, PJ_EINVAL); /* Must not be "attached" to same user */ for (i=0; i<loop->user_cnt; ++i) { PJ_ASSERT_RETURN(loop->users[i].user_data != user_data, PJ_EINVALIDOP); } PJ_ASSERT_RETURN(loop->user_cnt != PJ_ARRAY_SIZE(loop->users), PJ_ETOOMANY); PJ_UNUSED_ARG(rem_rtcp); PJ_UNUSED_ARG(rtcp_addr); /* "Attach" the application: */ /* Save the new user */ loop->users[loop->user_cnt].rtp_cb = rtp_cb; loop->users[loop->user_cnt].rtcp_cb = rtcp_cb; loop->users[loop->user_cnt].user_data = user_data; ++loop->user_cnt; return PJ_SUCCESS; }
/* * Enum codecs supported by this factory. */ static pj_status_t openh264_enum_codecs( pjmedia_vid_codec_factory *factory, unsigned *count, pjmedia_vid_codec_info codecs[]) { unsigned i, max_cnt; PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL); PJ_ASSERT_RETURN(factory == &openh264_factory.base, PJ_EINVAL); max_cnt = PJ_MIN(*count, PJ_ARRAY_SIZE(codec_desc)); *count = 0; for (i=0; i<max_cnt; ++i) { if (codec_desc[i].enabled) { pj_memcpy(&codecs[*count], &codec_desc[i].info, sizeof(pjmedia_vid_codec_info)); (*count)++; } } return PJ_SUCCESS; }
/* * Destroy recorder (this will complete recording). */ PJ_DEF(pj_status_t) pjsua_sxs_switcher_destroy(pjsua_recorder_id id) { PJ_ASSERT_RETURN(id>=0 && id<(int)PJ_ARRAY_SIZE(pjsua_var.recorder), PJ_EINVAL); PJ_ASSERT_RETURN(pjsua_var.recorder[id].port != NULL, PJ_EINVAL); PJSUA_LOCK(); if (pjsua_var.recorder[id].port) { pjsua_conf_remove_port(pjsua_var.recorder[id].slot); pjmedia_port_destroy(pjsua_var.recorder[id].port); pjsua_var.recorder[id].port = NULL; pjsua_var.recorder[id].slot = 0xFFFF; pj_pool_release(pjsua_var.recorder[id].pool); pjsua_var.recorder[id].pool = NULL; pjsua_var.rec_cnt--; } PJSUA_UNLOCK(); return PJ_SUCCESS; }
/* * Enum buddy IDs. */ PJ_DEF(pj_status_t) pjsua_enum_buddies( pjsua_buddy_id ids[], unsigned *count) { unsigned i, c; PJ_ASSERT_RETURN(ids && count, PJ_EINVAL); PJSUA_LOCK(); for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { if (!pjsua_var.buddy[i].uri.slen) continue; ids[c] = i; ++c; } *count = c; PJSUA_UNLOCK(); return PJ_SUCCESS; }
/* It does what it says.. */ static void refresh_client_subscriptions(void) { unsigned i; LOCK_BUDDIES; for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) { if (!pjsua_var.buddy[i].uri.slen) continue; if (pjsua_var.buddy[i].monitor && !pjsua_var.buddy[i].sub) { subscribe_buddy_presence(i); } else if (!pjsua_var.buddy[i].monitor && pjsua_var.buddy[i].sub) { unsubscribe_buddy_presence(i); } } UNLOCK_BUDDIES; }
static int enum_codecs() { unsigned i, cnt; pjmedia_vid_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS]; pj_status_t status; PJ_LOG(3, (THIS_FILE, " codec enums")); cnt = PJ_ARRAY_SIZE(info); status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &cnt, info, NULL); if (status != PJ_SUCCESS) return 100; for (i = 0; i < cnt; ++i) { PJ_LOG(3, (THIS_FILE, " %-16.*s %c%c %s", info[i].encoding_name.slen, info[i].encoding_name.ptr, (info[i].dir & PJMEDIA_DIR_ENCODING? 'E' : ' '), (info[i].dir & PJMEDIA_DIR_DECODING? 'D' : ' '), dump_codec_info(&info[i]))); } return PJ_SUCCESS; }