/*
 ** Copyright 2003-2010, VisualOn, Inc.
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
/*******************************************************************************
	File:		AAC_E_SAMPLES.h

	Content:	sample code for AAC encoder

*******************************************************************************/

#include		<dlfcn.h>
#include		<stdio.h>
#include		<stdlib.h>
#include		<string.h>
#include		<time.h>
#include		"voAAC.h"
#include		"cmnMemory.h"

#define  VO_AAC_E_OUTPUT	  1
#define READ_SIZE	(1024*8)	
unsigned char outBuf[1024*8];
unsigned char inBuf[READ_SIZE];

const char* HelpString = 
"VisualOn AAC encoder Usage:\n"
"voAACEncTest -if <inputfile.pcm> -of <outputfile.aac> -sr <samplerate> -ch <channel> -br <bitrate> -adts <adts> \n"
"-if input file name \n"
"-of output file name \n"
"-sr input pcm samplerate, default 44100 \n"
"-ch input pcm channel, default 2 channel \n"
"-br encoded aac bitrate, default 64000 * (samplerate/100)*channel/441(480)\n"
"-adts add or no adts header, default add adts header\n"
"For example: \n"
"./voAACEncTest -if raw.pcm -of raw.aac -sr 44100 -ch 2 -br 128000\n";

static int parsecmdline(int argc, char **argv,char  **input_filename, char  **output_filename, AACENC_PARAM *param)
{
	// notice that:
	// bitRate/nChannels > 8000
	// bitRate/nChannels < 160000 
	// bitRate/nChannels < sampleRate*6
	param->adtsUsed = 1;
	param->bitRate = 0;
	param->nChannels = 2;
	param->sampleRate = 44100;

	if(argc < 5 || argc > 13)
	{
		return -1;
	}

	argc--;
	argv++;
	while (argc > 0)
	{
		if (!strcmp(*argv, "-if"))
		{
			argv++;
			argc--;
			*input_filename = *argv; 
		}
		else if (!strcmp(*argv, "-of"))
		{
			argv++;
			argc--;
			*output_filename = *argv;
		}
		else if (!strcmp(*argv, "-sr"))
		{
			argv++;
			argc--;
			param->sampleRate = atoi(*argv);
		}
		else if (!strcmp(*argv, "-ch"))
		{
			argv++;
			argc--;
			param->nChannels = atoi(*argv);
		}
		else if (!strcmp(*argv, "-br"))
		{
			argv++;
			argc--;
			param->bitRate = atoi(*argv);
		}
		else if(!strcmp(*argv, "-adts"))
		{
			argv++;
			argc--;
			param->adtsUsed = atoi(*argv);
		}
		else
		{
			return -1;
		}

		argv++;
		argc--;
	}

	if(param->bitRate == 0)
	{
		int scale = 441;
		if(param->sampleRate%8000 == 0)
			scale = 480;
		param->bitRate = 640*param->nChannels*param->sampleRate/scale;
	}

	return 0;
}

int ReadFile2Buf(FILE* infile,unsigned char* dest,int readSize)
{
	int readBytes = 0;
	readBytes = fread(dest, 1, readSize, infile);
	return readBytes;
}

typedef int (VO_API * VOGETAUDIODECAPI) (VO_AUDIO_CODECAPI * pDecHandle);

int main(int argc, char **argv)
{
	FILE						*infile, *outfile;
	int							t1, t2;
	VO_AUDIO_CODECAPI			AudioAPI;
	VO_MEM_OPERATOR				moper;
	VO_CODEC_INIT_USERDATA		useData;
	VO_HANDLE					hCodec;
	VO_CODECBUFFER				inData;
	VO_CODECBUFFER				outData;
	VO_AUDIO_OUTPUTINFO			outInfo;
    int							firstWrite = 1;
	int							eofFile = 0;
	int							*info=(int*)inBuf;
	int							bytesLeft, nRead;
	int							EncoderdFrame = 0;
	int							total = 0;
	int							isOutput = 1;
	int							returnCode;
	AACENC_PARAM				aacpara;
	void						*handle;
	void						*pfunc;
	VOGETAUDIODECAPI			pGetAPI;
	const char					*infileName = NULL;
    const char					*outfileName = NULL;

	returnCode = parsecmdline(argc,argv, &infileName, &outfileName, &aacpara);
	if(returnCode)
	{
		printf("%s", HelpString);
		return 0;
	}

	/* open input file */
	infile = fopen(infileName, "rb");
	if (!infile) {
		printf("Open input file fail...");
		return -1;
	}

	/* open output file */
	if(isOutput)
	{
		outfile = fopen(outfileName, "wb"); 
		if (!outfile) {
			printf("Open output file fail...");
			return -1;
		}
	}
	// set memory operators;
	moper.Alloc = cmnMemAlloc;
	moper.Copy = cmnMemCopy;
	moper.Free = cmnMemFree;
	moper.Set = cmnMemSet;
	moper.Check = cmnMemCheck;
	useData.memflag = VO_IMF_USERMEMOPERATOR;
	useData.memData = (VO_PTR)(&moper);
	// open encoder dll;
	handle = dlopen("/data/local/tmp/libvoAACEncv7.so", RTLD_NOW);
	if(handle == 0)
	{
		printf("open dll error......");
		return -1;
	}
	// Get API;
	pfunc = dlsym(handle, "voGetAACEncAPI");	
	if(pfunc == 0)
	{
		printf("open function error......");
		return -1;
	}
	pGetAPI = (VOGETAUDIODECAPI)pfunc;
	returnCode  = pGetAPI(&AudioAPI);
	if(returnCode)
		return -1;


//#######################################   Init Encoding Section   #########################################
	returnCode = AudioAPI.Init(&hCodec, VO_AUDIO_CodingAAC, &useData);
	if(returnCode < 0)
	{
		printf("#### VOI_Error2:fail to initialize the Encoderr###\n");
		return -1;
	}

	returnCode = AudioAPI.SetParam(hCodec, VO_PID_AAC_ENCPARAM, &aacpara);	
	
	inData.Buffer = inBuf;
	bytesLeft = ReadFile2Buf(infile,inData.Buffer,READ_SIZE);

//#######################################    Encoding Section   #########################################
	
	do {

		inData.Length    = bytesLeft;
		outData.Buffer   = outBuf;
		outData.Length = 1024*8;

		t1 = clock();
		
		returnCode = AudioAPI.SetInputData(hCodec,&inData);
		
		do {
			outData.Buffer   = outBuf;
			outData.Length = 1024*8;

			returnCode = AudioAPI.GetOutputData(hCodec,&outData, &outInfo);

			if(returnCode == 0)
				EncoderdFrame++;
			if(returnCode == VO_ERR_LICENSE_ERROR)
				break;

#if VO_AAC_E_OUTPUT
			if (isOutput && returnCode == 0)
			{
				fwrite(outData.Buffer, 1, outData.Length, outfile);
			}
#endif
		} while(returnCode != (VO_ERR_INPUT_BUFFER_SMALL));

		if(returnCode == VO_ERR_LICENSE_ERROR)
			break;

		t2 = clock();
		total += t2 - t1;

		if (!eofFile) {
			nRead = ReadFile2Buf(infile, inBuf,READ_SIZE);
			bytesLeft = nRead;
			inData.Buffer = inBuf;
			if (feof(infile))
				eofFile = 1;
		}

	} while (!eofFile && returnCode);


//################################################  End Encoding Section  #######################################################
	returnCode = AudioAPI.Uninit(hCodec);

	fclose(infile);
	if (outfile)
    {
        fclose(outfile);
    }
	dlclose(handle);
	return 0;
}


