Esempio n. 1
0
/* Utility: display error message and exit application (usually
 * because of fatal error.
 */
void err_exit( const char *title, pj_status_t status , struct ice_trans_s* icetrans)
{

    int i;
        if (status != PJ_SUCCESS) {
            natclient_perror(title, status);
        }
        PJ_LOG(3,(THIS_FILE, "Shutting down.."));

        if (icetrans->icest)
            pj_ice_strans_destroy(icetrans->icest);

        pj_thread_sleep(500);

        icetrans->thread_quit_flag = PJ_TRUE;
        if (icetrans->thread) {
            pj_thread_join(icetrans->thread);
            pj_thread_destroy(icetrans->thread);
        }

        if (icetrans->ice_cfg.stun_cfg.ioqueue)
            pj_ioqueue_destroy(icetrans->ice_cfg.stun_cfg.ioqueue);

        if (icetrans->ice_cfg.stun_cfg.timer_heap)
            pj_timer_heap_destroy(icetrans->ice_cfg.stun_cfg.timer_heap);

        pj_caching_pool_destroy(&icetrans->cp);

        pj_shutdown();

        if (icetrans->log_fhnd) {
            fclose(icetrans->log_fhnd);
            icetrans->log_fhnd = NULL;
        }
    exit(status != PJ_SUCCESS);

}
Esempio n. 2
0
int main() {
    pj_caching_pool cp;
    pj_pool_t *pool;
    int i;
    pj_thread_t *thread1;
    
    pj_log_set_level(3);
    CHECK(__FILE__, pj_init());
    pj_srand(123765);
    pj_caching_pool_init(&cp, NULL, 1024);

    pool = pj_pool_create(&cp.factory, "objpool", 128, 128, NULL);

    pj_thread_create(pool, "thread1", &do_test, pool, PJ_THREAD_DEFAULT_STACK_SIZE, 0, &thread1);
    pj_thread_sleep(500);
    do_test(pool);

    pj_thread_join(thread1);

    pj_pool_release(pool);
    pj_caching_pool_destroy(&cp);
    pj_shutdown();
    return 0;
}
Esempio n. 3
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;

}
Esempio n. 4
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;
}
Esempio n. 5
0
static int main_func(int argc, char *argv[])
{
    pj_caching_pool cp;
    pj_pool_t *pool;
    int rc = 0;
    pj_status_t status = PJ_SUCCESS;

    if (argc != 2) {
        puts("Error: filename 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);

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

    pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
    pjmedia_converter_mgr_create(pool, NULL);
    pjmedia_event_mgr_create(pool, 0, NULL);
    pjmedia_vid_codec_mgr_create(pool, NULL);

    status = pjmedia_vid_dev_subsys_init(&cp.factory);
    if (status != PJ_SUCCESS)
        goto on_return;

    status = pjmedia_aud_subsys_init(&cp.factory);
    if (status != PJ_SUCCESS) {
        goto on_return;
    }

#if PJMEDIA_HAS_FFMPEG_VID_CODEC
    status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory);
    if (status != PJ_SUCCESS)
        goto on_return;
#endif

    rc = aviplay(pool, argv[1]);

    /*
     * File should be playing and looping now
     */

    /* Without this sleep, Windows/DirectSound will repeteadly
     * play the last frame during destroy.
     */
    pj_thread_sleep(100);

on_return:
#if PJMEDIA_HAS_FFMPEG_VID_CODEC
    pjmedia_codec_ffmpeg_vid_deinit();
#endif
    pjmedia_aud_subsys_shutdown();
    pjmedia_vid_dev_subsys_shutdown();

    pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance());
    pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance());
    pjmedia_event_mgr_destroy(pjmedia_event_mgr_instance());
    pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance());

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

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

    /* Shutdown PJLIB */
    pj_shutdown();

    /* Done. */
    return 0;
}
Esempio n. 6
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t	  *pool;
    pjmedia_port  *wav_play;
    pjmedia_port  *wav_rec;
    pjmedia_port  *wav_out;
    pj_status_t status;
    pjmedia_echo_state *ec;
    pjmedia_frame play_frame, rec_frame;
    unsigned opt = 0;
    unsigned latency_ms = 25;
    unsigned tail_ms = TAIL_LENGTH;
    pj_timestamp t0, t1;
    int i, repeat=1, interactive=0, c;

    pj_optind = 0;
    while ((c=pj_getopt(argc, argv, "d:l:a:r:i")) !=-1) {
	switch (c) {
	case 'd':
	    latency_ms = atoi(pj_optarg);
	    if (latency_ms < 25) {
		puts("Invalid delay");
		puts(desc);
	    }
	    break;
	case 'l':
	    tail_ms = atoi(pj_optarg);
	    break;
	case 'a':
	    {
		int alg = atoi(pj_optarg);
		switch (alg) {
		case 0:
		    opt = 0;
		case 1:
		    opt = PJMEDIA_ECHO_SPEEX;
		    break;
		case 3:
		    opt = PJMEDIA_ECHO_SIMPLE;
		    break;
		default:
		    puts("Invalid algorithm");
		    puts(desc);
		    return 1;
		}
	    }
	    break;
	case 'r':
	    repeat = atoi(pj_optarg);
	    if (repeat < 1) {
		puts("Invalid repeat count");
		puts(desc);
		return 1;
	    }
	    break;
	case 'i':
	    interactive = 1;
	    break;
	}
    }

    if (argc - pj_optind != 3) {
	puts("Error: missing argument(s)");
	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    */
			   );

    /* Open wav_play */
    status = pjmedia_wav_player_port_create(pool, argv[pj_optind], PTIME, 
					    PJMEDIA_FILE_NO_LOOP, 0, 
					    &wav_play);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Error opening playback WAV file", status);
	return 1;
    }
    
    /* Open recorded wav */
    status = pjmedia_wav_player_port_create(pool, argv[pj_optind+1], PTIME, 
					    PJMEDIA_FILE_NO_LOOP, 0, 
					    &wav_rec);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Error opening recorded WAV file", status);
	return 1;
    }

    /* play and rec WAVs must have the same clock rate */
    if (wav_play->info.clock_rate != wav_rec->info.clock_rate) {
	puts("Error: clock rate mismatch in the WAV files");
	return 1;
    }

    /* .. and channel count */
    if (wav_play->info.channel_count != wav_rec->info.channel_count) {
	puts("Error: clock rate mismatch in the WAV files");
	return 1;
    }

    /* Create output wav */
    status = pjmedia_wav_writer_port_create(pool, argv[pj_optind+2],
					    wav_play->info.clock_rate,
					    wav_play->info.channel_count,
					    wav_play->info.samples_per_frame,
					    wav_play->info.bits_per_sample,
					    0, 0, &wav_out);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Error opening output WAV file", status);
	return 1;
    }

    /* Create echo canceller */
    status = pjmedia_echo_create2(pool, wav_play->info.clock_rate,
				  wav_play->info.channel_count,
				  wav_play->info.samples_per_frame,
				  tail_ms, latency_ms,
				  opt, &ec);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Error creating EC", status);
	return 1;
    }


    /* Processing loop */
    play_frame.buf = pj_pool_alloc(pool, wav_play->info.samples_per_frame<<1);
    rec_frame.buf = pj_pool_alloc(pool, wav_play->info.samples_per_frame<<1);
    pj_get_timestamp(&t0);
    for (i=0; i < repeat; ++i) {
	for (;;) {
	    play_frame.size = wav_play->info.samples_per_frame << 1;
	    status = pjmedia_port_get_frame(wav_play, &play_frame);
	    if (status != PJ_SUCCESS)
		break;

	    status = pjmedia_echo_playback(ec, (short*)play_frame.buf);

	    rec_frame.size = wav_play->info.samples_per_frame << 1;
	    status = pjmedia_port_get_frame(wav_rec, &rec_frame);
	    if (status != PJ_SUCCESS)
		break;

	    status = pjmedia_echo_capture(ec, (short*)rec_frame.buf, 0);

	    //status = pjmedia_echo_cancel(ec, (short*)rec_frame.buf, 
	    //			     (short*)play_frame.buf, 0, NULL);

	    pjmedia_port_put_frame(wav_out, &rec_frame);
	}

	pjmedia_wav_player_port_set_pos(wav_play, 0);
	pjmedia_wav_player_port_set_pos(wav_rec, 0);
    }
    pj_get_timestamp(&t1);

    i = pjmedia_wav_writer_port_get_pos(wav_out) / sizeof(pj_int16_t) * 1000 / 
	(wav_out->info.clock_rate * wav_out->info.channel_count);
    PJ_LOG(3,(THIS_FILE, "Processed %3d.%03ds audio",
	      i / 1000, i % 1000));
    PJ_LOG(3,(THIS_FILE, "Completed in %u msec\n", pj_elapsed_msec(&t0, &t1)));

    /* Destroy file port(s) */
    status = pjmedia_port_destroy( wav_play );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    status = pjmedia_port_destroy( wav_rec );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
    status = pjmedia_port_destroy( wav_out );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Destroy ec */
    pjmedia_echo_destroy(ec);

    /* 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();

    if (interactive) {
	char s[10], *dummy;
	puts("ENTER to quit");
	dummy = fgets(s, sizeof(s), stdin);
    }

    /* Done. */
    return 0;
}
Esempio n. 7
0
int main()
{
    pj_caching_pool cp;
    pj_cli_cfg cli_cfg;
    pj_cli_telnet_cfg tcfg;
    pj_str_t xml;
    pj_status_t status;
    int i;        

    pj_init();
    pj_caching_pool_init(&cp, NULL, 0);
    pjlib_util_init();

    /*
     * Create CLI app.
     */
    pj_cli_cfg_default(&cli_cfg);
    cli_cfg.pf = &cp.factory;
    cli_cfg.name = pj_str("mycliapp");
    cli_cfg.title = pj_str("My CLI Application");

    status = pj_cli_create(&cli_cfg, &cli);
    if (status != PJ_SUCCESS)
	goto on_return;

    /*
     * Register some commands.
     */
    for (i = 0; i < sizeof(cmd_xmls)/sizeof(cmd_xmls[0]); i++) {
        xml = pj_str(cmd_xmls[i].xml);	
        status = pj_cli_add_cmd_from_xml(cli, NULL, &xml, 
	    cmd_xmls[i].handler, NULL, get_codec_list);
        if (status != PJ_SUCCESS)
	    goto on_return;
    }

    /*
     * Start telnet daemon
     */
    pj_cli_telnet_cfg_default(&tcfg);
//    tcfg.passwd = pj_str("pjsip");
#if USE_RANDOM_PORT
    tcfg.port = 0;
#else
    tcfg.port = 2233;
#endif    
    tcfg.prompt_str = pj_str("CoolWater% ");
    status = pj_cli_telnet_create(cli, &tcfg, NULL);
    if (status != PJ_SUCCESS)
	goto on_return;

    /*
     * Run the system specific main loop.
     */
    status = app_main(cli);

on_return:

    /*
     * Destroy
     */
    pj_cli_destroy(cli);
    cli = NULL;
    pj_caching_pool_destroy(&cp);
    pj_shutdown();

    return (status != PJ_SUCCESS ? 1 : 0);
}
Esempio n. 8
0
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pj_pool_t *pool;

    pjmedia_conf *conf;
    pjmedia_port *player_port1, *player_port2, *writer_port;
    pjmedia_master_port *master_port;
    unsigned slot1, slot2;

    pj_status_t status;

    char tmp[10];

    slot1 = 1;
    slot2 = 2;

    pj_ssize_t len;

    if (argc < 5) {
        printf("Usage: %s <clock_rate> <player file 1> <player file 2> <mix file>\n", argv[0]);
        exit(-1);
    }

    unsigned clock_rate = atoi(argv[1]);

    // Initialialize
    pj_init() ;
    pj_caching_pool_init(&cp, NULL, 0);
    pool = pj_pool_create(&cp.factory, "pool", 1000, 1000, NULL);

    // Create player port
    pjmedia_wav_player_port_create(pool, argv[2], 20, PJMEDIA_FILE_NO_LOOP, 0, &player_port1);
    pjmedia_wav_player_port_create(pool, argv[3], 20, PJMEDIA_FILE_NO_LOOP, 0, &player_port2);

    // Create the bridge
    pjmedia_conf_create(pool, MAX_WAV+4, clock_rate, 1, clock_rate * PTIME / 1000, 16, PJMEDIA_CONF_NO_DEVICE, &conf);

    pjmedia_conf_add_port(conf, pool, player_port2, NULL, &slot2);
    pjmedia_conf_add_port(conf, pool, player_port1, NULL, &slot1);

    pjmedia_conf_connect_port(conf, slot1, 0, 0);
    pjmedia_conf_connect_port(conf, slot2, 0, 0);

    pjmedia_port *port = pjmedia_conf_get_master_port(conf);

    //Both ports MUST have equal clock rate, samples per frame and channel count
    pjmedia_wav_writer_port_create(pool, argv[4], 
            PJMEDIA_PIA_SRATE(&port->info),
            PJMEDIA_PIA_CCNT(&port->info),
            PJMEDIA_PIA_SPF(&port->info),
            PJMEDIA_PIA_BITS(&port->info),
            0, 0, &writer_port);
    pjmedia_master_port_create(pool, port, writer_port, 0, &master_port);
    if (status != PJ_SUCCESS) {
        return 1;
    }

    status = pjmedia_master_port_start(master_port);
    pj_thread_sleep(5000);

    /* Shutdown everything */
    pjmedia_master_port_destroy(master_port, PJ_TRUE);

    pj_pool_release(pool);
    pj_caching_pool_destroy(&cp);
    pj_shutdown();

    return 0;
}
Esempio n. 9
0
/*
 * main()
 *
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pj_thread_t *thread;
    pj_pool_t *pool;
    pj_status_t status;
    
    if (argc != 2) {
	puts("Error: destination URL needed");
	return 0;
    }

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


    /* 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 the endpoint: */
    status = pjsip_endpt_create(&cp.factory, "sipstateless", 
				&sip_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* 
     * Add UDP transport, with hard-coded port 
     */
    {
	pj_sockaddr_in addr;

	addr.sin_family = pj_AF_INET();
	addr.sin_addr.s_addr = 0;
	addr.sin_port = pj_htons(PORT);

	status = pjsip_udp_transport_start( sip_endpt, &addr, NULL, 1, NULL);
	if (status != PJ_SUCCESS) {
	    PJ_LOG(3,(THIS_FILE, 
		      "Error starting UDP transport (port in use?)"));
	    return 1;
	}
    }

    status = pjsip_tsx_layer_init_module(sip_endpt);
    pj_assert(status == PJ_SUCCESS);

    status = pjsip_ua_init_module(sip_endpt, NULL);
    pj_assert(status == PJ_SUCCESS);

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

    pool = pjsip_endpt_create_pool(sip_endpt, "", 1000, 1000);

    status = pj_thread_create(pool, "", &worker_thread, NULL, 0, 0, &thread);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    printf("Destination URL: %s\n", argv[1]);

    for (;;) {
	char line[10];

	fgets(line, sizeof(line), stdin);

	switch (line[0]) {
	case 'm':
	    make_call(argv[1], PJ_FALSE);
	    break;
	case 'M':
	    make_call(argv[1], PJ_TRUE);
	    break;
	case 'r':
	    reinvite(PJ_FALSE);
	    break;
	case 'R':
	    reinvite(PJ_TRUE);
	    break;
	case 'h':
	    hangup();
	    break;
	case 'q':
	    goto on_quit;
	}
    }

on_quit:
    quit_flag = 1;
    pj_thread_join(thread);

    pjsip_endpt_destroy(sip_endpt);
    pj_caching_pool_destroy(&cp);
    pj_shutdown();
    return 0;
}
Esempio n. 10
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) {
	    pjmedia_port_get_frame(port, &frm);
	    fwrite(buf, SAMPLES_PER_FRAME, 2, f);
	}

	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;
}
Esempio n. 11
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_port *file_port;
    pjmedia_snd_port *snd_port;
    char tmp[10];
    pj_status_t status;


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

    /* 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    */
			   );

    /* Create WAVE file writer port. */
    status = pjmedia_wav_writer_port_create(  pool, argv[1],
					      CLOCK_RATE,
					      NCHANNELS,
					      SAMPLES_PER_FRAME,
					      BITS_PER_SAMPLE,
					      0, 0, 
					      &file_port);
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to open WAV file for writing", status);
	return 1;
    }

    /* Create sound player port. */
    status = pjmedia_snd_port_create_rec( 
		 pool,				    /* pool		    */
		 -1,				    /* use default dev.	    */
		 file_port->info.clock_rate,	    /* clock rate.	    */
		 file_port->info.channel_count,	    /* # of channels.	    */
		 file_port->info.samples_per_frame, /* samples per frame.   */
		 file_port->info.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 file port to the sound player.
     * Stream playing will commence immediately.
     */
    status = pjmedia_snd_port_connect( snd_port, file_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);



    /* 
     * Recording should be started now. 
     */


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


    printf("Recodring %s..\n", argv[1]);
    puts("");
    puts("Press <ENTER> to stop recording 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 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;
}
Esempio n. 12
0
int main() {
    pj_caching_pool cp;
    pj_cli_cfg cli_cfg;
    pj_cli_telnet_cfg tcfg;
    pj_str_t xml;
    pj_status_t status;
    pj_status_t cli_status;
    int i;
    pj_log_set_level(LOG_LEVEL);
    print_msg(("", "INITING .... \n"));
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    if (status != PJ_SUCCESS) {
        print_msg(("", "PJ INIT FAILED \n"));
    }

    pj_caching_pool_init(&cp, NULL, 0);
    pjlib_util_init();
    /*
     * Create CLI app.
     */
    pj_cli_cfg_default(&cli_cfg);

    print_msg(("", "INITING CLI CFG....  \n"));
    cli_cfg.pf = &cp.factory;
    cli_cfg.name = pj_str("tinysipcli");
    cli_cfg.title = pj_str("TINYSIP");

    cli_status = pj_cli_create(&cli_cfg, &cli);
    print_msg(("", "AFTER INITING CLI CFG....  \n"));

    if (cli_status != PJ_SUCCESS) {
        print_msg(("", "CLI FAILED \n"));
        goto on_return;
    }

    /*
     * Register some commands.
     */
    for (i = 0; i < sizeof(cmd_xmls) / sizeof(cmd_xmls[0]); i++) {
        xml = pj_str(cmd_xmls[i].xml);
//        print_msg(("",cmd_xmls[i].xml));
        status = pj_cli_add_cmd_from_xml(cli, NULL, &xml, cmd_xmls[i].handler,
                                         NULL, get_cmd_list);
        if (status != PJ_SUCCESS)
            continue;
//        goto on_return;
    }
    /* Create pjsua first! */
    status = pjsua_create();
    if (status != PJ_SUCCESS)
        error_exit("Error in pjsua_create()", status);

    /* Init pjsua */
    {
        pjsua_logging_config log_cfg;
        pjsua_logging_config_default(&log_cfg);
        log_cfg.console_level = LOG_LEVEL;

        pjsua_config cfg;
        pjsua_config_default(&cfg);


        cfg.cb.on_incoming_call = &on_incoming_call;
        cfg.cb.on_call_media_state = &on_call_media_state;
        cfg.cb.on_call_state = &on_call_state;

        status = pjsua_init(&cfg, &log_cfg, NULL);
        if (status != PJ_SUCCESS)
            error_exit("Error in pjsua_init()", status);
    }

    /* Add UDP transport. */
    {
        pjsua_transport_config cfg;

        pjsua_transport_config_default(&cfg);
        cfg.port = 5060;
        status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);
        if (status != PJ_SUCCESS)
            error_exit("Error creating transport", status);
    }


    /*
     * Start telnet daemon
     */
    pj_cli_telnet_cfg_default(&tcfg);
//    tcfg.passwd = pj_str("pjsip");
#if USE_RANDOM_PORT
    tcfg.port = 0;
#else
    tcfg.port = 2233;
#endif
    tcfg.prompt_str = pj_str("CMD % ");
    status = pj_cli_telnet_create(cli, &tcfg, NULL);
    if (status != PJ_SUCCESS)
        goto on_return;

    /*
     * Run the system specific main loop.
     */
    status = app_main(cli);

on_return:

    print_msg(("", "There're some issues, application is going down now!\n"));
    /*
     * Destroy
     */
    pj_cli_destroy(cli);
    cli = NULL;
    pj_caching_pool_destroy(&cp);
    pj_shutdown();

    return (status != PJ_SUCCESS ? 1 : 0);
}
Esempio n. 13
0
/* Application init */
static pj_status_t app_init()
{
    unsigned i, count;
    pj_status_t status;

    /* Redirect log */
    pj_log_set_log_func((void (*)(int,const char*,int)) &log_writer);
    pj_log_set_decor(PJ_LOG_HAS_NEWLINE);
    pj_log_set_level(3);

    /* Init pjlib */
    status = pj_init();
    if (status != PJ_SUCCESS) {
    	app_perror("pj_init()", status);
    	return status;
    }

    pj_caching_pool_init(&cp, NULL, 0);

    /* Init sound subsystem */
    status = pjmedia_snd_init(&cp.factory);
    if (status != PJ_SUCCESS) {
    	app_perror("pjmedia_snd_init()", status);
        pj_caching_pool_destroy(&cp);
    	pj_shutdown();
    	return status;
    }

    count = pjmedia_snd_get_dev_count();
    PJ_LOG(3,(THIS_FILE, "Device count: %d", count));
    for (i=0; i<count; ++i) {
    	const pjmedia_snd_dev_info *info;

    	info = pjmedia_snd_get_dev_info(i);
    	PJ_LOG(3, (THIS_FILE, "%d: %s %d/%d %dHz",
    		   i, info->name, info->input_count, info->output_count,
    		   info->default_samples_per_sec));
    }

    /* Create pool */
    pool = pj_pool_create(&cp.factory, THIS_FILE, 512, 512, NULL);
    if (pool == NULL) {
    	app_perror("pj_pool_create()", status);
        pj_caching_pool_destroy(&cp);
    	pj_shutdown();
    	return status;
    }

    /* Init delay buffer */
    status = pjmedia_delay_buf_create(pool, THIS_FILE, CLOCK_RATE,
				      SAMPLES_PER_FRAME, CHANNEL_COUNT,
				      0, 0, &delaybuf);
    if (status != PJ_SUCCESS) {
    	app_perror("pjmedia_delay_buf_create()", status);
        //pj_caching_pool_destroy(&cp);
    	//pj_shutdown();
    	//return status;
    }

    return PJ_SUCCESS;
}
Esempio n. 14
0
/* Application init */
static pj_status_t app_init()
{
    unsigned i, count;
    pj_status_t status;

    /* Redirect log */
    pj_log_set_log_func((void (*)(int,const char*,int)) &log_writer);
    pj_log_set_decor(PJ_LOG_HAS_NEWLINE);
    pj_log_set_level(3);

    /* Init pjlib */
    status = pj_init();
    if (status != PJ_SUCCESS) {
    	app_perror("pj_init()", status);
    	return status;
    }

    pj_caching_pool_init(&cp, NULL, 0);

    /* Init sound subsystem */
    status = pjmedia_aud_subsys_init(&cp.factory);
    if (status != PJ_SUCCESS) {
    	app_perror("pjmedia_snd_init()", status);
        pj_caching_pool_destroy(&cp);
    	pj_shutdown();
    	return status;
    }

    count = pjmedia_aud_dev_count();
    PJ_LOG(3,(THIS_FILE, "Device count: %d", count));
    for (i=0; i<count; ++i) {
    	pjmedia_aud_dev_info info;
    	pj_status_t status;

    	status = pjmedia_aud_dev_get_info(i, &info);
    	pj_assert(status == PJ_SUCCESS);
    	PJ_LOG(3, (THIS_FILE, "%d: %s %d/%d %dHz",
    		   i, info.name, info.input_count, info.output_count,
    		   info.default_samples_per_sec));
    	
	unsigned j;

	/* Print extended formats supported by this audio device */
	PJ_LOG(3, (THIS_FILE, "   Extended formats supported:"));
	for (j = 0; j < info.ext_fmt_cnt; ++j) {
	    const char *fmt_name = NULL;
	    
	    switch (info.ext_fmt[j].id) {
	    case PJMEDIA_FORMAT_PCMA:
		fmt_name = "PCMA";
		break;
	    case PJMEDIA_FORMAT_PCMU:
		fmt_name = "PCMU";
		break;
	    case PJMEDIA_FORMAT_AMR:
		fmt_name = "AMR-NB";
		break;
	    case PJMEDIA_FORMAT_G729:
		fmt_name = "G729";
		break;
	    case PJMEDIA_FORMAT_ILBC:
		fmt_name = "ILBC";
		break;
	    case PJMEDIA_FORMAT_PCM:
		fmt_name = "PCM";
		break;
	    default:
		fmt_name = "Unknown";
		break;
	    }
	    PJ_LOG(3, (THIS_FILE, "   - %s", fmt_name));
	}
    }

    /* Create pool */
    pool = pj_pool_create(&cp.factory, THIS_FILE, 512, 512, NULL);
    if (pool == NULL) {
    	app_perror("pj_pool_create()", status);
        pj_caching_pool_destroy(&cp);
    	pj_shutdown();
    	return status;
    }

    /* Init delay buffer */
    status = pjmedia_delay_buf_create(pool, THIS_FILE, CLOCK_RATE,
				      SAMPLES_PER_FRAME, CHANNEL_COUNT,
				      0, 0, &delaybuf);
    if (status != PJ_SUCCESS) {
    	app_perror("pjmedia_delay_buf_create()", status);
        //pj_caching_pool_destroy(&cp);
    	//pj_shutdown();
    	//return status;
    }

    return PJ_SUCCESS;
}
Esempio n. 15
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(0);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Must create a pool factory before we can allocate any memory. */
    pj_caching_pool_init(0, &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);
	// charles modified
    status = pjmedia_endpt_create(0, &cp.factory, NULL, 1, 0, &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(0);


    /* Done. */
    return 0;
}
Esempio n. 16
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_vid_stream *stream = NULL;
    pjmedia_port *enc_port, *dec_port;
    pj_status_t status; 

    pjmedia_vid_port *capture=NULL, *renderer=NULL;
    pjmedia_vid_port_param vpp;

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
    /* SRTP variables */
    pj_bool_t use_srtp = PJ_FALSE;
    char tmp_tx_key[64];
    char tmp_rx_key[64];
    pj_str_t  srtp_tx_key = {NULL, 0};
    pj_str_t  srtp_rx_key = {NULL, 0};
    pj_str_t  srtp_crypto_suite = {NULL, 0};
    int	tmp_key_len;
#endif

    /* Default values */
    const pjmedia_vid_codec_info *codec_info;
    pjmedia_vid_codec_param codec_param;
    pjmedia_dir dir = PJMEDIA_DIR_DECODING;
    pj_sockaddr_in remote_addr;
    pj_uint16_t local_port = 4000;
    char *codec_id = NULL;
    pjmedia_rect_size tx_size = {0};
    pj_int8_t rx_pt = -1, tx_pt = -1;

    play_file_data play_file = { NULL };
    pjmedia_port *play_port = NULL;
    pjmedia_vid_codec *play_decoder = NULL;
    pjmedia_clock *play_clock = NULL;

    enum {
	OPT_CODEC	= 'c',
	OPT_LOCAL_PORT	= 'p',
	OPT_REMOTE	= 'r',
	OPT_PLAY_FILE	= 'f',
	OPT_SEND_RECV	= 'b',
	OPT_SEND_ONLY	= 's',
	OPT_RECV_ONLY	= 'i',
	OPT_SEND_WIDTH	= 'W',
	OPT_SEND_HEIGHT	= 'H',
	OPT_RECV_PT	= 't',
	OPT_SEND_PT	= 'T',
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	OPT_USE_SRTP	= 'S',
#endif
	OPT_SRTP_TX_KEY	= 'x',
	OPT_SRTP_RX_KEY	= 'y',
	OPT_HELP	= 'h',
    };

    struct pj_getopt_option long_options[] = {
	{ "codec",	    1, 0, OPT_CODEC },
	{ "local-port",	    1, 0, OPT_LOCAL_PORT },
	{ "remote",	    1, 0, OPT_REMOTE },
	{ "play-file",	    1, 0, OPT_PLAY_FILE },
	{ "send-recv",      0, 0, OPT_SEND_RECV },
	{ "send-only",      0, 0, OPT_SEND_ONLY },
	{ "recv-only",      0, 0, OPT_RECV_ONLY },
	{ "send-width",     1, 0, OPT_SEND_WIDTH },
	{ "send-height",    1, 0, OPT_SEND_HEIGHT },
	{ "recv-pt",        1, 0, OPT_RECV_PT },
	{ "send-pt",        1, 0, OPT_SEND_PT },
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	{ "use-srtp",	    2, 0, OPT_USE_SRTP },
	{ "srtp-tx-key",    1, 0, OPT_SRTP_TX_KEY },
	{ "srtp-rx-key",    1, 0, OPT_SRTP_RX_KEY },
#endif
	{ "help",	    0, 0, OPT_HELP },
	{ NULL, 0, 0, 0 },
    };

    int c;
    int option_index;


    pj_bzero(&remote_addr, sizeof(remote_addr));


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


    /* Parse arguments */
    pj_optind = 0;
    while((c=pj_getopt_long(argc,argv, "h", long_options, &option_index))!=-1)
    {
	switch (c) {
	case OPT_CODEC:
	    codec_id = pj_optarg;
	    break;

	case OPT_LOCAL_PORT:
	    local_port = (pj_uint16_t) atoi(pj_optarg);
	    if (local_port < 1) {
		printf("Error: invalid local port %s\n", pj_optarg);
		return 1;
	    }
	    break;

	case OPT_REMOTE:
	    {
		pj_str_t ip = pj_str(strtok(pj_optarg, ":"));
		pj_uint16_t port = (pj_uint16_t) atoi(strtok(NULL, ":"));

		status = pj_sockaddr_in_init(&remote_addr, &ip, port);
		if (status != PJ_SUCCESS) {
		    app_perror(THIS_FILE, "Invalid remote address", status);
		    return 1;
		}
	    }
	    break;

	case OPT_PLAY_FILE:
	    play_file.file_name = pj_optarg;
	    break;

	case OPT_SEND_RECV:
	    dir = PJMEDIA_DIR_ENCODING_DECODING;
	    break;

	case OPT_SEND_ONLY:
	    dir = PJMEDIA_DIR_ENCODING;
	    break;

	case OPT_RECV_ONLY:
	    dir = PJMEDIA_DIR_DECODING;
	    break;

	case OPT_SEND_WIDTH:
	    tx_size.w = (unsigned)atoi(pj_optarg);
	    break;

	case OPT_SEND_HEIGHT:
	    tx_size.h = (unsigned)atoi(pj_optarg);
	    break;

	case OPT_RECV_PT:
	    rx_pt = (pj_int8_t)atoi(pj_optarg);
	    break;

	case OPT_SEND_PT:
	    tx_pt = (pj_int8_t)atoi(pj_optarg);
	    break;

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	case OPT_USE_SRTP:
	    use_srtp = PJ_TRUE;
	    if (pj_optarg) {
		pj_strset(&srtp_crypto_suite, pj_optarg, strlen(pj_optarg));
	    } else {
		srtp_crypto_suite = pj_str("AES_CM_128_HMAC_SHA1_80");
	    }
	    break;

	case OPT_SRTP_TX_KEY:
	    tmp_key_len = hex_string_to_octet_string(tmp_tx_key, pj_optarg, 
						     strlen(pj_optarg));
	    pj_strset(&srtp_tx_key, tmp_tx_key, tmp_key_len/2);
	    break;

	case OPT_SRTP_RX_KEY:
	    tmp_key_len = hex_string_to_octet_string(tmp_rx_key, pj_optarg,
						     strlen(pj_optarg));
	    pj_strset(&srtp_rx_key, tmp_rx_key, tmp_key_len/2);
	    break;
#endif

	case OPT_HELP:
	    usage();
	    return 1;

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

    }


    /* Verify arguments. */
    if (dir & PJMEDIA_DIR_ENCODING) {
	if (remote_addr.sin_addr.s_addr == 0) {
	    printf("Error: remote address must be set\n");
	    return 1;
	}
    }

    if (play_file.file_name != NULL && dir != PJMEDIA_DIR_ENCODING) {
	printf("Direction is set to --send-only because of --play-file\n");
	dir = PJMEDIA_DIR_ENCODING;
    }

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
    /* SRTP validation */
    if (use_srtp) {
	if (!srtp_tx_key.slen || !srtp_rx_key.slen)
	{
	    printf("Error: Key for each SRTP stream direction must be set\n");
	    return 1;
	}
    }
#endif

    /* 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 application purpose */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "app",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );

    /* Init video format manager */
    pjmedia_video_format_mgr_create(pool, 64, 0, NULL);

    /* Init video converter manager */
    pjmedia_converter_mgr_create(pool, NULL);

    /* Init event manager */
    pjmedia_event_mgr_create(pool, 0, NULL);

    /* Init video codec manager */
    pjmedia_vid_codec_mgr_create(pool, NULL);

    /* Init video subsystem */
    pjmedia_vid_dev_subsys_init(&cp.factory);

    /* Register all supported codecs */
    status = init_codecs(&cp.factory);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Find which codec to use. */
    if (codec_id) {
	unsigned count = 1;
	pj_str_t str_codec_id = pj_str(codec_id);

        status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL,
						         &str_codec_id, &count,
						         &codec_info, NULL);
	if (status != PJ_SUCCESS) {
	    printf("Error: unable to find codec %s\n", codec_id);
	    return 1;
	}
    } else {
        static pjmedia_vid_codec_info info[1];
        unsigned count = PJ_ARRAY_SIZE(info);

	/* Default to first codec */
	pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, NULL);
        codec_info = &info[0];
    }

    /* Get codec default param for info */
    status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info, 
				                     &codec_param);
    pj_assert(status == PJ_SUCCESS);
    
    /* Set outgoing video size */
    if (tx_size.w && tx_size.h)
        codec_param.enc_fmt.det.vid.size = tx_size;

#if DEF_RENDERER_WIDTH && DEF_RENDERER_HEIGHT
    /* Set incoming video size */
    if (DEF_RENDERER_WIDTH > codec_param.dec_fmt.det.vid.size.w)
	codec_param.dec_fmt.det.vid.size.w = DEF_RENDERER_WIDTH;
    if (DEF_RENDERER_HEIGHT > codec_param.dec_fmt.det.vid.size.h)
	codec_param.dec_fmt.det.vid.size.h = DEF_RENDERER_HEIGHT;
#endif

    if (play_file.file_name) {
	pjmedia_video_format_detail *file_vfd;
        pjmedia_clock_param clock_param;
        char fmt_name[5];

	/* Create file player */
	status = create_file_player(pool, play_file.file_name, &play_port);
	if (status != PJ_SUCCESS)
	    goto on_exit;

	/* Collect format info */
	file_vfd = pjmedia_format_get_video_format_detail(&play_port->info.fmt,
							  PJ_TRUE);
	PJ_LOG(2, (THIS_FILE, "Reading video stream %dx%d %s @%.2ffps",
		   file_vfd->size.w, file_vfd->size.h,
		   pjmedia_fourcc_name(play_port->info.fmt.id, fmt_name),
		   (1.0*file_vfd->fps.num/file_vfd->fps.denum)));

	/* Allocate file read buffer */
	play_file.read_buf_size = PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE;
	play_file.read_buf = pj_pool_zalloc(pool, play_file.read_buf_size);

	/* Create decoder, if the file and the stream uses different codec */
	if (codec_info->fmt_id != (pjmedia_format_id)play_port->info.fmt.id) {
	    const pjmedia_video_format_info *dec_vfi;
	    pjmedia_video_apply_fmt_param dec_vafp = {0};
	    const pjmedia_vid_codec_info *codec_info2;
	    pjmedia_vid_codec_param codec_param2;

	    /* Find decoder */
	    status = pjmedia_vid_codec_mgr_get_codec_info2(NULL,
							   play_port->info.fmt.id,
							   &codec_info2);
	    if (status != PJ_SUCCESS)
		goto on_exit;

	    /* Init decoder */
	    status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info2,
						       &play_decoder);
	    if (status != PJ_SUCCESS)
		goto on_exit;

	    status = play_decoder->op->init(play_decoder, pool);
	    if (status != PJ_SUCCESS)
		goto on_exit;

	    /* Open decoder */
	    status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info2,
							     &codec_param2);
	    if (status != PJ_SUCCESS)
		goto on_exit;

	    codec_param2.dir = PJMEDIA_DIR_DECODING;
	    status = play_decoder->op->open(play_decoder, &codec_param2);
	    if (status != PJ_SUCCESS)
		goto on_exit;

	    /* Get decoder format info and apply param */
	    dec_vfi = pjmedia_get_video_format_info(NULL,
						    codec_info2->dec_fmt_id[0]);
	    if (!dec_vfi || !dec_vfi->apply_fmt) {
		status = PJ_ENOTSUP;
		goto on_exit;
	    }
	    dec_vafp.size = file_vfd->size;
	    (*dec_vfi->apply_fmt)(dec_vfi, &dec_vafp);

	    /* Allocate buffer to receive decoder output */
	    play_file.dec_buf_size = dec_vafp.framebytes;
	    play_file.dec_buf = pj_pool_zalloc(pool, play_file.dec_buf_size);
	}

	/* Create player clock */
        clock_param.usec_interval = PJMEDIA_PTIME(&file_vfd->fps);
        clock_param.clock_rate = codec_info->clock_rate;
	status = pjmedia_clock_create2(pool, &clock_param,
				       PJMEDIA_CLOCK_NO_HIGHEST_PRIO,
				       &clock_cb, &play_file, &play_clock);
	if (status != PJ_SUCCESS)
	    goto on_exit;

	/* Override stream codec param for encoding direction */
	codec_param.enc_fmt.det.vid.size = file_vfd->size;
	codec_param.enc_fmt.det.vid.fps  = file_vfd->fps;

    } else {
        pjmedia_vid_port_param_default(&vpp);

        /* Set as active for all video devices */
        vpp.active = PJ_TRUE;

	/* Create video device port. */
        if (dir & PJMEDIA_DIR_ENCODING) {
            /* Create capture */
            status = pjmedia_vid_dev_default_param(
					pool,
					PJMEDIA_VID_DEFAULT_CAPTURE_DEV,
					&vpp.vidparam);
            if (status != PJ_SUCCESS)
	        goto on_exit;

            pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.enc_fmt);
	    vpp.vidparam.fmt.id = codec_param.dec_fmt.id;
            vpp.vidparam.dir = PJMEDIA_DIR_CAPTURE;
            
            status = pjmedia_vid_port_create(pool, &vpp, &capture);
            if (status != PJ_SUCCESS)
	        goto on_exit;
        }
	
        if (dir & PJMEDIA_DIR_DECODING) {
            /* Create renderer */
            status = pjmedia_vid_dev_default_param(
					pool,
					PJMEDIA_VID_DEFAULT_RENDER_DEV,
					&vpp.vidparam);
            if (status != PJ_SUCCESS)
	        goto on_exit;

            pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.dec_fmt);
            vpp.vidparam.dir = PJMEDIA_DIR_RENDER;
            vpp.vidparam.disp_size = vpp.vidparam.fmt.det.vid.size;
	    vpp.vidparam.flags |= PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW_FLAGS;
	    vpp.vidparam.window_flags = PJMEDIA_VID_DEV_WND_BORDER |
					PJMEDIA_VID_DEV_WND_RESIZABLE;

            status = pjmedia_vid_port_create(pool, &vpp, &renderer);
            if (status != PJ_SUCCESS)
	        goto on_exit;
        }
    }

    /* Set to ignore fmtp */
    codec_param.ignore_fmtp = PJ_TRUE;

    /* Create stream based on program arguments */
    status = create_stream(pool, med_endpt, codec_info, &codec_param,
                           dir, rx_pt, tx_pt, local_port, &remote_addr, 
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
			   use_srtp, &srtp_crypto_suite, 
			   &srtp_tx_key, &srtp_rx_key,
#endif
			   &stream);
    if (status != PJ_SUCCESS)
	goto on_exit;

    /* Get the port interface of the stream */
    status = pjmedia_vid_stream_get_port(stream, PJMEDIA_DIR_ENCODING,
				         &enc_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    status = pjmedia_vid_stream_get_port(stream, PJMEDIA_DIR_DECODING,
				         &dec_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Start streaming */
    status = pjmedia_vid_stream_start(stream);
    if (status != PJ_SUCCESS)
        goto on_exit;

    /* Start renderer */
    if (renderer) {
        status = pjmedia_vid_port_connect(renderer, dec_port, PJ_FALSE);
        if (status != PJ_SUCCESS)
	    goto on_exit;
        status = pjmedia_vid_port_start(renderer);
        if (status != PJ_SUCCESS)
            goto on_exit;
    }

    /* Start capture */
    if (capture) {
        status = pjmedia_vid_port_connect(capture, enc_port, PJ_FALSE);
        if (status != PJ_SUCCESS)
	    goto on_exit;
        status = pjmedia_vid_port_start(capture);
        if (status != PJ_SUCCESS)
            goto on_exit;
    }

    /* Start playing file */
    if (play_file.file_name) {

#if HAS_LOCAL_RENDERER_FOR_PLAY_FILE
        /* Create local renderer */
        pjmedia_vid_port_param_default(&vpp);
        vpp.active = PJ_FALSE;
        status = pjmedia_vid_dev_default_param(
				pool,
				PJMEDIA_VID_DEFAULT_RENDER_DEV,
				&vpp.vidparam);
        if (status != PJ_SUCCESS)
	    goto on_exit;

        vpp.vidparam.dir = PJMEDIA_DIR_RENDER;
        pjmedia_format_copy(&vpp.vidparam.fmt, &codec_param.dec_fmt);
	vpp.vidparam.fmt.det.vid.size = play_port->info.fmt.det.vid.size;
	vpp.vidparam.fmt.det.vid.fps = play_port->info.fmt.det.vid.fps;
        vpp.vidparam.disp_size = vpp.vidparam.fmt.det.vid.size;

	status = pjmedia_vid_port_create(pool, &vpp, &renderer);
        if (status != PJ_SUCCESS)
	    goto on_exit;
        status = pjmedia_vid_port_start(renderer);
        if (status != PJ_SUCCESS)
            goto on_exit;
#endif

	/* Init play file data */
	play_file.play_port = play_port;
	play_file.stream_port = enc_port;
	play_file.decoder = play_decoder;
	if (renderer) {
	    play_file.renderer = pjmedia_vid_port_get_passive_port(renderer);
	}

	status = pjmedia_clock_start(play_clock);
	if (status != PJ_SUCCESS)
	    goto on_exit;
    }

    /* Done */

    if (dir == PJMEDIA_DIR_DECODING)
	printf("Stream is active, dir is recv-only, local port is %d\n",
	       local_port);
    else if (dir == PJMEDIA_DIR_ENCODING)
	printf("Stream is active, dir is send-only, sending to %s:%d\n",
	       pj_inet_ntoa(remote_addr.sin_addr),
	       pj_ntohs(remote_addr.sin_port));
    else
	printf("Stream is active, send/recv, local port is %d, "
	       "sending to %s:%d\n",
	       local_port,
	       pj_inet_ntoa(remote_addr.sin_addr),
	       pj_ntohs(remote_addr.sin_port));

    if (dir & PJMEDIA_DIR_ENCODING)
	PJ_LOG(2, (THIS_FILE, "Sending %dx%d %.*s @%.2ffps",
		   codec_param.enc_fmt.det.vid.size.w,
		   codec_param.enc_fmt.det.vid.size.h,
		   codec_info->encoding_name.slen,
		   codec_info->encoding_name.ptr,
		   (1.0*codec_param.enc_fmt.det.vid.fps.num/
		    codec_param.enc_fmt.det.vid.fps.denum)));

    for (;;) {
	char tmp[10];

	puts("");
	puts("Commands:");
	puts("  q     Quit");
	puts("");

	printf("Command: "); fflush(stdout);

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

	if (tmp[0] == 'q')
	    break;

    }



    /* Start deinitialization: */
on_exit:

    /* Stop and destroy file clock */
    if (play_clock) {
	pjmedia_clock_stop(play_clock);
	pjmedia_clock_destroy(play_clock);
    }

    /* Destroy file reader/player */
    if (play_port)
	pjmedia_port_destroy(play_port);

    /* Destroy file decoder */
    if (play_decoder) {
	play_decoder->op->close(play_decoder);
	pjmedia_vid_codec_mgr_dealloc_codec(NULL, play_decoder);
    }

    /* Destroy video devices */
    if (capture)
	pjmedia_vid_port_destroy(capture);
    if (renderer)
	pjmedia_vid_port_destroy(renderer);

    /* Destroy stream */
    if (stream) {
	pjmedia_transport *tp;

	tp = pjmedia_vid_stream_get_transport(stream);
	pjmedia_vid_stream_destroy(stream);
	
	pjmedia_transport_close(tp);
    }

    /* Deinit codecs */
    deinit_codecs();

    /* Shutdown video subsystem */
    pjmedia_vid_dev_subsys_shutdown();

    /* Destroy event manager */
    pjmedia_event_mgr_destroy(NULL);

    /* 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();

    return (status == PJ_SUCCESS) ? 0 : 1;
}
Esempio n. 17
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	      */
			 15,
			 5,
		     &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		    */
			 15,
			 5,
			 &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;

}
Esempio n. 18
0
int test_inner(void)
{
    pj_caching_pool caching_pool;
    const char *filename;
    int line;
    int rc = 0;

    mem = &caching_pool.factory;

    pj_log_set_level(3);
    pj_log_set_decor(param_log_decor);

    rc = pj_init();
    if (rc != 0) {
	app_perror("pj_init() error!!", rc);
	return rc;
    }
    
    //pj_dump_config();
    pj_caching_pool_init( &caching_pool, NULL, 0 );

#if INCLUDE_ERRNO_TEST
    DO_TEST( errno_test() );
#endif

#if INCLUDE_EXCEPTION_TEST
    DO_TEST( exception_test() );
#endif

#if INCLUDE_OS_TEST
    DO_TEST( os_test() );
#endif

#if INCLUDE_RAND_TEST
    DO_TEST( rand_test() );
#endif

#if INCLUDE_LIST_TEST
    DO_TEST( list_test() );
#endif

#if INCLUDE_POOL_TEST
    DO_TEST( pool_test() );
#endif

#if INCLUDE_POOL_PERF_TEST
    DO_TEST( pool_perf_test() );
#endif

#if INCLUDE_STRING_TEST
    DO_TEST( string_test() );
#endif
    
#if INCLUDE_FIFOBUF_TEST
    DO_TEST( fifobuf_test() );
#endif

#if INCLUDE_RBTREE_TEST
    DO_TEST( rbtree_test() );
#endif

#if INCLUDE_HASH_TEST
    DO_TEST( hash_test() );
#endif

#if INCLUDE_TIMESTAMP_TEST
    DO_TEST( timestamp_test() );
#endif

#if INCLUDE_ATOMIC_TEST
    DO_TEST( atomic_test() );
#endif

#if INCLUDE_MUTEX_TEST
    DO_TEST( mutex_test() );
#endif

#if INCLUDE_TIMER_TEST
    DO_TEST( timer_test() );
#endif

#if INCLUDE_SLEEP_TEST
    DO_TEST( sleep_test() );
#endif

#if INCLUDE_THREAD_TEST
    DO_TEST( thread_test() );
#endif

#if INCLUDE_SOCK_TEST
    DO_TEST( sock_test() );
#endif

#if INCLUDE_SOCK_PERF_TEST
    DO_TEST( sock_perf_test() );
#endif

#if INCLUDE_SELECT_TEST
    DO_TEST( select_test() );
#endif

#if INCLUDE_UDP_IOQUEUE_TEST
    DO_TEST( udp_ioqueue_test() );
#endif

#if PJ_HAS_TCP && INCLUDE_TCP_IOQUEUE_TEST
    DO_TEST( tcp_ioqueue_test() );
#endif

#if INCLUDE_IOQUEUE_PERF_TEST
    DO_TEST( ioqueue_perf_test() );
#endif

#if INCLUDE_IOQUEUE_UNREG_TEST
    DO_TEST( udp_ioqueue_unreg_test() );
#endif

#if INCLUDE_ACTIVESOCK_TEST
    DO_TEST( activesock_test() );
#endif

#if INCLUDE_FILE_TEST
    DO_TEST( file_test() );
#endif

#if INCLUDE_SSLSOCK_TEST
    DO_TEST( ssl_sock_test() );
#endif

#if INCLUDE_ECHO_SERVER
    //echo_server();
    //echo_srv_sync();
    udp_echo_srv_ioqueue();

#elif INCLUDE_ECHO_CLIENT
    if (param_echo_sock_type == 0)
        param_echo_sock_type = pj_SOCK_DGRAM();

    echo_client( param_echo_sock_type, 
                 param_echo_server, 
                 param_echo_port);
#endif

    goto on_return;

on_return:

    pj_caching_pool_destroy( &caching_pool );

    PJ_LOG(3,("test", ""));
 
    pj_thread_get_stack_info(pj_thread_this(), &filename, &line);
    PJ_LOG(3,("test", "Stack max usage: %u, deepest: %s:%u", 
	              pj_thread_get_stack_max_usage(pj_thread_this()),
		      filename, line));
    if (rc == 0)
	PJ_LOG(3,("test", "Looks like everything is okay!.."));
    else
	PJ_LOG(3,("test", "Test completed with error(s)"));
    
    pj_shutdown();
    
    return 0;
}
Esempio n. 19
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_port *file_ori_port;
    pjmedia_port *file_deg_port;
    pj_status_t status;
    unsigned first_nsamples = 0;
    unsigned samples_compared = 0;

    char buf1[BYTES_PER_FRAME];
    char buf2[BYTES_PER_FRAME];

    double ref_mag = 0;
    double deg_mag = 0;
    double mix_mag = 0;

    int detail = 0;
    int res_deg, res_mix, res_overall;

    if (argc < 3) {
    	puts("Error: original & degraded filename required");
	puts(desc);
	return 1;
    }

    /* Set log level. */
    pj_log_set_level(3);

    /* 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 original WAV file */
    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
					      argv[1],	/* file to play	    */
					      40,	/* ptime.	    */
					      PJMEDIA_FILE_NO_LOOP,	/* flags	    */
					      0,	/* default buffer   */
					      &file_ori_port/* returned port    */
					      );
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to use WAV file", status);
	return 1;
    }

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

    if (file_ori_port->info.clock_rate != file_deg_port->info.clock_rate) {
	app_perror(THIS_FILE, "Clock rates must be same.", PJ_EINVAL);
	return 1;
    }

    if (argc > 3)
	first_nsamples = atoi(argv[3]) * file_ori_port->info.clock_rate / 1000;

    if (argc > 4)
	detail = atoi(argv[4]);

    while (1) {
	pjmedia_frame f1, f2;

	f1.buf = buf1;
	f1.size = BYTES_PER_FRAME;
	f2.buf = buf2;
	f2.size = BYTES_PER_FRAME;

	status = pjmedia_port_get_frame(file_ori_port, &f1);
	if (status == PJ_EEOF) {
	    break;
	} else if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Error occured while reading file", status);
	    break;
	}
	status = pjmedia_port_get_frame(file_deg_port, &f2);
	if (status == PJ_EEOF) {
	    break;
	} else if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Error occured while reading file", status);
	    break;
	}

	/* Calculate magnitudes */
	ref_mag += sum_mult_sig(f1.buf, f1.buf, BYTES_PER_FRAME >> 1);
	deg_mag += sum_mult_sig(f2.buf, f2.buf, BYTES_PER_FRAME >> 1);
	mix_mag += sum_mult_sig(f1.buf, f2.buf, BYTES_PER_FRAME >> 1);

	samples_compared += BYTES_PER_FRAME >> 1;
	if (first_nsamples && samples_compared >= first_nsamples)
	    break;
    }

    /* Degraded magnitude compared to reference magnitude 
     */
    res_deg = (int) (deg_mag / ref_mag * 100.0);
    if (res_deg < 0)
	res_deg = -1;
    else if (res_deg >= 81)
	res_deg = 9;
    else
	res_deg = pj_isqrt(res_deg);

    /* Mixed magnitude (don't know what this is actually :D) compared to 
     * reference magnitude 
     */
    res_mix = (int) (mix_mag / ref_mag * 100.0);
    if (res_mix < 0)
	res_mix = -1;
    else if (res_mix >= 81)
	res_mix = 9;
    else
	res_mix = pj_isqrt(res_mix);

    /* Overall score.
     * If mixed score is -1, then overall score should be -1 as well.
     * Apply no weighting (1:1) for now.
     */
    if (res_mix == -1)
	res_overall = -1;
    else
	res_overall = (res_mix*1 + res_deg*1) / 2;

    if (detail) {
	printf("Reference = %.0f\n", ref_mag);
	printf("Degraded  = %.0f\n", deg_mag);
	printf("Mixed     = %.0f\n", mix_mag);

	printf("\n");

	printf("Score 1   = %d\n", res_deg);
	printf("Score 2   = %d\n", res_mix);

	printf("\n");
    }

    printf("Overall   = %d\n", res_overall);

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

    status = pjmedia_port_destroy( file_deg_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;
}
Esempio n. 20
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_port *sine_port;
    pjmedia_snd_port *snd_port;
    char tmp[10];
    int channel_count = 1;
    pj_status_t status;

    if (argc == 2) {
	channel_count = atoi(argv[1]);
	if (channel_count < 1 || channel_count > 2) {
	    puts("Error: invalid arguments");
	    usage();
	    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 sine generator */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "wav",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );

    /* Create a media port to generate sine wave samples. */
    status = create_sine_port( pool,	    /* memory pool	    */
			       11025,	    /* sampling rate	    */
			       channel_count,/* # of channels	    */
			       &sine_port   /* returned port	    */
		             );
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to create sine port", status);
	return 1;
    }

    /* Create sound player port. */
    status = pjmedia_snd_port_create_player( 
		 pool,				    /* pool		    */
		 -1,				    /* use default dev.	    */
		 sine_port->info.clock_rate,	    /* clock rate.	    */
		 sine_port->info.channel_count,	    /* # of channels.	    */
		 sine_port->info.samples_per_frame, /* samples per frame.   */
		 sine_port->info.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 sine generator port to the sound player 
     * Stream playing will commence immediately.
     */
    status = pjmedia_snd_port_connect( snd_port, sine_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);



    /* 
     * Audio should be playing in a loop now, using sound device's thread. 
     */


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


    puts("Playing sine wave..");
    puts("");
    puts("Press <ENTER> to stop playing and quit");

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

    
    /* Start deinitialization: */

    /* Disconnect sound port from file port */
    status = pjmedia_snd_port_disconnect(snd_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Without this sleep, Windows/DirectSound will repeteadly
     * play the last frame during destroy.
     */
    pj_thread_sleep(100);

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


    /* Destroy sine generator */
    status = pjmedia_port_destroy( sine_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;
}
Esempio n. 21
0
int main()
{
    pj_caching_pool cp;
    pj_bool_t done = PJ_FALSE;
    pj_status_t status;

    /* Init pjlib */
    status = pj_init();
    PJ_ASSERT_RETURN(status==PJ_SUCCESS, 1);
    
    pj_log_set_decor(PJ_LOG_HAS_NEWLINE);

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

    status = pjmedia_aud_subsys_init(&cp.factory);
    if (status != PJ_SUCCESS) {
	app_perror("pjmedia_aud_subsys_init()", status);
	pj_caching_pool_destroy(&cp);
	pj_shutdown();
	return 1;
    }

    list_devices();

    while (!done) {
	char line[80];

	print_menu();

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

	switch (line[0]) {
	case 'l':
	    list_devices();
	    break;

	case 'R':
	    pjmedia_aud_dev_refresh();
	    puts("Audio device list refreshed.");
	    break;

	case 'i':
	    {
		unsigned dev_index;
		if (sscanf(line+2, "%u", &dev_index) != 1) {
		    puts("error: device ID required");
		    break;
		}
		show_dev_info(dev_index);
	    }
	    break;

	case 't':
	    {
		pjmedia_dir dir;
		int rec_id, play_id;
		unsigned clock_rate, ptime, chnum;
		int cnt;

		cnt = sscanf(line+2, "%d %d %u %u %u", &rec_id, &play_id, 
			     &clock_rate, &ptime, &chnum);
		if (cnt < 4) {
		    puts("error: not enough parameters");
		    break;
		}
		if (clock_rate < 8000 || clock_rate > 128000) {
		    puts("error: invalid clock rate");
		    break;
		}
		if (ptime < 10 || ptime > 500) {
		    puts("error: invalid ptime");
		    break;
		}
		if (cnt==5) {
		    if (chnum < 1 || chnum > 4) {
			puts("error: invalid number of channels");
			break;
		    }
		} else {
		    chnum = 1;
		}

		if (rec_id >= 0 && rec_id < (int)dev_count) {
		    if (play_id >= 0 && play_id < (int)dev_count)
			dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
		    else
			dir = PJMEDIA_DIR_CAPTURE;
		} else if (play_id >= 0 && play_id < (int)dev_count) {
		    dir = PJMEDIA_DIR_PLAYBACK;
		} else {
		    puts("error: at least one valid device index required");
		    break;
		}

		test_device(dir, rec_id, play_id, clock_rate, ptime, chnum);
		
	    }
	    break;

	case 'r':
	    /* record */
	    {
		int index;
		char filename[80];
		int count;

		count = sscanf(line+2, "%d %s", &index, filename);
		if (count==1)
		    record(index, NULL);
		else if (count==2)
		    record(index, filename);
		else
		    puts("error: invalid command syntax");
	    }
	    break;

	case 'p':
	    /* playback */
	    {
		int index;
		char filename[80];
		int count;

		count = sscanf(line+2, "%d %s", &index, filename);
		if (count==1)
		    play_file(index, NULL);
		else if (count==2)
		    play_file(index, filename);
		else
		    puts("error: invalid command syntax");
	    }
	    break;

	case 'd':
	    /* latencies */
	    {
		int rec_lat, play_lat;

		if (sscanf(line+2, "%d %d", &rec_lat, &play_lat) == 2) {
		    capture_lat = (unsigned) 
			 (rec_lat>=0? rec_lat:PJMEDIA_SND_DEFAULT_REC_LATENCY);
		    playback_lat = (unsigned)
			 (play_lat >= 0? play_lat : PJMEDIA_SND_DEFAULT_PLAY_LATENCY);
		    printf("Recording latency=%ums, playback latency=%ums",
			   capture_lat, playback_lat);
		} else {
		    printf("Current latencies: record=%ums, playback=%ums",
			   capture_lat, playback_lat);
		}
		puts("");
	    }
	    break;

	case 'v':
	    if (pj_log_get_level() <= 3) {
		pj_log_set_level(5);
		puts("Logging set to detail");
	    } else {
		pj_log_set_level(3);
		puts("Logging set to quiet");
	    }
	    break;

	case 'q':
	    done = PJ_TRUE;
	    break;
	}
    }

    pj_caching_pool_destroy(&cp);
    pj_shutdown();
    return 0;
}
Esempio n. 22
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pj_status_t status; 

    /* Codec */
    char *codec_id = (char*)"H264";
    const pjmedia_vid_codec_info *codec_info;
    pjmedia_vid_codec_param codec_param;
    pjmedia_vid_codec *codec = NULL;

    //const char *save_filename =
    //	"/home/bennylp/Desktop/opt/src/openh264-svn/testbin/test.264";
    const char *save_filename = NULL;

    /* File */
    enum
    {
	WIDTH = 320,
	HEIGHT = 192,
	FPS = 12,
	YUV_SIZE = WIDTH * HEIGHT * 3 >> 1,
	YUV_BUF_SIZE = YUV_SIZE + WIDTH,
	MAX_FRAMES = 32,
	MTU = 1500
    };
    FILE *fyuv = NULL;
    FILE *f264 = NULL;
    typedef pj_uint8_t enc_buf_type[MTU];
    pj_uint8_t yuv_frame[YUV_BUF_SIZE];
    enc_buf_type enc_buf[MAX_FRAMES];
    unsigned read_cnt = 0,
	     pkt_cnt = 0,
	     dec_cnt = 0,
	     enc_cnt;

    if (0) {
	diff_file();
	return 1;
    }

    /* 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. */
    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

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

    /* Init video format manager */
    pjmedia_video_format_mgr_create(pool, 64, 0, NULL);

    /* Init video converter manager */
    pjmedia_converter_mgr_create(pool, NULL);

    /* Init event manager */
    pjmedia_event_mgr_create(pool, 0, NULL);

    /* Init video codec manager */
    pjmedia_vid_codec_mgr_create(pool, NULL);

    /* Register all supported codecs */
    status = init_codecs(&cp.factory);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Open YUV file */
    fyuv = fopen("pjsip-apps/bin/CiscoVT2people_320x192_12fps.yuv", "rb");
    if (!fyuv) {
	puts("Unable to open ../CiscoVT2people_320x192_12fps.yuv");
	status = -1;
	goto on_exit;
    }

    /* Write 264 file if wanted */
    if (save_filename) {
	f264 = fopen(save_filename, "wb");
    }

    /* Find which codec to use. */
    if (codec_id) {
	unsigned count = 1;
	pj_str_t str_codec_id = pj_str(codec_id);

        status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL,
						         &str_codec_id, &count,
						         &codec_info, NULL);
	if (status != PJ_SUCCESS) {
	    printf("Error: unable to find codec %s\n", codec_id);
	    return 1;
	}
    } else {
        static pjmedia_vid_codec_info info[1];
        unsigned count = PJ_ARRAY_SIZE(info);

	/* Default to first codec */
	pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, NULL);
        codec_info = &info[0];
    }

    /* Get codec default param for info */
    status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info, 
				                     &codec_param);
    pj_assert(status == PJ_SUCCESS);
    
    /* Alloc encoder */
    status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info, &codec);
    if (status != PJ_SUCCESS) {
	PJ_PERROR(3,(THIS_FILE, status, "Error allocating codec"));
	goto on_exit;
    }

    codec_param.dir = PJMEDIA_DIR_ENCODING_DECODING;
    codec_param.packing = PJMEDIA_VID_PACKING_PACKETS;
    codec_param.enc_mtu = MTU;
    codec_param.enc_fmt.det.vid.size.w = WIDTH;
    codec_param.enc_fmt.det.vid.size.h = HEIGHT;
    codec_param.enc_fmt.det.vid.fps.num = FPS;
    codec_param.enc_fmt.det.vid.avg_bps = WIDTH * HEIGHT * FPS;

    status = pjmedia_vid_codec_init(codec, pool);
    if (status != PJ_SUCCESS) {
	PJ_PERROR(3,(THIS_FILE, status, "Error initializing codec"));
	goto on_exit;
    }

    status = pjmedia_vid_codec_open(codec, &codec_param);
    if (status != PJ_SUCCESS) {
	PJ_PERROR(3,(THIS_FILE, status, "Error opening codec"));
	goto on_exit;
    }

    while (fread(yuv_frame, 1, YUV_SIZE, fyuv) == YUV_SIZE) {
	pjmedia_frame frm_yuv, frm_enc[MAX_FRAMES];
	pj_bool_t has_more = PJ_FALSE;
	const pj_uint8_t start_nal[] = { 0, 0, 1 };
	unsigned i;

	++ read_cnt;

	pj_bzero(&frm_enc, sizeof(frm_enc));
	pj_bzero(&frm_yuv, sizeof(frm_yuv));

	frm_yuv.buf = yuv_frame;
	frm_yuv.size = YUV_SIZE;

	enc_cnt = 0;
	frm_enc[enc_cnt].buf = enc_buf[enc_cnt];
	frm_enc[enc_cnt].size = MTU;

	status = pjmedia_vid_codec_encode_begin(codec, NULL, &frm_yuv,
	                                        MTU, &frm_enc[enc_cnt],
	                                        &has_more);
	if (status != PJ_SUCCESS) {
	    PJ_PERROR(3,(THIS_FILE, status, "Codec encode error"));
	    goto on_exit;
	}
	if (frm_enc[enc_cnt].size) {
	    if (f264) {
		fwrite(start_nal, 1, sizeof(start_nal), f264);
		fwrite(frm_enc[enc_cnt].buf, 1, frm_enc[enc_cnt].size, f264);
	    }
	    ++pkt_cnt;
	    ++enc_cnt;
	}

	while (has_more) {

	    if (enc_cnt >= MAX_FRAMES) {
		status = -1;
		puts("Error: too many encoded frames");
		goto on_exit;
	    }

	    has_more = PJ_FALSE;
	    frm_enc[enc_cnt].buf = enc_buf[enc_cnt];
	    frm_enc[enc_cnt].size = MTU;

	    status = pjmedia_vid_codec_encode_more(codec, MTU,
	                                           &frm_enc[enc_cnt],
	                                           &has_more);
	    if (status != PJ_SUCCESS) {
		PJ_PERROR(3,(THIS_FILE, status, "Codec encode error"));
		goto on_exit;
	    }

	    if (frm_enc[enc_cnt].size) {
		if (f264) {
		    fwrite(start_nal, 1, sizeof(start_nal), f264);
		    fwrite(frm_enc[enc_cnt].buf, 1, frm_enc[enc_cnt].size,
		           f264);
		}
		++pkt_cnt;
		++enc_cnt;
	    }
	}

	if (enc_cnt) {
	    frm_yuv.buf = yuv_frame;
	    frm_yuv.size = YUV_BUF_SIZE;
	    status = pjmedia_vid_codec_decode(codec, enc_cnt,
					      frm_enc,
					      YUV_BUF_SIZE,
					      &frm_yuv);
	    if (status != PJ_SUCCESS) {
		PJ_PERROR(3,(THIS_FILE, status, "Codec decode error"));
		goto on_exit;
	    }

	    if (frm_yuv.size != 0) {
		++dec_cnt;
	    }
	}
    }

    printf("Done.\n"
	   " Read YUV frames:    %d\n"
	   " Encoded packets:    %d\n"
	   " Decoded YUV frames: %d\n",
	   read_cnt, pkt_cnt, dec_cnt);

    /* Start deinitialization: */
on_exit:
    if (codec) {
	pjmedia_vid_codec_close(codec);
	pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec);
    }

    if (f264)
	fclose(f264);

    if (fyuv)
	fclose(fyuv);

    /* Deinit codecs */
    deinit_codecs();

    /* Destroy event manager */
    pjmedia_event_mgr_destroy(NULL);

    /* 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();

    return (status == PJ_SUCCESS) ? 0 : 1;
}


#else

int main(int argc, char *argv[])
{
    PJ_UNUSED_ARG(argc);
    PJ_UNUSED_ARG(argv);
    puts("Error: this sample requires video capability "
	    "(PJMEDIA_HAS_VIDEO == 1)");
    return -1;
}
Esempio n. 23
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;
}
Esempio n. 24
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    enum { NSAMPLES = 160, COUNT=100 };
    pj_caching_pool cp;
    pj_pool_t *pool;
    pjmedia_port *wav;
    pj_status_t status;


    /* Verify cmd line arguments. */
    if (argc != 2) {
	puts("Error: missing argument(s)");
	puts("Usage: latency REV.WAV");
	return 1;
    }

    pj_log_set_level(0);

    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 = pj_register_strerror(PJMEDIA_ERRNO_START, PJ_ERRNO_SPACE_SIZE, 
				  &pjmedia_strerror);
    pj_assert(status == PJ_SUCCESS);

    /* Wav */
    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
					      argv[1],	/* file to play	    */
					      0,	/* use default ptime*/
					      0,	/* flags	    */
					      0,	/* default buffer   */
					      &wav	/* returned port    */
					      );
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, argv[1], status);
	return 1;
    }

    status = calculate_latency(pool, wav);
    if (status != PJ_SUCCESS)
	return 1;

    status = pjmedia_port_destroy( wav );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    pj_pool_release( pool );
    pj_caching_pool_destroy( &cp );
    pj_shutdown();

    /* Done. */
    return 0;
}
Esempio n. 25
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_port *rec_file_port = NULL, *play_file_port = NULL;
    pjmedia_master_port *master_port = NULL;
    pjmedia_snd_port *snd_port = NULL;
    pjmedia_stream *stream = NULL;
    pjmedia_port *stream_port;
    char tmp[10];
    pj_status_t status; 

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
    /* SRTP variables */
    pj_bool_t use_srtp = PJ_FALSE;
    char tmp_tx_key[64];
    char tmp_rx_key[64];
    pj_str_t  srtp_tx_key = {NULL, 0};
    pj_str_t  srtp_rx_key = {NULL, 0};
    pj_str_t  srtp_crypto_suite = {NULL, 0};
    int	tmp_key_len;
#endif

    /* Default values */
    const pjmedia_codec_info *codec_info;
    pjmedia_codec_param codec_param;
    pjmedia_dir dir = PJMEDIA_DIR_DECODING;
    pj_sockaddr_in remote_addr;
    pj_uint16_t local_port = 4000;
    char *codec_id = NULL;
    char *rec_file = NULL;
    char *play_file = NULL;

    enum {
	OPT_CODEC	= 'c',
	OPT_LOCAL_PORT	= 'p',
	OPT_REMOTE	= 'r',
	OPT_PLAY_FILE	= 'w',
	OPT_RECORD_FILE	= 'R',
	OPT_SEND_RECV	= 'b',
	OPT_SEND_ONLY	= 's',
	OPT_RECV_ONLY	= 'i',
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	OPT_USE_SRTP	= 'S',
#endif
	OPT_SRTP_TX_KEY	= 'x',
	OPT_SRTP_RX_KEY	= 'y',
	OPT_HELP	= 'h',
    };

    struct pj_getopt_option long_options[] = {
	{ "codec",	    1, 0, OPT_CODEC },
	{ "local-port",	    1, 0, OPT_LOCAL_PORT },
	{ "remote",	    1, 0, OPT_REMOTE },
	{ "play-file",	    1, 0, OPT_PLAY_FILE },
	{ "record-file",    1, 0, OPT_RECORD_FILE },
	{ "send-recv",      0, 0, OPT_SEND_RECV },
	{ "send-only",      0, 0, OPT_SEND_ONLY },
	{ "recv-only",      0, 0, OPT_RECV_ONLY },
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	{ "use-srtp",	    2, 0, OPT_USE_SRTP },
	{ "srtp-tx-key",    1, 0, OPT_SRTP_TX_KEY },
	{ "srtp-rx-key",    1, 0, OPT_SRTP_RX_KEY },
#endif
	{ "help",	    0, 0, OPT_HELP },
	{ NULL, 0, 0, 0 },
    };

    int c;
    int option_index;


    pj_bzero(&remote_addr, sizeof(remote_addr));


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


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

	switch (c) {
	case OPT_CODEC:
	    codec_id = pj_optarg;
	    break;

	case OPT_LOCAL_PORT:
	    local_port = (pj_uint16_t) atoi(pj_optarg);
	    if (local_port < 1) {
		printf("Error: invalid local port %s\n", pj_optarg);
		return 1;
	    }
	    break;

	case OPT_REMOTE:
	    {
		pj_str_t ip = pj_str(strtok(pj_optarg, ":"));
		pj_uint16_t port = (pj_uint16_t) atoi(strtok(NULL, ":"));

		status = pj_sockaddr_in_init(&remote_addr, &ip, port);
		if (status != PJ_SUCCESS) {
		    app_perror(THIS_FILE, "Invalid remote address", status);
		    return 1;
		}
	    }
	    break;

	case OPT_PLAY_FILE:
	    play_file = pj_optarg;
	    break;

	case OPT_RECORD_FILE:
	    rec_file = pj_optarg;
	    break;

	case OPT_SEND_RECV:
	    dir = PJMEDIA_DIR_ENCODING_DECODING;
	    break;

	case OPT_SEND_ONLY:
	    dir = PJMEDIA_DIR_ENCODING;
	    break;

	case OPT_RECV_ONLY:
	    dir = PJMEDIA_DIR_DECODING;
	    break;

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
	case OPT_USE_SRTP:
	    use_srtp = PJ_TRUE;
	    if (pj_optarg) {
		pj_strset(&srtp_crypto_suite, pj_optarg, strlen(pj_optarg));
	    } else {
		srtp_crypto_suite = pj_str("AES_CM_128_HMAC_SHA1_80");
	    }
	    break;

	case OPT_SRTP_TX_KEY:
	    tmp_key_len = hex_string_to_octet_string(tmp_tx_key, pj_optarg, 
						     (int)strlen(pj_optarg));
	    pj_strset(&srtp_tx_key, tmp_tx_key, tmp_key_len/2);
	    break;

	case OPT_SRTP_RX_KEY:
	    tmp_key_len = hex_string_to_octet_string(tmp_rx_key, pj_optarg, 
						     (int)strlen(pj_optarg));
	    pj_strset(&srtp_rx_key, tmp_rx_key, tmp_key_len/2);
	    break;
#endif

	case OPT_HELP:
	    usage();
	    return 1;

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

    }


    /* Verify arguments. */
    if (dir & PJMEDIA_DIR_ENCODING) {
	if (remote_addr.sin_addr.s_addr == 0) {
	    printf("Error: remote address must be set\n");
	    return 1;
	}
    }

    if (play_file != NULL && dir != PJMEDIA_DIR_ENCODING) {
	printf("Direction is set to --send-only because of --play-file\n");
	dir = PJMEDIA_DIR_ENCODING;
    }

#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
    /* SRTP validation */
    if (use_srtp) {
	if (!srtp_tx_key.slen || !srtp_rx_key.slen)
	{
	    printf("Error: Key for each SRTP stream direction must be set\n");
	    return 1;
	}
    }
#endif

    /* 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 application purpose */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "app",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );


    /* Register all supported codecs */
    status = init_codecs(med_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Find which codec to use. */
    if (codec_id) {
	unsigned count = 1;
	pj_str_t str_codec_id = pj_str(codec_id);
	pjmedia_codec_mgr *codec_mgr = pjmedia_endpt_get_codec_mgr(med_endpt);
	status = pjmedia_codec_mgr_find_codecs_by_id( codec_mgr,
						      &str_codec_id, &count,
						      &codec_info, NULL);
	if (status != PJ_SUCCESS) {
	    printf("Error: unable to find codec %s\n", codec_id);
	    return 1;
	}
    } else {
	/* Default to pcmu */
	pjmedia_codec_mgr_get_codec_info( pjmedia_endpt_get_codec_mgr(med_endpt),
					  0, &codec_info);
    }

    /* Create stream based on program arguments */
    status = create_stream(pool, med_endpt, codec_info, dir, local_port, 
			   &remote_addr, 
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
			   use_srtp, &srtp_crypto_suite, 
			   &srtp_tx_key, &srtp_rx_key,
#endif
			   &stream);
    if (status != PJ_SUCCESS)
	goto on_exit;

    /* Get codec default param for info */
    status = pjmedia_codec_mgr_get_default_param(
				    pjmedia_endpt_get_codec_mgr(med_endpt), 
				    codec_info, 
				    &codec_param);
    /* Should be ok, as create_stream() above succeeded */
    pj_assert(status == PJ_SUCCESS);

    /* Get the port interface of the stream */
    status = pjmedia_stream_get_port( stream, &stream_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    if (play_file) {
	unsigned wav_ptime;

	wav_ptime = PJMEDIA_PIA_PTIME(&stream_port->info);
	status = pjmedia_wav_player_port_create(pool, play_file, wav_ptime,
						0, -1, &play_file_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to use file", status);
	    goto on_exit;
	}

	status = pjmedia_master_port_create(pool, play_file_port, stream_port,
					    0, &master_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to create master port", status);
	    goto on_exit;
	}

	status = pjmedia_master_port_start(master_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Error starting master port", status);
	    goto on_exit;
	}

	printf("Playing from WAV file %s..\n", play_file);

    } else if (rec_file) {

	status = pjmedia_wav_writer_port_create(pool, rec_file,
					        PJMEDIA_PIA_SRATE(&stream_port->info),
					        PJMEDIA_PIA_CCNT(&stream_port->info),
					        PJMEDIA_PIA_SPF(&stream_port->info),
					        PJMEDIA_PIA_BITS(&stream_port->info),
						0, 0, &rec_file_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to use file", status);
	    goto on_exit;
	}

	status = pjmedia_master_port_create(pool, stream_port, rec_file_port, 
					    0, &master_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to create master port", status);
	    goto on_exit;
	}

	status = pjmedia_master_port_start(master_port);
	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Error starting master port", status);
	    goto on_exit;
	}

	printf("Recording to WAV file %s..\n", rec_file);
	
    } else {

	/* Create sound device port. */
	if (dir == PJMEDIA_DIR_ENCODING_DECODING)
	    status = pjmedia_snd_port_create(pool, -1, -1, 
					PJMEDIA_PIA_SRATE(&stream_port->info),
					PJMEDIA_PIA_CCNT(&stream_port->info),
					PJMEDIA_PIA_SPF(&stream_port->info),
					PJMEDIA_PIA_BITS(&stream_port->info),
					0, &snd_port);
	else if (dir == PJMEDIA_DIR_ENCODING)
	    status = pjmedia_snd_port_create_rec(pool, -1, 
					PJMEDIA_PIA_SRATE(&stream_port->info),
					PJMEDIA_PIA_CCNT(&stream_port->info),
					PJMEDIA_PIA_SPF(&stream_port->info),
					PJMEDIA_PIA_BITS(&stream_port->info),
					0, &snd_port);
	else
	    status = pjmedia_snd_port_create_player(pool, -1, 
					PJMEDIA_PIA_SRATE(&stream_port->info),
					PJMEDIA_PIA_CCNT(&stream_port->info),
					PJMEDIA_PIA_SPF(&stream_port->info),
					PJMEDIA_PIA_BITS(&stream_port->info),
					0, &snd_port);


	if (status != PJ_SUCCESS) {
	    app_perror(THIS_FILE, "Unable to create sound port", status);
	    goto on_exit;
	}

	/* Connect sound port to stream */
	status = pjmedia_snd_port_connect( snd_port, stream_port );
	PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    }

    /* Start streaming */
    pjmedia_stream_start(stream);


    /* Done */

    if (dir == PJMEDIA_DIR_DECODING)
	printf("Stream is active, dir is recv-only, local port is %d\n",
	       local_port);
    else if (dir == PJMEDIA_DIR_ENCODING)
	printf("Stream is active, dir is send-only, sending to %s:%d\n",
	       pj_inet_ntoa(remote_addr.sin_addr),
	       pj_ntohs(remote_addr.sin_port));
    else
	printf("Stream is active, send/recv, local port is %d, "
	       "sending to %s:%d\n",
	       local_port,
	       pj_inet_ntoa(remote_addr.sin_addr),
	       pj_ntohs(remote_addr.sin_port));


    for (;;) {

	puts("");
	puts("Commands:");
	puts("  s     Display media statistics");
	puts("  q     Quit");
	puts("");

	printf("Command: "); fflush(stdout);

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

	if (tmp[0] == 's')
	    print_stream_stat(stream, &codec_param);
	else if (tmp[0] == 'q')
	    break;

    }



    /* Start deinitialization: */
on_exit:

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

    /* If there is master port, then we just need to destroy master port
     * (it will recursively destroy upstream and downstream ports, which
     * in this case are file_port and stream_port).
     */
    if (master_port) {
	pjmedia_master_port_destroy(master_port, PJ_TRUE);
	play_file_port = NULL;
	stream = NULL;
    }

    /* Destroy stream */
    if (stream) {
	pjmedia_transport *tp;

	tp = pjmedia_stream_get_transport(stream);
	pjmedia_stream_destroy(stream);
	
	pjmedia_transport_close(tp);
    }

    /* Destroy file ports */
    if (play_file_port)
	pjmedia_port_destroy( play_file_port );
    if (rec_file_port)
	pjmedia_port_destroy( rec_file_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();


    return (status == PJ_SUCCESS) ? 0 : 1;
}
Esempio n. 26
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_port *file_port;
    pjmedia_snd_port *snd_port;
    char tmp[10];
    pj_status_t status;


    if (argc != 2) {
    	puts("Error: filename 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	    */
					      20,	/* 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;
    }

    /* Create sound player port. */
    status = pjmedia_snd_port_create_player( 
		 pool,				    /* pool		    */
		 -1,				    /* use default dev.	    */
		 file_port->info.clock_rate,	    /* clock rate.	    */
		 file_port->info.channel_count,	    /* # of channels.	    */
		 file_port->info.samples_per_frame, /* samples per frame.   */
		 file_port->info.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 file port to the sound player.
     * Stream playing will commence immediately.
     */
    status = pjmedia_snd_port_connect( snd_port, file_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);



    /* 
     * 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..\n", argv[1]);
    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: */

    /* Disconnect sound port from file port */
    status = pjmedia_snd_port_disconnect(snd_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Without this sleep, Windows/DirectSound will repeteadly
     * play the last frame during destroy.
     */
    pj_thread_sleep(100);

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


    /* 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;
}
Esempio n. 27
0
int main(int argc, char *argv[])
{
    struct pj_getopt_option long_options[] = {
	{ "realm",	1, 0, 'r'},
	{ "username",	1, 0, 'u'},
	{ "password",	1, 0, 'p'},
	{ "nonce",	1, 0, 'N'},
	{ "fingerprint",0, 0, 'F'},
	{ "help",	0, 0, 'h'}
    };
    int c, opt_id;
    pj_caching_pool cp;
    pj_stun_server *srv;
    pj_stun_usage *turn;
    pj_status_t status;

    while((c=pj_getopt_long(argc,argv, "r:u:p:N:hF", long_options, &opt_id))!=-1) {
	switch (c) {
	case 'r':
	    o.realm = pj_optarg;
	    break;
	case 'u':
	    o.user_name = pj_optarg;
	    break;
	case 'p':
	    o.password = pj_optarg;
	    break;
	case 'N':
	    o.nonce = pj_optarg;
	    break;
	case 'h':
	    usage();
	    return 0;
	case 'F':
	    o.use_fingerprint = PJ_TRUE;
	    break;
	default:
	    printf("Argument \"%s\" is not valid. Use -h to see help",
		   argv[pj_optind]);
	    return 1;
	}
    }

    if (pj_optind != argc) {
	puts("Error: invalid arguments");
	return 1;
    }

    pj_init();
    pjlib_util_init();
    pjnath_init();
    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);

    status = pj_stun_server_create(&cp.factory, 1, &srv);
    if (status != PJ_SUCCESS) {
	pj_stun_perror(THIS_FILE, "Unable to create server", status);
	return 1;
    }

    /*
    status = pj_stun_bind_usage_create(srv, NULL, 3478, NULL);
    if (status != PJ_SUCCESS) {
	pj_stun_perror(THIS_FILE, "Unable to create bind usage", status);
	return 1;
    }
    */

    status = pj_stun_turn_usage_create(srv, pj_SOCK_DGRAM(), NULL,
				       3478, o.use_fingerprint, &turn);
    if (status != PJ_SUCCESS) {
	pj_stun_perror(THIS_FILE, "Unable to create bind usage", status);
	return 1;
    }

    if (o.user_name && o.password) {
	pj_stun_auth_cred cred;
	pj_bzero(&cred, sizeof(cred));
	cred.type = PJ_STUN_AUTH_CRED_STATIC;
	cred.data.static_cred.realm = pj_str(o.realm);
	cred.data.static_cred.username = pj_str(o.user_name);
	cred.data.static_cred.data_type = 0;
	cred.data.static_cred.data = pj_str(o.password);
	cred.data.static_cred.nonce = pj_str(o.nonce);
	pj_stun_turn_usage_set_credential(turn, &cred);
    }

    server_main(srv);

    pj_stun_server_destroy(srv);
    pj_pool_factory_dump(&cp.factory, PJ_TRUE);
    pj_shutdown();
    return 0;
}