/* $Id$ */
/* 
 * 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( codec->op->init(codec, pool) );
    CHECK( codec->op->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(codec->op->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( codec->op->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( codec->op->recover(codec, sizeof(pcmbuf), &out_frm) );
	    TRACE_((THIS_FILE, "%d.%03d Packet lost", T));
	} else {
	    /* Decode */
	    CHECK( codec->op->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 */
    codec->op->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 */
#if PJMEDIA_HAS_G711_CODEC
    CHECK( pjmedia_codec_g711_init(mept) );
#endif
#if PJMEDIA_HAS_GSM_CODEC
    CHECK( pjmedia_codec_gsm_init(mept) );
#endif
#if PJMEDIA_HAS_ILBC_CODEC
    CHECK( pjmedia_codec_ilbc_init(mept, 30) );
#endif
#if PJMEDIA_HAS_SPEEX_CODEC
    CHECK( pjmedia_codec_speex_init(mept, 0, 5, 5) );
#endif
#if PJMEDIA_HAS_G722_CODEC
    CHECK( pjmedia_codec_g722_init(mept) );
#endif

    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;
}

