/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */

 /**
 * \page page_pjmedia_samples_encdec_c Samples: Encoding and Decoding
 *
 * This sample shows how to use codec.
 *
 * This file is pjsip-apps/src/samples/encdec.c
 *
 * \includelineno encdec.c
 */

#include <pjlib.h>
#include <pjmedia.h>
#include <pjmedia-codec.h>

#define THIS_FILE   "encdec.c"

static const char *desc = 
 " encdec								\n"
 "									\n"
 " PURPOSE:								\n"
 "  Encode input WAV with a codec, and decode the result to another WAV \n"
 "\n"
 "\n"
 " USAGE:								\n"
 "  encdec codec input.wav output.wav                                   \n"
 "\n"
 "\n"
 " where:\n"
 "  codec         Set the codec name.                                   \n"
 "  input.wav     Set the input WAV filename.                           \n"
 "  output.wav    Set the output WAV filename.                          \n"

 "\n"
;

//#undef PJ_TRACE
//#define PJ_TRACE 1

#ifndef PJ_TRACE
#	define PJ_TRACE 0
#endif

#if PJ_TRACE
#   define TRACE_(expr)	    PJ_LOG(4,expr)
#else
#   define TRACE_(expr)
#endif


static void err(const char *op, pj_status_t status)
{
    char errmsg[PJ_ERR_MSG_SIZE];
    pj_strerror(status, errmsg, sizeof(errmsg));
    PJ_LOG(3,("", "%s error: %s", op, errmsg));
}

#define CHECK(op)   do { \
			status = op; \
			if (status != PJ_SUCCESS) { \
			    err(#op, status); \
			    return status; \
			} \
		    } \
		    while (0)

static pjmedia_endpt *mept;
static unsigned file_msec_duration;

static pj_status_t enc_dec_test(const char *codec_id,
				const char *filein,
			        const char *fileout)
{
    pj_pool_t *pool;
    pjmedia_codec_mgr *cm;
    pjmedia_codec *codec;
    const pjmedia_codec_info *pci;
    pjmedia_codec_param param;
    unsigned cnt, samples_per_frame;
    pj_str_t tmp;
    pjmedia_port *wavin, *wavout;
    unsigned lost_pct;
    pj_status_t status;

#define T   file_msec_duration/1000, file_msec_duration%1000
    
    pool = pjmedia_endpt_create_pool(mept, "encdec", 1000, 1000);

    cm = pjmedia_endpt_get_codec_mgr(mept);

#ifdef LOST_PCT
    lost_pct = LOST_PCT;
#else
    lost_pct = 0;
#endif
    
    cnt = 1;
    CHECK( pjmedia_codec_mgr_find_codecs_by_id(cm, pj_cstr(&tmp, codec_id), 
					       &cnt, &pci, NULL) );
    CHECK( pjmedia_codec_mgr_get_default_param(cm, pci, &param) );

    samples_per_frame = param.info.clock_rate * param.info.frm_ptime / 1000;

    /* Control VAD */
    param.setting.vad = 1;

    /* Open wav for reading */
    CHECK( pjmedia_wav_player_port_create(pool, filein, 
					  param.info.frm_ptime, 
					  PJMEDIA_FILE_NO_LOOP, 0, &wavin) );

    /* Open wav for writing */
    CHECK( pjmedia_wav_writer_port_create(pool, fileout,
					  param.info.clock_rate, 
					  param.info.channel_cnt,
					  samples_per_frame,
					  16, 0, 0, &wavout) );

    /* Alloc codec */
    CHECK( pjmedia_codec_mgr_alloc_codec(cm, pci, &codec) );
    CHECK( pjmedia_codec_init(codec, pool) );
    CHECK( pjmedia_codec_open(codec, &param) );
    
    for (;;) {
	pjmedia_frame frm_pcm, frm_bit, out_frm, frames[4];
	pj_int16_t pcmbuf[320];
	pj_timestamp ts;
	pj_uint8_t bitstream[160];

	frm_pcm.buf = (char*)pcmbuf;
	frm_pcm.size = samples_per_frame * 2;

	/* Read from WAV */
	if (pjmedia_port_get_frame(wavin, &frm_pcm) != PJ_SUCCESS)
	    break;
	if (frm_pcm.type != PJMEDIA_FRAME_TYPE_AUDIO)
	    break;;

	/* Update duration */
	file_msec_duration += samples_per_frame * 1000 / 
			      param.info.clock_rate;

	/* Encode */
	frm_bit.buf = bitstream;
	frm_bit.size = sizeof(bitstream);
	CHECK(pjmedia_codec_encode(codec, &frm_pcm, sizeof(bitstream), 
	                           &frm_bit));

	/* On DTX, write zero frame to wavout to maintain duration */
	if (frm_bit.size == 0 || frm_bit.type != PJMEDIA_FRAME_TYPE_AUDIO) {
	    out_frm.buf = (char*)pcmbuf;
	    out_frm.size = 160;
	    CHECK( pjmedia_port_put_frame(wavout, &out_frm) );
	    TRACE_((THIS_FILE, "%d.%03d read: %u, enc: %u",
		    T, frm_pcm.size, frm_bit.size));
	    continue;
	}
	
	/* Parse the bitstream (not really necessary for this case
	 * since we always decode 1 frame, but it's still good
	 * for testing)
	 */
	ts.u64 = 0;
	cnt = PJ_ARRAY_SIZE(frames);
	CHECK( pjmedia_codec_parse(codec, bitstream, frm_bit.size, &ts, &cnt, 
			           frames) );
	CHECK( (cnt==1 ? PJ_SUCCESS : -1) );

	/* Decode or simulate packet loss */
	out_frm.buf = (char*)pcmbuf;
	out_frm.size = sizeof(pcmbuf);
	
	if ((pj_rand() % 100) < (int)lost_pct) {
	    /* Simulate loss */
	    CHECK( pjmedia_codec_recover(codec, sizeof(pcmbuf), &out_frm) );
	    TRACE_((THIS_FILE, "%d.%03d Packet lost", T));
	} else {
	    /* Decode */
	    CHECK( pjmedia_codec_decode(codec, &frames[0], sizeof(pcmbuf), 
				     &out_frm) );
	}

	/* Write to WAV */
	CHECK( pjmedia_port_put_frame(wavout, &out_frm) );

	TRACE_((THIS_FILE, "%d.%03d read: %u, enc: %u, dec/write: %u",
		T, frm_pcm.size, frm_bit.size, out_frm.size));
    }

    /* Close wavs */
    pjmedia_port_destroy(wavout);
    pjmedia_port_destroy(wavin);

    /* Close codec */
    pjmedia_codec_close(codec);
    pjmedia_codec_mgr_dealloc_codec(cm, codec);

    /* Release pool */
    pj_pool_release(pool);

    return PJ_SUCCESS;
}


int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pj_time_val t0, t1;
    pj_status_t status;

    if (argc != 4) {
	puts(desc);
	return 1;
    }

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

    CHECK( pjmedia_endpt_create(&cp.factory, NULL, 1, &mept) );

    /* Register all codecs */
    CHECK( pjmedia_codec_register_audio_codecs(mept, NULL) );

    pj_gettimeofday(&t0);
    status = enc_dec_test(argv[1], argv[2], argv[3]);
    pj_gettimeofday(&t1);
    PJ_TIME_VAL_SUB(t1, t0);

    pjmedia_endpt_destroy(mept);
    pj_caching_pool_destroy(&cp);
    pj_shutdown();

    if (status == PJ_SUCCESS) {
	puts("");
	puts("Success");
	printf("Duration: %ds.%03d\n", file_msec_duration/1000, 
				       file_msec_duration%1000);
	printf("Time: %lds.%03ld\n", t1.sec, t1.msec);
    }

    return 0;
}

