/* INTEL CONFIDENTIAL
* Copyright (c) 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 <dlfcn.h>

#include "vc1.h"
#include "h264.h"
#include "vbp_loader.h"
#include "vbp_utils.h"
#include "vbp_vc1_parser.h"
#include "vbp_h264_parser.h"
#include "vbp_mp42_parser.h"
#ifdef USE_HW_VP8
#include "vbp_vp8_parser.h"
#endif


/* buffer counter */
uint32 buffer_counter = 0;


void* vbp_try_malloc0(uint32 size) {
    void* pMem = malloc(size);
    if (pMem)
        memset(pMem, 0, size);
    return pMem;
}

/**
 *
 * uninitialize parser context
 *
 */
static uint32 vbp_utils_uninitialize_context(vbp_context *pcontext)
{
    uint32 error = VBP_OK;

    if (NULL == pcontext)
    {
        return error;
    }

    /* not need to reset parser entry points. */

    free(pcontext->parser_ops);
    pcontext->parser_ops = NULL;


    if (pcontext->fd_parser)
    {
        dlclose(pcontext->fd_parser);
        pcontext->fd_parser = NULL;
    }

    return error;
}

/**
 *
 * initialize parser context
 *
 */
static uint32 vbp_utils_initialize_context(vbp_context *pcontext)
{
    uint32 error = VBP_OK;
    char *parser_name;

    switch (pcontext->parser_type)
    {
    case VBP_VC1:
#ifndef ANDROID
        parser_name = "libmixvbp_vc1.so.0";
#else
        parser_name = "libmixvbp_vc1.so";
#endif
        break;

        /* MPEG-2 parser is not supported. */

        /*  case VBP_MPEG2:
        parser_name = "libmixvbp_mpeg2.so.0";
        break;*/

    case VBP_MPEG4:
#ifndef ANDROID
        parser_name = "libmixvbp_mpeg4.so.0";
#else
        parser_name = "libmixvbp_mpeg4.so";
#endif
        break;

    case VBP_H264:
#ifndef ANDROID
        parser_name = "libmixvbp_h264.so.0";
#else
        parser_name = "libmixvbp_h264.so";
#endif
        break;
#ifdef USE_HW_VP8
    case VBP_VP8:
#ifndef ANDROID
        parser_name = "libmixvbp_vp8.so.0";
#else
        parser_name = "libmixvbp_vp8.so";
#endif
        break;
#endif
    default:
        WTRACE("Unsupported parser type!");
        return VBP_TYPE;
    }

    pcontext->fd_parser = dlopen(parser_name, RTLD_LAZY);
    if (NULL == pcontext->fd_parser)
    {
        ETRACE("Failed to load parser %s.", parser_name);
        error =  VBP_LOAD;
        goto cleanup;
    }

    pcontext->parser_ops = vbp_malloc(viddec_parser_ops_t, 1);
    if (NULL == pcontext->parser_ops)
    {
        ETRACE("Failed to allocate memory");
        error =  VBP_MEM;
        goto cleanup;
    }

#define SET_FUNC_POINTER(X, Y)\
    case X:\
    pcontext->func_init_parser_entries = vbp_init_parser_entries_##Y;\
    pcontext->func_allocate_query_data = vbp_allocate_query_data_##Y;\
    pcontext->func_free_query_data = vbp_free_query_data_##Y;\
    pcontext->func_parse_init_data = vbp_parse_init_data_##Y;\
    pcontext->func_parse_start_code = vbp_parse_start_code_##Y;\
    pcontext->func_process_parsing_result = vbp_process_parsing_result_##Y;\
    pcontext->func_populate_query_data = vbp_populate_query_data_##Y;\
    break;

    switch (pcontext->parser_type)
    {
        SET_FUNC_POINTER(VBP_VC1, vc1);
        SET_FUNC_POINTER(VBP_MPEG4, mp42);
        SET_FUNC_POINTER(VBP_H264, h264);
#ifdef USE_HW_VP8
        SET_FUNC_POINTER(VBP_VP8, vp8);
#endif
    }

    /* set entry points for parser operations:
    	init
    	parse_sc
    	parse_syntax
    	get_cxt_size
    	is_wkld_done
    	is_frame_start
    */
    error = pcontext->func_init_parser_entries(pcontext);

cleanup:

    if (VBP_OK != error)
    {
        /* no need to log error.  the loader would have done so already. */
        vbp_utils_uninitialize_context(pcontext);
    }

    return error;
}

/**
*
* free allocated memory.
*
*/
static uint32 vbp_utils_free_parser_memory(vbp_context *pcontext)
{
    if (NULL == pcontext)
    {
        return VBP_OK;
    }

    if (pcontext->func_free_query_data)
    {
        pcontext->func_free_query_data(pcontext);
    }

    free(pcontext->workload2);
    pcontext->workload2 = NULL;

    free(pcontext->workload1);
    pcontext->workload1 = NULL;

    free(pcontext->persist_mem);
    pcontext->persist_mem = NULL;

    free(pcontext->parser_cxt);
    pcontext->parser_cxt = NULL;

    return VBP_OK;
}


/**
 *
 * allocate memory
 *
 */
static uint32 vbp_utils_allocate_parser_memory(vbp_context *pcontext)
{
    /* pcontext is guaranteed to be valid input. */
    uint32 error = VBP_OK;
    viddec_parser_memory_sizes_t sizes;

    pcontext->parser_cxt = vbp_malloc(viddec_pm_cxt_t, 1);
    if (NULL == pcontext->parser_cxt)
    {
        ETRACE("Failed to allocate memory");
        error = VBP_MEM;
        goto cleanup;
    }

    /* invoke parser entry to get context size */
    /* no return value, should always succeed. */
    pcontext->parser_ops->get_cxt_size(&sizes);

    /* allocate persistent memory for parser */
    if (sizes.persist_size)
    {
        pcontext->persist_mem = malloc(sizes.persist_size);
        if (NULL == pcontext->persist_mem)
        {
            ETRACE("Failed to allocate memory");
            error = VBP_MEM;
            goto cleanup;
        }
    }
    else
    {
        /* OK for VC-1, MPEG2 and MPEG4. */
        if ((VBP_VC1 == pcontext->parser_type) ||
            (VBP_MPEG2 == pcontext->parser_type) ||
            (VBP_MPEG4 == pcontext->parser_type)
#ifdef USE_HW_VP8
            || (VBP_VP8 == pcontext->parser_type)
#endif
)
        {
            pcontext->persist_mem = NULL;
        }
        else
        {
            /* mandatory for H.264 */
            ETRACE("Failed to allocate memory");
            error =  VBP_TYPE;
            goto cleanup;
        }
    }

    /* allocate a new workload with 1000 items. */
    pcontext->workload1 = malloc(sizeof(viddec_workload_t) +
                                       (MAX_WORKLOAD_ITEMS * sizeof(viddec_workload_item_t)));
    if (NULL == pcontext->workload1)
    {
        ETRACE("Failed to allocate memory");
        error = VBP_MEM;
        goto cleanup;
    }

    /* allocate a second workload with 1000 items. */
    pcontext->workload2 = malloc(sizeof(viddec_workload_t) +
                                       (MAX_WORKLOAD_ITEMS * sizeof(viddec_workload_item_t)));
    if (NULL == pcontext->workload2)
    {
        ETRACE("Failed to allocate memory");
        error = VBP_MEM;
        goto cleanup;
    }

    /* allocate format-specific query data */
    error = pcontext->func_allocate_query_data(pcontext);

cleanup:
    if (error != VBP_OK)
    {
        vbp_utils_free_parser_memory(pcontext);
    }
    return error;
}



/**
 *
 * parse the elementary sample buffer or codec configuration data
 *
 */
static uint32 vbp_utils_parse_es_buffer(vbp_context *pcontext, uint8 init_data_flag)
{
    viddec_pm_cxt_t *cxt = pcontext->parser_cxt;
    viddec_parser_ops_t *ops = pcontext->parser_ops;
    uint32 error = VBP_OK;
    int i;

    /* reset list number. func_parse_init_data or func_parse_start_code will
    * set it equal to number of sequence headers, picture headers or slices headers
    * found in the sample buffer
    */
    cxt->list.num_items = 0;

    /**
    * READ THIS NOTE: cxt->getbits.is_emul_reqd must be set to 1
    * for H.264 and MPEG-4, VC1 advanced profile and set to 0
    * for VC1 simple or main profile when parsing the frame
    * buffer. When parsing the sequence header, it must be set to 1
    * always.
    *
    * PARSER IMPLEMENTOR: set this flag in the parser.
    */

    /*
    if ((codec_type == VBP_H264)  || (codec_type == VBP_MPEG4))
    {
    	cxt->getbits.is_emul_reqd = 1;
    }
    */


    /* populate the list.*/
    if (init_data_flag)
    {
        error = pcontext->func_parse_init_data(pcontext);
    }
    else
    {
        error = pcontext->func_parse_start_code(pcontext);
    }

    if (VBP_OK != error)
    {
        ETRACE("Failed to parse the start code!");
        return error;
    }

    /* set up bitstream buffer */
    cxt->getbits.list = &(cxt->list);

    /* setup buffer pointer */
    cxt->getbits.bstrm_buf.buf = cxt->parse_cubby.buf;

    // TODO: check if cxt->getbits.is_emul_reqd is set properly

    for (i = 0; i < cxt->list.num_items; i++)
    {
        /* setup bitstream parser */
        cxt->getbits.bstrm_buf.buf_index = cxt->list.data[i].stpos;
        cxt->getbits.bstrm_buf.buf_st = cxt->list.data[i].stpos;
        cxt->getbits.bstrm_buf.buf_end = cxt->list.data[i].edpos;

        /* It is possible to end up with buf_offset not equal zero. */
        cxt->getbits.bstrm_buf.buf_bitoff = 0;

        cxt->getbits.au_pos = 0;
        cxt->getbits.list_off = 0;
        cxt->getbits.phase = 0;
        cxt->getbits.emulation_byte_counter = 0;

        cxt->list.start_offset = cxt->list.data[i].stpos;
        cxt->list.end_offset = cxt->list.data[i].edpos;
        cxt->list.total_bytes = cxt->list.data[i].edpos - cxt->list.data[i].stpos;

        /* invoke parse entry point to parse the buffer */
        error = ops->parse_syntax((void *)cxt, (void *)&(cxt->codec_data[0]));

        /* can't return error for now. Neet further investigation */
#if 0
        if (0 != error)
        {
            ETRACE("failed to parse the syntax: %d!", error);
            return error;
        }
#endif

        /* process parsing result */
        error = pcontext->func_process_parsing_result(pcontext, i);

        if (VBP_MULTI == error) {
            return VBP_OK;
        }
        else if (0 != error)
        {
            ETRACE("Failed to process parsing result.");
            return error;
        }
    }

    return VBP_OK;
}


/**
 *
 * create the parser context
 *
 */
uint32 vbp_utils_create_context(uint32 parser_type, vbp_context **ppcontext)
{
    uint32 error = VBP_OK;
    vbp_context *pcontext = NULL;

    /* prevention from the failure */
    *ppcontext =  NULL;

    pcontext = vbp_malloc_set0(vbp_context, 1);
    if (NULL == pcontext)
    {
        error = VBP_MEM;
        goto cleanup;
    }

    pcontext->parser_type = parser_type;

    /* load parser, initialize parser operators and entry points */
    error = vbp_utils_initialize_context(pcontext);
    if (VBP_OK != error)
    {
        goto cleanup;
    }

    /* allocate parser context, persistent memory, query data and workload */
    error = vbp_utils_allocate_parser_memory(pcontext);
    if (VBP_OK != error)
    {
        goto cleanup;
    }

    viddec_pm_utils_list_init(&(pcontext->parser_cxt->list));
    viddec_pm_utils_bstream_init(&(pcontext->parser_cxt->getbits), NULL, 0);
    pcontext->parser_cxt->cur_buf.list_index = -1;
    pcontext->parser_cxt->parse_cubby.phase = 0;

    /* invoke the entry point to initialize the parser. */
    pcontext->parser_ops->init(
        (uint32_t *)pcontext->parser_cxt->codec_data,
        (uint32_t *)pcontext->persist_mem,
        FALSE);

    viddec_emit_init(&(pcontext->parser_cxt->emitter));

    /* overwrite init with our number of items. */
    pcontext->parser_cxt->emitter.cur.max_items = MAX_WORKLOAD_ITEMS;
    pcontext->parser_cxt->emitter.next.max_items = MAX_WORKLOAD_ITEMS;

    /* set up to find the first start code. */
    pcontext->parser_cxt->sc_prefix_info.first_sc_detect = 1;

    /* indicates initialized OK. */
    pcontext->identifier = MAGIC_NUMBER;
    *ppcontext = pcontext;
    error = VBP_OK;

cleanup:

    if (VBP_OK != error)
    {
        vbp_utils_free_parser_memory(pcontext);
        vbp_utils_uninitialize_context(pcontext);
        free(pcontext);
        pcontext = NULL;
    }

    return error;
}

/**
 *
 * destroy the context.
 *
 */
uint32 vbp_utils_destroy_context(vbp_context *pcontext)
{
    /* entry point, not need to validate input parameters. */
    vbp_utils_free_parser_memory(pcontext);
    vbp_utils_uninitialize_context(pcontext);
    free(pcontext);
    pcontext = NULL;

    return VBP_OK;
}


/**
 *
 * parse the sample buffer or parser configuration data.
 *
 */
uint32 vbp_utils_parse_buffer(vbp_context *pcontext, uint8 *data, uint32 size,  uint8 init_data_flag)
{
    /* entry point, not need to validate input parameters. */

    uint32 error = VBP_OK;

    //ITRACE("buffer counter: %d",buffer_counter);

    /* set up emitter. */
    pcontext->parser_cxt->emitter.cur.data = pcontext->workload1;
    pcontext->parser_cxt->emitter.next.data = pcontext->workload2;

    /* reset bit offset */
    pcontext->parser_cxt->getbits.bstrm_buf.buf_bitoff = 0;


    /* set up cubby. */
    pcontext->parser_cxt->parse_cubby.buf = data;
    pcontext->parser_cxt->parse_cubby.size = size;
    pcontext->parser_cxt->parse_cubby.phase = 0;

    error = vbp_utils_parse_es_buffer(pcontext, init_data_flag);

    /* rolling count of buffers. */
    if (0 == init_data_flag)
    {
        buffer_counter++;
    }
    return error;
}

/**
 *
 * provide query data back to the consumer
 *
 */
uint32 vbp_utils_query(vbp_context *pcontext, void **data)
{
    /* entry point, not need to validate input parameters. */
    uint32 error = VBP_OK;

    error = pcontext->func_populate_query_data(pcontext);
    if (VBP_OK == error)
    {
        *data = pcontext->query_data;
    }
    else
    {
        *data = NULL;
    }
    return error;
}

/**
 *
 * flush parsing buffer. Currently it is no op.
 *
 */
uint32 vbp_utils_flush(vbp_context *pcontext)
{
    return VBP_OK;
}

