/***************************************************************************//**
 * @file	profile.c
 * @date	2009/01/14 23:19:27
 * @author	jef-Linux
 * @brief
 *	Brief description
 * @details
 *	Released under GPL license, see gnu.org
 * encoding	UTF8 !-UTF8-!
 * Long description
*******************************************************************************/
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>

#include <gnome.h>

#include "globals.h"
#include "profile.h"
#include "dvdformat.h"
#include "systools.h"

#define gettext_noop(x)		x

/*@$#[profile.c] static proto. AutoProtoSigV1.1. date: 2009/02/04 23:21:36 */
#include "proto.h"
#ifdef __cplusplus
extern "C" {
#endif
/* profile.c */
static int VerifVideoCodec PROTO((Profile_t *p));
static int VerifAudioCodec PROTO((Profile_t *p));
static int VerifProfile PROTO((Profile_t *p));
#ifdef __cplusplus
}
#endif
/*@$% end of AutoProtoSigV1.1 (Dont remove this line) [-I ../include]*/


static Profile_t Profiles[] = {
	{
		DVD5,
		PROFILE_AVAIL_F | PROFILE_MULTI_AUDIO_F | PROFILE_HANDLE_SUBS_F,
		gettext_noop("DVD 4.7 GiO"),
		0,
		2,
		DVD5_WANTED_BYTES_LL,
		0,
		"ac3",
		"mpeg2",
		"none",
		"",
		"",
		"mpeg",
		0,
		0
	},
	{
		DVD9,
		PROFILE_AVAIL_F | PROFILE_MULTI_AUDIO_F | PROFILE_HANDLE_SUBS_F,
		gettext_noop("DVD 8.5 GiO"),
		0,
		2,
		DVD5_WANTED_BYTES_LL,
		0,
		"ac3",
		"mpeg2",
		"none",
		"",
		"",
		"mpeg",
		0,
		0
	},
/* from http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-enc-libavcodec.html AVGPSNR = 28.31 1H38 => 2H00 */
	{
		AVI700,
		PROFILE_AVI_F,
		gettext_noop("AVI 700Mo mp3-128k MPEG4 2Pass"),
		0.22,
		2,
		700 * 1024 * 1024,
		128000,
		"mp3lame",
		"lavc",
		"mencoder",
		"\"%i\" -o /dev/null -passlogfile \"%p\" -ovc lavc -lavcopts threads=%u:vcodec=mpeg4:autoaspect:vbitrate=%b:vpass=1:turbo -ofps 25.0 -aspect %a -oac copy -aid %A -vf crop=%c,scale=%x:%y",
		"\"%i\" -o \"%o\" -passlogfile \"%p\" -ovc lavc -lavcopts threads=%u:vcodec=mpeg4:autoaspect:mbd=2:mv0:trell:v4mv:cbp:last_pred=3:predia=2:dia=2:vmax_b_frames=2:vb_strategy=1:precmp=2:cmp=2:subcmp=2:preme=2:qns=2:vbitrate=%b:vpass=2 -ofps 25.0 -aspect %a -oac mp3lame -lameopts br=128:q=9:aq=9:cbr:mode=1 -vf crop=%c,scale=%x:%y",
/*
		"\"%i\" -o /dev/null -passlogfile \"%p\" -ovc lavc -lavcopts threads=%u:vcodec=mpeg4:autoaspect:vhq:vbitrate=%b:vpass=1:turbo -ofps 25.0 -aspect %a -oac mp3lame -lameopts br=128:q=9:aq=9:cbr:mode=1 -vf crop=%c,scale=%x:%y",
		"\"%i\" -o \"%o\" -passlogfile \"%p\" -ovc lavc -lavcopts threads=%u:vcodec=mpeg4:autoaspect:mbd=2:trell:vbitrate=%b:vpass=2 -ofps 25.0 -aspect %a -oac mp3lame -lameopts br=128:q=9:aq=9:cbr:mode=1 -vf crop=%c,scale=%x:%y",
*/
		"avi",
		0.05,
		0
	},
	{
		AVI700+1,
		PROFILE_AVI_F,
		gettext_noop("AVI 1Go mp3-128k MPEG4 1Pass"),
		0.25,
		1,
		1000 * 1024 * 1024,
		128000,
		"mp3lame",
		"lavc",
		"mencoder",
		"\"%i\" -o \"%o\" -ovc lavc -lavcopts threads=%u:vcodec=mpeg4:autoaspect:vhq:vbitrate=%b -ofps 25.0 -aspect %a -oac mp3lame -lameopts br=128:q=9:aq=9:cbr:mode=1 -vf crop=%c,scale=%x:%y",
		"",
		"avi",
		0.05,
		1
	},
/* From: http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-x264.html */
	{
		AVI700+2,
		PROFILE_AVI_F,
		gettext_noop("AVI 1Go mp3-128k X264 1Pass"),
		0.20,
		1,
		1000 * 1024 * 1024,
		128000,
		"mp3lame",
		"x264",
		"mencoder",
		"\"%i\" -o \"%o\" -ovc x264 -x264encopts threads=%u:subq=6:partitions=all:8x8dct:me=umh:frameref=5:bframes=3:b_pyramid=normal:weight_b:bitrate=%b -ofps 25.0 -aspect %a -oac mp3lame -lameopts br=128:q=9:aq=9:cbr:mode=1 -vf crop=%c,scale=%x:%y",
		"",
		"avi",
		0.05,
		1
	},
	{
		AVI700+3,
		PROFILE_AVI_F,
		gettext_noop("AVI 1.5Go mp3-128k MPEG4 1Pass"),
		0.30,
		1,
		1500 * 1024 * 1024,
		128000,
		"mp3lame",
		"lavc",
		"mencoder",
		"\"%i\" -o \"%o\" -ovc lavc -lavcopts threads=%u:vcodec=mpeg4:autoaspect:vhq:vbitrate=%b -ofps 25.0 -aspect %a -oac mp3lame -lameopts br=128:q=9:aq=9:cbr:mode=1 -vf crop=%c,scale=%x:%y",
		"",
		"avi",
		0.05,
		1
	},
/* AVGPSNR= 41.42 1H38 => 20MN*/
	{
		AVI700+4,
		PROFILE_AVI_F,
		gettext_noop("AVI 2Go AC3 MPEG4 1Pass"),
		0.30,
		1,
		2000LL * 1024LL * 1024LL,
		-1,
		"copy",
		"lavc",
		"mencoder",
		"\"%i\" -o \"%o\" -ovc lavc -lavcopts threads=%u:vcodec=mpeg4:autoaspect:vhq:vbitrate=%b -ofps 25.0 -aspect %a -oac copy -aid %A -vf crop=%c,scale=%x:%y",
		"",
		"avi",
		0.05,
		1
	},
/* From: http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-x264.html */
	{
		AVI700+5,
		PROFILE_AVI_F,
		gettext_noop("AVI 2Go AC3 X264 1Pass"),
		0.20,
		1,
		2000LL * 1024LL * 1024LL,
		-1,
		"copy",
		"x264",
		"mencoder",
		"\"%i\" -o \"%o\" -ovc x264 -x264encopts threads=%u:subq=6:partitions=all:8x8dct:me=umh:frameref=5:bframes=3:b_pyramid=normal:weight_b:bitrate=%b -ofps 25.0 -aspect %a -oac copy -aid %A -vf crop=%c,scale=%x:%y",
		"",
		"avi",
		0.05,
		1
	},
	{
		AVI700+6,
		PROFILE_AVI_F,
		gettext_noop("PSP 300Mo"),
		0.16,
		1,
		300 * 1024 * 1024,
		24000,
		"faac",
		"mpeg4",
		"ffmpeg",
//faac		"\"%i\" -o \"%o\" -oac lavc -ovc lavc -of lavf -lavcopts threads=%u:aglobal=1:vglobal=1:vcodec=mpeg4:vbitrate=%b:acodec=libfaac -af lavcresample=24000 -vf harddup -vf crop=%c,scale=320:240 -lavfopts format=psp -ofps 30000/1001",
		"-i \"%i\" -y -threads %u -acodec libfaac -ab 128kb -vcodec mpeg4 -b %bkb -ar 24000 -mbd 2 -flags +4mv -trellis 2 -ac 2 -cmp 2 -subcmp 2 -s 320x240 -r 30000/1001 -f psp \"%o\"",
		"",
		"mp4",
		0.05,
		0
	},
	{
		AVI700+7,
		PROFILE_AVI_F,
		gettext_noop("PSP 500Mo"),
		0.16,
		1,
		500 * 1024 * 1024,
		24000,
		"faac",
		"mpeg4",
		"ffmpeg",
//faac		"\"%i\" -o \"%o\" -oac lavc -ovc lavc -of lavf -lavcopts threads=%u:aglobal=1:vglobal=1:vcodec=mpeg4:vbitrate=%b:acodec=libfaac -af lavcresample=24000 -vf harddup -vf crop=%c,scale=320:240 -lavfopts format=psp -ofps 30000/1001",
		"-i \"%i\" -y -threads %u -acodec libfaac -ab 128kb -vcodec mpeg4 -b %bkb -ar 24000 -mbd 2 -flags +4mv -trellis 2 -ac 2 -cmp 2 -subcmp 2 -s 320x240 -r 30000/1001 -f psp \"%o\"",
		"",
		"mp4",
		0.05,
		0
	},
/* From: http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-x264.html */
	{
		AVI700+8,
		PROFILE_AVI_F,
		gettext_noop("AVI 2Go AC3 X264 2Pass High Quality"),
		0.20,
		2,
		2000LL * 1024LL * 1024LL,
		-1,
		"copy",
		"x264",
		"mencoder",
		"\"%i\" -o /dev/null -passlogfile \"%p\" -ovc x264 -x264encopts threads=auto:subq=1:frameref=1:bframes=3:bitrate=%b:pass=1 -ofps 25.0 -aspect %a -oac copy -vf crop=%c,scale=%x:%y",
		"\"%i\" -o \"%o\" -passlogfile \"%p\" -ovc x264 -x264encopts threads=auto:subq=5:8x8dct:frameref=2:bframes=3:b_pyramid=normal:weight_b:bitrate=%b:pass=2 -ofps 25.0 -aspect %a -oac copy -vf crop=%c,scale=%x:%y",
		"avi",
		0.05,
		0
	},
/* AVGPSNR= 40.61 1H38=20MN*/
	{
		AVI700+9,
		PROFILE_AVI_F,
		gettext_noop("AVI 1.5Go AC3 MPEG4 1Pass"),
		0.30,
		1,
		1500 * 1024 * 1024,
		-1,
		"copy",
		"lavc",
		"mencoder",
		"\"%i\" -o \"%o\" -ovc lavc -lavcopts threads=%u:vcodec=mpeg4:autoaspect:vhq:vbitrate=%b -ofps 25.0 -aspect %a -oac copy -aid %A -vf crop=%c,scale=%x:%y",
		"",
		"avi",
		0.05,
		1
	},
/* From: http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-x264.html AVGPSNR=41.33 1H38 => 2H00*/
	{
		AVI700+10,
		PROFILE_AVI_F,
		gettext_noop("AVI 1.5Go AC3 X264 1Pass"),
		0.20,
		1,
		1500 * 1024 * 1024,
		-1,
		"copy",
		"x264",
		"mencoder",
		"\"%i\" -o \"%o\" -ovc x264 -x264encopts threads=%u:subq=6:partitions=all:8x8dct:me=umh:frameref=5:bframes=3:b_pyramid=normal:weight_b:bitrate=%b -ofps 25.0 -aspect %a -oac copy -aid %A -vf crop=%c,scale=%x:%y",
		"",
		"avi",
		0.05,
		1
	},
	{ /* for very long movies */
		AVI700+11,
		PROFILE_AVI_F,
		gettext_noop("AVI 2.5Go AC3 MPEG4 1Pass"),
		0.30,
		1,
		2500LL * 1024LL * 1024LL,
		-1,
		"copy",
		"lavc",
		"mencoder",
		"\"%i\" -o \"%o\" -ovc lavc -lavcopts threads=%u:vcodec=mpeg4:autoaspect:vhq:vbitrate=%b -ofps 25.0 -aspect %a -oac copy -aid %A -vf crop=%c,scale=%x:%y",
		"",
		"avi",
		0.05,
		1
	},
	{ -1 }
};

/***************************************************************************//**
 *	GETPROFILES-
 * @date	2009/01/14 23:26:01
 * @author	jef-Linux
 * @brief
 *	Pas d'explication
 * @details
 *	Pas de details
 * @param[in]	Pas de detail
 * @param[out]	Pas de detail
*******************************************************************************/

Profile_t * GetProfiles()
{
	return( Profiles );
}

/***************************************************************************//**
 *	GETPROFILE-
 * @date	2009/01/14 23:34:06
 * @author	jef-Linux
 * @brief
 *	Pas d'explication
 * @details
 *	Pas de details
 * @param[in]	Pas de detail
 * @param[out]	Pas de detail
*******************************************************************************/

Profile_t * GetProfile( int profileCode )
{
	Profile_t * p = Profiles;

	while( p->profileCode != -1 ) {
		if( p->profileCode == profileCode )	return( p );
		p++;
	}
	return( NULL );
}
/***************************************************************************//**
 *	VERIFVIDEOCODEC-
 * @date	2009/01/22 21:18:25
 * @author	jef-Linux
 * @brief
 *	Pas d'explication
 * @details
 *	Pas de details
 * @param[in]	Pas de detail
 * @param[out]	Pas de detail
*******************************************************************************/

static int VerifVideoCodec( Profile_t * p )
{
	char sysCmd[1024];
	FILE * fp;
	char line[1024];
	int res = 0;

/* Assuming encTool is mencoder */
	if( !strcmp( p->encTool, "mencoder" ) )	{
		sprintf( sysCmd, "%s -ovc help | grep %s", p->encTool, p->videoCodec );
		fp = popen( sysCmd, "r" );
		if( !fp )	return( 0 );
		while( 1 ) {
			if( !fgets( line, sizeof(line), fp ) )	break;
			if( strstr( line, p->videoCodec ) ) {
				res = 1;
				break;
			}
		}
		pclose( fp );
		return( res );
	}
/* Assuming encTool is ffmpeg */
	if( !strcmp( p->encTool, "ffmpeg" ) )	{
		sprintf( sysCmd, "%s -formats 2>&1 | grep %s | grep EV", p->encTool, p->videoCodec );
		fp = popen( sysCmd, "r" );
		if( !fp )	return( 0 );
		while( 1 ) {
			if( !fgets( line, sizeof(line), fp ) )	break;
			if( strstr( line, p->videoCodec ) ) {
				res = 1;
				break;
			}
		}
		pclose( fp );
		return( res );
	}

	return( 0 );
}

/***************************************************************************//**
 *	VERIFAUDIOCODEC-
 * @date	2009/01/22 21:18:25
 * @author	jef-Linux
 * @brief
 *	Pas d'explication
 * @details
 *	Pas de details
 * @param[in]	Pas de detail
 * @param[out]	Pas de detail
*******************************************************************************/

static int VerifAudioCodec( Profile_t * p )
{
	char sysCmd[1024];
	FILE * fp;
	char line[1024];
	int res = 0;

/* Assuming encTool is mencoder */
	if( !strcmp( p->encTool, "mencoder" ) )	{
		sprintf( sysCmd, "%s -oac help | grep %s", p->encTool, p->audioCodec );
		fp = popen( sysCmd, "r" );
		if( !fp )	return( 0 );
		while( 1 ) {
			if( !fgets( line, sizeof(line), fp ) )	break;
			if( strstr( line, p->audioCodec ) ) {
				res = 1;
				break;
			}
		}
		pclose( fp );
		return( res );
	}
/* Assuming encTool is ffmpeg */
	if( !strcmp( p->encTool, "ffmpeg" ) )	{
		sprintf( sysCmd, "%s -formats 2>&1 | grep %s | grep EV", p->encTool, p->videoCodec );
		fp = popen( sysCmd, "r" );
		if( !fp )	return( 0 );
		while( 1 ) {
			if( !fgets( line, sizeof(line), fp ) )	break;
			if( strstr( line, p->videoCodec ) ) {
				res = 1;
				break;
			}
		}
		pclose( fp );
		return( res );
	}
	return( 0 );
}

/***************************************************************************//**
 *	VERIFPROFILE-
 * @date	2009/01/21 23:32:46
 * @author	jef-Linux
 * @brief
 *	Pas d'explication
 * @details
 *	Pas de details
 * @param[in]	Pas de detail
 * @param[out]	Pas de detail
*******************************************************************************/

static int VerifProfile( Profile_t * p )
{
	if( ! (p->profileFlags & PROFILE_AVI_F) )	return( 1 );
	if( !flook( "mplayer" ) )	return( 0 );
	if( !flook( p->encTool ) )	return( 0 );
	if( !VerifVideoCodec( p ) ) {
		DBG('b',fprintf(stderr,"%s: profile %s videoCodec: %s notfound !\n", __FUNCTION__, p->libel, p->videoCodec ););
		return( 0 );
	}
	if( !VerifAudioCodec( p ) ) {
		DBG('b',fprintf(stderr,"%s: profile %s audioCodec: %s notfound !\n", __FUNCTION__, p->libel, p->audioCodec ););
		return( 0 );
	}
	return( 1 );
}

/***************************************************************************//**
 *	INITPROFILES-
 * @date	2009/01/21 21:27:59
 * @author	jef-Linux
 * @brief
 *	Pas d'explication
 * @details
 *	Pas de details
 * @param[in]	Pas de detail
 * @param[out]	Pas de detail
*******************************************************************************/

void InitProfiles()
{
	Profile_t * p = Profiles;

	while( p->profileCode != -1 ) {
		if( VerifProfile( p ) )		p->profileFlags |= PROFILE_AVAIL_F;
		p->libel = gettext( p->libel );
		p++;
	}
}

