/*
 INTEL CONFIDENTIAL
 Copyright 2009 Intel Corporation All Rights Reserved.
 The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.

 No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
 */
#include <glib.h>
#include "mixvideolog.h"

#include "mixvideoformat.h"

#define MIXUNREF(obj, unref) if(obj) { unref(obj); obj = NULL; }


/* Default vmethods implementation */
static MIX_RESULT mix_videofmt_getcaps_default(MixVideoFormat *mix,
		GString *msg);
static MIX_RESULT mix_videofmt_initialize_default(MixVideoFormat *mix,
		MixVideoConfigParamsDec * config_params,
                MixFrameManager * frame_mgr,
		MixBufferPool * input_buf_pool,
		MixSurfacePool ** surface_pool,
                VADisplay vadisplay);
static MIX_RESULT
		mix_videofmt_decode_default(MixVideoFormat *mix, 
		MixBuffer * bufin[], gint bufincnt, 
                MixVideoDecodeParams * decode_params);
static MIX_RESULT mix_videofmt_flush_default(MixVideoFormat *mix);
static MIX_RESULT mix_videofmt_eos_default(MixVideoFormat *mix);
static MIX_RESULT mix_videofmt_deinitialize_default(MixVideoFormat *mix);

static GObjectClass *parent_class = NULL;

static void mix_videoformat_finalize(GObject * obj);
G_DEFINE_TYPE (MixVideoFormat, mix_videoformat, G_TYPE_OBJECT);

static void mix_videoformat_init(MixVideoFormat * self) {

	/* public member initialization */
	/* These are all public because MixVideoFormat objects are completely internal to MixVideo,
		no need for private members  */

    self->initialized = FALSE;
    self->va_initialized = FALSE;
    self->framemgr = NULL;
    self->surfacepool = NULL;
    self->inputbufpool = NULL;
    self->inputbufqueue = NULL;
    self->va_display = NULL;
    self->va_context = VA_INVALID_ID;
    self->va_config = VA_INVALID_ID;
    self->va_surfaces = NULL;
    self->va_num_surfaces = 0;
    self->mime_type = NULL;
    self->frame_rate_num = 0;
    self->frame_rate_denom = 0;
    self->picture_width = 0;
    self->picture_height = 0;
    self->parse_in_progress = FALSE;
    self->current_timestamp = (guint64)-1;
    self->end_picture_pending = FALSE;
    self->video_frame = NULL;
    self->extra_surfaces = 0;
}

static void mix_videoformat_class_init(MixVideoFormatClass * klass) {
	GObjectClass *gobject_class = (GObjectClass *) klass;

	/* parent class for later use */
	parent_class = g_type_class_peek_parent(klass);

	gobject_class->finalize = mix_videoformat_finalize;

	/* setup vmethods with base implementation */
	klass->getcaps = mix_videofmt_getcaps_default;
	klass->initialize = mix_videofmt_initialize_default;
	klass->decode = mix_videofmt_decode_default;
	klass->flush = mix_videofmt_flush_default;
	klass->eos = mix_videofmt_eos_default;
	klass->deinitialize = mix_videofmt_deinitialize_default;
}

MixVideoFormat *
mix_videoformat_new(void) {
	MixVideoFormat *ret = g_object_new(MIX_TYPE_VIDEOFORMAT, NULL);

	return ret;
}

void mix_videoformat_finalize(GObject * obj) {
	/* clean up here. */
	VAStatus va_status;

	MixVideoFormat *mix = MIX_VIDEOFORMAT(obj); 
	MixInputBufferEntry *buf_entry = NULL;

        if(mix->objectlock) {
                g_mutex_free(mix->objectlock);
                mix->objectlock = NULL;
        }

	if (mix->mime_type)
	{
		if (mix->mime_type->str)
			g_string_free(mix->mime_type, TRUE);
		else
			g_string_free(mix->mime_type, FALSE);
	}

	//MiVideo object calls the _deinitialize() for frame manager
	MIXUNREF(mix->framemgr, mix_framemanager_unref);

	if (mix->surfacepool)
	{
	  mix_surfacepool_deinitialize(mix->surfacepool);
	  MIXUNREF(mix->surfacepool, mix_surfacepool_unref);
	}

	//libVA cleanup (vaTerminate is called from MixVideo object)
	if (mix->va_display) {
		if (mix->va_context != VA_INVALID_ID)
		{
			va_status = vaDestroyContext(mix->va_display, mix->va_context);
			if (va_status != VA_STATUS_SUCCESS) {
				LOG_W( "Failed vaDestroyContext\n");
			}
			mix->va_context = VA_INVALID_ID;
		}
		if (mix->va_config != VA_INVALID_ID)
		{
			va_status = vaDestroyConfig(mix->va_display, mix->va_config);
			if (va_status != VA_STATUS_SUCCESS) {
			LOG_W( "Failed vaDestroyConfig\n");
			} 
			mix->va_config = VA_INVALID_ID;
		}
		if (mix->va_surfaces)
		{
			va_status = vaDestroySurfaces(mix->va_display, mix->va_surfaces, mix->va_num_surfaces);
			if (va_status != VA_STATUS_SUCCESS) {
				LOG_W( "Failed vaDestroySurfaces\n");
			} 
			g_free(mix->va_surfaces);
			mix->va_surfaces = NULL;
			mix->va_num_surfaces = 0;
		}
	}

    if (mix->video_frame)
    {
        mix_videoframe_unref(mix->video_frame);
        mix->video_frame = NULL;
    }

	//Deinit input buffer queue 

	while (!g_queue_is_empty(mix->inputbufqueue))
	{
		buf_entry = g_queue_pop_head(mix->inputbufqueue); 
		mix_buffer_unref(buf_entry->buf);
		g_free(buf_entry);
	}

	g_queue_free(mix->inputbufqueue);

	//MixBuffer pool is deallocated in MixVideo object
	mix->inputbufpool = NULL;

	/* Chain up parent */
	if (parent_class->finalize) {
		parent_class->finalize(obj);
	}
}

MixVideoFormat *
mix_videoformat_ref(MixVideoFormat * mix) {
	return (MixVideoFormat *) g_object_ref(G_OBJECT(mix));
}

/* Default vmethods implementation */
static MIX_RESULT mix_videofmt_getcaps_default(MixVideoFormat *mix,
		GString *msg) {
	g_print("mix_videofmt_getcaps_default\n");
	return MIX_RESULT_SUCCESS;
}

static MIX_RESULT mix_videofmt_initialize_default(MixVideoFormat *mix,
		MixVideoConfigParamsDec * config_params,
                MixFrameManager * frame_mgr,
		MixBufferPool * input_buf_pool,
		MixSurfacePool ** surface_pool,
                VADisplay va_display) {

	LOG_V(	"Begin\n");

	MIX_RESULT res = MIX_RESULT_SUCCESS;
	MixInputBufferEntry *buf_entry = NULL;

	if (!mix || !config_params || !frame_mgr || !input_buf_pool || !surface_pool || !va_display)
	{
		LOG_E( "NUll pointer passed in\n");
		return (MIX_RESULT_NULL_PTR);
	}

	// Create object lock
	// Note that g_thread_init() has already been called by mix_video_init()
	if (mix->objectlock)  //If already exists, then deallocate old one (we are being re-initialized)
	{
                g_mutex_free(mix->objectlock);
                mix->objectlock = NULL;
	}
	mix->objectlock = g_mutex_new();
	if (!mix->objectlock) {
		LOG_E( "!mix->objectlock\n");
		return (MIX_RESULT_NO_MEMORY);
	}

	g_mutex_lock(mix->objectlock);

	//Clean up any previous framemgr
	MIXUNREF(mix->framemgr, mix_framemanager_unref);
	mix->framemgr = frame_mgr;
	mix_framemanager_ref(mix->framemgr);

	mix->va_display = va_display;

	if (mix->mime_type)  //Clean up any previous mime_type
	{
		if (mix->mime_type->str)
			g_string_free(mix->mime_type, TRUE);
		else
			g_string_free(mix->mime_type, FALSE);
	}
	gchar *mime_tmp = NULL;
	res = mix_videoconfigparamsdec_get_mime_type(config_params, &mime_tmp);
	if (mime_tmp)
	{
		mix->mime_type = g_string_new(mime_tmp);
		g_free(mime_tmp);
		if (!mix->mime_type) //new failed
		{
			res = MIX_RESULT_NO_MEMORY;
			LOG_E( "Could not duplicate mime_type\n");
			goto cleanup;
		}
	}  //else there is no mime_type; leave as NULL

	res = mix_videoconfigparamsdec_get_frame_rate(config_params, &(mix->frame_rate_num), &(mix->frame_rate_denom));
	if (res != MIX_RESULT_SUCCESS)
	{
		LOG_E( "Error getting frame_rate\n");
		goto cleanup;
	}
	res = mix_videoconfigparamsdec_get_picture_res(config_params, &(mix->picture_width), &(mix->picture_height));
	if (res != MIX_RESULT_SUCCESS)
	{
		LOG_E( "Error getting picture_res\n");
		goto cleanup;
	}

	if (mix->inputbufqueue)
	{
		//Deinit previous input buffer queue 
	
		while (!g_queue_is_empty(mix->inputbufqueue))
		{
			buf_entry = g_queue_pop_head(mix->inputbufqueue); 
			mix_buffer_unref(buf_entry->buf);
			g_free(buf_entry);
		}

		g_queue_free(mix->inputbufqueue);
	}

	//MixBuffer pool is cleaned up in MixVideo object
	mix->inputbufpool = NULL;

	mix->inputbufpool = input_buf_pool;
	mix->inputbufqueue = g_queue_new();
	if (!mix->inputbufqueue)  //New failed
	{
		res = MIX_RESULT_NO_MEMORY;
		LOG_E( "Could not duplicate mime_type\n");
		goto cleanup;
	}

	// surface pool, VA context/config and parser handle are initialized by
	// derived classes

	
	cleanup:
	if (res != MIX_RESULT_SUCCESS) {

		MIXUNREF(mix->framemgr, mix_framemanager_unref);
		if (mix->mime_type)
		{
			if (mix->mime_type->str)
				g_string_free(mix->mime_type, TRUE);
			else
				g_string_free(mix->mime_type, FALSE);
			mix->mime_type = NULL;
		}

		if (mix->objectlock)
			g_mutex_unlock(mix->objectlock);
                g_mutex_free(mix->objectlock);
                mix->objectlock = NULL;
		mix->frame_rate_num = 0;
		mix->frame_rate_denom = 1;
		mix->picture_width = 0;
		mix->picture_height = 0;

	} else {
	//Normal unlock
		if (mix->objectlock)
			g_mutex_unlock(mix->objectlock);
	}

	LOG_V( "End\n");

	return res;
}

static MIX_RESULT mix_videofmt_decode_default(MixVideoFormat *mix, 
		MixBuffer * bufin[], gint bufincnt, 
                MixVideoDecodeParams * decode_params) {
	return MIX_RESULT_SUCCESS;
}

static MIX_RESULT mix_videofmt_flush_default(MixVideoFormat *mix) {
	return MIX_RESULT_SUCCESS;
}

static MIX_RESULT mix_videofmt_eos_default(MixVideoFormat *mix) {
	return MIX_RESULT_SUCCESS;
}

static MIX_RESULT mix_videofmt_deinitialize_default(MixVideoFormat *mix) {

	//All teardown is being done in _finalize()

	return MIX_RESULT_SUCCESS;
}

/* mixvideoformat class methods implementation */

MIX_RESULT mix_videofmt_getcaps(MixVideoFormat *mix, GString *msg) {
	MixVideoFormatClass *klass = MIX_VIDEOFORMAT_GET_CLASS(mix);
	g_print("mix_videofmt_getcaps\n");
	if (klass->getcaps) {
		return klass->getcaps(mix, msg);
	}
	return MIX_RESULT_NOTIMPL;
}

MIX_RESULT mix_videofmt_initialize(MixVideoFormat *mix,
		MixVideoConfigParamsDec * config_params,
                MixFrameManager * frame_mgr,
		MixBufferPool * input_buf_pool,
		MixSurfacePool ** surface_pool,
		VADisplay va_display) {
	MixVideoFormatClass *klass = MIX_VIDEOFORMAT_GET_CLASS(mix);

	if (klass->initialize) {
		return klass->initialize(mix, config_params, frame_mgr,
					input_buf_pool, surface_pool, va_display);
	}

	return MIX_RESULT_FAIL;

}

MIX_RESULT mix_videofmt_decode(MixVideoFormat *mix, MixBuffer * bufin[],
                gint bufincnt, MixVideoDecodeParams * decode_params) {

	MixVideoFormatClass *klass = MIX_VIDEOFORMAT_GET_CLASS(mix);
	if (klass->decode) {
		return klass->decode(mix, bufin, bufincnt, decode_params);
	}

	return MIX_RESULT_FAIL;
}

MIX_RESULT mix_videofmt_flush(MixVideoFormat *mix) {
	MixVideoFormatClass *klass = MIX_VIDEOFORMAT_GET_CLASS(mix);
	if (klass->flush) {
		return klass->flush(mix);
	}

	return MIX_RESULT_FAIL;
}

MIX_RESULT mix_videofmt_eos(MixVideoFormat *mix) {
	MixVideoFormatClass *klass = MIX_VIDEOFORMAT_GET_CLASS(mix);
	if (klass->eos) {
		return klass->eos(mix);
	}

	return MIX_RESULT_FAIL;
}

MIX_RESULT mix_videofmt_deinitialize(MixVideoFormat *mix) {
	MixVideoFormatClass *klass = MIX_VIDEOFORMAT_GET_CLASS(mix);
	if (klass->deinitialize) {
		return klass->deinitialize(mix);
	}

	return MIX_RESULT_FAIL;
}
