/*#define LOG_NDEBUG 0*/
#define LOG_TAG "IntelImageEncoder"

#include <cutils/log.h>
#include "ImageEncoder.h"

IntelImageEncoder::IntelImageEncoder(void)
{
	/* Initialize variables */
	encoder_status = LIBVA_UNINITIALIZED;
	quality = INTEL_IMAGE_ENCODER_DEFAULT_QUALITY;

	va_dpy = NULL;
	memset((void *)&va_configattrib, 0, sizeof(va_configattrib));

	images_count = 0;
	memset((void *)va_surfaceid, 0x0, sizeof(va_surfaceid));
	memset((void *)surface_width, 0x0, sizeof(surface_width));
	memset((void *)surface_height, 0x0, sizeof(surface_height));
	memset((void *)surface_fourcc, 0x0, sizeof(surface_fourcc));

	va_configid = 0;
	va_contextid = 0;
	context_width = 0;
	context_height = 0;
	context_fourcc = 0;
	va_codedbufferid = 0;
	coded_buf_size = 0;

	reserved_image_seq = -1;

	LOGV("IntelImageEncoder: done\n");
}

int IntelImageEncoder::initializeEncoder(void)
{
	int i =0;
	VAStatus va_status;
	int display_num = 0;
	int major_version = -1, minor_version = -1;
	const char *driver_version = NULL;
	VAEntrypoint va_entrypoints[5];
	int va_entrypoints_count = 0;

	if (encoder_status != LIBVA_UNINITIALIZED) {
		LOGE("initializeEncoder: already initialized!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	/* Get display */
	va_dpy = vaGetDisplay(&display_num);
	if (NULL == va_dpy) {
		LOGE("initializeEncoder: vaGetDisplay failed!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	/* Initialize */
	va_status = vaInitialize(va_dpy, &major_version, &minor_version);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("initializeEncoder: vaInitialize failed (%d)!\n", va_status);
		return va_status;
	}
	LOGV("initializeEncoder: LibVA version: %d.%d\n", major_version, minor_version);

	/* Query driver version */
	driver_version = vaQueryVendorString(va_dpy);
	if (NULL == driver_version) {
		LOGE("initializeEncoder: vaQueryVendorString failed!\n");
		vaTerminate(va_dpy);
		va_dpy = NULL;
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}
	LOGV("initializeEncoder: Driver version: %s\n", driver_version);

	/* Query JPEG baseline encoding's entrypoint */
	va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileJPEGBaseline, va_entrypoints,
										&va_entrypoints_count);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("initializeEncoder: vaQueryConfigEntrypoints failed (%d)!\n", va_status);
		vaTerminate(va_dpy);
		va_dpy = NULL;
		return va_status;
	}

	for (i=0; i < va_entrypoints_count; ++i) {
		if (VAEntrypointEncPicture == va_entrypoints[i])
			break;
	}
	if (i == va_entrypoints_count) {
		LOGE("initializeEncoder: no JPEG Baseline encoding entrypoint was found!\n");
		vaTerminate(va_dpy);
		va_dpy = NULL;
		return VA_STATUS_ERROR_UNIMPLEMENTED;
	}

	/* Get supported configuration attributes */
	va_configattrib.type = VAConfigAttribRTFormat;
	va_status = vaGetConfigAttributes(va_dpy, VAProfileJPEGBaseline, VAEntrypointEncPicture,
									&va_configattrib, 1);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("initializeEncoder: vaGetConfigAttributes failed (%d)!\n", va_status);
		vaTerminate(va_dpy);
		va_dpy = NULL;
		memset((void *)&va_configattrib, 0x0, sizeof(va_configattrib));
		return va_status;
	}

	encoder_status = LIBVA_INITIALIZED;
	LOGV("initializeEncoder: done\n");
	return VA_STATUS_SUCCESS;
}

int IntelImageEncoder::createSourceSurface(int source_type, void *source_buffer,
						unsigned int width,unsigned int height,
						unsigned int stride, unsigned int fourcc,
						int *image_seqp)
{
	int i =0;
	VAStatus va_status;
	VASurfaceAttribExternalBuffers va_surfacebuf;
	VASurfaceAttrib va_surfaceattrib[2];
	unsigned long ptr = 0;

	if (LIBVA_UNINITIALIZED == encoder_status) {
		LOGE("createSourceSurface: uninitialized, not ready to create surface!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	if (images_count > INTEL_IMAGE_ENCODER_MAX_BUFFERS) {
		LOGE("createSourceSurface: the max supported count was already reached!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	if ((source_type != SURFACE_TYPE_USER_PTR) &&
	(source_type != SURFACE_TYPE_GRALLOC)) {
		LOGE("createSourceSurface: buffer type 0x%x was not supported!\n", source_type);
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	}

	if (NULL == source_buffer) {
		LOGE("createSourceSurface: the input buffer address can't be null!\n");
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	} else if ((unsigned int)source_buffer & 0xFFF) {
		LOGE("createSourceSurface: the input buffer wasn't aligned to 4096!\n");
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	}

	if (stride % INTEL_IMAGE_ENCODER_REQUIRED_STRIDE) {
		LOGE("createSourceSurface: the stride value %d is not alligned to %d!\n",
			stride, INTEL_IMAGE_ENCODER_REQUIRED_STRIDE);
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	}

	if ((width % 2) || (height % 2)) {
		LOGE("createSourceSurface: only even dimensions were supportd!\n");
		return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
	}

	if (((fourcc != VA_RT_FORMAT_YUV420) && (fourcc != VA_RT_FORMAT_YUV422)) ||
		!(fourcc & va_configattrib.value)) {
		/* Currently supported image formats:
		 * #define VA_RT_FORMAT_YUV420	0x00000001
		 * #define VA_RT_FORMAT_YUV422	0x00000002
		 */
		LOGE("createSourceSurface: the image format %d was not supported!\n", fourcc);
		return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
	}

	/* Find the first available image sequential number */
	for (i=0; i<INTEL_IMAGE_ENCODER_MAX_BUFFERS; ++i) {
		if (0 == va_surfaceid[i]) { /* Empty */
			break;
		}
	}

	/* Allocate a source surface */
	if (VA_RT_FORMAT_YUV420 == fourcc)
		va_surfacebuf.pixel_format = VA_FOURCC_NV12;
	else if (VA_RT_FORMAT_YUV422 == fourcc)
		va_surfacebuf.pixel_format = VA_FOURCC_YV16;
	va_surfacebuf.width = width;
	va_surfacebuf.height = height;
	va_surfacebuf.data_size = stride * height * 1.5;
	va_surfacebuf.num_buffers = 1;
	va_surfacebuf.num_planes = 3;
	va_surfacebuf.pitches[0] = stride;
	va_surfacebuf.pitches[1] = stride;
	va_surfacebuf.pitches[2] = stride;
	va_surfacebuf.pitches[3] = 0;
	va_surfacebuf.offsets[0] = 0;
	va_surfacebuf.offsets[1] = stride * height;
	va_surfacebuf.offsets[2] = va_surfacebuf.offsets[1];
	va_surfacebuf.offsets[3] = 0;
	va_surfacebuf.buffers = (unsigned long *)&ptr;
	*(va_surfacebuf.buffers) = (unsigned long)source_buffer;
	va_surfacebuf.flags = 0;
	va_surfacebuf.private_data = NULL;
	va_surfaceattrib[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
	va_surfaceattrib[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
	va_surfaceattrib[0].value.type = VAGenericValueTypeInteger;
	va_surfaceattrib[0].value.value.i = source_type;
	va_surfaceattrib[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
	va_surfaceattrib[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
	va_surfaceattrib[1].value.type = VAGenericValueTypePointer;
	va_surfaceattrib[1].value.value.p = (void *)&va_surfacebuf;

	va_status = vaCreateSurfaces(va_dpy, fourcc, width, height,
					&va_surfaceid[i], 1, va_surfaceattrib, 2);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("createSourceSurface: vaCreateSurfaces failed (%d)!\n", va_status);
		va_surfaceid[i] = 0;
		return va_status;
	}

	surface_width[i] = width;
	surface_height[i] = height;
	surface_fourcc[i] = fourcc;

	*image_seqp = i;
	++images_count;

	return VA_STATUS_SUCCESS;
}

int IntelImageEncoder::createContext(int first_image_seq, unsigned int *max_coded_sizep)
{
	VAStatus va_status;
	VAConfigAttrib va_cur_configattrib;

	*max_coded_sizep = 0;

	if (LIBVA_UNINITIALIZED == encoder_status) {
		LOGE("createContext: uninitialized, not ready to create context!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	} else if (encoder_status >= LIBVA_CONTEXT_CREATED) {
		LOGE("createContext: there already is an active context!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	if ((first_image_seq < 0) ||
		(first_image_seq >= INTEL_IMAGE_ENCODER_MAX_BUFFERS) ||
		(0 == va_surfaceid[first_image_seq])) {
		LOGE("createContext: invalid image sequential number!\n");
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	}

	context_width = surface_width[first_image_seq];
	context_height = surface_height[first_image_seq];
	context_fourcc = surface_fourcc[first_image_seq];

	/* Create a config */
	va_cur_configattrib.type = VAConfigAttribRTFormat;
	va_cur_configattrib.value = context_fourcc;
	va_status = vaCreateConfig(va_dpy, VAProfileJPEGBaseline, VAEntrypointEncPicture,
								&va_cur_configattrib, 1, &va_configid);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("createContext: vaCreateConfig failed (%d)!\n", va_status);
		va_configid = 0;
		return va_status;
	}

	/* Create a context */
	va_status = vaCreateContext(va_dpy, va_configid, context_width, context_height,
					VA_PROGRESSIVE, &va_surfaceid[first_image_seq], 1, &va_contextid);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("createContext: vaCreateContext failed (%d)!\n", va_status);
		va_contextid = 0;
		vaDestroyConfig(va_dpy, va_configid);
		va_configid = 0;
		return va_status;
	}


	/* Create a coded buffer */
	coded_buf_size = (((context_width+15)/16)*((context_height+15)/16)*160) + 640;
	coded_buf_size = (coded_buf_size+0xf) & ~0xf;
	va_status = vaCreateBuffer(va_dpy, va_contextid, VAEncCodedBufferType, coded_buf_size,
					1, NULL, &va_codedbufferid);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("createContext: vaCreateBuffer VAEncCodedBufferType failed (%d)!\n", va_status);
		vaDestroyContext(va_dpy, va_contextid);
		va_contextid = 0;
		vaDestroyConfig(va_dpy, va_configid);
		va_configid = 0;
		va_codedbufferid = 0;
		return va_status;
	}

	*max_coded_sizep = coded_buf_size;

	encoder_status = LIBVA_CONTEXT_CREATED;
	LOGV("createContext: done\n");
	return VA_STATUS_SUCCESS;
}

int IntelImageEncoder::setQuality(unsigned int new_quality)
{
	if (quality == new_quality) {
		return VA_STATUS_SUCCESS;
	}

	if (LIBVA_ENCODING == encoder_status) {
		LOGE("setQuality: can't update quality while encoding!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	if ((new_quality > INTEL_IMAGE_ENCODER_MAX_QUALITY) ||
		(new_quality < INTEL_IMAGE_ENCODER_MIN_QUALITY)) {
		LOGE("setQuality: invalid new quality value, not updated!\n");
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	}

	quality = new_quality;

	LOGV("setQuality: quality was updated to %d\n", quality);
	return VA_STATUS_SUCCESS;
}

int IntelImageEncoder::encode(int image_seq, unsigned int new_quality)
{
	VAStatus va_status;
	VAEncPictureParameterBufferJPEG va_picparabuffer;
	VABufferID va_picparabufferid = 0;

	if (encoder_status < LIBVA_CONTEXT_CREATED) {
		LOGE("encode: no context created to perform encoding!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	} else if (encoder_status > LIBVA_CONTEXT_CREATED) {
		LOGE("encode: there already is an active encoding task!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	if ((image_seq < 0) ||
		(image_seq >= INTEL_IMAGE_ENCODER_MAX_BUFFERS) ||
		(0 == va_surfaceid[image_seq])) {
		LOGE("encode: invalid image sequential number!\n");
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	} else if ((context_width != surface_width[image_seq]) ||
				(context_height != surface_height[image_seq]) ||
				(context_fourcc != surface_fourcc[image_seq])) {
		LOGE("encode: the input image didn't fit in the current context!\n");
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	}

	/* Update quality */
	if (setQuality(new_quality) != VA_STATUS_SUCCESS) {
		LOGE("encode: the input quality value was invalid, encoding aborted!\n");
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	}

	/* Begin picture */
	va_status = vaBeginPicture(va_dpy, va_contextid, va_surfaceid[image_seq]);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("encode: vaBeginPicture failed (%d)!\n", va_status);
		return va_status;
	}

	/* Create a picture-parameter buffer */
	va_picparabuffer.picture_width  = context_width;
	va_picparabuffer.picture_height = context_height;
	va_picparabuffer.reconstructed_picture= 0;
	va_picparabuffer.coded_buf = va_codedbufferid;
	va_picparabuffer.pic_flags.bits.profile = 0; /* Baseline */
	va_picparabuffer.pic_flags.bits.progressive = 0; /* Sequential */
	va_picparabuffer.pic_flags.bits.huffman = 1; /* Huffman */
	va_picparabuffer.pic_flags.bits.interleaved = 0; /* Non-interleaved */
	va_picparabuffer.pic_flags.bits.differential = 0; /* Non-differential */
	va_picparabuffer.sample_bit_depth = 8; /* 8-bits */
	va_picparabuffer.num_components = 3; /* 3-components */
	va_picparabuffer.quality = quality; /* JPEG ENC quality */
	va_status = vaCreateBuffer(va_dpy, va_contextid, VAEncPictureParameterBufferType,
					sizeof(va_picparabuffer), 1, &va_picparabuffer,&va_picparabufferid);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("encode: vaCreateBuffer VAEncPictureParameterBufferType failed (%d)!\n", va_status);
		return va_status;
	}

	/* Render picture */
	va_status = vaRenderPicture(va_dpy, va_contextid, &va_picparabufferid, 1);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("encode: vaRenderPicture failed (%d)!\n", va_status);
		vaDestroyBuffer(va_dpy, va_picparabufferid);
		return va_status;
	}

	/* Destroy the used picture-parameter buffer */
	vaDestroyBuffer(va_dpy, va_picparabufferid);

	/* End picture */
	va_status = vaEndPicture(va_dpy, va_contextid);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("encode: vaEndPicture failed (%d)!\n", va_status);
		vaDestroyBuffer(va_dpy, va_picparabufferid);
		return va_status;
	}

	reserved_image_seq = image_seq;
	encoder_status = LIBVA_ENCODING;
	LOGV("encode: done\n");
	return VA_STATUS_SUCCESS;
}

int IntelImageEncoder::getCoded(void *user_coded_buf,
					unsigned int user_coded_buf_size,
					unsigned int *coded_data_sizep)
{
	VAStatus va_status;
	VACodedBufferSegment *va_codedbuffersegment = NULL;

	if ((NULL == user_coded_buf) ||
		(NULL == coded_data_sizep)) {
		LOGE("getCoded: invalid NULL pointer as input paramter!\n");
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	}

	if (user_coded_buf_size < coded_buf_size) {
		LOGE("getCoded: the coded buffer was too small!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	if (encoder_status != LIBVA_ENCODING) {
		LOGE("getCoded: no encoding active to get coded data!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	if (0 == va_surfaceid[reserved_image_seq]) {
		LOGE("getCoded: invalid image, probably already destroyed!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	/* Sync surface */
	va_status = vaSyncSurface(va_dpy, va_surfaceid[reserved_image_seq]);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("getCoded: vaSyncSurface failed (%d)!\n", va_status);
		reserved_image_seq = -1;
		encoder_status = LIBVA_CONTEXT_CREATED;
		return va_status;
	}

	/* Map the coded buffer */
	va_status = vaMapBuffer(va_dpy, va_codedbufferid, (void **)&va_codedbuffersegment);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("getCoded: vaMapBuffer failed (%d)!\n", va_status);
		reserved_image_seq = -1;
		encoder_status = LIBVA_CONTEXT_CREATED;
		return va_status;
	}

	/* Mark the coded buffer empty */
	*coded_data_sizep = 0;

	/* Get the total size of coded data */
	while (va_codedbuffersegment != NULL) {
		memcpy((void *)((unsigned int)user_coded_buf+*coded_data_sizep),
				va_codedbuffersegment->buf,
				va_codedbuffersegment->size);
		*coded_data_sizep += va_codedbuffersegment->size;
		va_codedbuffersegment = (VACodedBufferSegment *)va_codedbuffersegment->next;
	}

	va_status = vaUnmapBuffer(va_dpy, va_codedbufferid);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("getCoded: vaUnmapBuffer failed (%d)!\n", va_status);
	}

	reserved_image_seq = -1;
	encoder_status = LIBVA_CONTEXT_CREATED;

	LOGV("getCoded: done\n");
	return va_status;
}

int IntelImageEncoder::destroySourceSurface(int image_seq)
{
	VAStatus va_status;

	if ((image_seq < 0) || ((unsigned int)image_seq >= images_count) ||
		(0 == va_surfaceid[image_seq])) {
		LOGE("destroySourceSurface: invalid image sequential number!\n");
		return VA_STATUS_ERROR_INVALID_PARAMETER;
	} else if (image_seq == reserved_image_seq) {
		LOGE("destroySourceSurface: Image %d was under encoding and can't be destroyed!\n",
			image_seq);
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	if (LIBVA_UNINITIALIZED == encoder_status) {
		LOGE("destroySourceSurface: uninitialized, not ready to destroy surface!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	/* Destroy a source surface */
	va_status = vaDestroySurfaces(va_dpy, &va_surfaceid[image_seq], 1);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("destroySourceSurface: vaDestroySurfaces failed (%d)!\n", va_status);
	}

	va_surfaceid[image_seq] = 0;
	surface_width[image_seq] = 0;
	surface_height[image_seq] = 0;
	surface_fourcc[image_seq] = 0;

	--images_count;

	return va_status;
}

int IntelImageEncoder::destroyContext(void)
{
	VAStatus va_status, va_final_status;

	if (0 == va_contextid) {
		LOGE("destroyContext: no context to destroy!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	if (LIBVA_ENCODING == encoder_status) {
		LOGE("destroyContext: encoding was ongoing, can't destroy context!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	/* Destroy the coded buffer */
	va_status = vaDestroyBuffer(va_dpy, va_codedbufferid);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("createContext: vaDestroyBuffer VAEncCodedBufferType failed (%d)!\n", va_status);
	}
	va_final_status = va_status;
	va_codedbufferid = 0;
	coded_buf_size = 0;

	/* Destroy context */
	va_status = vaDestroyContext(va_dpy, va_contextid);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("destroyContext: vaDestroyContext failed (%d)!\n", va_status);
	}
	va_final_status |= va_status;
	va_contextid = 0;
	context_width = 0;
	context_height = 0;
	context_fourcc = 0;

	/* Destroy config */
	va_status = vaDestroyConfig(va_dpy, va_configid);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("destroyContext: vaDestroyConfig failed (%d)!\n", va_status);
	}
	va_final_status |= va_status;
	va_configid = 0;

	encoder_status = LIBVA_INITIALIZED;

	LOGV("destroyContext: done\n");
	return va_final_status;
}

int IntelImageEncoder::deinitializeEncoder(void)
{
	int i;
	VAStatus va_status;

	if (NULL == va_dpy) {
		LOGE("deinitializeEncoder: no LibVA display to deinitialized!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	}

	if (LIBVA_ENCODING == encoder_status) {
		LOGE("deinitializeEncoder: encoding was ongoing, can't deinitialize LibVA!\n");
		return VA_STATUS_ERROR_OPERATION_FAILED;
	} else if (LIBVA_CONTEXT_CREATED == encoder_status) {
		/* Destroy context if it exists */
		destroyContext();
	}

	if (images_count > 0) {
		for (i=0; i<INTEL_IMAGE_ENCODER_MAX_BUFFERS; ++i) {
			if (va_surfaceid[i]) {
				/* Destroy any surface if it exists */
				destroySourceSurface(i);
			}
		}
	}

	va_status = vaTerminate(va_dpy);
	if (va_status != VA_STATUS_SUCCESS) {
		LOGE("deinitializeEncoder: vaTerminate failed (%d)!\n", va_status);
	}

	memset((void *)&va_configattrib, 0, sizeof(va_configattrib));
	va_dpy = NULL;
	encoder_status = LIBVA_UNINITIALIZED;

	LOGV("deinitializeEncoder: done\n");
	return va_status;
}
