Initial support for stereo codecs, and added L16 codecs. Also better handling for case remote media is restarted

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@412 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip-apps/src/samples/confsample.c b/pjsip-apps/src/samples/confsample.c
index 843b99f..539a2c0 100644
--- a/pjsip-apps/src/samples/confsample.c
+++ b/pjsip-apps/src/samples/confsample.c
@@ -184,7 +184,7 @@
     }
 
 #if RECORDER
-    status = pjmedia_file_writer_port_create( pool, "confrecord.wav",
+    status = pjmedia_wav_writer_port_create(  pool, "confrecord.wav",
 					      clock_rate, channel_count,
 					      samples_per_frame, 
 					      bits_per_sample, 0, 0, NULL,
@@ -204,9 +204,10 @@
     for (i=0; i<file_count; ++i) {
 
 	/* Load the WAV file to file port. */
-	status = pjmedia_file_player_port_create( 
+	status = pjmedia_wav_player_port_create( 
 			pool,		    /* pool.	    */
 			argv[i+pj_optind],  /* filename	    */
+			0,		    /* use default ptime */
 			0,		    /* flags	    */
 			0,		    /* buf size	    */
 			NULL,		    /* user data    */
diff --git a/pjsip-apps/src/samples/level.c b/pjsip-apps/src/samples/level.c
index 8723d62..e216984 100644
--- a/pjsip-apps/src/samples/level.c
+++ b/pjsip-apps/src/samples/level.c
@@ -45,6 +45,8 @@
 {
     char errmsg[PJ_ERR_MSG_SIZE];
 
+    PJ_UNUSED_ARG(sender);
+
     pj_strerror(status, errmsg, sizeof(errmsg));
 
     printf("%s: %s [code=%d]\n", title, errmsg, status);
@@ -96,8 +98,9 @@
 			   );
 
     /* Create file media port from the WAV file */
-    status = pjmedia_file_player_port_create( pool,	/* memory pool	    */
+    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
 					      argv[1],	/* file to play	    */
+					      0,	/* use default ptime*/
 					      0,	/* flags	    */
 					      0,	/* default buffer   */
 					      NULL,	/* user data	    */
diff --git a/pjsip-apps/src/samples/playfile.c b/pjsip-apps/src/samples/playfile.c
index 1ae9a6c..06f4c1f 100644
--- a/pjsip-apps/src/samples/playfile.c
+++ b/pjsip-apps/src/samples/playfile.c
@@ -76,6 +76,9 @@
     pj_status_t status;
 
 
+    PJ_UNUSED_ARG(argc);
+
+
     /* Must init PJLIB first: */
     status = pj_init();
     PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
@@ -99,8 +102,9 @@
 			   );
 
     /* Create file media port from the WAV file */
-    status = pjmedia_file_player_port_create( pool,	/* memory pool	    */
+    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
 					      argv[1],	/* file to play	    */
+					      20,	/* ptime.	    */
 					      0,	/* flags	    */
 					      0,	/* default buffer   */
 					      NULL,	/* user data	    */
@@ -115,7 +119,7 @@
     status = pjmedia_snd_port_create_player( 
 		 pool,				    /* pool		    */
 		 -1,				    /* use default dev.	    */
-		 file_port->info.sample_rate,	    /* clock rate.	    */
+		 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.	    */
diff --git a/pjsip-apps/src/samples/playsine.c b/pjsip-apps/src/samples/playsine.c
index 2e83221..931f912 100644
--- a/pjsip-apps/src/samples/playsine.c
+++ b/pjsip-apps/src/samples/playsine.c
@@ -48,6 +48,8 @@
 {
     char errmsg[PJ_ERR_MSG_SIZE];
 
+    PJ_UNUSED_ARG(sender);
+
     pj_strerror(status, errmsg, sizeof(errmsg));
 
     printf("%s: %s [code=%d]\n", title, errmsg, status);
@@ -127,7 +129,7 @@
     port->info.name = pj_str("sine generator");
     port->info.need_info = 0;
     port->info.pt = 0xFF;
-    port->info.sample_rate = sampling_rate;
+    port->info.clock_rate = sampling_rate;
     port->info.samples_per_frame = sampling_rate * 20 / 1000 * channel_count;
     port->info.bytes_per_frame = port->info.samples_per_frame * 2;
     port->info.type = PJMEDIA_TYPE_AUDIO;
@@ -229,7 +231,7 @@
     status = pjmedia_snd_port_create_player( 
 		 pool,				    /* pool		    */
 		 -1,				    /* use default dev.	    */
-		 sine_port->info.sample_rate,	    /* clock rate.	    */
+		 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.	    */
diff --git a/pjsip-apps/src/samples/recfile.c b/pjsip-apps/src/samples/recfile.c
index 3fd9612..2236dca 100644
--- a/pjsip-apps/src/samples/recfile.c
+++ b/pjsip-apps/src/samples/recfile.c
@@ -104,7 +104,7 @@
 			   );
 
     /* Create WAVE file writer port. */
-    status = pjmedia_file_writer_port_create( pool, argv[1],
+    status = pjmedia_wav_writer_port_create(  pool, argv[1],
 					      CLOCK_RATE,
 					      NCHANNELS,
 					      SAMPLES_PER_FRAME,
@@ -120,7 +120,7 @@
     status = pjmedia_snd_port_create_rec( 
 		 pool,				    /* pool		    */
 		 -1,				    /* use default dev.	    */
-		 file_port->info.sample_rate,	    /* clock rate.	    */
+		 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.	    */
diff --git a/pjsip-apps/src/samples/resampleplay.c b/pjsip-apps/src/samples/resampleplay.c
index 62b6761..e4440e1 100644
--- a/pjsip-apps/src/samples/resampleplay.c
+++ b/pjsip-apps/src/samples/resampleplay.c
@@ -108,8 +108,8 @@
 			   );
 
     /* Create the file port. */
-    status = pjmedia_file_player_port_create( pool, argv[pj_optind], 0,
-					      0, 0, &file_port);
+    status = pjmedia_wav_player_port_create( pool, argv[pj_optind], 0, 0,
+					     0, 0, &file_port);
     if (status != PJ_SUCCESS) {
 	app_perror(THIS_FILE, "Unable to open file", status);
 	return 1;
@@ -128,12 +128,12 @@
 
     /* Create the resample port. */
     status = pjmedia_resample_port_create( pool, 1, 1,
-					   file_port->info.sample_rate,
+					   file_port->info.clock_rate,
 					   sampling_rate,
 					   channel_count,
 					   (unsigned)(
 					   samples_per_frame * 1.0 *
-					    file_port->info.sample_rate / 
+					    file_port->info.clock_rate / 
 					    sampling_rate),
 					   &resample_port);
     if (status != PJ_SUCCESS) {
@@ -186,7 +186,7 @@
 
 
     printf("Playing %s at sampling rate %d (original file sampling rate=%d)\n",
-	   argv[pj_optind], sampling_rate, file_port->info.sample_rate);
+	   argv[pj_optind], sampling_rate, file_port->info.clock_rate);
     puts("");
     puts("Press <ENTER> to stop playing and quit");
 
diff --git a/pjsip-apps/src/samples/simpleua.c b/pjsip-apps/src/samples/simpleua.c
index 8079225..59991af 100644
--- a/pjsip-apps/src/samples/simpleua.c
+++ b/pjsip-apps/src/samples/simpleua.c
@@ -419,6 +419,8 @@
 static void call_on_state_changed( pjsip_inv_session *inv, 
 				   pjsip_event *e)
 {
+    PJ_UNUSED_ARG(e);
+
     if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
 
 	PJ_LOG(3,(THIS_FILE, "Call DISCONNECTED [reason=%d (%s)]", 
@@ -441,6 +443,8 @@
 static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e)
 {
     /* To be done... */
+    PJ_UNUSED_ARG(inv);
+    PJ_UNUSED_ARG(e);
 }
 
 
@@ -633,7 +637,7 @@
     status = pjmedia_snd_port_create_player( 
 		    inv->pool,				/* pool		    */
 		    -1,					/* sound dev id	    */
-		    media_port->info.sample_rate,	/* clock rate	    */
+		    media_port->info.clock_rate,	/* clock rate	    */
 		    media_port->info.channel_count,	/* channel count    */
 		    media_port->info.samples_per_frame, /* samples per frame*/
 		    media_port->info.bits_per_sample,   /* bits per sample  */
@@ -642,7 +646,7 @@
     if (status != PJ_SUCCESS) {
 	app_perror( THIS_FILE, "Unable to create sound player", status);
 	PJ_LOG(3,(THIS_FILE, "%d %d %d %d",
-	    	    media_port->info.sample_rate,	/* clock rate	    */
+	    	    media_port->info.clock_rate,	/* clock rate	    */
 		    media_port->info.channel_count,	/* channel count    */
 		    media_port->info.samples_per_frame, /* samples per frame*/
 		    media_port->info.bits_per_sample    /* bits per sample  */
@@ -659,7 +663,7 @@
     status = pjmedia_snd_port_create_rec( 
 		    inv->pool,				/* pool		    */
 		    -1,					/* sound dev id	    */
-		    media_port->info.sample_rate,	/* clock rate	    */
+		    media_port->info.clock_rate,	/* clock rate	    */
 		    media_port->info.channel_count,	/* channel count    */
 		    media_port->info.samples_per_frame, /* samples per frame*/
 		    media_port->info.bits_per_sample,   /* bits per sample  */
diff --git a/pjsip-apps/src/samples/siprtp.c b/pjsip-apps/src/samples/siprtp.c
index ed14154..6d1b1dc 100644
--- a/pjsip-apps/src/samples/siprtp.c
+++ b/pjsip-apps/src/samples/siprtp.c
@@ -1238,7 +1238,7 @@
 	}
     }
 
-    audio->clock_rate = audio->si.fmt.sample_rate;
+    audio->clock_rate = audio->si.fmt.clock_rate;
     audio->samples_per_frame = audio->clock_rate * codec_desc->ptime / 1000;
     audio->bytes_per_frame = codec_desc->bit_rate * codec_desc->ptime / 1000 / 8;
 
diff --git a/pjsip-apps/src/samples/sndinfo.c b/pjsip-apps/src/samples/sndinfo.c
index ee9a385..3a18416 100644
--- a/pjsip-apps/src/samples/sndinfo.c
+++ b/pjsip-apps/src/samples/sndinfo.c
@@ -73,10 +73,10 @@
     puts("Run with -h to get more options");
 }
 
-static int clock_rate;
-static int play_counter;
-static int rec_counter;
-static int min_delay = 0xFFFF, max_delay;
+static unsigned clock_rate;
+static unsigned play_counter;
+static unsigned rec_counter;
+static unsigned min_delay = 0xFFFF, max_delay;
 static char play_delays[1000];
 static pj_uint32_t last_play_timestamp, last_rec_timestamp;
 
@@ -85,6 +85,12 @@
 {
     static pj_timestamp last_cb;
 
+
+    PJ_UNUSED_ARG(user_data);
+    PJ_UNUSED_ARG(output);
+    PJ_UNUSED_ARG(size);
+
+
     ++play_counter;
     last_play_timestamp = timestamp;
 
@@ -92,7 +98,7 @@
 	pj_get_timestamp(&last_cb);
     } else if (play_counter <= PJ_ARRAY_SIZE(play_delays)) {
 	pj_timestamp now;
-	int delay;
+	unsigned delay;
 
 	pj_get_timestamp(&now);
 	
@@ -104,7 +110,7 @@
 
 	last_cb = now;
 
-	play_delays[play_counter-1] = delay;
+	play_delays[play_counter-1] = (char)delay;
     }
 
     return PJ_SUCCESS;
@@ -113,6 +119,12 @@
 static pj_status_t rec_cb(void *user_data, pj_uint32_t timestamp,
 			  const void *input, unsigned size)
 {
+
+    PJ_UNUSED_ARG(size);
+    PJ_UNUSED_ARG(input);
+    PJ_UNUSED_ARG(user_data);
+
+
     ++rec_counter;
 
     if (timestamp - last_rec_timestamp >= clock_rate) {
@@ -248,7 +260,7 @@
     } else if (argc == 6) {
 	
 	int dev_id;
-	pjmedia_dir dir;
+	pjmedia_dir dir = PJMEDIA_DIR_NONE;
 	int nchannel;
 	int bits;
 
diff --git a/pjsip-apps/src/samples/streamutil.c b/pjsip-apps/src/samples/streamutil.c
index 8c412c8..686a2ef 100644
--- a/pjsip-apps/src/samples/streamutil.c
+++ b/pjsip-apps/src/samples/streamutil.c
@@ -31,9 +31,7 @@
  "\n"
  "\n"
  " Options:\n"
- "  --codec=CODEC         Set the codec name. Valid codec names are:	\n"
- "                        pcma, pcmu, gsm, speexnb, speexwb, speexuwb.	\n"
- "                        (default: pcma).				\n"
+ "  --codec=CODEC         Set the codec name.                           \n"
  "  --local-port=PORT     Set local RTP port (default=4000)		\n"
  "  --remote=IP:PORT      Set the remote peer. If this option is set,	\n"
  "                        the program will transmit RTP audio to the	\n"
@@ -64,22 +62,6 @@
 #define THIS_FILE	"stream.c"
 
 
-struct codec
-{
-    char    *name;
-    char    *encoding_name;
-    int	     pt;
-    int	     clock_rate;
-} codec[] = 
-{
-    { "pcma",	  "pcma",  PJMEDIA_RTP_PT_PCMA, 8000 },
-    { "pcmu",	  "pcmu",  PJMEDIA_RTP_PT_PCMU, 8000 },
-    { "gsm",	  "gsm",   PJMEDIA_RTP_PT_GSM, 8000 },
-    { "speexnb",  "speex", 120, 8000 },
-    { "speexwb",  "speex", 121, 16000 },
-    { "speexuwb", "speex", 122, 32000 },
-};
-
 
 /* Prototype */
 static void print_stream_stat(pjmedia_stream *stream);
@@ -101,6 +83,9 @@
     status = pjmedia_codec_speex_init(med_endpt, 0, -1, -1);
     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
 
+    status = pjmedia_codec_l16_init(med_endpt, 0);
+    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+
     return PJ_SUCCESS;
 }
 
@@ -110,7 +95,7 @@
  */
 static pj_status_t create_stream( pj_pool_t *pool,
 				  pjmedia_endpt *med_endpt,
-				  unsigned codec_index,
+				  const pjmedia_codec_info *codec_info,
 				  pjmedia_dir dir,
 				  pj_uint16_t local_port,
 				  const pj_sockaddr_in *rem_addr,
@@ -127,11 +112,8 @@
     /* Initialize stream info formats */
     info.type = PJMEDIA_TYPE_AUDIO;
     info.dir = dir;
-    info.fmt.encoding_name = pj_str(codec[codec_index].encoding_name);
-    info.fmt.type = PJMEDIA_TYPE_AUDIO;
-    info.fmt.sample_rate = codec[codec_index].clock_rate;
-    info.fmt.pt = codec[codec_index].pt;
-    info.tx_pt = codec[codec_index].pt;
+    pj_memcpy(&info.fmt, codec_info, sizeof(pjmedia_codec_info));
+    info.tx_pt = codec_info->pt;
     info.ssrc = pj_rand();
     
 
@@ -200,6 +182,14 @@
 
 
 /*
+ * usage()
+ */
+static void usage()
+{
+    puts(desc);
+}
+
+/*
  * main()
  */
 int main(int argc, char *argv[])
@@ -217,10 +207,11 @@
 
 
     /* Default values */
-    int codec_index = 0;
+    const pjmedia_codec_info *codec_info;
     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;
 
@@ -233,6 +224,7 @@
 	OPT_SEND_RECV	= 'b',
 	OPT_SEND_ONLY	= 's',
 	OPT_RECV_ONLY	= 'i',
+	OPT_HELP	= 'h',
     };
 
     struct pj_getopt_option long_options[] = {
@@ -244,6 +236,7 @@
 	{ "send-recv",      0, 0, OPT_SEND_RECV },
 	{ "send-only",      0, 0, OPT_SEND_ONLY },
 	{ "recv-only",      0, 0, OPT_RECV_ONLY },
+	{ "help",	    0, 0, OPT_HELP },
 	{ NULL, 0, 0, 0 },
     };
 
@@ -261,25 +254,11 @@
 
     /* Parse arguments */
     pj_optind = 0;
-    while((c=pj_getopt_long(argc,argv, "", long_options, &option_index))!=-1) {
+    while((c=pj_getopt_long(argc,argv, "h", long_options, &option_index))!=-1) {
 
 	switch (c) {
 	case OPT_CODEC:
-	    {
-		unsigned i;
-		for (i=0; i<PJ_ARRAY_SIZE(codec); ++i) {
-		    if (pj_ansi_stricmp(pj_optarg, codec[i].name)==0) {
-			break;
-		    }
-		}
-
-		if (i == PJ_ARRAY_SIZE(codec)) {
-		    printf("Error: unknown codec %s\n", pj_optarg);
-		    return 1;
-		}
-
-		codec_index = i;
-	    }
+	    codec_id = pj_optarg;
 	    break;
 
 	case OPT_LOCAL_PORT:
@@ -323,6 +302,10 @@
 	    dir = PJMEDIA_DIR_DECODING;
 	    break;
 
+	case OPT_HELP:
+	    usage();
+	    return 1;
+
 	default:
 	    printf("Invalid options %s\n", argv[pj_optind]);
 	    return 1;
@@ -369,8 +352,26 @@
     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_index, dir, local_port, 
+    status = create_stream(pool, med_endpt, codec_info, dir, local_port, 
 			   &remote_addr, &stream);
     if (status != PJ_SUCCESS)
 	goto on_exit;
@@ -382,9 +383,12 @@
 
 
     if (play_file) {
+	unsigned wav_ptime;
 
-	status = pjmedia_file_player_port_create(pool, play_file, 0,
-						 -1, NULL, &play_file_port);
+	wav_ptime = stream_port->info.samples_per_frame * 1000 /
+		    stream_port->info.clock_rate;
+	status = pjmedia_wav_player_port_create(pool, play_file, wav_ptime,
+						0, -1, NULL, &play_file_port);
 	if (status != PJ_SUCCESS) {
 	    app_perror(THIS_FILE, "Unable to use file", status);
 	    goto on_exit;
@@ -409,21 +413,21 @@
 	/* Create sound device port. */
 	if (dir == PJMEDIA_DIR_ENCODING_DECODING)
 	    status = pjmedia_snd_port_create(pool, -1, -1, 
-					stream_port->info.sample_rate,
+					stream_port->info.clock_rate,
 					stream_port->info.channel_count,
 					stream_port->info.samples_per_frame,
 					stream_port->info.bits_per_sample,
 					0, &snd_port);
 	else if (dir == PJMEDIA_DIR_ENCODING)
 	    status = pjmedia_snd_port_create_rec(pool, -1, 
-					stream_port->info.sample_rate,
+					stream_port->info.clock_rate,
 					stream_port->info.channel_count,
 					stream_port->info.samples_per_frame,
 					stream_port->info.bits_per_sample,
 					0, &snd_port);
 	else
 	    status = pjmedia_snd_port_create_player(pool, -1, 
-					stream_port->info.sample_rate,
+					stream_port->info.clock_rate,
 					stream_port->info.channel_count,
 					stream_port->info.samples_per_frame,
 					stream_port->info.bits_per_sample,
@@ -576,12 +580,12 @@
     printf(" Info: audio %.*s@%dHz, %dms/frame, %sB/s (%sB/s +IP hdr)\n",
    	(int)port->info.encoding_name.slen,
 	port->info.encoding_name.ptr,
-	port->info.sample_rate,
-	port->info.samples_per_frame * 1000 / port->info.sample_rate,
-	good_number(bps, port->info.bytes_per_frame * port->info.sample_rate /
-		    port->info.sample_rate),
+	port->info.clock_rate,
+	port->info.samples_per_frame * 1000 / port->info.clock_rate,
+	good_number(bps, port->info.bytes_per_frame * port->info.clock_rate /
+		    port->info.samples_per_frame),
 	good_number(ipbps, (port->info.bytes_per_frame+32) * 
-			    port->info.sample_rate / port->info.sample_rate));
+			    port->info.clock_rate / port->info.clock_rate));
 
     if (stat.rx.update_cnt == 0)
 	strcpy(last_update, "never");