/* INTEL CONFIDENTIAL
* Copyright (c) 2009, 2012 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
#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
#include "vbp_h264secure_parser.h"
#endif

#ifdef USE_MULTI_THREADING
#include "vbp_thread.h"
#endif

#define LEAST_SLICES_MULTI_THREADING 10

typedef long long int nsecs_t;

static nsecs_t systemTime()
{
    struct timeval t;
    gettimeofday(&t, NULL);
    return 1000000 * t.tv_sec + t.tv_usec;
}


/* 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

#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
    case VBP_H264SECURE:
        parser_name = "libmixvbp_h264secure.so";
        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
#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
        SET_FUNC_POINTER(VBP_H264SECURE, h264secure);
#endif
    }
#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
    if (pcontext->parser_type == VBP_H264SECURE) {
        pcontext->func_update_data = vbp_update_data_h264secure;
    }
#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->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 format-specific query data */
    error = pcontext->func_allocate_query_data(pcontext);

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


static void vbp_setup_parser_for_item(viddec_pm_cxt_t *cxt, uint32 item)
{
    /* setup bitstream parser */
    cxt->getbits.bstrm_buf.buf_index = cxt->list.data[item].stpos;
    cxt->getbits.bstrm_buf.buf_st = cxt->list.data[item].stpos;
    cxt->getbits.bstrm_buf.buf_end = cxt->list.data[item].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[item].stpos;
    cxt->list.end_offset = cxt->list.data[item].edpos;
    cxt->list.total_bytes = cxt->list.data[item].edpos - cxt->list.data[item].stpos;

}


/**
 *
 * parse the elementary sample buffer or codec configuration data
 *
 */
//static uint32 frame_num = 0;
//static nsecs_t total_time_of_multislice = 0;
//static uint32 frame_multislice_num = 0;
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;
    }
    */

    uint32_t multi_parse_done = 0;

    /* 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

    //frame_num ++;

    nsecs_t t0, t1, t2, tt0, tt1, tt2;
    t0 = t1 = t2 = tt0 = tt1 = tt2 = 0;
    //t0 = systemTime();

    if (0 == pcontext->is_multithread_parsing_enabled) {
        for (i = 0; i < cxt->list.num_items; i++) {
            vbp_setup_parser_for_item(cxt, i);
            /* invoke parse entry point to parse the buffer */
            //t1 = systemTime();
            error = ops->parse_syntax((void *)cxt, (void *)&(cxt->codec_data[0]));
            //t2 = systemTime();
            //tt1 += t2 - t1;

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

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

            if (VBP_MULTI == error) {
                ITRACE("Multiple frames are found in one bufffer.");
                return VBP_OK;
            }
            else if (0 != error) {
                ETRACE("Failed to process parsing result.");
                return error;
            }
        }
    }
    // Multi-threading option is enabled
    else if (1 == pcontext->is_multithread_parsing_enabled) {

        int got_output = 0;
        int is_payload_start = 0;
        int single_parse_count = 0;
        int use_thread_parsing = 0;

        for (i = 0; i < cxt->list.num_items; i++) {

            vbp_setup_parser_for_item(cxt, i);

            // we assume no configuration data following slice data in a frame's buffer
            is_payload_start = ops->is_payload_start((void *)cxt);

            if (is_payload_start == 0) {
                //t1 = systemTime();
                error = ops->parse_syntax((void *)cxt, (void *)&(cxt->codec_data[0]));
                //tt1 += systemTime() - t1;

                //t2 = systemTime();
                error = pcontext->func_process_parsing_result(pcontext, i);
                single_parse_count ++;
                //tt2 += systemTime() - t2;
            } else if (((cxt->list.num_items - single_parse_count) < LEAST_SLICES_MULTI_THREADING)) {
                //t1 = systemTime();
                error = ops->parse_syntax((void *)cxt, (void *)&(cxt->codec_data[0]));
                //tt1 += systemTime() - t1;

                //t2 = systemTime();
                error = pcontext->func_process_parsing_result(pcontext, i);
                //tt2 += systemTime() - t2;
            } else {
                use_thread_parsing = 1;
                break;
            }

            if (VBP_MULTI == error) {
                ITRACE("Multiple frames are found in one bufffer.");
                return VBP_OK;
            }
            else if (0 != error) {
                ETRACE("Failed to process parsing result.");
                return error;
            }
        }

        if (use_thread_parsing) {
            vbp_thread_set_active(pcontext, cxt->list.num_items - single_parse_count);
            uint32_t thread_count = vbp_thread_get_active(pcontext);

            //t1 = systemTime();
            if (pcontext->threading_parse_scheme == SCHEME_BUNDLE) {
            // Multithread parsing Scheme-Bundle-Input
            // This interface push threads to parse all slice header without interrupt.
                vbp_thread_parse_syntax_bundle((void *)cxt,
                                               (void *)&(cxt->codec_data[0]),
                                               pcontext,
                                               i); //first slice's item num

                uint32_t j;
                for (j = i; j < cxt->list.num_items; j++) {
                    error = ops->post_parse_threading((void *)cxt,
                                                      (void *)&(cxt->codec_data[0]),
                                                      j-single_parse_count); // slice index
                    error = pcontext->func_process_parsing_result(pcontext, j); // item num
                }
                //tt1 += systemTime() - t1;

            } else if (pcontext->threading_parse_scheme == SCHEME_SEQUENTIAL) {
            // Multithread parsing Scheme-Sequential-Input.
            // This interface push threads to parse one slice header one time.
                uint32_t j;
                for (j = i; j < cxt->list.num_items; j++) {
                    vbp_setup_parser_for_item(cxt, j);

                    //t1 = systemTime();
                    got_output = vbp_thread_parse_syntax((void *)cxt,
                                                         (void *)&(cxt->codec_data[0]),
                                                         pcontext);
                    //tt1 += systemTime() - t1;

                    if (got_output == 1) {
                        //t2 = systemTime();
                        error = ops->post_parse_threading((void *)cxt,
                                                          (void *)&(cxt->codec_data[0]),
                                                          //slice count with thread delay
                                                          (j-(thread_count-1)-single_parse_count) % thread_count);

                        error = pcontext->func_process_parsing_result(pcontext,
                                                                      // item count with thread delay
                                                                      j-(thread_count-1));

                        multi_parse_done ++;
                        //tt2 += systemTime() - t2;
                    }
                }

                int need_to_clearance = thread_count -1;
                cxt->getbits.bstrm_buf.buf = NULL;
                for (i = cxt->list.num_items - need_to_clearance; i < cxt->list.num_items; i++) {
                    //t1 = systemTime();
                    got_output = vbp_thread_parse_syntax((void *)cxt,
                                                         (void *)&(cxt->codec_data[0]),
                                                         pcontext);
                                                         //&got_output);
                    //tt1 += systemTime() - t1;

                    if (got_output == 1) {
                        //t2 = systemTime();
                        error = ops->post_parse_threading((void *)cxt,
                                                          (void *)&(cxt->codec_data[0]),
                                                          (i-single_parse_count) % thread_count);

                        error = pcontext->func_process_parsing_result(pcontext, i);
                        multi_parse_done ++;
                        //tt2 += systemTime() - t2;
                    }
                }
            }
        }
    }
#if 0
    tt0 = systemTime() - t0;
    if (cxt->list.num_items > 8) {
        total_time_of_multislice += tt0;
        frame_multislice_num ++;
        ETRACE("### ================== TIME CALCULATION =======================");
        ETRACE("### ------------item num: %d", cxt->list.num_items);
        ETRACE("### ------------The frame[%d] cost time: %lld us", frame_num-1, tt0);
        ETRACE("### ------------Accumulated multi-slice frames: %d", frame_multislice_num);
        ETRACE("### ------------Accumulated average time that multislice frame cost: %lld us", total_time_of_multislice/frame_multislice_num);
        ETRACE("### ================== TIME CALCULATION END ===================");
    }
#endif
    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_bstream_init(&(pcontext->parser_cxt->getbits), NULL, 0);
    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);

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


    /* default is not enabled */
    pcontext->is_multithread_parsing_enabled = 0;

#if (!defined USE_AVC_SHORT_FORMAT && !defined USE_SLICE_HEADER_PARSING)
#ifdef USE_MULTI_THREADING
    if (pcontext->parser_ops->query_thread_parsing_cap != NULL) {
        if (pcontext->parser_ops->query_thread_parsing_cap() == 1) {
            pcontext->is_multithread_parsing_enabled = 1;
            ITRACE("Multi-thead parsing is enabled.");
            vbp_thread_init(pcontext);
        }
    }
#endif
#endif
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)
{
#ifdef USE_MULTI_THREADING
    if (1 == pcontext->is_multithread_parsing_enabled) {
        vbp_thread_free(pcontext);
    }
#endif

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

    /* 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 always succeed.
 *
 */
uint32 vbp_utils_flush(vbp_context *pcontext)
{
    viddec_pm_cxt_t *cxt = pcontext->parser_cxt;
    viddec_parser_ops_t *ops = pcontext->parser_ops;
    if (ops->flush != NULL) {
        ops->flush((void *)cxt, (void *)&(cxt->codec_data[0]));
    }
    return VBP_OK;
}

#if (defined USE_AVC_SHORT_FORMAT || defined USE_SLICE_HEADER_PARSING)
/**
 *
 * provide query data back to the consumer
 *
 */
uint32 vbp_utils_update(vbp_context *pcontext, void *newdata, uint32 size, void **data)
{
    /* entry point, not need to validate input parameters. */
    uint32 error = VBP_OK;

    error = pcontext->func_update_data(pcontext,newdata,size);

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