Пример #1
0
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    int id = -1, verbose = 0;
    int clock_rate = 8000;
    int frame = -1;
    int channel = 1;
    struct pj_getopt_option long_options[] = {
    { "id",      1, 0, 'i' },
    { "rate",    1, 0, 'r' },
    { "frame",   1, 0, 'f' },
    { "channel", 1, 0, 'n' },
    { "verbose", 0, 0, 'v' },
    { "help",    0, 0, 'h' },
    { NULL, 0, 0, 0 }
    };
    int c, option_index;
    

    pj_status_t status;

    /* Init pjlib */
    status = pj_init();
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, 1);
    
    /* 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);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Print devices */
    enum_devices();

    /* Parse options */
    pj_optind = 0;
    while((c=pj_getopt_long(argc,argv, "i:r:f:n:vh", 
                long_options, &option_index))!=-1) 
    {
    switch (c) {
    case 'i':
        id = atoi(pj_optarg);
        break;
    case 'r':
        clock_rate = atoi(pj_optarg);
        break;
    case 'f':
        frame = atoi(pj_optarg);
        break;
    case 'n':
        channel = atoi(pj_optarg);
        break;
    case 'v':
        verbose = 1;
        break;
    case 'h':
        puts(desc);
        return 0;
        break;
    default:
        printf("Error: invalid options %s\n", argv[pj_optind-1]);
        puts(desc);
        return 1;
    }
    }

    if (pj_optind != argc) {
    printf("Error: invalid options\n");
    puts(desc);
    return 1;
    }

    if (!verbose)
    pj_log_set_level(3);

    if (frame == -1)
    frame = 10 * clock_rate / 1000;


    status = perform_test(get_dev_name(id), id, PJMEDIA_DIR_CAPTURE_PLAYBACK, 
              clock_rate, frame, channel, verbose);
    if (status != 0)
    return 1;

    
    return 0;
}
Пример #2
0
/*
 * main()
 */
int main()
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_port *port;
    unsigned i;
    pj_status_t status;


    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* 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);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Create memory pool for our file player */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "app",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );

    status = pjmedia_tonegen_create(pool, 8000, 1, SAMPLES_PER_FRAME, 16, 0, &port);
    if (status != PJ_SUCCESS)
	return 1;

    {
	pjmedia_tone_desc tones[3];

	tones[0].freq1 = 200;
	tones[0].freq2 = 0;
	tones[0].on_msec = ON_DURATION;
	tones[0].off_msec = OFF_DURATION;

	tones[1].freq1 = 400;
	tones[1].freq2 = 0;
	tones[1].on_msec = ON_DURATION;
	tones[1].off_msec = OFF_DURATION;

	tones[2].freq1 = 800;
	tones[2].freq2 = 0;
	tones[2].on_msec = ON_DURATION;
	tones[2].off_msec = OFF_DURATION;

	status = pjmedia_tonegen_play(port, 3, tones, 0);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, 1);
    }

    {
	pjmedia_tone_digit digits[2];

	digits[0].digit = '0';
	digits[0].on_msec = ON_DURATION;
	digits[0].off_msec = OFF_DURATION;

	digits[1].digit = '0';
	digits[1].on_msec = ON_DURATION;
	digits[1].off_msec = OFF_DURATION;

	status = pjmedia_tonegen_play_digits(port, 2, digits, 0);
	PJ_ASSERT_RETURN(status==PJ_SUCCESS, 1);
    }

    {
	pjmedia_frame frm;
	FILE *f;
	void *buf;

	buf = pj_pool_alloc(pool, 2*8000);
	frm.buf = buf;

	f = fopen("tonegen.pcm", "wb");

	for (i=0; i<8000/SAMPLES_PER_FRAME; ++i) {
	    int count;
	    pjmedia_port_get_frame(port, &frm);
	    count = fwrite(buf, SAMPLES_PER_FRAME, 2, f);
	    if (count != 2)
		break;
	}

	pj_assert(pjmedia_tonegen_is_busy(port) == 0);
	fclose(f);
    }

    /* Delete port */
    pjmedia_port_destroy(port);

    /* Release application pool */
    pj_pool_release( pool );

    /* Destroy media endpoint. */
    pjmedia_endpt_destroy( med_endpt );

    /* Destroy pool factory */
    pj_caching_pool_destroy( &cp );

    /* Shutdown PJLIB */
    pj_shutdown();


    /* Done. */
    return 0;
}
Пример #3
0
static pj_status_t test_init(void)
{
    struct stream_cfg strm_cfg;
    pj_status_t status;

    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /* Must create a pool factory before we can allocate any memory. */
    pj_caching_pool_init(&g_app.cp, &pj_pool_factory_default_policy, 0);

    /* Pool */
    g_app.pool = pj_pool_create(&g_app.cp.factory, "g_app", 512, 512, NULL);

    /* Log file */
    if (g_app.cfg.log_file) {
	status = pj_file_open(g_app.pool, g_app.cfg.log_file, 
			      PJ_O_WRONLY,
			      &g_app.log_fd);
	if (status != PJ_SUCCESS) {
	    jbsim_perror("Error writing output file", status);
	    goto on_error;
	}

	pj_log_set_decor(PJ_LOG_HAS_SENDER | PJ_LOG_HAS_COLOR | PJ_LOG_HAS_LEVEL_TEXT);
	pj_log_set_log_func(&log_cb);
    }

    /* 
     * Initialize media endpoint.
     * This will implicitly initialize PJMEDIA too.
     */
    status = pjmedia_endpt_create(&g_app.cp.factory, NULL, 0, &g_app.endpt);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating media endpoint", status);
	goto on_error;
    }

    /* Register codecs */
    pjmedia_codec_register_audio_codecs(g_app.endpt, NULL);

    /* Create the loop transport */
    status = pjmedia_transport_loop_create(g_app.endpt, &g_app.loop);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating loop transport", status);
	goto on_error;
    }

    /* Create transmitter stream */
    pj_bzero(&strm_cfg, sizeof(strm_cfg));
    strm_cfg.name = "tx";
    strm_cfg.dir = PJMEDIA_DIR_ENCODING;
    strm_cfg.codec = g_app.cfg.codec;
    strm_cfg.ptime = g_app.cfg.tx_ptime;
    strm_cfg.dtx = g_app.cfg.tx_dtx;
    strm_cfg.plc = PJ_TRUE;
    status = stream_init(&strm_cfg, &g_app.tx);
    if (status != PJ_SUCCESS) 
	goto on_error;

    /* Create transmitter WAV */
    status = pjmedia_wav_player_port_create(g_app.pool, 
					    g_app.cfg.tx_wav_in,
					    g_app.cfg.tx_ptime,
					    0,
					    0,
					    &g_app.tx_wav);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error reading input WAV file", status);
	goto on_error;
    }

    /* Make sure stream and WAV parameters match */
    if (PJMEDIA_PIA_SRATE(&g_app.tx_wav->info) != PJMEDIA_PIA_SRATE(&g_app.tx->port->info) ||
	PJMEDIA_PIA_CCNT(&g_app.tx_wav->info) != PJMEDIA_PIA_CCNT(&g_app.tx->port->info))
    {
	jbsim_perror("Error: Input WAV file has different clock rate "
		     "or number of channels than the codec", PJ_SUCCESS);
	goto on_error;
    }


    /* Create receiver */
    pj_bzero(&strm_cfg, sizeof(strm_cfg));
    strm_cfg.name = "rx";
    strm_cfg.dir = PJMEDIA_DIR_DECODING;
    strm_cfg.codec = g_app.cfg.codec;
    strm_cfg.ptime = g_app.cfg.rx_ptime;
    strm_cfg.dtx = PJ_TRUE;
    strm_cfg.plc = g_app.cfg.rx_plc;
    status = stream_init(&strm_cfg, &g_app.rx);
    if (status != PJ_SUCCESS) 
	goto on_error;

    /* Create receiver WAV */
    status = pjmedia_wav_writer_port_create(g_app.pool, 
					    g_app.cfg.rx_wav_out,
					    PJMEDIA_PIA_SRATE(&g_app.rx->port->info),
					    PJMEDIA_PIA_CCNT(&g_app.rx->port->info),
					    PJMEDIA_PIA_SPF(&g_app.rx->port->info),
					    PJMEDIA_PIA_BITS(&g_app.rx->port->info),
					    0,
					    0,
					    &g_app.rx_wav);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating output WAV file", status);
	goto on_error;
    }


    /* Frame buffer */
    g_app.framebuf = (pj_int16_t*)
		     pj_pool_alloc(g_app.pool,
				   MAX(PJMEDIA_PIA_SPF(&g_app.rx->port->info),
				       PJMEDIA_PIA_SPF(&g_app.tx->port->info)) * sizeof(pj_int16_t));


    /* Set the receiver in the loop transport */
    pjmedia_transport_loop_disable_rx(g_app.loop, g_app.tx->strm, PJ_TRUE);

    /* Done */
    return PJ_SUCCESS;

on_error:
    test_destroy();
    return status;
}
Пример #4
0
/*
 * main()
 *
 * If called with argument, treat argument as SIP URL to be called.
 * Otherwise wait for incoming calls.
 */
int main(int argc, char *argv[])
{
    pj_pool_t *pool = NULL;
    pj_status_t status;
    unsigned i;

    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    pj_log_set_level(5);

    /* Then init PJLIB-UTIL: */
    status = pjlib_util_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Must create a pool factory before we can allocate any memory. */
    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);


    /* Create global endpoint: */
    {
	const pj_str_t *hostname;
	const char *endpt_name;

	/* Endpoint MUST be assigned a globally unique name.
	 * The name will be used as the hostname in Warning header.
	 */

	/* For this implementation, we'll use hostname for simplicity */
	hostname = pj_gethostname();
	endpt_name = hostname->ptr;

	/* Create the endpoint: */

	status = pjsip_endpt_create(&cp.factory, endpt_name, 
				    &g_endpt);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    }


    /* 
     * Add UDP transport, with hard-coded port 
     * Alternatively, application can use pjsip_udp_transport_attach() to
     * start UDP transport, if it already has an UDP socket (e.g. after it
     * resolves the address with STUN).
     */
    {
	pj_sockaddr addr;

	pj_sockaddr_init(AF, &addr, NULL, (pj_uint16_t)SIP_PORT);
	
	if (AF == pj_AF_INET()) {
	    status = pjsip_udp_transport_start( g_endpt, &addr.ipv4, NULL, 
						1, NULL);
	} else if (AF == pj_AF_INET6()) {
	    status = pjsip_udp_transport_start6(g_endpt, &addr.ipv6, NULL,
						1, NULL);
	} else {
	    status = PJ_EAFNOTSUP;
	}

	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to start UDP transport", status);
	    return 1;
	}
    }


    /* 
     * Init transaction layer.
     * This will create/initialize transaction hash tables etc.
     */
    status = pjsip_tsx_layer_init_module(g_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* 
     * Initialize UA layer module.
     * This will create/initialize dialog hash tables etc.
     */
    status = pjsip_ua_init_module( g_endpt, NULL );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* 
     * Init invite session module.
     * The invite session module initialization takes additional argument,
     * i.e. a structure containing callbacks to be called on specific
     * occurence of events.
     *
     * The on_state_changed and on_new_session callbacks are mandatory.
     * Application must supply the callback function.
     *
     * We use on_media_update() callback in this application to start
     * media transmission.
     */
    {
	pjsip_inv_callback inv_cb;

	/* Init the callback for INVITE session: */
	pj_bzero(&inv_cb, sizeof(inv_cb));
	inv_cb.on_state_changed = &call_on_state_changed;
	inv_cb.on_new_session = &call_on_forked;
	inv_cb.on_media_update = &call_on_media_update;

	/* Initialize invite session module:  */
	status = pjsip_inv_usage_init(g_endpt, &inv_cb);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    }

    /* Initialize 100rel support */
    status = pjsip_100rel_init_module(g_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /*
     * Register our module to receive incoming requests.
     */
    status = pjsip_endpt_register_module( g_endpt, &mod_simpleua);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /*
     * Register message logger module.
     */
    status = pjsip_endpt_register_module( g_endpt, &msg_logger);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* 
     * Initialize media endpoint.
     * This will implicitly initialize PJMEDIA too.
     */
#if PJ_HAS_THREADS
    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &g_med_endpt);
#else
    status = pjmedia_endpt_create(&cp.factory, 
				  pjsip_endpt_get_ioqueue(g_endpt), 
				  0, &g_med_endpt);
#endif
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* 
     * Add PCMA/PCMU codec to the media endpoint. 
     */
#if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
    status = pjmedia_codec_g711_init(g_med_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
#endif


#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
    /* Init video subsystem */
    pool = pjmedia_endpt_create_pool(g_med_endpt, "Video subsystem", 512, 512);
    status = pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    status = pjmedia_converter_mgr_create(pool, NULL);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    status = pjmedia_vid_codec_mgr_create(pool, NULL);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    status = pjmedia_vid_dev_subsys_init(&cp.factory);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

#  if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC!=0
    /* Init ffmpeg video codecs */
    status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
#  endif  /* PJMEDIA_HAS_FFMPEG_VID_CODEC */

#endif	/* PJMEDIA_HAS_VIDEO */
    
    /* 
     * Create media transport used to send/receive RTP/RTCP socket.
     * One media transport is needed for each call. Application may
     * opt to re-use the same media transport for subsequent calls.
     */
    for (i = 0; i < PJ_ARRAY_SIZE(g_med_transport); ++i) {
	status = pjmedia_transport_udp_create3(g_med_endpt, AF, NULL, NULL, 
					       RTP_PORT + i*2, 0, 
					       &g_med_transport[i]);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to create media transport", status);
	    return 1;
	}

	/* 
	 * Get socket info (address, port) of the media transport. We will
	 * need this info to create SDP (i.e. the address and port info in
	 * the SDP).
	 */
	pjmedia_transport_info_init(&g_med_tpinfo[i]);
	pjmedia_transport_get_info(g_med_transport[i], &g_med_tpinfo[i]);

	pj_memcpy(&g_sock_info[i], &g_med_tpinfo[i].sock_info,
		  sizeof(pjmedia_sock_info));
    }

    /*
     * If URL is specified, then make call immediately.
     */
    if (argc > 1) {
	pj_sockaddr hostaddr;
	char hostip[PJ_INET6_ADDRSTRLEN+2];
	char temp[80];
	pj_str_t dst_uri = pj_str(argv[1]);
	pj_str_t local_uri;
	pjsip_dialog *dlg;
	pjmedia_sdp_session *local_sdp;
	pjsip_tx_data *tdata;

	if (pj_gethostip(AF, &hostaddr) != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to retrieve local host IP", status);
	    return 1;
	}
	pj_sockaddr_print(&hostaddr, hostip, sizeof(hostip), 2);

	pj_ansi_sprintf(temp, "<sip:simpleuac@%s:%d>", 
			hostip, SIP_PORT);
	local_uri = pj_str(temp);

	/* Create UAC dialog */
	status = pjsip_dlg_create_uac( pjsip_ua_instance(), 
				       &local_uri,  /* local URI */
				       &local_uri,  /* local Contact */
				       &dst_uri,    /* remote URI */
				       &dst_uri,    /* remote target */
				       &dlg);	    /* dialog */
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to create UAC dialog", status);
	    return 1;
	}

	/* If we expect the outgoing INVITE to be challenged, then we should
	 * put the credentials in the dialog here, with something like this:
	 *
	    {
		pjsip_cred_info	cred[1];

		cred[0].realm	  = pj_str("sip.server.realm");
		cred[0].scheme    = pj_str("digest");
		cred[0].username  = pj_str("theuser");
		cred[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
		cred[0].data      = pj_str("thepassword");

		pjsip_auth_clt_set_credentials( &dlg->auth_sess, 1, cred);
	    }
	 *
	 */


	/* Get the SDP body to be put in the outgoing INVITE, by asking
	 * media endpoint to create one for us.
	 */
	status = pjmedia_endpt_create_sdp( g_med_endpt,	    /* the media endpt	*/
					   dlg->pool,	    /* pool.		*/
					   MAX_MEDIA_CNT,   /* # of streams	*/
					   g_sock_info,     /* RTP sock info	*/
					   &local_sdp);	    /* the SDP result	*/
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);



	/* Create the INVITE session, and pass the SDP returned earlier
	 * as the session's initial capability.
	 */
	status = pjsip_inv_create_uac( dlg, local_sdp, 0, &g_inv);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

	/* If we want the initial INVITE to travel to specific SIP proxies,
	 * then we should put the initial dialog's route set here. The final
	 * route set will be updated once a dialog has been established.
	 * To set the dialog's initial route set, we do it with something
	 * like this:
	 *
	    {
		pjsip_route_hdr route_set;
		pjsip_route_hdr *route;
		const pj_str_t hname = { "Route", 5 };
		char *uri = "sip:proxy.server;lr";

		pj_list_init(&route_set);

		route = pjsip_parse_hdr( dlg->pool, &hname, 
					 uri, strlen(uri),
					 NULL);
		PJ_ASSERT_RETURN(route != NULL, 1);
		pj_list_push_back(&route_set, route);

		pjsip_dlg_set_route_set(dlg, &route_set);
	    }
	 *
	 * Note that Route URI SHOULD have an ";lr" parameter!
	 */

	/* Create initial INVITE request.
	 * This INVITE request will contain a perfectly good request and 
	 * an SDP body as well.
	 */
	status = pjsip_inv_invite(g_inv, &tdata);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);



	/* Send initial INVITE request. 
	 * From now on, the invite session's state will be reported to us
	 * via the invite session callbacks.
	 */
	status = pjsip_inv_send_msg(g_inv, tdata);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    } else {

	/* No URL to make call to */

	PJ_LOG(3,(THIS_FILE, "Ready to accept incoming calls..."));
    }


    /* Loop until one call is completed */
    for (;!g_complete;) {
	pj_time_val timeout = {0, 10};
	pjsip_endpt_handle_events(g_endpt, &timeout);
    }

    /* On exit, dump current memory usage: */
    dump_pool_usage(THIS_FILE, &cp);

    /* Destroy audio ports. Destroy the audio port first
     * before the stream since the audio port has threads
     * that get/put frames to the stream.
     */
    if (g_snd_port)
	pjmedia_snd_port_destroy(g_snd_port);

#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
    /* Destroy video ports */
    if (g_vid_capturer)
	pjmedia_vid_port_destroy(g_vid_capturer);
    if (g_vid_renderer)
	pjmedia_vid_port_destroy(g_vid_renderer);
#endif

    /* Destroy streams */
    if (g_med_stream)
	pjmedia_stream_destroy(g_med_stream);
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
    if (g_med_vstream)
	pjmedia_vid_stream_destroy(g_med_vstream);

    /* Deinit ffmpeg codec */
#   if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC!=0
    pjmedia_codec_ffmpeg_vid_deinit();
#   endif

#endif

    /* Destroy media transports */
    for (i = 0; i < MAX_MEDIA_CNT; ++i) {
	if (g_med_transport[i])
	    pjmedia_transport_close(g_med_transport[i]);
    }

    /* Deinit pjmedia endpoint */
    if (g_med_endpt)
	pjmedia_endpt_destroy(g_med_endpt);

    /* Deinit pjsip endpoint */
    if (g_endpt)
	pjsip_endpt_destroy(g_endpt);

    /* Release pool */
    if (pool)
	pj_pool_release(pool);

    return 0;
}
Пример #5
0
static pj_status_t test_init(void)
{
    struct stream_cfg strm_cfg;
    pj_status_t status;

    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /* Must create a pool factory before we can allocate any memory. */
    pj_caching_pool_init(&g_app.cp, &pj_pool_factory_default_policy, 0);

    /* Pool */
    g_app.pool = pj_pool_create(&g_app.cp.factory, "g_app", 512, 512, NULL);

    /* Log file */
    if (g_app.cfg.log_file) {
	status = pj_file_open(g_app.pool, g_app.cfg.log_file, 
			      PJ_O_WRONLY,
			      &g_app.log_fd);
	if (status != PJ_SUCCESS) {
	    jbsim_perror("Error writing output file", status);
	    goto on_error;
	}

	pj_log_set_decor(PJ_LOG_HAS_SENDER | PJ_LOG_HAS_COLOR | PJ_LOG_HAS_LEVEL_TEXT);
	pj_log_set_log_func(&log_cb);
    }

    /* 
     * Initialize media endpoint.
     * This will implicitly initialize PJMEDIA too.
     */
    status = pjmedia_endpt_create(&g_app.cp.factory, NULL, 0, &g_app.endpt);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating media endpoint", status);
	goto on_error;
    }

    /* Register codecs */
#if defined(PJMEDIA_HAS_GSM_CODEC) && PJMEDIA_HAS_GSM_CODEC != 0
    pjmedia_codec_gsm_init(g_app.endpt);
#endif
#if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
    pjmedia_codec_g711_init(g_app.endpt);
#endif
#if defined(PJMEDIA_HAS_SPEEX_CODEC) && PJMEDIA_HAS_SPEEX_CODEC!=0
    pjmedia_codec_speex_init(g_app.endpt, 0, PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY,
			     PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY);
#endif
#if defined(PJMEDIA_HAS_G722_CODEC) && (PJMEDIA_HAS_G722_CODEC != 0)
    pjmedia_codec_g722_init(g_app.endpt);
#endif
#if defined(PJMEDIA_HAS_ILBC_CODEC) && PJMEDIA_HAS_ILBC_CODEC != 0
    /* Init ILBC with mode=20 to make the losts occur at the same
     * places as other codecs.
     */
    pjmedia_codec_ilbc_init(g_app.endpt, 20);
#endif
#if defined(PJMEDIA_HAS_INTEL_IPP) && PJMEDIA_HAS_INTEL_IPP != 0
    pjmedia_codec_ipp_init(g_app.endpt);
#endif
#if defined(PJMEDIA_HAS_OPENCORE_AMRNB_CODEC) && (PJMEDIA_HAS_OPENCORE_AMRNB_CODEC != 0)
    pjmedia_codec_opencore_amrnb_init(g_app.endpt);
#endif
#if defined(PJMEDIA_HAS_L16_CODEC) && PJMEDIA_HAS_L16_CODEC != 0
    pjmedia_codec_l16_init(g_app.endpt, 0);
#endif

    /* Create the loop transport */
    status = pjmedia_transport_loop_create(g_app.endpt, &g_app.loop);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating loop transport", status);
	goto on_error;
    }

    /* Create transmitter stream */
    pj_bzero(&strm_cfg, sizeof(strm_cfg));
    strm_cfg.name = "tx";
    strm_cfg.dir = PJMEDIA_DIR_ENCODING;
    strm_cfg.codec = g_app.cfg.codec;
    strm_cfg.ptime = g_app.cfg.tx_ptime;
    strm_cfg.dtx = g_app.cfg.tx_dtx;
    strm_cfg.plc = PJ_TRUE;
    status = stream_init(&strm_cfg, &g_app.tx);
    if (status != PJ_SUCCESS) 
	goto on_error;

    /* Create transmitter WAV */
    status = pjmedia_wav_player_port_create(g_app.pool, 
					    g_app.cfg.tx_wav_in,
					    g_app.cfg.tx_ptime,
					    0,
					    0,
					    &g_app.tx_wav);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error reading input WAV file", status);
	goto on_error;
    }

    /* Make sure stream and WAV parameters match */
    if (g_app.tx_wav->info.clock_rate != g_app.tx->port->info.clock_rate ||
	g_app.tx_wav->info.channel_count != g_app.tx->port->info.channel_count)
    {
	jbsim_perror("Error: Input WAV file has different clock rate "
		     "or number of channels than the codec", PJ_SUCCESS);
	goto on_error;
    }


    /* Create receiver */
    pj_bzero(&strm_cfg, sizeof(strm_cfg));
    strm_cfg.name = "rx";
    strm_cfg.dir = PJMEDIA_DIR_DECODING;
    strm_cfg.codec = g_app.cfg.codec;
    strm_cfg.ptime = g_app.cfg.rx_ptime;
    strm_cfg.dtx = PJ_TRUE;
    strm_cfg.plc = g_app.cfg.rx_plc;
    status = stream_init(&strm_cfg, &g_app.rx);
    if (status != PJ_SUCCESS) 
	goto on_error;

    /* Create receiver WAV */
    status = pjmedia_wav_writer_port_create(g_app.pool, 
					    g_app.cfg.rx_wav_out,
					    g_app.rx->port->info.clock_rate,
					    g_app.rx->port->info.channel_count,
					    g_app.rx->port->info.samples_per_frame,
					    g_app.rx->port->info.bits_per_sample,
					    0,
					    0,
					    &g_app.rx_wav);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating output WAV file", status);
	goto on_error;
    }


    /* Frame buffer */
    g_app.framebuf = (pj_int16_t*)
		     pj_pool_alloc(g_app.pool,
				   MAX(g_app.rx->port->info.samples_per_frame,
				       g_app.tx->port->info.samples_per_frame) * sizeof(pj_int16_t));


    /* Set the receiver in the loop transport */
    pjmedia_transport_loop_disable_rx(g_app.loop, g_app.tx->strm, PJ_TRUE);

    /* Done */
    return PJ_SUCCESS;

on_error:
    test_destroy();
    return status;
}
Пример #6
0
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;

    pjmedia_port *file_port = NULL;
    pjmedia_port *stereo_port = NULL;
    pjmedia_snd_port *snd_port = NULL;

    int dev_id = -1;
    char tmp[10];
    pj_status_t status;

    char *wav_file = NULL;
    unsigned mode = 0;
    unsigned rec_ch_cnt = 1;
    unsigned snd_ch_cnt = 2;

    enum {
        OPT_MODE	= 'm',
        OPT_REC_CHANNEL = 'C',
        OPT_SND_CHANNEL = 'c',
    };

    struct pj_getopt_option long_options[] = {
        { "mode",	    1, 0, OPT_MODE },
        { "rec-ch-cnt",	    1, 0, OPT_REC_CHANNEL },
        { "snd-ch-cnt",	    1, 0, OPT_SND_CHANNEL },
        { NULL, 0, 0, 0 },
    };

    int c;
    int option_index;

    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Parse arguments */
    pj_optind = 0;
    while((c=pj_getopt_long(argc,argv, "m:C:c:", long_options, &option_index))!=-1) {

        switch (c) {
        case OPT_MODE:
            if (mode) {
                app_perror(THIS_FILE, "Cannot record and play at once!",
                           PJ_EINVAL);
                return 1;
            }
            mode = atoi(pj_optarg);
            break;

        case OPT_REC_CHANNEL:
            rec_ch_cnt = atoi(pj_optarg);
            break;

        case OPT_SND_CHANNEL:
            snd_ch_cnt = atoi(pj_optarg);
            break;

        default:
            printf("Invalid options %s\n", argv[pj_optind]);
            puts(desc);
            return 1;
        }

    }

    wav_file = argv[pj_optind];

    /* Verify arguments. */
    if (!wav_file) {
        app_perror(THIS_FILE, "WAV file not specified!", PJ_EINVAL);
        puts(desc);
        return 1;
    }
    if (!snd_ch_cnt || !rec_ch_cnt || rec_ch_cnt > 6) {
        app_perror(THIS_FILE, "Invalid or too many channel count!", PJ_EINVAL);
        puts(desc);
        return 1;
    }
    if (mode != MODE_RECORD && mode != MODE_PLAY) {
        app_perror(THIS_FILE, "Invalid operation mode!", PJ_EINVAL);
        puts(desc);
        return 1;
    }

    /* 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);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Create memory pool for our file player */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
                           "app",	    /* pool name.	    */
                           4000,	    /* init size	    */
                           4000,	    /* increment size	    */
                           NULL		    /* callback on error    */
                         );

    if (mode == MODE_PLAY) {
        /* Create WAVE file player port. */
        status = pjmedia_wav_player_port_create( pool, wav_file, PTIME, 0,
                 0, &file_port);
        if (status != PJ_SUCCESS) {
            app_perror(THIS_FILE, "Unable to open file", status);
            return 1;
        }

        /* Create sound player port. */
        status = pjmedia_snd_port_create_player(
                     pool,				/* pool		      */
                     dev_id,				/* device id.	      */
                     PJMEDIA_PIA_SRATE(&file_port->info),/* clock rate.	      */
                     snd_ch_cnt,			/* # of channels.     */
                     snd_ch_cnt * PTIME *		/* samples per frame. */
                     PJMEDIA_PIA_SRATE(&file_port->info) / 1000,
                     PJMEDIA_PIA_BITS(&file_port->info),/* bits per sample.   */
                     0,					/* options	      */
                     &snd_port				/* returned port      */
                 );
        if (status != PJ_SUCCESS) {
            app_perror(THIS_FILE, "Unable to open sound device", status);
            return 1;
        }

        if (snd_ch_cnt != PJMEDIA_PIA_CCNT(&file_port->info)) {
            status = pjmedia_stereo_port_create( pool,
                                                 file_port,
                                                 snd_ch_cnt,
                                                 0,
                                                 &stereo_port);
            if (status != PJ_SUCCESS) {
                app_perror(THIS_FILE, "Unable to create stereo port", status);
                return 1;
            }

            status = pjmedia_snd_port_connect(snd_port, stereo_port);
        } else {
            status = pjmedia_snd_port_connect(snd_port, file_port);
        }

        if (status != PJ_SUCCESS) {
            app_perror(THIS_FILE, "Unable to connect sound port", status);
            return 1;
        }

    } else {
        /* Create WAVE file writer port. */
        status = pjmedia_wav_writer_port_create(pool, wav_file,
                                                REC_CLOCK_RATE,
                                                rec_ch_cnt,
                                                rec_ch_cnt * PTIME *
                                                REC_CLOCK_RATE / 1000,
                                                NBITS,
                                                0, 0,
                                                &file_port);
        if (status != PJ_SUCCESS) {
            app_perror(THIS_FILE, "Unable to open file", status);
            return 1;
        }

        /* Create sound player port. */
        status = pjmedia_snd_port_create_rec(
                     pool,			    /* pool		    */
                     dev_id,		    /* device id.	    */
                     REC_CLOCK_RATE,	    /* clock rate.	    */
                     snd_ch_cnt,		    /* # of channels.	    */
                     snd_ch_cnt * PTIME *
                     REC_CLOCK_RATE / 1000,	    /* samples per frame.   */
                     NBITS,			    /* bits per sample.	    */
                     0,			    /* options		    */
                     &snd_port		    /* returned port	    */
                 );
        if (status != PJ_SUCCESS) {
            app_perror(THIS_FILE, "Unable to open sound device", status);
            return 1;
        }

        if (rec_ch_cnt != snd_ch_cnt) {
            status = pjmedia_stereo_port_create( pool,
                                                 file_port,
                                                 snd_ch_cnt,
                                                 0,
                                                 &stereo_port);
            if (status != PJ_SUCCESS) {
                app_perror(THIS_FILE, "Unable to create stereo port", status);
                return 1;
            }

            status = pjmedia_snd_port_connect(snd_port, stereo_port);
        } else {
            status = pjmedia_snd_port_connect(snd_port, file_port);
        }

        if (status != PJ_SUCCESS) {
            app_perror(THIS_FILE, "Unable to connect sound port", status);
            return 1;
        }
    }

    /* Dump memory usage */
    dump_pool_usage(THIS_FILE, &cp);

    /*
     * File should be playing and looping now, using sound device's thread.
     */


    /* Sleep to allow log messages to flush */
    pj_thread_sleep(100);

    printf("Mode = %s\n", (mode == MODE_PLAY? "playing" : "recording") );
    printf("File  port channel count = %d\n", PJMEDIA_PIA_CCNT(&file_port->info));
    printf("Sound port channel count = %d\n",
           PJMEDIA_PIA_CCNT(&pjmedia_snd_port_get_port(snd_port)->info));
    puts("");
    puts("Press <ENTER> to stop and quit");

    if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
        puts("EOF while reading stdin, will quit now..");
    }

    /* Start deinitialization: */


    /* Destroy sound device */
    status = pjmedia_snd_port_destroy( snd_port );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Destroy stereo port and file_port.
     * Stereo port will destroy all downstream ports (e.g. the file port)
     */
    status = pjmedia_port_destroy( stereo_port? stereo_port : file_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Release application pool */
    pj_pool_release( pool );

    /* Destroy media endpoint. */
    pjmedia_endpt_destroy( med_endpt );

    /* Destroy pool factory */
    pj_caching_pool_destroy( &cp );

    /* Shutdown PJLIB */
    pj_shutdown();


    /* Done. */
    return 0;

}
Пример #7
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    enum { NSAMPLES = 640, COUNT=100 };
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_port *file_port;
    int i;
    pj_status_t status;


    /* Verify cmd line arguments. */
    if (argc != 2) {
	puts("");
	puts(desc);
	return 1;
    }

    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* 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);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Create memory pool for our file player */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "wav",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );

    /* Create file media port from the WAV file */
    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
					      argv[1],	/* file to play	    */
					      0,	/* use default ptime*/
					      0,	/* flags	    */
					      0,	/* default buffer   */
					      &file_port/* returned port    */
					      );
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to use WAV file", status);
	return 1;
    }

    if (file_port->info.samples_per_frame > NSAMPLES) {
	app_perror(THIS_FILE, "WAV clock rate is too big", PJ_EINVAL);
	return 1;
    }

    puts("Time\tPCMU\tLinear");
    puts("------------------------");

    for (i=0; i<COUNT; ++i) {
	pj_int16_t framebuf[NSAMPLES];
	pjmedia_frame frm;
	pj_int32_t level32;
	unsigned ms;
	int level;

	frm.buf = framebuf;
	frm.size = sizeof(framebuf);
	
	pjmedia_port_get_frame(file_port, &frm);

	level32 = pjmedia_calc_avg_signal(framebuf, 
					  file_port->info.samples_per_frame);
	level = pjmedia_linear2ulaw(level32) ^ 0xFF;

	ms = i * 1000 * file_port->info.samples_per_frame /
			file_port->info.clock_rate;
	printf("%03d.%03d\t%7d\t%7d\n", 
	        ms/1000, ms%1000, level, level32);
    }
    puts("");
    

    /* Destroy file port */
    status = pjmedia_port_destroy( file_port );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Release application pool */
    pj_pool_release( pool );

    /* Destroy media endpoint. */
    pjmedia_endpt_destroy( med_endpt );

    /* Destroy pool factory */
    pj_caching_pool_destroy( &cp );

    /* Shutdown PJLIB */
    pj_shutdown();


    /* Done. */
    return 0;
}
Пример #8
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t	  *pool;
    pjmedia_port  *play_port;
    pjmedia_port  *rec_port;
    pjmedia_port  *bidir_port;
    pjmedia_snd_port *snd;
    char tmp[10];
    pj_status_t status;


    if (argc != 3) {
    	puts("Error: arguments required");
	puts(desc);
	return 1;
    }


    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* 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);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Create memory pool for our file player */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "wav",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );

    /* Create file media port from the WAV file */
    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
					      argv[1],	/* file to play	    */
					      PTIME,	/* ptime.	    */
					      0,	/* flags	    */
					      0,	/* default buffer   */
					      &play_port);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to open input WAV file", status);
	return 1;
    }

    if (play_port->info.channel_count != 1) {
	puts("Error: input WAV must have 1 channel audio");
	return 1;
    }
    if (play_port->info.bits_per_sample != 16) {
	puts("Error: input WAV must be encoded as 16bit PCM");
	return 1;
    }

#ifdef PJ_DARWINOS
    /* Need to force clock rate on MacOS */
    if (play_port->info.clock_rate != 44100) {
	pjmedia_port *resample_port;

	status = pjmedia_resample_port_create(pool, play_port, 44100, 0,
					      &resample_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to create resampling port", status);
	    return 1;
	}

	data.play_port = resample_port;
    }
#endif

    /* Create WAV output file port */
    status = pjmedia_wav_writer_port_create(pool, argv[2], 
					    play_port->info.clock_rate,
					    play_port->info.channel_count,
					    play_port->info.samples_per_frame,
					    play_port->info.bits_per_sample,
					    0, 0, &rec_port);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to open output file", status);
	return 1;
    }

    /* Create bidirectional port from the WAV ports */
    pjmedia_bidirectional_port_create(pool, play_port, rec_port, &bidir_port);

    /* Create sound device. */
    status = pjmedia_snd_port_create(pool, -1, -1, 
				     play_port->info.clock_rate,
				     play_port->info.channel_count,
				     play_port->info.samples_per_frame,
				     play_port->info.bits_per_sample,
				     0, &snd);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to open sound device", status);
	return 1;
    }


    /* Customize AEC */
    pjmedia_snd_port_set_ec(snd, pool, TAIL_LENGTH, 0);

    /* Connect sound to the port */
    pjmedia_snd_port_connect(snd, bidir_port);


    puts("");
    printf("Playing %s and recording to %s\n", argv[1], argv[2]);
    puts("Press <ENTER> to quit");

    fgets(tmp, sizeof(tmp), stdin);

    
    /* Start deinitialization: */

    /* Destroy sound device */
    status = pjmedia_snd_port_destroy( snd );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Destroy file port(s) */
    status = pjmedia_port_destroy( play_port );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    status = pjmedia_port_destroy( rec_port );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Release application pool */
    pj_pool_release( pool );

    /* Destroy media endpoint. */
    pjmedia_endpt_destroy( med_endpt );

    /* Destroy pool factory */
    pj_caching_pool_destroy( &cp );

    /* Shutdown PJLIB */
    pj_shutdown();

    /* Done. */
    return 0;
}
Пример #9
0
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_port *file_port;
    pjmedia_port *resample_port;
    pjmedia_snd_port *snd_port;
    char tmp[10];
    pj_status_t status;

    int dev_id = -1;
    int sampling_rate = CLOCK_RATE;
    int channel_count = NCHANNELS;
    int samples_per_frame = NSAMPLES;
    int bits_per_sample = NBITS;
    //int ptime;
    //int down_samples;

    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Get options */
    if (get_snd_options(THIS_FILE, argc, argv, &dev_id, &sampling_rate,
			&channel_count, &samples_per_frame, &bits_per_sample))
    {
	puts("");
	puts(desc);
	return 1;
    }

    if (!argv[pj_optind]) {
	puts("Error: no file is specified");
	puts(desc);
	return 1;
    }

    /* 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);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Create memory pool for our file player */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "app",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );

    /* Create the file port. */
    status = pjmedia_wav_player_port_create( pool, argv[pj_optind], 0, 0,
					     0, &file_port);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to open file", status);
	return 1;
    }

    /* File must have same number of channels. */
    if (PJMEDIA_PIA_CCNT(&file_port->info) != (unsigned)channel_count) {
	PJ_LOG(3,(THIS_FILE, "Error: file has different number of channels. "
			     "Perhaps you'd need -c option?"));
	pjmedia_port_destroy(file_port);
	return 1;
    }

    /* Calculate number of samples per frame to be taken from file port */
    //ptime = samples_per_frame * 1000 / sampling_rate;

    /* Create the resample port. */
    status = pjmedia_resample_port_create( pool, file_port,
					   sampling_rate, 0,
					   &resample_port);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to create resample port", status);
	return 1;
    }

    /* Create sound player port. */
    status = pjmedia_snd_port_create( 
		 pool,			/* pool			    */
		 dev_id,		/* device		    */
		 dev_id,		/* device		    */
		 sampling_rate,		/* clock rate.		    */
		 channel_count,		/* # of channels.	    */
		 samples_per_frame,	/* samples per frame.	    */
		 bits_per_sample,	/* bits per sample.	    */
		 0,			/* options		    */
		 &snd_port		/* returned port	    */
		 );
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to open sound device", status);
	return 1;
    }

    /* Connect resample port to sound device */
    status = pjmedia_snd_port_connect( snd_port, resample_port);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Error connecting sound ports", status);
	return 1;
    }


    /* Dump memory usage */
    dump_pool_usage(THIS_FILE, &cp);

    /* 
     * File should be playing and looping now, using sound device's thread. 
     */


    /* Sleep to allow log messages to flush */
    pj_thread_sleep(100);


    printf("Playing %s at sampling rate %d (original file sampling rate=%d)\n",
	   argv[pj_optind], sampling_rate,
	   PJMEDIA_PIA_SRATE(&file_port->info));
    puts("");
    puts("Press <ENTER> to stop playing and quit");

    if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
	puts("EOF while reading stdin, will quit now..");
    }
    
    /* Start deinitialization: */


    /* Destroy sound device */
    status = pjmedia_snd_port_destroy( snd_port );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Destroy resample port. 
     * This will destroy all downstream ports (e.g. the file port)
     */
    status = pjmedia_port_destroy( resample_port );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Release application pool */
    pj_pool_release( pool );

    /* Destroy media endpoint. */
    pjmedia_endpt_destroy( med_endpt );

    /* Destroy pool factory */
    pj_caching_pool_destroy( &cp );

    /* Shutdown PJLIB */
    pj_shutdown();


    /* Done. */
    return 0;

}
Пример #10
0
int main()
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_conf *conf;
    int i;
    pjmedia_port *sine_port[SINE_COUNT], *null_port, *conf_port;
    pjmedia_port *nulls[NULL_COUNT];
    unsigned null_slots[NULL_COUNT];
    pjmedia_master_port *master_port;
    pj_status_t status;


    pj_log_set_level(3);

    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "wav",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );

    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);



    status = pjmedia_conf_create( pool,
				  PORT_COUNT,
				  CLOCK_RATE,
				  1, SAMPLES_PER_FRAME, 16,
				  PJMEDIA_CONF_NO_DEVICE,
				  &conf);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to create conference bridge", status);
	return 1;
    }

    printf("Resampling is %s\n", (HAS_RESAMPLE?"active":"disabled"));

    /* Create Null ports */
    printf("Creating %d null ports..\n", NULL_COUNT);
    for (i=0; i<NULL_COUNT; ++i) {
	status = pjmedia_null_port_create(pool, CLOCK_RATE, 1, SAMPLES_PER_FRAME*2, 16, &nulls[i]);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

	status = pjmedia_conf_add_port(conf, pool, nulls[i], NULL, &null_slots[i]);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    }

    /* Create sine ports. */
    printf("Creating %d sine generator ports..\n", SINE_COUNT);
    for (i=0; i<SINE_COUNT; ++i) {
	unsigned j, slot;

	/* Load the WAV file to file port. */
	status = create_sine_port(pool, SINE_CLOCK, 1, &sine_port[i]);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

	/* Add the file port to conference bridge */
	status = pjmedia_conf_add_port( conf,		/* The bridge	    */
					pool,		/* pool		    */
					sine_port[i],	/* port to connect  */
					NULL,		/* Use port's name  */
					&slot		/* ptr for slot #   */
					);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to add conference port", status);
	    return 1;
	}

	status = pjmedia_conf_connect_port(conf, slot, 0, 0);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

	for (j=0; j<NULL_COUNT; ++j) {
	    status = pjmedia_conf_connect_port(conf, slot, null_slots[j], 0);
	    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
	}
    }

    /* Create idle ports */
    printf("Creating %d idle ports..\n", IDLE_COUNT);
    for (i=0; i<IDLE_COUNT; ++i) {
	pjmedia_port *dummy;
	status = pjmedia_null_port_create(pool, CLOCK_RATE, 1, SAMPLES_PER_FRAME, 16, &dummy);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
	status = pjmedia_conf_add_port(conf, pool, dummy, NULL, NULL);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    }

    /* Create null port */
    status = pjmedia_null_port_create(pool, CLOCK_RATE, 1, SAMPLES_PER_FRAME, 16,
				      &null_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    conf_port = pjmedia_conf_get_master_port(conf);

    /* Create master port */
    status = pjmedia_master_port_create(pool, null_port, conf_port, 0, &master_port);


    pjmedia_master_port_start(master_port);

    puts("Waiting to settle.."); fflush(stdout);
    pj_thread_sleep(5000);


    benchmark();


    /* Done. */
    return 0;
}
Пример #11
0
/*****************************************************************************
 * main()
 */
int main(int argc, char *argv[])
{
    int dev_id = -1;
    int clock_rate = CLOCK_RATE;
    int channel_count = NCHANNELS;
    int samples_per_frame = NSAMPLES;
    int bits_per_sample = NBITS;

    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_conf *conf;

    int i, port_count, file_count;
    pjmedia_port **file_port;	/* Array of file ports */
    pjmedia_port *rec_port = NULL;  /* Wav writer port */

    char tmp[10];
    pj_status_t status;


    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Get command line options. */
    if (get_snd_options(THIS_FILE, argc, argv, &dev_id, &clock_rate,
			&channel_count, &samples_per_frame, &bits_per_sample))
    {
	usage();
	return 1;
    }

    /* 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);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Create memory pool to allocate memory */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "wav",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );


    file_count = argc - pj_optind;
    port_count = file_count + 1 + RECORDER;

    /* Create the conference bridge. 
     * With default options (zero), the bridge will create an instance of
     * sound capture and playback device and connect them to slot zero.
     */
    status = pjmedia_conf_create( pool,	    /* pool to use	    */
				  port_count,/* number of ports	    */
				  clock_rate,
				  channel_count,
				  samples_per_frame,
				  bits_per_sample,
				  0,	    /* options		    */
				  &conf	    /* result		    */
				  );
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to create conference bridge", status);
	return 1;
    }

#if RECORDER
    status = pjmedia_wav_writer_port_create(  pool, "confrecord.wav",
					      clock_rate, channel_count,
					      samples_per_frame, 
					      bits_per_sample, 0, 0, 
					      &rec_port);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to create WAV writer", status);
	return 1;
    }

    pjmedia_conf_add_port(conf, pool, rec_port, NULL, NULL);
#endif


    /* Create file ports. */
    file_port = pj_pool_alloc(pool, file_count * sizeof(pjmedia_port*));

    for (i=0; i<file_count; ++i) {

	/* Load the WAV file to file port. */
	status = pjmedia_wav_player_port_create( 
			pool,		    /* pool.	    */
			argv[i+pj_optind],  /* filename	    */
			0,		    /* use default ptime */
			0,		    /* flags	    */
			0,		    /* buf size	    */
			&file_port[i]	    /* result	    */
			);
	if (status != PJ_SUCCESS) {
	    char title[80];
	    pj_ansi_sprintf(title, "Unable to use %s", argv[i+pj_optind]);
	    app_perror(THIS_FILE, title, status);
	    usage();
	    return 1;
	}

	/* Add the file port to conference bridge */
	status = pjmedia_conf_add_port( conf,		/* The bridge	    */
					pool,		/* pool		    */
					file_port[i],	/* port to connect  */
					NULL,		/* Use port's name  */
					NULL		/* ptr for slot #   */
					);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to add conference port", status);
	    return 1;
	}
    }


    /* 
     * All ports are set up in the conference bridge.
     * But at this point, no media will be flowing since no ports are
     * "connected". User must connect the port manually.
     */


    /* Dump memory usage */
    dump_pool_usage(THIS_FILE, &cp);

    /* Sleep to allow log messages to flush */
    pj_thread_sleep(100);


    /*
     * UI Menu: 
     */
    for (;;) {
	char tmp1[10];
	char tmp2[10];
	char *err;
	int src, dst, level, dur;

	puts("");
	conf_list(conf, 0);
	puts("");
	puts("Menu:");
	puts("  s    Show ports details");
	puts("  c    Connect one port to another");
	puts("  d    Disconnect port connection");
	puts("  t    Adjust signal level transmitted (tx) to a port");
	puts("  r    Adjust signal level received (rx) from a port");
	puts("  v    Display VU meter for a particular port");
	puts("  q    Quit");
	puts("");
	
	printf("Enter selection: "); fflush(stdout);

	if (fgets(tmp, sizeof(tmp), stdin) == NULL)
	    break;

	switch (tmp[0]) {
	case 's':
	    puts("");
	    conf_list(conf, 1);
	    break;

	case 'c':
	    puts("");
	    puts("Connect source port to destination port");
	    if (!input("Enter source port number", tmp1, sizeof(tmp1)) )
		continue;
	    src = strtol(tmp1, &err, 10);
	    if (*err || src < 0 || src >= port_count) {
		puts("Invalid slot number");
		continue;
	    }

	    if (!input("Enter destination port number", tmp2, sizeof(tmp2)) )
		continue;
	    dst = strtol(tmp2, &err, 10);
	    if (*err || dst < 0 || dst >= port_count) {
		puts("Invalid slot number");
		continue;
	    }

	    status = pjmedia_conf_connect_port(conf, src, dst, 0);
	    if (status != PJ_SUCCESS)
		app_perror(THIS_FILE, "Error connecting port", status);
	    
	    break;

	case 'd':
	    puts("");
	    puts("Disconnect port connection");
	    if (!input("Enter source port number", tmp1, sizeof(tmp1)) )
		continue;
	    src = strtol(tmp1, &err, 10);
	    if (*err || src < 0 || src >= port_count) {
		puts("Invalid slot number");
		continue;
	    }

	    if (!input("Enter destination port number", tmp2, sizeof(tmp2)) )
		continue;
	    dst = strtol(tmp2, &err, 10);
	    if (*err || dst < 0 || dst >= port_count) {
		puts("Invalid slot number");
		continue;
	    }

	    status = pjmedia_conf_disconnect_port(conf, src, dst);
	    if (status != PJ_SUCCESS)
		app_perror(THIS_FILE, "Error connecting port", status);
	    

	    break;

	case 't':
	    puts("");
	    puts("Adjust transmit level of a port");
	    if (!input("Enter port number", tmp1, sizeof(tmp1)) )
		continue;
	    src = strtol(tmp1, &err, 10);
	    if (*err || src < 0 || src >= port_count) {
		puts("Invalid slot number");
		continue;
	    }

	    if (!input("Enter level (-128 to >127, 0 for normal)", 
			      tmp2, sizeof(tmp2)) )
		continue;
	    level = strtol(tmp2, &err, 10);
	    if (*err || level < -128) {
		puts("Invalid level");
		continue;
	    }

	    status = pjmedia_conf_adjust_tx_level( conf, src, level);
	    if (status != PJ_SUCCESS)
		app_perror(THIS_FILE, "Error adjusting level", status);
	    break;


	case 'r':
	    puts("");
	    puts("Adjust receive level of a port");
	    if (!input("Enter port number", tmp1, sizeof(tmp1)) )
		continue;
	    src = strtol(tmp1, &err, 10);
	    if (*err || src < 0 || src >= port_count) {
		puts("Invalid slot number");
		continue;
	    }

	    if (!input("Enter level (-128 to >127, 0 for normal)", 
			      tmp2, sizeof(tmp2)) )
		continue;
	    level = strtol(tmp2, &err, 10);
	    if (*err || level < -128) {
		puts("Invalid level");
		continue;
	    }

	    status = pjmedia_conf_adjust_rx_level( conf, src, level);
	    if (status != PJ_SUCCESS)
		app_perror(THIS_FILE, "Error adjusting level", status);
	    break;

	case 'v':
	    puts("");
	    puts("Display VU meter");
	    if (!input("Enter port number to monitor", tmp1, sizeof(tmp1)) )
		continue;
	    src = strtol(tmp1, &err, 10);
	    if (*err || src < 0 || src >= port_count) {
		puts("Invalid slot number");
		continue;
	    }

	    if (!input("Enter r for rx level or t for tx level", tmp2, sizeof(tmp2)))
		continue;
	    if (tmp2[0] != 'r' && tmp2[0] != 't') {
		puts("Invalid option");
		continue;
	    }

	    if (!input("Duration to monitor (in seconds)", tmp1, sizeof(tmp1)) )
		continue;
	    dur = strtol(tmp1, &err, 10);
	    if (*err) {
		puts("Invalid duration number");
		continue;
	    }

	    monitor_level(conf, src, tmp2[0], dur);
	    break;

	case 'q':
	    goto on_quit;

	default:
	    printf("Invalid input character '%c'\n", tmp[0]);
	    break;
	}
    }

on_quit:
    
    /* Start deinitialization: */

    /* Destroy conference bridge */
    status = pjmedia_conf_destroy( conf );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Destroy file ports */
    for (i=0; i<file_count; ++i) {
	status = pjmedia_port_destroy( file_port[i]);
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    }

    /* Destroy recorder port */
    if (rec_port)
	pjmedia_port_destroy(rec_port);

    /* Release application pool */
    pj_pool_release( pool );

    /* Destroy media endpoint. */
    pjmedia_endpt_destroy( med_endpt );

    /* Destroy pool factory */
    pj_caching_pool_destroy( &cp );

    /* Shutdown PJLIB */
    pj_shutdown();

    /* Done. */
    return 0;
}
Пример #12
0
int main(int argc, char *argv[])
{
    pj_str_t input, output, srtp_crypto, srtp_key, codec;
    pjmedia_aud_dev_index dev_id = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
    pj_pcap_filter filter;
    pj_status_t status;

    enum { 
	OPT_SRC_IP = 1, OPT_DST_IP, OPT_SRC_PORT, OPT_DST_PORT,
	OPT_CODEC, OPT_PLAY_DEV_ID
    };
    struct pj_getopt_option long_options[] = {
	{ "srtp-crypto",    1, 0, 'c' },
	{ "srtp-key",	    1, 0, 'k' },
	{ "src-ip",	    1, 0, OPT_SRC_IP },
	{ "dst-ip",	    1, 0, OPT_DST_IP },
	{ "src-port",	    1, 0, OPT_SRC_PORT },
	{ "dst-port",	    1, 0, OPT_DST_PORT },
	{ "codec",	    1, 0, OPT_CODEC },
	{ "play-dev-id",    1, 0, OPT_PLAY_DEV_ID },
	{ NULL, 0, 0, 0}
    };
    int c;
    int option_index;
    char key_bin[32];

    srtp_crypto.slen = srtp_key.slen = 0;
    codec.slen = 0;

    pj_pcap_filter_default(&filter);
    filter.link = PJ_PCAP_LINK_TYPE_ETH;
    filter.proto = PJ_PCAP_PROTO_TYPE_UDP;

    /* Parse arguments */
    pj_optind = 0;
    while((c=pj_getopt_long(argc,argv, "c:k:", long_options, &option_index))!=-1) {
	switch (c) {
	case 'c':
	    srtp_crypto = pj_str(pj_optarg);
	    break;
	case 'k':
	    {
		int key_len = sizeof(key_bin);
		srtp_key = pj_str(pj_optarg);
		if (pj_base64_decode(&srtp_key, (pj_uint8_t*)key_bin, &key_len)) {
		    puts("Error: invalid key");
		    return 1;
		}
		srtp_key.ptr = key_bin;
		srtp_key.slen = key_len;
	    }
	    break;
	case OPT_SRC_IP:
	    {
		pj_str_t t = pj_str(pj_optarg);
		pj_in_addr a = pj_inet_addr(&t);
		filter.ip_src = a.s_addr;
	    }
	    break;
	case OPT_DST_IP:
	    {
		pj_str_t t = pj_str(pj_optarg);
		pj_in_addr a = pj_inet_addr(&t);
		filter.ip_dst = a.s_addr;
	    }
	    break;
	case OPT_SRC_PORT:
	    filter.src_port = pj_htons((pj_uint16_t)atoi(pj_optarg));
	    break;
	case OPT_DST_PORT:
	    filter.dst_port = pj_htons((pj_uint16_t)atoi(pj_optarg));
	    break;
	case OPT_CODEC:
	    codec = pj_str(pj_optarg);
	    break;
	case OPT_PLAY_DEV_ID:
	    dev_id = atoi(pj_optarg);
	    break;
	default:
	    puts("Error: invalid option");
	    return 1;
	}
    }

    if (pj_optind != argc - 2) {
	puts(USAGE);
	return 1;
    }

    if (!(srtp_crypto.slen) != !(srtp_key.slen)) {
	puts("Error: both SRTP crypto and key must be specified");
	puts(USAGE);
	return 1;
    }

    input = pj_str(argv[pj_optind]);
    output = pj_str(argv[pj_optind+1]);
    
    T( pj_init() );

    pj_caching_pool_init(&app.cp, NULL, 0);
    app.pool = pj_pool_create(&app.cp.factory, "pcaputil", 1000, 1000, NULL);

    T( pjlib_util_init() );
    T( pjmedia_endpt_create(&app.cp.factory, NULL, 0, &app.mept) );

    T( pj_pcap_open(app.pool, input.ptr, &app.pcap) );
    T( pj_pcap_set_filter(app.pcap, &filter) );

    pcap2wav(&codec, &output, dev_id, &srtp_crypto, &srtp_key);

    cleanup();
    return 0;
}
Пример #13
0
int codec_test_vectors(void)
{
    pjmedia_endpt *endpt;
    pjmedia_codec_mgr *mgr;
    int rc, rc_final = 0;
    struct enc_vectors {
	char	    *codec_name;
	unsigned     bit_rate;
	const char  *wav_file;
	const char  *ref_encoded_file;
    } enc_vectors[] = 
    {
#if PJMEDIA_HAS_G7221_CODEC
	{ "G7221/16000/1", 24000, 
	  "../src/test/vectors/g722_1_enc_in.wav", 
	  "../src/test/vectors/g722_1_enc_out_24000_be.pak"
	},
	{ "G7221/16000/1", 32000, 
	  "../src/test/vectors/g722_1_enc_in.wav", 
	  "../src/test/vectors/g722_1_enc_out_32000_be.pak"
	},
#endif
	{ NULL }
    };
    struct dec_vectors {
	char	    *codec_name;
	unsigned     bit_rate;
	unsigned     encoded_frame_len;
	void	    (*manip)(short *pcm, unsigned count);
	const char  *enc_file;
	const char  *ref_pcm_file;
    } dec_vectors[] = 
    {
#if PJMEDIA_HAS_G7221_CODEC
	{ "G7221/16000/1", 24000, 60,
	  &g7221_pcm_manip,
	  "../src/test/vectors/g722_1_enc_out_24000_be.pak", 
	  "../src/test/vectors/g722_1_dec_out_24000.pcm"
	},
	{ "G7221/16000/1", 32000, 80,
	  &g7221_pcm_manip,
	  "../src/test/vectors/g722_1_enc_out_32000_be.pak", 
	  "../src/test/vectors/g722_1_dec_out_32000.pcm"
	},
	{ "G7221/16000/1", 24000, 60,
	  &g7221_pcm_manip,
	  "../src/test/vectors/g722_1_dec_in_24000_fe.itu",
	  "../src/test/vectors/g722_1_dec_out_24000_fe.pcm"
	},
	{ "G7221/16000/1", 32000, 80,
	  &g7221_pcm_manip,
	  "../src/test/vectors/g722_1_dec_in_32000_fe.itu",
	  "../src/test/vectors/g722_1_dec_out_32000_fe.pcm"
	},
#endif
	{ NULL }
    };
    unsigned i;
    pj_status_t status;

    status = pjmedia_endpt_create(mem, NULL, 0, &endpt);
    if (status != PJ_SUCCESS)
	return -5;

    mgr = pjmedia_endpt_get_codec_mgr(endpt);

#if PJMEDIA_HAS_G7221_CODEC
    status = pjmedia_codec_g7221_init(endpt);
    if (status != PJ_SUCCESS) {
	pjmedia_endpt_destroy(endpt);
	return -7;
    }

    /* Set shift value to zero for the test vectors */
    pjmedia_codec_g7221_set_pcm_shift(0);
#endif

    PJ_LOG(3,(THIS_FILE,"  encode tests:"));
    for (i=0; i<PJ_ARRAY_SIZE(enc_vectors); ++i) {
	if (!enc_vectors[i].codec_name)
	    continue;
	PJ_LOG(3,(THIS_FILE,"    %s @%d bps %s ==> %s", 
		  enc_vectors[i].codec_name, 
		  enc_vectors[i].bit_rate,
		  enc_vectors[i].wav_file,
		  enc_vectors[i].ref_encoded_file));
	rc = codec_test_encode(mgr, enc_vectors[i].codec_name,
			       enc_vectors[i].bit_rate,
			       enc_vectors[i].wav_file,
			       enc_vectors[i].ref_encoded_file);
	if (rc != 0)
	    rc_final = rc;
    }

    PJ_LOG(3,(THIS_FILE,"  decode tests:"));
    for (i=0; i<PJ_ARRAY_SIZE(dec_vectors); ++i) {
	if (!dec_vectors[i].codec_name)
	    continue;
	PJ_LOG(3,(THIS_FILE,"    %s @%d bps %s ==> %s", 
		  dec_vectors[i].codec_name, 
		  dec_vectors[i].bit_rate,
		  dec_vectors[i].enc_file,
		  dec_vectors[i].ref_pcm_file));
	rc = codec_test_decode(mgr, dec_vectors[i].codec_name,
			       dec_vectors[i].bit_rate,
			       dec_vectors[i].encoded_frame_len,
			       dec_vectors[i].enc_file,
			       dec_vectors[i].ref_pcm_file,
			       dec_vectors[i].manip);
	if (rc != 0)
	    rc_final = rc;
    }

    if (pj_file_exists(TMP_OUT))
	pj_file_delete(TMP_OUT);

    pjmedia_endpt_destroy(endpt);
    return rc_final;
}