/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "onyx_int.h"
#include "vp8/common/threading.h"
#include "vp8/common/common.h"
#include "vp8/common/extend.h"
#include "bitstream.h"
#include "encodeframe.h"

#if CONFIG_MULTITHREAD

extern int vp8cx_encode_inter_macroblock(VP8_COMP *cpi, MACROBLOCK *x,
                                         TOKENEXTRA **t,
                                         int recon_yoffset, int recon_uvoffset,
                                         int mb_row, int mb_col);
extern int vp8cx_encode_intra_macroblock(VP8_COMP *cpi, MACROBLOCK *x,
                                         TOKENEXTRA **t);
extern void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x, int ok_to_skip);

extern void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm);

static THREAD_FUNCTION thread_loopfilter(void *p_data)
{
    VP8_COMP *cpi = (VP8_COMP *)(((LPFTHREAD_DATA *)p_data)->ptr1);
    VP8_COMMON *cm = &cpi->common;

    while (1)
    {
        if (cpi->b_multi_threaded == 0)
            break;

        if (sem_wait(&cpi->h_event_start_lpf) == 0)
        {
            if (cpi->b_multi_threaded == 0) /* we're shutting down */
                break;

            vp8_loopfilter_frame(cpi, cm);

            sem_post(&cpi->h_event_end_lpf);
        }
    }

    return 0;
}

static
THREAD_FUNCTION thread_encoding_proc(void *p_data)
{
    int ithread = ((ENCODETHREAD_DATA *)p_data)->ithread;
    VP8_COMP *cpi = (VP8_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr1);
    MB_ROW_COMP *mbri = (MB_ROW_COMP *)(((ENCODETHREAD_DATA *)p_data)->ptr2);
    ENTROPY_CONTEXT_PLANES mb_row_left_context;

    while (1)
    {
        if (cpi->b_multi_threaded == 0)
            break;

        if (sem_wait(&cpi->h_event_start_encoding[ithread]) == 0)
        {
            const int nsync = cpi->mt_sync_range;
            VP8_COMMON *cm = &cpi->common;
            int mb_row;
            MACROBLOCK *x = &mbri->mb;
            MACROBLOCKD *xd = &x->e_mbd;
            TOKENEXTRA *tp ;
#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
            TOKENEXTRA *tp_start = cpi->tok + (1 + ithread) * (16 * 24);
            const int num_part = (1 << cm->multi_token_partition);
#endif

            int *segment_counts = mbri->segment_counts;
            int *totalrate = &mbri->totalrate;

            if (cpi->b_multi_threaded == 0) /* we're shutting down */
                break;

            for (mb_row = ithread + 1; mb_row < cm->mb_rows; mb_row += (cpi->encoding_thread_count + 1))
            {

                int recon_yoffset, recon_uvoffset;
                int mb_col;
                int ref_fb_idx = cm->lst_fb_idx;
                int dst_fb_idx = cm->new_fb_idx;
                int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
                int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
                int map_index = (mb_row * cm->mb_cols);
                volatile const int *last_row_current_mb_col;
                volatile int *current_mb_col = &cpi->mt_current_mb_col[mb_row];

#if  (CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING)
                vp8_writer *w = &cpi->bc[1 + (mb_row % num_part)];
#else
                tp = cpi->tok + (mb_row * (cm->mb_cols * 16 * 24));
                cpi->tplist[mb_row].start = tp;
#endif

                last_row_current_mb_col = &cpi->mt_current_mb_col[mb_row - 1];

                /* reset above block coeffs */
                xd->above_context = cm->above_context;
                xd->left_context = &mb_row_left_context;

                vp8_zero(mb_row_left_context);

                xd->up_available = (mb_row != 0);
                recon_yoffset = (mb_row * recon_y_stride * 16);
                recon_uvoffset = (mb_row * recon_uv_stride * 8);

                /* Set the mb activity pointer to the start of the row. */
                x->mb_activity_ptr = &cpi->mb_activity_map[map_index];

                /* for each macroblock col in image */
                for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
                {
                    *current_mb_col = mb_col - 1;

                    if ((mb_col & (nsync - 1)) == 0)
                    {
                        while (mb_col > (*last_row_current_mb_col - nsync))
                        {
                            x86_pause_hint();
                            thread_sleep(0);
                        }
                    }

#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
                    tp = tp_start;
#endif

                    /* Distance of Mb to the various image edges.
                     * These specified to 8th pel as they are always compared
                     * to values that are in 1/8th pel units
                     */
                    xd->mb_to_left_edge = -((mb_col * 16) << 3);
                    xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
                    xd->mb_to_top_edge = -((mb_row * 16) << 3);
                    xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;

                    /* Set up limit values for motion vectors used to prevent
                     * them extending outside the UMV borders
                     */
                    x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
                    x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);
                    x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
                    x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16);

                    xd->dst.y_buffer = cm->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
                    xd->dst.u_buffer = cm->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
                    xd->dst.v_buffer = cm->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
                    xd->left_available = (mb_col != 0);

                    x->rddiv = cpi->RDDIV;
                    x->rdmult = cpi->RDMULT;

                    /* Copy current mb to a buffer */
                    vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);

                    if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
                        vp8_activity_masking(cpi, x);

                    /* Is segmentation enabled */
                    /* MB level adjustment to quantizer */
                    if (xd->segmentation_enabled)
                    {
                        /* Code to set segment id in xd->mbmi.segment_id for
                         * current MB (with range checking)
                         */
                        if (cpi->segmentation_map[map_index + mb_col] <= 3)
                            xd->mode_info_context->mbmi.segment_id = cpi->segmentation_map[map_index + mb_col];
                        else
                            xd->mode_info_context->mbmi.segment_id = 0;

                        vp8cx_mb_init_quantizer(cpi, x, 1);
                    }
                    else
                        /* Set to Segment 0 by default */
                        xd->mode_info_context->mbmi.segment_id = 0;

                    x->active_ptr = cpi->active_map + map_index + mb_col;

                    if (cm->frame_type == KEY_FRAME)
                    {
                        *totalrate += vp8cx_encode_intra_macroblock(cpi, x, &tp);
#ifdef MODE_STATS
                        y_modes[xd->mbmi.mode] ++;
#endif
                    }
                    else
                    {
                        *totalrate += vp8cx_encode_inter_macroblock(cpi, x, &tp, recon_yoffset, recon_uvoffset, mb_row, mb_col);

#ifdef MODE_STATS
                        inter_y_modes[xd->mbmi.mode] ++;

                        if (xd->mbmi.mode == SPLITMV)
                        {
                            int b;

                            for (b = 0; b < xd->mbmi.partition_count; b++)
                            {
                                inter_b_modes[x->partition->bmi[b].mode] ++;
                            }
                        }

#endif

                        /* Special case code for cyclic refresh
                         * If cyclic update enabled then copy
                         * xd->mbmi.segment_id; (which may have been updated
                         * based on mode during
                         * vp8cx_encode_inter_macroblock()) back into the
                         * global segmentation map
                         */
                        if (cpi->cyclic_refresh_mode_enabled && xd->segmentation_enabled)
                        {
                            const MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
                            cpi->segmentation_map[map_index + mb_col] = mbmi->segment_id;

                            /* If the block has been refreshed mark it as clean
                             * (the magnitude of the -ve influences how long it
                             * will be before we consider another refresh):
                             * Else if it was coded (last frame 0,0) and has
                             * not already been refreshed then mark it as a
                             * candidate for cleanup next time (marked 0) else
                             * mark it as dirty (1).
                             */
                            if (mbmi->segment_id)
                                cpi->cyclic_refresh_map[map_index + mb_col] = -1;
                            else if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame == LAST_FRAME))
                            {
                                if (cpi->cyclic_refresh_map[map_index + mb_col] == 1)
                                    cpi->cyclic_refresh_map[map_index + mb_col] = 0;
                            }
                            else
                                cpi->cyclic_refresh_map[map_index + mb_col] = 1;

                        }
                    }

#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
                    /* pack tokens for this MB */
                    {
                        int tok_count = tp - tp_start;
                        pack_tokens(w, tp_start, tok_count);
                    }
#else
                    cpi->tplist[mb_row].stop = tp;
#endif
                    /* Increment pointer into gf usage flags structure. */
                    x->gf_active_ptr++;

                    /* Increment the activity mask pointers. */
                    x->mb_activity_ptr++;

                    /* adjust to the next column of macroblocks */
                    x->src.y_buffer += 16;
                    x->src.u_buffer += 8;
                    x->src.v_buffer += 8;

                    recon_yoffset += 16;
                    recon_uvoffset += 8;

                    /* Keep track of segment usage */
                    segment_counts[xd->mode_info_context->mbmi.segment_id]++;

                    /* skip to next mb */
                    xd->mode_info_context++;
                    x->partition_info++;
                    xd->above_context++;
                }

                vp8_extend_mb_row( &cm->yv12_fb[dst_fb_idx],
                                    xd->dst.y_buffer + 16,
                                    xd->dst.u_buffer + 8,
                                    xd->dst.v_buffer + 8);

                *current_mb_col = mb_col + nsync;

                /* this is to account for the border */
                xd->mode_info_context++;
                x->partition_info++;

                x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols;
                x->src.u_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;
                x->src.v_buffer += 8 * x->src.uv_stride * (cpi->encoding_thread_count + 1) - 8 * cm->mb_cols;

                xd->mode_info_context += xd->mode_info_stride * cpi->encoding_thread_count;
                x->partition_info += xd->mode_info_stride * cpi->encoding_thread_count;
                x->gf_active_ptr   += cm->mb_cols * cpi->encoding_thread_count;

                if (mb_row == cm->mb_rows - 1)
                {
                    sem_post(&cpi->h_event_end_encoding); /* signal frame encoding end */
                }
            }
        }
    }

    /* printf("exit thread %d\n", ithread); */
    return 0;
}

static void setup_mbby_copy(MACROBLOCK *mbdst, MACROBLOCK *mbsrc)
{

    MACROBLOCK *x = mbsrc;
    MACROBLOCK *z = mbdst;
    int i;

    z->ss               = x->ss;
    z->ss_count          = x->ss_count;
    z->searches_per_step  = x->searches_per_step;
    z->errorperbit      = x->errorperbit;

    z->sadperbit16      = x->sadperbit16;
    z->sadperbit4       = x->sadperbit4;

    /*
    z->mv_col_min    = x->mv_col_min;
    z->mv_col_max    = x->mv_col_max;
    z->mv_row_min    = x->mv_row_min;
    z->mv_row_max    = x->mv_row_max;
    */

    z->short_fdct4x4     = x->short_fdct4x4;
    z->short_fdct8x4     = x->short_fdct8x4;
    z->short_walsh4x4    = x->short_walsh4x4;
    z->quantize_b        = x->quantize_b;
    z->quantize_b_pair   = x->quantize_b_pair;
    z->optimize          = x->optimize;

    /*
    z->mvc              = x->mvc;
    z->src.y_buffer      = x->src.y_buffer;
    z->src.u_buffer      = x->src.u_buffer;
    z->src.v_buffer      = x->src.v_buffer;
    */

    z->mvcost[0] =  x->mvcost[0];
    z->mvcost[1] =  x->mvcost[1];
    z->mvsadcost[0] =  x->mvsadcost[0];
    z->mvsadcost[1] =  x->mvsadcost[1];

    z->token_costs = x->token_costs;
    z->inter_bmode_costs = x->inter_bmode_costs;
    z->mbmode_cost = x->mbmode_cost;
    z->intra_uv_mode_cost = x->intra_uv_mode_cost;
    z->bmode_costs = x->bmode_costs;

    for (i = 0; i < 25; i++)
    {
        z->block[i].quant           = x->block[i].quant;
        z->block[i].quant_fast      = x->block[i].quant_fast;
        z->block[i].quant_shift     = x->block[i].quant_shift;
        z->block[i].zbin            = x->block[i].zbin;
        z->block[i].zrun_zbin_boost = x->block[i].zrun_zbin_boost;
        z->block[i].round           = x->block[i].round;
        z->block[i].src_stride      = x->block[i].src_stride;
    }

    z->q_index           = x->q_index;
    z->act_zbin_adj      = x->act_zbin_adj;
    z->last_act_zbin_adj = x->last_act_zbin_adj;

    {
        MACROBLOCKD *xd = &x->e_mbd;
        MACROBLOCKD *zd = &z->e_mbd;

        /*
        zd->mode_info_context = xd->mode_info_context;
        zd->mode_info        = xd->mode_info;

        zd->mode_info_stride  = xd->mode_info_stride;
        zd->frame_type       = xd->frame_type;
        zd->up_available     = xd->up_available   ;
        zd->left_available   = xd->left_available;
        zd->left_context     = xd->left_context;
        zd->last_frame_dc     = xd->last_frame_dc;
        zd->last_frame_dccons = xd->last_frame_dccons;
        zd->gold_frame_dc     = xd->gold_frame_dc;
        zd->gold_frame_dccons = xd->gold_frame_dccons;
        zd->mb_to_left_edge    = xd->mb_to_left_edge;
        zd->mb_to_right_edge   = xd->mb_to_right_edge;
        zd->mb_to_top_edge     = xd->mb_to_top_edge   ;
        zd->mb_to_bottom_edge  = xd->mb_to_bottom_edge;
        zd->gf_active_ptr     = xd->gf_active_ptr;
        zd->frames_since_golden       = xd->frames_since_golden;
        zd->frames_till_alt_ref_frame   = xd->frames_till_alt_ref_frame;
        */
        zd->subpixel_predict         = xd->subpixel_predict;
        zd->subpixel_predict8x4      = xd->subpixel_predict8x4;
        zd->subpixel_predict8x8      = xd->subpixel_predict8x8;
        zd->subpixel_predict16x16    = xd->subpixel_predict16x16;
        zd->segmentation_enabled     = xd->segmentation_enabled;
        zd->mb_segement_abs_delta      = xd->mb_segement_abs_delta;
        vpx_memcpy(zd->segment_feature_data, xd->segment_feature_data,
                   sizeof(xd->segment_feature_data));

        vpx_memcpy(zd->dequant_y1_dc, xd->dequant_y1_dc,
                   sizeof(xd->dequant_y1_dc));
        vpx_memcpy(zd->dequant_y1, xd->dequant_y1, sizeof(xd->dequant_y1));
        vpx_memcpy(zd->dequant_y2, xd->dequant_y2, sizeof(xd->dequant_y2));
        vpx_memcpy(zd->dequant_uv, xd->dequant_uv, sizeof(xd->dequant_uv));

#if 1
        /*TODO:  Remove dequant from BLOCKD.  This is a temporary solution until
         * the quantizer code uses a passed in pointer to the dequant constants.
         * This will also require modifications to the x86 and neon assembly.
         * */
        for (i = 0; i < 16; i++)
            zd->block[i].dequant = zd->dequant_y1;
        for (i = 16; i < 24; i++)
            zd->block[i].dequant = zd->dequant_uv;
        zd->block[24].dequant = zd->dequant_y2;
#endif
    }
}

void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
                               MACROBLOCK *x,
                               MB_ROW_COMP *mbr_ei,
                               int mb_row,
                               int count
                              )
{

    VP8_COMMON *const cm = & cpi->common;
    MACROBLOCKD *const xd = & x->e_mbd;
    int i;
    (void) mb_row;

    for (i = 0; i < count; i++)
    {
        MACROBLOCK *mb = & mbr_ei[i].mb;
        MACROBLOCKD *mbd = &mb->e_mbd;

        mbd->subpixel_predict        = xd->subpixel_predict;
        mbd->subpixel_predict8x4     = xd->subpixel_predict8x4;
        mbd->subpixel_predict8x8     = xd->subpixel_predict8x8;
        mbd->subpixel_predict16x16   = xd->subpixel_predict16x16;
        mb->gf_active_ptr            = x->gf_active_ptr;

        vpx_memset(mbr_ei[i].segment_counts, 0, sizeof(mbr_ei[i].segment_counts));
        mbr_ei[i].totalrate = 0;

        mb->partition_info = x->pi + x->e_mbd.mode_info_stride * (i + 1);

        mbd->mode_info_context = cm->mi   + x->e_mbd.mode_info_stride * (i + 1);
        mbd->mode_info_stride  = cm->mode_info_stride;

        mbd->frame_type = cm->frame_type;

        mb->src = * cpi->Source;
        mbd->pre = cm->yv12_fb[cm->lst_fb_idx];
        mbd->dst = cm->yv12_fb[cm->new_fb_idx];

        mb->src.y_buffer += 16 * x->src.y_stride * (i + 1);
        mb->src.u_buffer +=  8 * x->src.uv_stride * (i + 1);
        mb->src.v_buffer +=  8 * x->src.uv_stride * (i + 1);

        vp8_build_block_offsets(mb);

        mbd->left_context = &cm->left_context;
        mb->mvc = cm->fc.mvc;

        setup_mbby_copy(&mbr_ei[i].mb, x);

        mbd->fullpixel_mask = 0xffffffff;
        if(cm->full_pixel)
            mbd->fullpixel_mask = 0xfffffff8;
    }
}

int vp8cx_create_encoder_threads(VP8_COMP *cpi)
{
    const VP8_COMMON * cm = &cpi->common;

    cpi->b_multi_threaded = 0;
    cpi->encoding_thread_count = 0;
    cpi->b_lpf_running = 0;

    if (cm->processor_core_count > 1 && cpi->oxcf.multi_threaded > 1)
    {
        int ithread;
        int th_count = cpi->oxcf.multi_threaded - 1;
        int rc = 0;

        /* don't allocate more threads than cores available */
        if (cpi->oxcf.multi_threaded > cm->processor_core_count)
            th_count = cm->processor_core_count - 1;

        /* we have th_count + 1 (main) threads processing one row each */
        /* no point to have more threads than the sync range allows */
        if(th_count > ((cm->mb_cols / cpi->mt_sync_range) - 1))
        {
            th_count = (cm->mb_cols / cpi->mt_sync_range) - 1;
        }

        if(th_count == 0)
            return 0;

        CHECK_MEM_ERROR(cpi->h_encoding_thread,
                        vpx_malloc(sizeof(pthread_t) * th_count));
        CHECK_MEM_ERROR(cpi->h_event_start_encoding,
                        vpx_malloc(sizeof(sem_t) * th_count));
        CHECK_MEM_ERROR(cpi->mb_row_ei,
                        vpx_memalign(32, sizeof(MB_ROW_COMP) * th_count));
        vpx_memset(cpi->mb_row_ei, 0, sizeof(MB_ROW_COMP) * th_count);
        CHECK_MEM_ERROR(cpi->en_thread_data,
                        vpx_malloc(sizeof(ENCODETHREAD_DATA) * th_count));

        sem_init(&cpi->h_event_end_encoding, 0, 0);

        cpi->b_multi_threaded = 1;
        cpi->encoding_thread_count = th_count;

        /*
        printf("[VP8:] multi_threaded encoding is enabled with %d threads\n\n",
               (cpi->encoding_thread_count +1));
        */

        for (ithread = 0; ithread < th_count; ithread++)
        {
            ENCODETHREAD_DATA *ethd = &cpi->en_thread_data[ithread];

            /* Setup block ptrs and offsets */
            vp8_setup_block_ptrs(&cpi->mb_row_ei[ithread].mb);
            vp8_setup_block_dptrs(&cpi->mb_row_ei[ithread].mb.e_mbd);

            sem_init(&cpi->h_event_start_encoding[ithread], 0, 0);

            ethd->ithread = ithread;
            ethd->ptr1 = (void *)cpi;
            ethd->ptr2 = (void *)&cpi->mb_row_ei[ithread];

            rc = pthread_create(&cpi->h_encoding_thread[ithread], 0,
                                thread_encoding_proc, ethd);
            if(rc)
                break;
        }

        if(rc)
        {
            /* shutdown other threads */
            cpi->b_multi_threaded = 0;
            for(--ithread; ithread >= 0; ithread--)
            {
                pthread_join(cpi->h_encoding_thread[ithread], 0);
                sem_destroy(&cpi->h_event_start_encoding[ithread]);
            }
            sem_destroy(&cpi->h_event_end_encoding);

            /* free thread related resources */
            vpx_free(cpi->h_event_start_encoding);
            vpx_free(cpi->h_encoding_thread);
            vpx_free(cpi->mb_row_ei);
            vpx_free(cpi->en_thread_data);

            return -1;
        }


        {
            LPFTHREAD_DATA * lpfthd = &cpi->lpf_thread_data;

            sem_init(&cpi->h_event_start_lpf, 0, 0);
            sem_init(&cpi->h_event_end_lpf, 0, 0);

            lpfthd->ptr1 = (void *)cpi;
            rc = pthread_create(&cpi->h_filter_thread, 0, thread_loopfilter,
                                lpfthd);

            if(rc)
            {
                /* shutdown other threads */
                cpi->b_multi_threaded = 0;
                for(--ithread; ithread >= 0; ithread--)
                {
                    sem_post(&cpi->h_event_start_encoding[ithread]);
                    pthread_join(cpi->h_encoding_thread[ithread], 0);
                    sem_destroy(&cpi->h_event_start_encoding[ithread]);
                }
                sem_destroy(&cpi->h_event_end_encoding);
                sem_destroy(&cpi->h_event_end_lpf);
                sem_destroy(&cpi->h_event_start_lpf);

                /* free thread related resources */
                vpx_free(cpi->h_event_start_encoding);
                vpx_free(cpi->h_encoding_thread);
                vpx_free(cpi->mb_row_ei);
                vpx_free(cpi->en_thread_data);

                return -2;
            }
        }
    }
    return 0;
}

void vp8cx_remove_encoder_threads(VP8_COMP *cpi)
{
    if (cpi->b_multi_threaded)
    {
        /* shutdown other threads */
        cpi->b_multi_threaded = 0;
        {
            int i;

            for (i = 0; i < cpi->encoding_thread_count; i++)
            {
                sem_post(&cpi->h_event_start_encoding[i]);
                pthread_join(cpi->h_encoding_thread[i], 0);

                sem_destroy(&cpi->h_event_start_encoding[i]);
            }

            sem_post(&cpi->h_event_start_lpf);
            pthread_join(cpi->h_filter_thread, 0);
        }

        sem_destroy(&cpi->h_event_end_encoding);
        sem_destroy(&cpi->h_event_end_lpf);
        sem_destroy(&cpi->h_event_start_lpf);

        /* free thread related resources */
        vpx_free(cpi->h_event_start_encoding);
        vpx_free(cpi->h_encoding_thread);
        vpx_free(cpi->mb_row_ei);
        vpx_free(cpi->en_thread_data);
    }
}
#endif
