예제 #1
0
/* API: find device */
PJ_DEF(pj_status_t) pjmedia_aud_dev_lookup( const char *drv_name,
					    const char *dev_name,
					    pjmedia_aud_dev_index *id)
{
    pjmedia_aud_dev_factory *f = NULL;
    unsigned drv_idx, dev_idx;

	PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
	//PJ_ASSERT_RETURN(aud_subsys.pf, PJMEDIA_EAUD_INIT);
	// DEAN don't assertion
	if (!aud_subsys.pf)
		return PJMEDIA_EAUD_INIT;

    for (drv_idx=0; drv_idx<aud_subsys.drv_cnt; ++drv_idx) {
	if (!pj_ansi_stricmp(drv_name, aud_subsys.drv[drv_idx].name)) {
	    f = aud_subsys.drv[drv_idx].f;
	    break;
	}
    }

    if (!f)
	{
		PJ_LOG(4, (THIS_FILE, "pjmedia_aud_dev_lookup() pjmedia_aud_dev_factory not found."));
		return PJ_ENOTFOUND;
	}

    for (dev_idx=0; dev_idx<aud_subsys.drv[drv_idx].dev_cnt; ++dev_idx) {
	pjmedia_aud_dev_info info;
	pj_status_t status;

	status = f->op->get_dev_info(f, dev_idx, &info);
	if (status != PJ_SUCCESS)
	    return status;

	if (!pj_ansi_stricmp(dev_name, info.name))
	    break;
    }

	if (dev_idx==aud_subsys.drv[drv_idx].dev_cnt)
	{
		PJ_LOG(4, (THIS_FILE, "pjmedia_aud_dev_lookup() aud_subsys.drv not found."));
		return PJ_ENOTFOUND;
	}

    *id = dev_idx;
    make_global_index(drv_idx, id);

    return PJ_SUCCESS;
}
예제 #2
0
/**
 * Get TAG reason code from pjsip_event
 */
int get_reason_code(pjsip_event *e, char* tag, int (*code_parser)(const char*)) {
	int code = 0;
	const pj_str_t HDR = { "Reason", 6 };
	pj_bool_t has_tag = PJ_FALSE;

	if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {

		pjsip_generic_string_hdr *hdr =
				(pjsip_generic_string_hdr*) pjsip_msg_find_hdr_by_name(
						e->body.tsx_state.src.rdata->msg_info.msg, &HDR, NULL);

		// TODO : check if the header should not be parsed here? -- I don't see how it could work without parsing.
		if (hdr) {
	        char *reason_header = strdup(hdr->hvalue.ptr);
			char *token = strtok(reason_header, ";");
			while (token != NULL) {
				if (!has_tag && pj_ansi_stricmp(token, tag) == 0) {
				    has_tag = PJ_TRUE;
				} else if (code == 0) {
				    code = code_parser(token);
				}
				token = strtok(NULL, ";");
			}
			free(reason_header);
		}
	}

	return (has_tag) ? code : 0;
}
예제 #3
0
/**
 * Get Q.850 reason code from pjsip_event
 */
int get_q850_reason_code(pjsip_event *e) {
	int cause = 0;
	const pj_str_t HDR = { "Reason", 6 };
	pj_bool_t is_q850 = PJ_FALSE;

	if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) {

		pjsip_generic_string_hdr *hdr =
				(pjsip_generic_string_hdr*) pjsip_msg_find_hdr_by_name(
						e->body.tsx_state.src.rdata->msg_info.msg, &HDR, NULL);

		if (hdr) {
			char *token = strtok(hdr->hvalue.ptr, ";");
			while (token != NULL) {
				if (!is_q850 && pj_ansi_stricmp(token, "Q.850") == 0) {
					is_q850 = PJ_TRUE;
				} else if (cause == 0) {
					cause = lookup_q850_cause(token);
				}
				token = strtok(NULL, ";");
			}
		}
	}

	return (is_q850) ? cause : 0;
}
예제 #4
0
/**
 * Utility to extract code from SIP cause
 */
int lookup_sip_cause(const char *cause) {
       if (pj_ansi_stricmp(cause, "cause=200") == 0) {
               return 200; // only useful reason code for now
       } else {
               return 0;
       }
}
예제 #5
0
/* API: find device */
PJ_DEF(pj_status_t) pjmedia_vid_dev_lookup( const char *drv_name,
					    const char *dev_name,
					    pjmedia_vid_dev_index *id)
{
    pjmedia_vid_dev_factory *f = NULL;
    unsigned drv_idx, dev_idx;

    PJ_ASSERT_RETURN(drv_name && dev_name && id, PJ_EINVAL);
    PJ_ASSERT_RETURN(vid_subsys.pf, PJMEDIA_EVID_INIT);

    for (drv_idx=0; drv_idx<vid_subsys.drv_cnt; ++drv_idx) {
	if (!pj_ansi_stricmp(drv_name, vid_subsys.drv[drv_idx].name))
	{
	    f = vid_subsys.drv[drv_idx].f;
	    break;
	}
    }

    if (!f)
	return PJ_ENOTFOUND;

    for (dev_idx=0; dev_idx<vid_subsys.drv[drv_idx].dev_cnt; ++dev_idx)
    {
	pjmedia_vid_dev_info info;
	pj_status_t status;

	status = f->op->get_dev_info(f, dev_idx, &info);
	if (status != PJ_SUCCESS)
	    return status;

	if (!pj_ansi_stricmp(dev_name, info.name))
	    break;
    }

    if (dev_idx==vid_subsys.drv[drv_idx].dev_cnt)
	return PJ_ENOTFOUND;

    *id = dev_idx;
    make_global_index(drv_idx, id);

    return PJ_SUCCESS;
}
예제 #6
0
static pj_bool_t parse_test_headers(char *line, test_param_t *param, 
			       test_cond_t *cond)
{
    char *p = line;

    if (*p == '%') {
	/* Test params. */
	char mode_st[16];

	sscanf(p+1, "%s %u %u %u", mode_st, &param->init_prefetch, 
	       &param->min_prefetch, &param->max_prefetch);
	param->adaptive = (pj_ansi_stricmp(mode_st, "adaptive") == 0);

    } else if (*p == '!') {
	/* Success condition. */
	char cond_st[16];
	unsigned cond_val;

	sscanf(p+1, "%s %u", cond_st, &cond_val);
	if (pj_ansi_stricmp(cond_st, "burst") == 0)
	    cond->burst = cond_val;
	else if (pj_ansi_stricmp(cond_st, "delay") == 0)
	    cond->delay = cond_val;
	else if (pj_ansi_stricmp(cond_st, "delay_min") == 0)
	    cond->delay_min = cond_val;
	else if (pj_ansi_stricmp(cond_st, "discard") == 0)
	    cond->discard = cond_val;
	else if (pj_ansi_stricmp(cond_st, "empty") == 0)
	    cond->empty = cond_val;
	else if (pj_ansi_stricmp(cond_st, "lost") == 0)
	    cond->lost = cond_val;

    } else if (*p == '=') {
	/* Test title. */
	++p;
	while (*p && isspace(*p)) ++p;
	printf("%s", p);

    } else if (*p == '#') {
	/* Ignore comment line. */

    } else {
	/* Unknown header, perhaps this is the test data */

	/* Skip spaces */
	while (*p && isspace(*p)) ++p;

	/* Test data started.*/
	if (*p != 0)
	    return PJ_FALSE;
    }

    return PJ_TRUE;
}
/* Get cipher identifier */
PJ_DEF(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name)
{
    unsigned i;
    
    if (ciphers_num_ == 0) {
	pj_ssl_cipher c[1];
	i = 0;
	pj_ssl_cipher_get_availables(c, &i);
    }
    
    for (i = 0; i < ciphers_num_; ++i) {
        if (!pj_ansi_stricmp(ciphers_[i].name, cipher_name))
            return ciphers_[i].id;
    }

    return PJ_TLS_UNKNOWN_CIPHER;
}
예제 #8
0
/**
 * Utility from freeswitch to extract code from q.850 cause
 */
int lookup_q850_cause(const char *cause) {
	// Taken from http://wiki.freeswitch.org/wiki/Hangup_causes
	if (pj_ansi_stricmp(cause, "cause=1") == 0) {
		return 404;
	} else if (pj_ansi_stricmp(cause, "cause=2") == 0) {
		return 404;
	} else if (pj_ansi_stricmp(cause, "cause=3") == 0) {
		return 404;
	} else if (pj_ansi_stricmp(cause, "cause=17") == 0) {
		return 486;
	} else if (pj_ansi_stricmp(cause, "cause=18") == 0) {
		return 408;
	} else if (pj_ansi_stricmp(cause, "cause=19") == 0) {
		return 480;
	} else if (pj_ansi_stricmp(cause, "cause=20") == 0) {
		return 480;
	} else if (pj_ansi_stricmp(cause, "cause=21") == 0) {
		return 603;
	} else if (pj_ansi_stricmp(cause, "cause=22") == 0) {
		return 410;
	} else if (pj_ansi_stricmp(cause, "cause=23") == 0) {
		return 410;
	} else if (pj_ansi_stricmp(cause, "cause=25") == 0) {
		return 483;
	} else if (pj_ansi_stricmp(cause, "cause=27") == 0) {
		return 502;
	} else if (pj_ansi_stricmp(cause, "cause=28") == 0) {
		return 484;
	} else if (pj_ansi_stricmp(cause, "cause=29") == 0) {
		return 501;
	} else if (pj_ansi_stricmp(cause, "cause=31") == 0) {
		return 480;
	} else if (pj_ansi_stricmp(cause, "cause=34") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=38") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=41") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=42") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=44") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=52") == 0) {
		return 403;
	} else if (pj_ansi_stricmp(cause, "cause=54") == 0) {
		return 403;
	} else if (pj_ansi_stricmp(cause, "cause=57") == 0) {
		return 403;
	} else if (pj_ansi_stricmp(cause, "cause=58") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=65") == 0) {
		return 488;
	} else if (pj_ansi_stricmp(cause, "cause=69") == 0) {
		return 501;
	} else if (pj_ansi_stricmp(cause, "cause=79") == 0) {
		return 501;
	} else if (pj_ansi_stricmp(cause, "cause=88") == 0) {
		return 488;
	} else if (pj_ansi_stricmp(cause, "cause=102") == 0) {
		return 504;
	} else if (pj_ansi_stricmp(cause, "cause=487") == 0) {
		return 487;
	} else {
		return 0;
	}
}
예제 #9
0
/* Parse crypto attribute line */
static pj_status_t parse_attr_crypto(pj_pool_t *pool,
				     const pjmedia_sdp_attr *attr,
				     pjmedia_srtp_crypto *crypto,
				     int *tag)
{
    pj_str_t input;
    char *token;
    int token_len;
    pj_str_t tmp;
    pj_status_t status;
    int itmp;

    pj_bzero(crypto, sizeof(*crypto));
    pj_strdup_with_null(pool, &input, &attr->value);

    /* Tag */
    token = strtok(input.ptr, " ");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting tag"));
	return PJMEDIA_SDP_EINATTR;
    }
    token_len = pj_ansi_strlen(token);

    /* Tag must not use leading zeroes. */
    if (token_len > 1 && *token == '0')
	return PJMEDIA_SDP_EINATTR;

    /* Tag must be decimal, i.e: contains only digit '0'-'9'. */
    for (itmp = 0; itmp < token_len; ++itmp)
	if (!pj_isdigit(token[itmp]))
	    return PJMEDIA_SDP_EINATTR;

    /* Get tag value. */
    *tag = atoi(token);

    /* Crypto-suite */
    token = strtok(NULL, " ");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting crypto suite"));
	return PJMEDIA_SDP_EINATTR;
    }
    crypto->name = pj_str(token);

    /* Key method */
    token = strtok(NULL, ":");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key method"));
	return PJMEDIA_SDP_EINATTR;
    }
    if (pj_ansi_stricmp(token, "inline")) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto key method '%s' not supported!",
	          token));
	return PJMEDIA_SDP_EINATTR;
    }

    /* Key */
    token = strtok(NULL, "| ");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key"));
	return PJMEDIA_SDP_EINATTR;
    }
    tmp = pj_str(token);
    crypto->key.ptr = (char*) pj_pool_zalloc(pool, MAX_KEY_LEN);

    /* Decode key */
    itmp = MAX_KEY_LEN;
    status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr, 
			      &itmp);
    if (status != PJ_SUCCESS) {
	PJ_LOG(4,(THIS_FILE, "Failed decoding crypto key from base64"));
	return status;
    }
    crypto->key.slen = itmp;

    return PJ_SUCCESS;
}
예제 #10
0
static int encode_decode_test(pj_pool_t *pool, const char *codec_id,
                              pjmedia_vid_packing packing)
{
    const pj_str_t port_name = {"codec", 5};

    pjmedia_vid_codec *codec=NULL;
    pjmedia_port codec_port;
    codec_port_data_t codec_port_data;
    pjmedia_vid_codec_param codec_param;
    const pjmedia_vid_codec_info *codec_info;
    const char *packing_name;
    pjmedia_vid_dev_index cap_idx, rdr_idx;
    pjmedia_vid_port *capture=NULL, *renderer=NULL;
    pjmedia_vid_port_param vport_param;
    pjmedia_video_format_detail *vfd;
    char codec_name[5];
    pj_status_t status;
    int rc = 0;

    switch (packing) {
    case PJMEDIA_VID_PACKING_PACKETS:
        packing_name = "framed";
        break;
    case PJMEDIA_VID_PACKING_WHOLE:
        packing_name = "whole";
        break;
    default:
        packing_name = "unknown";
        break;
    }

    PJ_LOG(3, (THIS_FILE, "  encode decode test: codec=%s, packing=%s",
               codec_id, packing_name));

    /* Lookup codec */
    {
        pj_str_t codec_id_st;
        unsigned info_cnt = 1;

        /* Lookup codec */
        pj_cstr(&codec_id_st, codec_id);
        status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &codec_id_st,
                 &info_cnt,
                 &codec_info, NULL);
        if (status != PJ_SUCCESS) {
            rc = 205;
            goto on_return;
        }
    }


#if CAPTURE_DEV == -1
    /* Lookup colorbar source */
    status = pjmedia_vid_dev_lookup("Colorbar", "Colorbar generator", &cap_idx);
    if (status != PJ_SUCCESS) {
        rc = 206;
        goto on_return;
    }
#elif CAPTURE_DEV == -2
    /* Lookup any first non-colorbar source */
    {
        unsigned i, cnt;
        pjmedia_vid_dev_info info;

        cap_idx = -1;
        cnt = pjmedia_vid_dev_count();
        for (i = 0; i < cnt; ++i) {
            status = pjmedia_vid_dev_get_info(i, &info);
            if (status != PJ_SUCCESS) {
                rc = 206;
                goto on_return;
            }
            if (info.dir & PJMEDIA_DIR_CAPTURE &&
                    pj_ansi_stricmp(info.driver, "Colorbar"))
            {
                cap_idx = i;
                break;
            }
        }

        if (cap_idx == -1) {
            status = PJ_ENOTFOUND;
            rc = 206;
            goto on_return;
        }
    }
#else
    cap_idx = CAPTURE_DEV;
#endif

    /* Lookup SDL renderer */
    status = pjmedia_vid_dev_lookup("SDL", "SDL renderer", &rdr_idx);
    if (status != PJ_SUCCESS) {
        rc = 207;
        goto on_return;
    }

    /* Prepare codec */
    {
        pj_str_t codec_id_st;
        unsigned info_cnt = 1;
        const pjmedia_vid_codec_info *codec_info;

        /* Lookup codec */
        pj_cstr(&codec_id_st, codec_id);
        status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &codec_id_st,
                 &info_cnt,
                 &codec_info, NULL);
        if (status != PJ_SUCCESS) {
            rc = 245;
            goto on_return;
        }
        status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
                 &codec_param);
        if (status != PJ_SUCCESS) {
            rc = 246;
            goto on_return;
        }

        codec_param.packing = packing;

        /* Open codec */
        status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
                 &codec);
        if (status != PJ_SUCCESS) {
            rc = 250;
            goto on_return;
        }

        status = pjmedia_vid_codec_init(codec, pool);
        if (status != PJ_SUCCESS) {
            rc = 251;
            goto on_return;
        }

        status = pjmedia_vid_codec_open(codec, &codec_param);
        if (status != PJ_SUCCESS) {
            rc = 252;
            goto on_return;
        }

        /* After opened, codec will update the param, let's sync encoder &
         * decoder format detail.
         */
        codec_param.dec_fmt.det = codec_param.enc_fmt.det;

        /* Subscribe to codec events */
        pjmedia_event_subscribe(NULL, &codec_on_event, &codec_port_data,
                                codec);
    }

    pjmedia_vid_port_param_default(&vport_param);

    /* Create capture, set it to active (master) */
    status = pjmedia_vid_dev_default_param(pool, cap_idx,
                                           &vport_param.vidparam);
    if (status != PJ_SUCCESS) {
        rc = 220;
        goto on_return;
    }
    pjmedia_format_copy(&vport_param.vidparam.fmt, &codec_param.dec_fmt);
    vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
    vport_param.active = PJ_TRUE;

    if (vport_param.vidparam.fmt.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO) {
        rc = 221;
        goto on_return;
    }

    vfd = pjmedia_format_get_video_format_detail(&vport_param.vidparam.fmt,
            PJ_TRUE);
    if (vfd == NULL) {
        rc = 225;
        goto on_return;
    }

    status = pjmedia_vid_port_create(pool, &vport_param, &capture);
    if (status != PJ_SUCCESS) {
        rc = 226;
        goto on_return;
    }

    /* Create renderer, set it to passive (slave)  */
    vport_param.active = PJ_FALSE;
    vport_param.vidparam.dir = PJMEDIA_DIR_RENDER;
    vport_param.vidparam.rend_id = rdr_idx;
    vport_param.vidparam.disp_size = vfd->size;

    status = pjmedia_vid_port_create(pool, &vport_param, &renderer);
    if (status != PJ_SUCCESS) {
        rc = 230;
        goto on_return;
    }

    /* Init codec port */
    pj_bzero(&codec_port, sizeof(codec_port));
    status = pjmedia_port_info_init2(&codec_port.info, &port_name, 0x1234,
                                     PJMEDIA_DIR_ENCODING,
                                     &codec_param.dec_fmt);
    if (status != PJ_SUCCESS) {
        rc = 260;
        goto on_return;
    }

    codec_port_data.codec = codec;
    codec_port_data.rdr_port = renderer;
    codec_port_data.enc_buf_size = codec_param.dec_fmt.det.vid.size.w *
                                   codec_param.dec_fmt.det.vid.size.h * 4;
    codec_port_data.enc_buf = pj_pool_alloc(pool,
                                            codec_port_data.enc_buf_size);
    codec_port_data.pack_buf_size = codec_port_data.enc_buf_size;
    codec_port_data.pack_buf = pj_pool_alloc(pool,
                               codec_port_data.pack_buf_size);

    codec_port.put_frame = &codec_put_frame;
    codec_port.port_data.pdata = &codec_port_data;

    /* Connect capture to codec port */
    status = pjmedia_vid_port_connect(capture,
                                      &codec_port,
                                      PJ_FALSE);
    if (status != PJ_SUCCESS) {
        rc = 270;
        goto on_return;
    }

    PJ_LOG(3, (THIS_FILE, "    starting codec test: %s<->%.*s %dx%d",
               pjmedia_fourcc_name(codec_param.dec_fmt.id, codec_name),
               codec_info->encoding_name.slen,
               codec_info->encoding_name.ptr,
               codec_param.dec_fmt.det.vid.size.w,
               codec_param.dec_fmt.det.vid.size.h
              ));

    /* Start streaming.. */
    status = pjmedia_vid_port_start(renderer);
    if (status != PJ_SUCCESS) {
        rc = 275;
        goto on_return;
    }
    status = pjmedia_vid_port_start(capture);
    if (status != PJ_SUCCESS) {
        rc = 280;
        goto on_return;
    }

    /* Sleep while the video is being displayed... */
    pj_thread_sleep(10000);

on_return:
    if (status != PJ_SUCCESS) {
        PJ_PERROR(3, (THIS_FILE, status, "  error"));
    }
    if (capture)
        pjmedia_vid_port_stop(capture);
    if (renderer)
        pjmedia_vid_port_stop(renderer);
    if (capture)
        pjmedia_vid_port_destroy(capture);
    if (renderer)
        pjmedia_vid_port_destroy(renderer);
    if (codec) {
        pjmedia_event_unsubscribe(NULL, &codec_on_event, &codec_port_data,
                                  codec);
        pjmedia_vid_codec_close(codec);
        pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec);
    }

    return rc;
}
예제 #11
0
파일: vid_codec.c 프로젝트: k2gadu/sip-ptt
/*
 * Set default codec parameter.
 */
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_set_default_param( 
					    pjmedia_vid_codec_mgr *mgr,
					    const pjmedia_vid_codec_info *info,
					    const pjmedia_vid_codec_param *param )
{
    unsigned i;
    pjmedia_codec_id codec_id;
    pjmedia_vid_codec_desc *codec_desc = NULL;
    pj_pool_t *pool, *old_pool = NULL;
    pjmedia_vid_codec_default_param *p;

    PJ_ASSERT_RETURN(info, PJ_EINVAL);

    if (!mgr) mgr = def_vid_codec_mgr;
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);

    if (!pjmedia_vid_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id)))
	return PJ_EINVAL;

    pj_mutex_lock(mgr->mutex);

    /* Lookup codec desc */
    for (i=0; i < mgr->codec_cnt; ++i) {
	if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {
	    codec_desc = &mgr->codec_desc[i];
	    break;
	}
    }

    /* Codec not found */
    if (!codec_desc) {
	pj_mutex_unlock(mgr->mutex);
	return PJMEDIA_CODEC_EUNSUP;
    }

    /* If codec param is previously set */
    if (codec_desc->def_param) {
	pj_assert(codec_desc->def_param->pool);
        old_pool = codec_desc->def_param->pool;
	codec_desc->def_param = NULL;
    }

    /* When param is set to NULL, i.e: setting default codec param to library
     * default setting, just return PJ_SUCCESS.
     */
    if (NULL == param) {
	pj_mutex_unlock(mgr->mutex);
        if (old_pool)
	    pj_pool_release(old_pool);
	return PJ_SUCCESS;
    }

    /* Create new default codec param instance */
    pool = pj_pool_create(mgr->pf, (char*)codec_id, 256, 256, NULL);
    codec_desc->def_param = PJ_POOL_ZALLOC_T(pool,
					     pjmedia_vid_codec_default_param);
    p = codec_desc->def_param;
    p->pool = pool;

    /* Update codec default param */
    p->param = pjmedia_vid_codec_param_clone(pool, param);
    if (!p)
	return PJ_EINVAL;
    codec_desc->def_param = p;

    pj_mutex_unlock(mgr->mutex);

    return PJ_SUCCESS;
}
예제 #12
0
파일: vid_codec.c 프로젝트: k2gadu/sip-ptt
/*
 * Get default codec parameter.
 */
PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_get_default_param(
                                        pjmedia_vid_codec_mgr *mgr,
					const pjmedia_vid_codec_info *info,
					pjmedia_vid_codec_param *param )
{
    pjmedia_vid_codec_factory *factory;
    pj_status_t status;
    pjmedia_codec_id codec_id;
    pjmedia_vid_codec_desc *codec_desc = NULL;
    unsigned i;

    PJ_ASSERT_RETURN(info && param, PJ_EINVAL);

    if (!mgr) mgr = def_vid_codec_mgr;
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);

    if (!pjmedia_vid_codec_info_to_id(info, (char*)&codec_id, 
                                      sizeof(codec_id)))
	return PJ_EINVAL;

    pj_mutex_lock(mgr->mutex);

    /* First, lookup default param in codec desc */
    for (i=0; i < mgr->codec_cnt; ++i) {
	if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {
	    codec_desc = &mgr->codec_desc[i];
	    break;
	}
    }

    /* If we found the codec and its default param is set, return it */
    if (codec_desc && codec_desc->def_param) {
	pj_memcpy(param, codec_desc->def_param->param, 
		  sizeof(pjmedia_vid_codec_param));

	pj_mutex_unlock(mgr->mutex);
	return PJ_SUCCESS;
    }

    /* Otherwise query the default param from codec factory */
    factory = mgr->factory_list.next;
    while (factory != &mgr->factory_list) {

	if ( (*factory->op->test_alloc)(factory, info) == PJ_SUCCESS ) {

	    status = (*factory->op->default_attr)(factory, info, param);
	    if (status == PJ_SUCCESS) {
		/* Check for invalid max_bps. */
		//if (param->info.max_bps < param->info.avg_bps)
		//    param->info.max_bps = param->info.avg_bps;

		pj_mutex_unlock(mgr->mutex);
		return PJ_SUCCESS;
	    }

	}

	factory = factory->next;
    }

    pj_mutex_unlock(mgr->mutex);


    return PJMEDIA_CODEC_EUNSUP;
}
예제 #13
0
/*
 * Decode test
 *
 * Decode the specified encoded file in "in_encoded_file" into temporary
 * PCM output file, and compare the temporary PCM output file with
 * the PCM reference file.
 *
 * Some reference file requires manipulation to the PCM output
 * before comparison, such manipulation can be done by supplying
 * this function with the "manip" function.
 */
static int codec_test_decode(pjmedia_codec_mgr *mgr, 
			     char *codec_name, 
			     unsigned bitrate,
			     unsigned encoded_len,
			     const char *in_encoded_file,
			     const char *ref_pcm_file,
			     void (*manip)(short *pcm, unsigned count))
{
    pj_str_t codec_id = pj_str(codec_name);
    pj_pool_t *pool = NULL;
    unsigned count, samples_per_frame, pos;
    pjmedia_codec *codec = NULL;
    const pjmedia_codec_info *ci[1];
    pjmedia_codec_param codec_param;
    pjmedia_frame out_frame;
    void *pkt;
    FILE *input = NULL, *output = NULL, *fref = NULL;
    pj_bool_t is_itu_format = PJ_FALSE;
    int rc = 0;
    pj_status_t status;

    pool = pj_pool_create(mem, "codec-vectors", 512, 512, NULL);
    if (!pool)  {
	rc = -20;
	goto on_return;
    }

    /* Find and open the codec */
    count = 1;
    status = pjmedia_codec_mgr_find_codecs_by_id(mgr, &codec_id, &count, ci, NULL);
    if (status != PJ_SUCCESS) {
	rc = -30;
	goto on_return;
    }

    status = pjmedia_codec_mgr_alloc_codec(mgr, ci[0], &codec);
    if (status != PJ_SUCCESS) {
	rc = -40;
	goto on_return;
    }

    status = pjmedia_codec_mgr_get_default_param(mgr, ci[0], &codec_param);
    if (status != PJ_SUCCESS) {
	rc = -50;
	goto on_return;
    }

    codec_param.info.avg_bps = bitrate;
    codec_param.setting.vad = 0;

    /* For G7221, the bitrate is set via param.setting.dec_fmtp, if it has
     * no info about bitrate, the codec will check info.avg_bps. So, let's
     * just clear the SDP fmtp.
     */
    if (pj_ansi_strstr(codec_name, "G7221/")) {
	codec_param.setting.dec_fmtp.cnt = 0;
    }

    status = pjmedia_codec_init(codec, pool);
    if (status != PJ_SUCCESS) {
	rc = -60;
	goto on_return;
    }

    status = pjmedia_codec_open(codec, &codec_param);
    if (status != PJ_SUCCESS) {
	rc = -70;
	goto on_return;
    }

    /* Open input file */
    input = fopen(in_encoded_file, "rb");
    if (!input) {
	rc = -80;
	goto on_return;
    }

    /* Is the file in ITU format? */
    is_itu_format = pj_ansi_stricmp(in_encoded_file+strlen(in_encoded_file)-4,
				    ".itu")==0;

    /* Open output file */
    output = fopen(TMP_OUT, "wb");
    if (!output) {
	rc = -90;
	goto on_return;
    }

    /* Allocate buffer for PCM and encoded frames */
    samples_per_frame = codec_param.info.clock_rate * codec_param.info.frm_ptime / 1000;
    pkt = pj_pool_alloc(pool, samples_per_frame * 2);
    out_frame.buf = (pj_uint8_t*) pj_pool_alloc(pool, samples_per_frame * 2);

    /* Loop read WAV file and encode and write to output file */
    for (;;) {
	pjmedia_frame in_frame[2];
	pj_timestamp ts;
	unsigned count;
	pj_bool_t has_frame;

	if (is_itu_format) {
	    int nsamp;
	    short frame_err = 0;

	    nsamp = read_ITU_format(input, (short*)pkt, &frame_err,
				    encoded_len / 2, PJ_TRUE);
	    if (nsamp != (int)encoded_len / 2)
		break;

	    has_frame = !frame_err;
	} else {
	    if (fread(pkt, encoded_len, 1, input) != 1)
		break;

	    has_frame = PJ_TRUE;
	}

	if (has_frame) {
	    count = 2;
	    if (pjmedia_codec_parse(codec, pkt, encoded_len, &ts, 
				    &count, in_frame) != PJ_SUCCESS) 
	    {
		rc = -100;
		goto on_return;
	    }

	    if (count != 1) {
		rc = -110;
		goto on_return;
	    }

	    if (pjmedia_codec_decode(codec, &in_frame[0], samples_per_frame*2,
				     &out_frame) != PJ_SUCCESS) 
	    {
		rc = -120;
		goto on_return;
	    }
	} else {
	    if (pjmedia_codec_recover(codec, samples_per_frame*2, 
				      &out_frame) != PJ_SUCCESS)
	    {
		rc = -125;
		goto on_return;
	    }
	}

	if (manip)
	    manip((short*)out_frame.buf, samples_per_frame);

	if (fwrite(out_frame.buf, out_frame.size, 1, output) != 1) {
	    rc = -130;
	    goto on_return;
	}
    }

    fclose(input);
    input = NULL;

    fclose(output);
    output = NULL;
    
    /* Compare encoded files */
    fref = fopen(ref_pcm_file, "rb");
    if (!fref) {
	rc = -140;
	goto on_return;
    }

    output = fopen(TMP_OUT, "rb");
    if (!output) {
	rc = -110;
	goto on_return;
    }

    pos = 0;
    for (;;) {
	pj_size_t count;
	
	count = fread(pkt, samples_per_frame*2, 1, fref);
	if (count != 1)
	    break;

	count = fread(out_frame.buf, samples_per_frame*2, 1, output);
	if (count != 1)
	    break;

	if (memcmp(pkt, out_frame.buf, samples_per_frame*2)) {
	    unsigned i;
	    pj_int16_t *in = (pj_int16_t*)pkt;
	    pj_int16_t *out = (pj_int16_t*)out_frame.buf;

	    for (i=0; i<samples_per_frame; ++i) {
		if (in[i] != out[i])
		    break;
	    }

	    PJ_LOG(1,(THIS_FILE,"     failed: mismatch at samples %d", pos+i));
	    rc = -200;
	    break;
	}

	pos += samples_per_frame;
    }

on_return:
    if (output)
	fclose(output);

    if (fref)
	fclose(fref);

    if (input)
	fclose(input);

    if (codec) {
	pjmedia_codec_close(codec);
	pjmedia_codec_mgr_dealloc_codec(mgr, codec);
    }

    if (pool)
	pj_pool_release(pool);

    return rc;
}
예제 #14
0
/**
 * Utility from freeswitch to extract code from q.850 cause
 */
int lookup_q850_cause(const char *cause) {

  // VoX Mobile
  //
  // Re-purposed Q.850 codes that are necessary for prepaid services.
  if (pj_ansi_stricmp(cause, "cause=602") == 0) {
    // prepaid caller credit card was declined
    return 901;
  } else if (pj_ansi_stricmp(cause, "cause=603") == 0) {
    // prepaid caller out cash, called location requires cash
    return 902;
  } else if (pj_ansi_stricmp(cause, "cause=604") == 0) {
    // prepaid caller out of funds (minutes and cash)
    return 903;
  }

	// Taken from http://wiki.freeswitch.org/wiki/Hangup_causes
	if (pj_ansi_stricmp(cause, "cause=1") == 0) {
		return 404;
	} else if (pj_ansi_stricmp(cause, "cause=2") == 0) {
		return 404;
	} else if (pj_ansi_stricmp(cause, "cause=3") == 0) {
		return 404;
	} else if (pj_ansi_stricmp(cause, "cause=17") == 0) {
		return 486;
	} else if (pj_ansi_stricmp(cause, "cause=18") == 0) {
		return 408;
	} else if (pj_ansi_stricmp(cause, "cause=19") == 0) {
		return 480;
	} else if (pj_ansi_stricmp(cause, "cause=20") == 0) {
		return 480;
	} else if (pj_ansi_stricmp(cause, "cause=21") == 0) {
		return 603;
	} else if (pj_ansi_stricmp(cause, "cause=22") == 0) {
		return 410;
	} else if (pj_ansi_stricmp(cause, "cause=23") == 0) {
		return 410;
	} else if (pj_ansi_stricmp(cause, "cause=25") == 0) {
		return 483;
	} else if (pj_ansi_stricmp(cause, "cause=27") == 0) {
		return 502;
	} else if (pj_ansi_stricmp(cause, "cause=28") == 0) {
		return 484;
	} else if (pj_ansi_stricmp(cause, "cause=29") == 0) {
		return 501;
	} else if (pj_ansi_stricmp(cause, "cause=31") == 0) {
		return 480;
	} else if (pj_ansi_stricmp(cause, "cause=34") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=38") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=41") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=42") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=44") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=52") == 0) {
		return 403;
	} else if (pj_ansi_stricmp(cause, "cause=54") == 0) {
		return 403;
	} else if (pj_ansi_stricmp(cause, "cause=57") == 0) {
		return 403;
	} else if (pj_ansi_stricmp(cause, "cause=58") == 0) {
		return 503;
	} else if (pj_ansi_stricmp(cause, "cause=65") == 0) {
		return 488;
	} else if (pj_ansi_stricmp(cause, "cause=69") == 0) {
		return 501;
	} else if (pj_ansi_stricmp(cause, "cause=79") == 0) {
		return 501;
	} else if (pj_ansi_stricmp(cause, "cause=88") == 0) {
		return 488;
	} else if (pj_ansi_stricmp(cause, "cause=102") == 0) {
		return 504;
	} else if (pj_ansi_stricmp(cause, "cause=487") == 0) {
		return 487;
	} else {
		return 0;
	}
}
예제 #15
0
/* Parse a=candidate line */
static pj_status_t parse_cand(const char *obj_name,
			      pj_pool_t *pool,
			      const pj_str_t *orig_input,
			      pj_ice_sess_cand *cand)
{
    pj_str_t input;
    char *token, *host;
    int af;
    pj_str_t s;
    pj_status_t status = PJNATH_EICEINCANDSDP;

    pj_bzero(cand, sizeof(*cand));
    pj_strdup_with_null(pool, &input, orig_input);

    PJ_UNUSED_ARG(obj_name);

    /* Foundation */
    token = strtok(input.ptr, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE foundation in candidate"));
	goto on_return;
    }
    pj_strdup2(pool, &cand->foundation, token);

    /* Component ID */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE component ID in candidate"));
	goto on_return;
    }
    cand->comp_id = (pj_uint8_t) atoi(token);

    /* Transport */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE transport in candidate"));
	goto on_return;
    }
    if (pj_ansi_stricmp(token, "UDP") != 0) {
	TRACE__((obj_name, 
		 "Expecting ICE UDP transport only in candidate"));
	goto on_return;
    }

    /* Priority */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE priority in candidate"));
	goto on_return;
    }
    cand->prio = atoi(token);

    /* Host */
    host = strtok(NULL, " ");
    if (!host) {
	TRACE__((obj_name, "Expecting ICE host in candidate"));
	goto on_return;
    }
    /* Detect address family */
    if (pj_ansi_strchr(host, ':'))
	af = pj_AF_INET6();
    else
	af = pj_AF_INET();
    /* Assign address */
    if (pj_sockaddr_init(af, &cand->addr, pj_cstr(&s, host), 0)) {
	TRACE__((obj_name, "Invalid ICE candidate address"));
	goto on_return;
    }

    /* Port */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE port number in candidate"));
	goto on_return;
    }
    pj_sockaddr_set_port(&cand->addr, (pj_uint16_t)atoi(token));

    /* typ */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE \"typ\" in candidate"));
	goto on_return;
    }
    if (pj_ansi_stricmp(token, "typ") != 0) {
	TRACE__((obj_name, "Expecting ICE \"typ\" in candidate"));
	goto on_return;
    }

    /* candidate type */
    token = strtok(NULL, " ");
    if (!token) {
	TRACE__((obj_name, "Expecting ICE candidate type in candidate"));
	goto on_return;
    }

    if (pj_ansi_stricmp(token, "host") == 0) {
	cand->type = PJ_ICE_CAND_TYPE_HOST;

    } else if (pj_ansi_stricmp(token, "srflx") == 0) {
	cand->type = PJ_ICE_CAND_TYPE_SRFLX;

    } else if (pj_ansi_stricmp(token, "relay") == 0) {
	cand->type = PJ_ICE_CAND_TYPE_RELAYED;

    } else if (pj_ansi_stricmp(token, "prflx") == 0) {
	cand->type = PJ_ICE_CAND_TYPE_PRFLX;

    } else {
	PJ_LOG(5,(obj_name, "Invalid ICE candidate type %s in candidate", 
		  token));
	goto on_return;
    }

    status = PJ_SUCCESS;

on_return:
    return status;
}
예제 #16
0
/* Parse crypto attribute line */
static pj_status_t parse_attr_crypto(pj_pool_t *pool,
				     const pjmedia_sdp_attr *attr,
				     pjmedia_srtp_crypto *crypto,
				     int *tag)
{
    pj_str_t input;
    char *token;
    pj_str_t tmp;
    pj_status_t status;
    int itmp;

    pj_bzero(crypto, sizeof(*crypto));
    pj_strdup_with_null(pool, &input, &attr->value);

    /* Tag */
    token = strtok(input.ptr, " ");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting tag"));
	return PJMEDIA_SDP_EINATTR;
    }
    *tag = atoi(token);
    if (*tag == 0)
	return PJMEDIA_SDP_EINATTR;

    /* Crypto-suite */
    token = strtok(NULL, " ");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting crypto suite"));
	return PJMEDIA_SDP_EINATTR;
    }
    crypto->name = pj_str(token);

    /* Key method */
    token = strtok(NULL, ":");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key method"));
	return PJMEDIA_SDP_EINATTR;
    }
    if (pj_ansi_stricmp(token, "inline")) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto key method '%s' not supported!",
	          token));
	return PJMEDIA_SDP_EINATTR;
    }

    /* Key */
    token = strtok(NULL, "| ");
    if (!token) {
	PJ_LOG(4,(THIS_FILE, "Attribute crypto expecting key"));
	return PJMEDIA_SDP_EINATTR;
    }
    tmp = pj_str(token);
    crypto->key.ptr = (char*) pj_pool_zalloc(pool, MAX_KEY_LEN);

    /* Decode key */
    itmp = MAX_KEY_LEN;
    status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr, 
			      &itmp);
    if (status != PJ_SUCCESS) {
	PJ_LOG(4,(THIS_FILE, "Failed decoding crypto key from base64"));
	return status;
    }
    crypto->key.slen = itmp;

    return PJ_SUCCESS;
}
예제 #17
0
파일: codec.c 프로젝트: xhook/asterisk-v11
/*
 * Set default codec parameter.
 */
PJ_DEF(pj_status_t) pjmedia_codec_mgr_set_default_param( 
					    pjmedia_codec_mgr *mgr,
					    const pjmedia_codec_info *info,
					    const pjmedia_codec_param *param )
{
    unsigned i;
    pjmedia_codec_id codec_id;
    pj_pool_t *pool, *old_pool = NULL;
    struct pjmedia_codec_desc *codec_desc = NULL;
    pjmedia_codec_default_param *p;

    PJ_ASSERT_RETURN(mgr && info, PJ_EINVAL);

    if (!pjmedia_codec_info_to_id(info, (char*)&codec_id, sizeof(codec_id)))
	return PJ_EINVAL;

    pj_mutex_lock(mgr->mutex);

    /* Lookup codec desc */
    for (i=0; i < mgr->codec_cnt; ++i) {
	if (pj_ansi_stricmp(codec_id, mgr->codec_desc[i].id) == 0) {
	    codec_desc = &mgr->codec_desc[i];
	    break;
	}
    }

    /* Codec not found */
    if (!codec_desc) {
	pj_mutex_unlock(mgr->mutex);
	return PJMEDIA_CODEC_EUNSUP;
    }

    /* If codec param is previously set, reset the codec param but release
     * the codec param pool later after the new param is set (ticket #1171).
     */
    if (codec_desc->param) {
	pj_assert(codec_desc->param->pool);
        old_pool = codec_desc->param->pool;
	codec_desc->param = NULL;
    }

    /* When param is set to NULL, i.e: setting default codec param to library
     * default setting, just return PJ_SUCCESS.
     */
    if (NULL == param) {
	pj_mutex_unlock(mgr->mutex);
        if (old_pool)
	    pj_pool_release(old_pool);
	return PJ_SUCCESS;
    }

    /* Instantiate and initialize codec param */
    pool = pj_pool_create(mgr->pf, (char*)codec_id, 256, 256, NULL);
    codec_desc->param = PJ_POOL_ZALLOC_T(pool, pjmedia_codec_default_param);
    p = codec_desc->param;
    p->pool = pool;
    p->param = PJ_POOL_ZALLOC_T(pool, pjmedia_codec_param);

    /* Update codec param */
    pj_memcpy(p->param, param, sizeof(pjmedia_codec_param));
    for (i = 0; i < param->setting.dec_fmtp.cnt; ++i) {
	pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].name, 
		  &param->setting.dec_fmtp.param[i].name);
	pj_strdup(pool, &p->param->setting.dec_fmtp.param[i].val, 
		  &param->setting.dec_fmtp.param[i].val);
    }
    for (i = 0; i < param->setting.enc_fmtp.cnt; ++i) {
	pj_strdup(pool, &p->param->setting.enc_fmtp.param[i].name, 
		  &param->setting.enc_fmtp.param[i].name);
	pj_strdup(pool, &p->param->setting.enc_fmtp.param[i].val, 
		  &param->setting.enc_fmtp.param[i].val);
    }

    pj_mutex_unlock(mgr->mutex);

    if (old_pool)
	pj_pool_release(old_pool);

    return PJ_SUCCESS;
}