/*
 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;
    self->config_params = NULL;
}

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);
	}

    if (mix->config_params)
	{
	    mix_videoconfigparams_unref(mix->config_params);
	    mix->config_params = NULL;
	}	

	//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);

	if (mix->config_params)
	{
	    mix_videoconfigparams_unref(mix->config_params);
	}
	mix->config_params = config_params;
	mix_videoconfigparams_ref(mix->config_params);

	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;
}
