#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include "sample.h"

char *g_inputfilename=NULL;
char *g_outputfilename = NULL;
int g_codecid = 0;
int g_width = 3840;
int g_height = 2160;
int g_samplemode = 0;
int g_pixfmt = 1;

void print_usage(const char *prog)
{
	printf("Usage: %s \n", prog);
	puts("  -m --samplemode sample mode\n"
		"  -i --inputfile input file name\n"
		"  -o --outputfile output file name\n"
		"  -c --codecid codec id\n"
		"  -w --width width\n"
		"  -h --height height\n"
		"  -p --pixfmt pix fmt\n"
		);
	exit(1);
}

void parse_opts(int argc, char *argv[])
{
	int cmd_ret;
	static const char short_options[] =
			"i:o:c:w:h:m:p:y";
	static const struct option long_options[] = {
		{ "inputfile", 1, 0, 'i' },
		{ "outputfile", 1, 0, 'o' },
		{ "codecid", 1, 0, 'c' },
		{ "width", 1, 0, 'w' },
		{ "height", 1, 0, 'h' },
		{ "samplemode", 1, 0, 'm' },
		{ "pixfmt", 1, 0, 'p' },
		{ NULL, 0, 0, 0 },
	};

	while (1) {
		cmd_ret = getopt_long(argc, argv, short_options, long_options, NULL);
		if (cmd_ret == -1)
			break;

		switch (cmd_ret) {
			case 'i':
				g_inputfilename = optarg;
				printf("g_inputfilename = %s\n", g_inputfilename);
				break;
			case 'o':
				g_outputfilename = optarg;
				printf("g_outputfilename = %s\n", g_outputfilename);
				break;
			case 'c':
				g_codecid = atoi(optarg);
				printf("g_codecid = %d\n", g_codecid);
				break;
			case 'w':
				g_width = atoi(optarg);
				printf("g_width = %d\n", g_width);
				break;
			case 'h':
				g_height = atoi(optarg);
				printf("g_height = %d\n", g_height);
				break;
			case 'm':
				g_samplemode = atoi(optarg);
				printf("g_samplemode = %d\n", g_samplemode);
				break;
			case 'p':
				printf("g_pixfmt = %s\n", optarg);
				g_pixfmt = atoi(optarg);
				printf("g_pixfmt = %d\n", g_pixfmt);
				break;
			default:
				print_usage(argv[0]);
				break;
		}
	}
}

int sample_enc()
{
	mc_video_codec_enc_params_t *params;
	media_codec_context_t *context;
	MediaCodecTestContext ctx;

	context = (media_codec_context_t *)malloc(sizeof(media_codec_context_t ));
	if (context == NULL) {
		printf("malloc media_codec_context_t failed\n");
		return -1;
	}

	memset(context, 0x00, sizeof(media_codec_context_t));
	context->codec_id = g_codecid;
	context->encoder = TRUE;
	params = &context->video_enc_params;
	params->width = g_width;
	params->height = g_height;
	params->pix_fmt = g_pixfmt;
	params->frame_buf_count = 5;
	params->external_frame_buf = FALSE;
	params->bitstream_buf_count = 5;
	if (context->codec_id == MEDIA_CODEC_ID_H264) {
		params->rc_params.mode = MC_AV_RC_MODE_H264CBR;
	} else if (context->codec_id == MEDIA_CODEC_ID_H265) {
		params->rc_params.mode = MC_AV_RC_MODE_H265CBR;
	}
	get_rc_params(context, &params->rc_params);

	params->gop_params.decoding_refresh_type = 2;
	params->gop_params.gop_preset_idx = 2;
	params->rot_degree = MC_CCW_0;
	params->mir_direction = MC_DIRECTION_NONE;
	params->frame_cropping_flag = FALSE;

	memset(&ctx, 0x00, sizeof(ctx));
	ctx.context = context;
	ctx.inputFileName = g_inputfilename;
	ctx.outputFileName = g_outputfilename;

	do_sync_encoding(&ctx);
	free(context);

	return 0;
}

int sample_dec()
{
	mc_video_codec_dec_params_t *params;
	media_codec_context_t *context;
	MediaCodecTestContext ctx;

	context = (media_codec_context_t *)malloc(sizeof(media_codec_context_t ));
	memset(context, 0x00, sizeof(media_codec_context_t));
	context->codec_id = g_codecid;
	context->encoder = FALSE;
	params = &context->video_dec_params;
	params->feed_mode = MC_FEEDING_MODE_FRAME_SIZE;
	params->pix_fmt = g_pixfmt;
	params->bitstream_buf_size = (g_width * g_height *3/2 + 0x3ff)&~0x3ff;;
	params->bitstream_buf_count = 6;
	params->frame_buf_count = 6;
	if (context->codec_id == MEDIA_CODEC_ID_H264) {
		params->h264_dec_config.bandwidth_Opt = TRUE;
		params->h264_dec_config.reorder_enable = TRUE;
		params->h264_dec_config.skip_mode = 0;
	} else if (context->codec_id == MEDIA_CODEC_ID_H265) {
		params->h265_dec_config.bandwidth_Opt = TRUE;
		params->h265_dec_config.reorder_enable = TRUE;
		params->h265_dec_config.skip_mode = 0;
		params->h265_dec_config.cra_as_bla = FALSE;
		params->h265_dec_config.dec_temporal_id_mode = 0;
		params->h265_dec_config.target_dec_temporal_id_plus1 = 0;
	} else if (context->codec_id == MEDIA_CODEC_ID_MJPEG) {
		params->mjpeg_dec_config.rot_degree = MC_CCW_0;
		params->mjpeg_dec_config.mir_direction = MC_DIRECTION_NONE;
		params->mjpeg_dec_config.frame_crop_enable = FALSE;
	} else {
		params->jpeg_dec_config.rot_degree = MC_CCW_0;
		params->jpeg_dec_config.mir_direction = MC_DIRECTION_NONE;
		params->jpeg_dec_config.frame_crop_enable = FALSE;
	}

	memset(&ctx, 0x00, sizeof(ctx));
	ctx.context = context;
	ctx.inputFileName = g_inputfilename;
	ctx.outputFileName = g_outputfilename;
	do_sync_decoding(&ctx);
	free(context);

	return 0;
}

int main(int argc, char *argv[])
{
	if (argc < 2) {
		print_usage(argv[0]);
		exit(1);
	}

	parse_opts(argc, argv);

	if (g_samplemode == 0) {
		sample_enc();
	} else if (g_samplemode == 1) {
		sample_dec();
	}

	return 0;
}
