/* 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 <string.h>
#include "vbp_loader.h"
#include "vbp_utils.h"
#include "vbp_mp42_parser.h"
#include "vbp_common.h"
#include "viddec_mp4_parse.h"



typedef struct vbp_mp42_parser_private_t vbp_mp42_parser_private;

struct vbp_mp42_parser_private_t
{
    bool short_video_header;
};

static uint8 mp4_aspect_ratio_table[][2] =
{
    // forbidden
    {0, 0},
    {1, 1},
    {12, 11},
    {10, 11},
    {16, 11},
    {40, 33},

    // reserved
    {0, 0}
};


/*
 * Some divX avi files contains 2 frames in one gstbuffer.
 */


uint32 vbp_get_sc_pos_mp42(
    uint8 *buf,
    uint32 length,
    uint32 *sc_end_pos,
    uint8 *is_normal_sc,
    uint8* resync_marker,
    const bool svh_search);

void vbp_on_vop_mp42(vbp_context *pcontext, int list_index);
void vbp_on_vop_svh_mp42(vbp_context *pcontext, int list_index);
void vbp_fill_codec_data(vbp_context *pcontext);
vbp_picture_data_mp42* vbp_get_mp42_picture_data(vbp_data_mp42 * query_data);
uint32 vbp_process_slices_mp42(vbp_context *pcontext, int list_index);
uint32 vbp_process_slices_svh_mp42(vbp_context *pcontext, int list_index);
uint32 vbp_process_video_packet_mp42(vbp_context *pcontext);

static inline uint32 vbp_sprite_trajectory_mp42(
    void *parent,
    mp4_VideoObjectLayer_t *vidObjLay,
    mp4_VideoObjectPlane_t *vidObjPlane);


static inline uint32 vbp_sprite_dmv_length_mp42(
    void * parent,
    int32_t *dmv_length);


/**
 *
 */
uint32 vbp_init_parser_entries_mp42( vbp_context *pcontext)
{
    if (NULL == pcontext->parser_ops)
    {
        // absolutely impossible, just sanity check
        return VBP_PARM;
    }
    pcontext->parser_ops->init = dlsym(pcontext->fd_parser, "viddec_mp4_init");
    if (pcontext->parser_ops->init == NULL)
    {
        ETRACE ("Failed to set entry point." );
        return VBP_LOAD;
    }

    pcontext->parser_ops->parse_sc = NULL;
    pcontext->parser_ops->parse_syntax = dlsym(pcontext->fd_parser, "viddec_mp4_parse");
    if (pcontext->parser_ops->parse_syntax == NULL)
    {
        ETRACE ("Failed to set entry point." );
        return VBP_LOAD;
    }

    pcontext->parser_ops->get_cxt_size =dlsym(pcontext->fd_parser, "viddec_mp4_get_context_size");
    if (pcontext->parser_ops->get_cxt_size == NULL)
    {
        ETRACE ("Failed to set entry point." );
        return VBP_LOAD;
    }

    /* entry point not needed */
    pcontext->parser_ops->flush = NULL;

    return VBP_OK;
}


/*
 * For the codec_data passed by gstreamer
 */
uint32 vbp_parse_init_data_mp42(vbp_context *pcontext)
{
    uint32 ret = VBP_OK;
    ret = vbp_parse_start_code_mp42(pcontext);
    return ret;
}

uint32 vbp_process_parsing_result_mp42(vbp_context *pcontext, int list_index)
{
    vbp_data_mp42 *query_data = (vbp_data_mp42 *) pcontext->query_data;
    viddec_mp4_parser_t *parser =
        (viddec_mp4_parser_t *) &(pcontext->parser_cxt->codec_data[0]);
    vbp_mp42_parser_private *parser_private = (vbp_mp42_parser_private *)pcontext->parser_private;

    uint8 is_svh = 0;
    uint32 current_sc = parser->current_sc;
    is_svh = parser->cur_sc_prefix ? false : true;

    if (!is_svh)
    {
        // remove prefix from current_sc
        current_sc &= 0x0FF;
        switch (current_sc)
        {
        case MP4_SC_VISUAL_OBJECT_SEQUENCE:
            VTRACE ("Visual Object Sequence is parsed.\n");
            query_data->codec_data.profile_and_level_indication
                    = parser->info.profile_and_level_indication;
            VTRACE ("profile_and_level_indication = 0x%x\n", parser->info.profile_and_level_indication);
            break;

        case MP4_SC_VIDEO_OBJECT_PLANE:
            //VTRACE ("Video Object Plane is parsed.\n");
            vbp_on_vop_mp42(pcontext, list_index);
            break;

        default:
            if ((current_sc >= MP4_SC_VIDEO_OBJECT_LAYER_MIN) &&
                (current_sc <= MP4_SC_VIDEO_OBJECT_LAYER_MAX))
            {
                VTRACE ("Video Object Layer is parsed\n");
                parser_private->short_video_header = FALSE;
                vbp_fill_codec_data(pcontext);
            }
            else if (current_sc <= MP4_SC_VIDEO_OBJECT_MAX &&
                     current_sc >= MP4_SC_VIDEO_OBJECT_MIN)
            {
                if (parser->sc_seen == MP4_SC_SEEN_SVH)
                {
                    // this should never happen!!!!
                    WTRACE ("Short video header is parsed.\n");
                    // vbp_on_vop_svh_mp42(pcontext, list_index);
                    return VBP_TYPE;
                }
            }
            break;
        }
    }
    else
    {
        if (parser->sc_seen == MP4_SC_SEEN_SVH)
        {
            //VTRACE ("Short video header is parsed.\n");
            vbp_on_vop_svh_mp42(pcontext, list_index);
        }
    }

    return VBP_OK;
}



/*
* partial frame handling:
*
* h.263: picture header is lost if the first GOB is discarded, a redudant pic header must be
* conveyed in the packet  (RFC 4629) for each following GOB, otherwise,
* picture can't be decoded.
*
* MPEG4:  VideoObjectPlane header is lost if the first slice is discarded. However, picture
* is still decodable as long as the header_extension_code is 1 in video_packet_header.
*
*MPEG-4 with short header:   video_plane_with_short_header is lost if the first GOB
* is discarded. As this header is not duplicated (RFC 3016), picture is not decodable.
*
* In sum:
* If buffer contains the 32-bit start code (0x000001xx), proceed  as normal.
*
* If buffer contains 22-bits of "0000 0000 0000 0000 1000 00", which indicates h.263
* picture start code or short_video_start_marker, proceed as normal.
*
* If buffer contains 22-bits of "0000 0000 0000 0000 1XXX XX", (when XXX XX starts from 000 01), which
* indicates  h.263 Group Start code or gob_resync_marker of gob_layer in MPEG-4 with
* short header, we should report packet as a partial frame - no more parsing is needed.
*
* If buffer contains a string of 0 between 16 bits and 22 bits, followed by 1-bit of '1', which indicates a resync-marker,
* the buffer will be immeidately parsed and num_items is set to 0.
*/
uint32 vbp_parse_start_code_mp42(vbp_context *pcontext)
{
    viddec_pm_cxt_t *cxt = pcontext->parser_cxt;
    uint8 *buf = NULL;
    uint32 size = 0;
    uint32 sc_end_pos = -1;
    uint32 bytes_parsed = 0;
    viddec_mp4_parser_t *pinfo = NULL;
    vbp_data_mp42 *query_data = (vbp_data_mp42 *) pcontext->query_data;
    vbp_mp42_parser_private *parser_private = (vbp_mp42_parser_private *)pcontext->parser_private;


    // reset query data for the new sample buffer
    query_data->number_picture_data= 0;
    query_data->number_pictures = 0;

    // emulation prevention byte is not needed
    cxt->getbits.is_emul_reqd = 0;

    cxt->list.num_items = 0;
    cxt->list.data[0].stpos = 0;
    cxt->list.data[0].edpos = cxt->parse_cubby.size;

    buf = cxt->parse_cubby.buf;
    size = cxt->parse_cubby.size;

    pinfo = (viddec_mp4_parser_t *) &(cxt->codec_data[0]);

    uint8 is_normal_sc = 0;
    uint8 resync_marker = 0;
    uint32 found_sc = 0;
    uint32 ret = VBP_OK;

    while (1)
    {
        found_sc = vbp_get_sc_pos_mp42(
                        buf + bytes_parsed,
                        size - bytes_parsed,
                        &sc_end_pos,
                        &is_normal_sc,
                        &resync_marker,
                        parser_private->short_video_header);

        if (found_sc)
        {
            cxt->list.data[cxt->list.num_items].stpos = bytes_parsed + sc_end_pos - 3;
            if (cxt->list.num_items != 0)
            {
                cxt->list.data[cxt->list.num_items - 1].edpos = bytes_parsed + sc_end_pos - 3;
            }
            bytes_parsed += sc_end_pos;

            cxt->list.num_items++;
            pinfo->cur_sc_prefix = is_normal_sc;
        }
        else
        {
            if (cxt->list.num_items != 0)
            {
                cxt->list.data[cxt->list.num_items - 1].edpos = cxt->parse_cubby.size;
                break;
            }
            else
            {
                WTRACE ("No start-code is found in cubby buffer! The size of cubby is %d\n", size);
                cxt->list.num_items = 1;
                cxt->list.data[0].stpos = 0;
                cxt->list.data[0].edpos = cxt->parse_cubby.size;

                if (resync_marker)
                {
                    // either the first slice (GOB) is lost or parser receives a single slice (GOB)
                    if (parser_private->short_video_header)
                    {
                        // TODO: revisit if HW supportd GOB layer decoding for h.263
                        WTRACE("Partial frame: GOB buffer.\n");
                        ret = VBP_PARTIAL;
                    }
                    else
                    {
                        WTRACE("Partial frame: video packet header buffer.\n");
                        ret =  vbp_process_video_packet_mp42(pcontext);
                    }

                    // set num_items to 0 so buffer will not be parsed again
                    cxt->list.num_items = 0;
                }
                else
                {
                    ETRACE("Invalid data received.\n");
                    cxt->list.num_items = 0;
                    return VBP_DATA;
                }

                break;
            }
        }
    }

    return ret;
}

uint32 vbp_populate_query_data_mp42(vbp_context *pcontext)
{
#if 0
    vbp_dump_query_data(pcontext);
#endif
    return VBP_OK;
}

vbp_picture_data_mp42* vbp_get_mp42_picture_data(vbp_data_mp42 * query_data)
{
    vbp_picture_data_mp42 *picture_data = query_data->picture_data;
    int num_pictures = query_data->number_picture_data;
    while (num_pictures > 1)
    {
        picture_data = picture_data->next_picture_data;
        num_pictures--;
    }

    return picture_data;
}

void vbp_fill_codec_data(vbp_context *pcontext)
{
    viddec_mp4_parser_t *parser =
            (viddec_mp4_parser_t *) &(pcontext->parser_cxt->codec_data[0]);
    vbp_data_mp42 *query_data = (vbp_data_mp42 *) pcontext->query_data;
    vbp_codec_data_mp42* codec_data = &(query_data->codec_data);
    vbp_mp42_parser_private *parser_private = (vbp_mp42_parser_private *)pcontext->parser_private;

    codec_data->bit_rate = parser->info.VisualObject.VideoObject.VOLControlParameters.bit_rate;

    codec_data->profile_and_level_indication
            = parser->info.profile_and_level_indication;

    codec_data->video_object_layer_width =
            parser->info.VisualObject.VideoObject.video_object_layer_width;

    codec_data->video_object_layer_height =
            parser->info.VisualObject.VideoObject.video_object_layer_height;

    if (parser->info.VisualObject.VideoSignalType.is_video_signal_type)
    {
        codec_data->video_format =
                parser->info.VisualObject.VideoSignalType.video_format;
    }
    else
    {
        // Unspecified video format
        codec_data->video_format =  5;
    }

    codec_data->video_range =
            parser->info.VisualObject.VideoSignalType.video_range;

    if (parser->info.VisualObject.VideoSignalType.is_colour_description)
    {
        codec_data->matrix_coefficients =
                parser->info.VisualObject.VideoSignalType.matrix_coefficients;
    }
    else if (parser_private->short_video_header)
    {
        // SMPTE 170M
        codec_data->matrix_coefficients = 6;
    }
    else
    {
        // ITU-R Recommendation BT.709
        codec_data->matrix_coefficients = 1;
    }

    codec_data->short_video_header = parser_private->short_video_header;

    // aspect ratio
    codec_data->aspect_ratio_info = parser->info.VisualObject.VideoObject.aspect_ratio_info;
    if (codec_data->aspect_ratio_info < 6)
    {
        codec_data->par_width = mp4_aspect_ratio_table[codec_data->aspect_ratio_info][0];
        codec_data->par_height = mp4_aspect_ratio_table[codec_data->aspect_ratio_info][1];
    }
    else if (codec_data->aspect_ratio_info == 15)
    {
        codec_data->par_width = parser->info.VisualObject.VideoObject.aspect_ratio_info_par_width;
        codec_data->par_height = parser->info.VisualObject.VideoObject.aspect_ratio_info_par_height;
    }
    else
    {
        codec_data->par_width = 0;
        codec_data->par_height = 0;
    }
}

void vbp_fill_slice_data(vbp_context *pcontext, int list_index)
{
    viddec_mp4_parser_t *parser =
            (viddec_mp4_parser_t *) &(pcontext->parser_cxt->codec_data[0]);

    if (!parser->info.VisualObject.VideoObject.short_video_header)
    {
        vbp_process_slices_mp42(pcontext, list_index);
    }
    else
    {
        vbp_process_slices_svh_mp42(pcontext, list_index);
    }
}

void vbp_fill_picture_param(vbp_context *pcontext, uint8 new_picture_flag)
{
    viddec_mp4_parser_t *parser =
            (viddec_mp4_parser_t *) &(pcontext->parser_cxt->codec_data[0]);
    vbp_data_mp42 *query_data = (vbp_data_mp42 *) pcontext->query_data;

    vbp_picture_data_mp42 *picture_data = NULL;
    VAPictureParameterBufferMPEG4 *picture_param = NULL;

    if (new_picture_flag)
    {
        query_data->number_pictures++;
    }

    picture_data = query_data->picture_data;
    if (picture_data == NULL || query_data->number_picture_data == 0)
    {
        // first entry
        if (picture_data == NULL)
        {
            picture_data = vbp_malloc_set0(vbp_picture_data_mp42, 1);
            query_data->picture_data = picture_data;
            if (picture_data == NULL) {
                query_data->number_picture_data = 0;
                return;
            }
        }
        query_data->number_picture_data = 1;
    }
    else
    {
        // find the last active one
        int i = query_data->number_picture_data;
        while (i > 1)
        {
            picture_data = picture_data->next_picture_data;
            i--;
        }
        if (picture_data->next_picture_data == NULL)
        {
            picture_data->next_picture_data = vbp_malloc_set0(vbp_picture_data_mp42, 1);
            if (picture_data->next_picture_data == NULL) {
                return;
            }
        }

        query_data->number_picture_data++;

        picture_data = picture_data->next_picture_data;
    }

    picture_param = &(picture_data->picture_param);

    uint8 idx = 0;

    picture_data->new_picture_flag = new_picture_flag;

    picture_data->vop_coded
            = parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_coded;



    picture_data->vop_time_increment =
            parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_time_increment;

    // fill picture_param


    /*
     * NOTE: for short video header, the parser saves vop_width and vop_height
     * to VOL->video_object_layer_width and VOL->video_object_layer_height
     */
    picture_param->vop_width
            = parser->info.VisualObject.VideoObject.video_object_layer_width;
    picture_param->vop_height
            = parser->info.VisualObject.VideoObject.video_object_layer_height;

    picture_param->forward_reference_picture = VA_INVALID_SURFACE;
    picture_param->backward_reference_picture = VA_INVALID_SURFACE;

    // Fill VAPictureParameterBufferMPEG4::vol_fields

    picture_param->vol_fields.bits.short_video_header
            = parser->info.VisualObject.VideoObject.short_video_header;
    picture_param->vol_fields.bits.chroma_format
            = parser->info.VisualObject.VideoObject.VOLControlParameters.chroma_format;

    // TODO: find out why testsuite always set this value to be 0
    picture_param->vol_fields.bits.chroma_format = 0;

    picture_param->vol_fields.bits.interlaced
            = parser->info.VisualObject.VideoObject.interlaced;
    picture_param->vol_fields.bits.obmc_disable
            = parser->info.VisualObject.VideoObject.obmc_disable;
    picture_param->vol_fields.bits.sprite_enable
            = parser->info.VisualObject.VideoObject.sprite_enable;
    picture_param->vol_fields.bits.sprite_warping_accuracy
            = parser->info.VisualObject.VideoObject.sprite_info.sprite_warping_accuracy;
    picture_param->vol_fields.bits.quant_type
            = parser->info.VisualObject.VideoObject.quant_type;
    picture_param->vol_fields.bits.quarter_sample
            = parser->info.VisualObject.VideoObject.quarter_sample;
    picture_param->vol_fields.bits.data_partitioned
            = parser->info.VisualObject.VideoObject.data_partitioned;
    picture_param->vol_fields.bits.reversible_vlc
            = parser->info.VisualObject.VideoObject.reversible_vlc;
    picture_param->vol_fields.bits.resync_marker_disable
            = parser->info.VisualObject.VideoObject.resync_marker_disable;
    picture_param->no_of_sprite_warping_points
            = parser->info.VisualObject.VideoObject.sprite_info.no_of_sprite_warping_points;

    for (idx = 0; idx < 3; idx++)
    {
        picture_param->sprite_trajectory_du[idx]
                = parser->info.VisualObject.VideoObject.VideoObjectPlane.warping_mv_code_du[idx];
        picture_param->sprite_trajectory_dv[idx]
                = parser->info.VisualObject.VideoObject.VideoObjectPlane.warping_mv_code_dv[idx];
    }

    picture_param->quant_precision
            = parser->info.VisualObject.VideoObject.quant_precision;

    // fill VAPictureParameterBufferMPEG4::vop_fields


    if (!parser->info.VisualObject.VideoObject.short_video_header)
    {
        picture_param->vop_fields.bits.vop_coding_type
                = parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_coding_type;
    }
    else
    {
        picture_param->vop_fields.bits.vop_coding_type
                = parser->info.VisualObject.VideoObject.VideoObjectPlaneH263.picture_coding_type;
    }

      // TODO: fill picture_param->vop_fields.bits.backward_reference_vop_coding_type
      // This shall be done in mixvideoformat_mp42. See M42 spec 7.6.7

    if (picture_param->vop_fields.bits.vop_coding_type != MP4_VOP_TYPE_B)
    {
        picture_param->vop_fields.bits.backward_reference_vop_coding_type
                = picture_param->vop_fields.bits.vop_coding_type;
    }

    picture_param->vop_fields.bits.vop_rounding_type
            = parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_rounding_type;
    picture_param->vop_fields.bits.intra_dc_vlc_thr
            = parser->info.VisualObject.VideoObject.VideoObjectPlane.intra_dc_vlc_thr;
    picture_param->vop_fields.bits.top_field_first
            = parser->info.VisualObject.VideoObject.VideoObjectPlane.top_field_first;
    picture_param->vop_fields.bits.alternate_vertical_scan_flag
            = parser->info.VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag;

    picture_param->vop_fcode_forward
            = parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_fcode_forward;
    picture_param->vop_fcode_backward
            = parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_fcode_backward;
    picture_param->vop_time_increment_resolution
            = parser->info.VisualObject.VideoObject.vop_time_increment_resolution;

    // short header related
    picture_param->num_gobs_in_vop
            = parser->info.VisualObject.VideoObject.VideoObjectPlaneH263.num_gobs_in_vop;
    picture_param->num_macroblocks_in_gob
            = parser->info.VisualObject.VideoObject.VideoObjectPlaneH263.num_macroblocks_in_gob;

    // for direct mode prediction
    picture_param->TRB = parser->info.VisualObject.VideoObject.TRB;
    picture_param->TRD = parser->info.VisualObject.VideoObject.TRD;
}

void vbp_fill_iq_matrix_buffer(vbp_context *pcontext)
{
    viddec_mp4_parser_t *parser =
            (viddec_mp4_parser_t *) &(pcontext->parser_cxt->codec_data[0]);
    vbp_data_mp42 *query_data = (vbp_data_mp42 *) pcontext->query_data;

    mp4_VOLQuant_mat_t *quant_mat_info =
            &(parser->info.VisualObject.VideoObject.quant_mat_info);

    VAIQMatrixBufferMPEG4 *iq_matrix = NULL;

    iq_matrix = &(query_data->iq_matrix_buffer);

    iq_matrix->load_intra_quant_mat = 1; //quant_mat_info->load_intra_quant_mat;
    iq_matrix->load_non_intra_quant_mat = 1; // = quant_mat_info->load_nonintra_quant_mat;
    memcpy(iq_matrix->intra_quant_mat, quant_mat_info->intra_quant_mat, 64);
    memcpy(iq_matrix->non_intra_quant_mat, quant_mat_info->nonintra_quant_mat, 64);
}


void vbp_on_vop_mp42(vbp_context *pcontext, int list_index)
{
    vbp_fill_codec_data(pcontext);
    vbp_fill_picture_param(pcontext, 1);
    vbp_fill_iq_matrix_buffer(pcontext);
    vbp_fill_slice_data(pcontext, list_index);
}

void vbp_on_vop_svh_mp42(vbp_context *pcontext, int list_index)
{
    vbp_fill_codec_data(pcontext);
    vbp_fill_picture_param(pcontext, 1);
    vbp_fill_iq_matrix_buffer(pcontext);
    vbp_fill_slice_data(pcontext, list_index);
}

/* Parse for Sc code of pattern 0x00 0x00 0xXX in the current buffer. Returns either sc found or success.
   The conext is updated with current phase and sc_code position in the buffer.

   What is phase?: phase is a value between [0-4], we keep track of consecutive '0's with this.
   Any time a '0' is found its incremented by 1(uptp 2) and reset to '0' if a zero not found.
   if 0xXX code is found and current phase is 2, its changed to 3 which means we found the pattern
   we are looking for. Its incremented to 4 once we see a byte after this pattern.

   For MP4 there are two startcode patterns LVH & SVH. LVH is same as other codecs (00 00 01), SVH
   A.K.A H263 is (00 00 8X). So we have to look for both kind of start codes. The spec doesn't
   explicitly say if both of them can exist in a stream? So current implemenation will assume
   that only one of them is present in a given stream to simplify implementation. The reason it can
   get complicated is resync marker in LVH can potentially be (00 00 8) which will cause false detect
   of SVH start code.
*/
uint32 vbp_get_sc_pos_mp42(
    uint8 *buf,
    uint32 length,
    uint32 *sc_end_pos,
    uint8 *is_normal_sc,
    uint8 *resync_marker,
    const bool svh_search)
{
    uint8 *ptr = buf;
    uint32 size;
    uint32 data_left = 0, phase = 0, ret = 0;
    size = 0;

    data_left = length;
    *sc_end_pos = -1;

    /* parse until there is more data and start code not found */
    while ((data_left > 0) && (phase < 3))
    {
        /* Check if we are byte aligned & phase=0, if thats the case we can check
         work at a time instead of byte*/
        if (((((uint32) ptr) & 0x3) == 0) && (phase == 0))
        {
            while (data_left > 3)
            {
                uint32 data;
                char mask1 = 0, mask2 = 0;

                data = *((uint32 *) ptr);
#ifndef MFDBIGENDIAN
                data = SWAP_WORD(data);
#endif
                mask1 = (FIRST_STARTCODE_BYTE != (data & SC_BYTE_MASK0));
                mask2 = (FIRST_STARTCODE_BYTE != (data & SC_BYTE_MASK1));
                /* If second byte and fourth byte are not zero's then we cannot have a start code here as we need
                 two consecutive zero bytes for a start code pattern */
                if (mask1 && mask2)
                {
                    /* Success so skip 4 bytes and start over */
                    ptr += 4;
                    size += 4;
                    data_left -= 4;
                    continue;
                }
                else
                {
                    break;
                }
            }
        }

        /* At this point either data is not on a word boundary or phase > 0 or On a word boundary but we detected
         two zero bytes in the word so we look one byte at a time*/
        if (data_left > 0)
        {
            if (*ptr == FIRST_STARTCODE_BYTE)
            {
                /* Phase can be 3 only if third start code byte is found */
                phase++;
                ptr++;
                size++;
                data_left--;
                if (phase > 2)
                {
                    phase = 2;

                    if ((((uint32) ptr) & 0x3) == 0)
                    {
                        while (data_left > 3)
                        {
                            if (*((uint32 *) ptr) != 0)
                            {
                                break;
                            }
                            ptr += 4;
                            size += 4;
                            data_left -= 4;
                        }
                    }
                }
            }
            else
            {
                uint8 normal_sc = 0, short_sc = 0;
                if (phase == 2)
                {
                    normal_sc = (*ptr == THIRD_STARTCODE_BYTE);
                    if (svh_search)
                    {
                       short_sc = (SHORT_THIRD_STARTCODE_BYTE == (*ptr & 0xFC));
                    }
                    *is_normal_sc = normal_sc;

                    // at least 16-bit 0, may be GOB start code or
                    // resync marker.
                    *resync_marker = 1;
                }

                if (!(normal_sc | short_sc))
                {
                    phase = 0;
                }
                else
                {
                    /* Match for start code so update context with byte position */
                    *sc_end_pos = size;
                    phase = 3;
                }
                ptr++;
                size++;
                data_left--;
            }
        }
    }
    if ((data_left > 0) && (phase == 3))
    {
        (*sc_end_pos)++;
        phase++;
        ret = 1;
    }

    // Return 1 only if phase is 4, else always return 0
    return ret;
}


uint32 vbp_macroblock_number_length_mp42(uint32 numOfMbs)
{
    uint32 length = 0;
    numOfMbs--;
    do
    {
        numOfMbs >>= 1;
        length++;
    }
    while (numOfMbs);
    return length;
}

uint32 vbp_parse_video_packet_header_mp42(
    void *parent,
    viddec_mp4_parser_t *parser_cxt,
    uint16_t *quant_scale,
    uint32 *macroblock_number)
{
    uint32 ret = VBP_DATA;
    mp4_Info_t *pInfo = &(parser_cxt->info);
    mp4_VideoObjectLayer_t *vidObjLay = &(pInfo->VisualObject.VideoObject);
    mp4_VideoObjectPlane_t *vidObjPlane =
            &(pInfo->VisualObject.VideoObject.VideoObjectPlane);

    uint32 code = 0;
    int32_t getbits = 0;

    uint16_t _quant_scale = 0;
    uint32 _macroblock_number = 0;
    uint32 header_extension_codes = 0;
    uint8 vop_coding_type = vidObjPlane->vop_coding_type;

    if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_RECTANGULAR)
    {
        ETRACE("VOL shape: %d is not supported",vidObjLay->video_object_layer_shape);
        return VBP_DATA;
    }

    do
    {
        // get macroblock_number
        uint16_t mbs_x = (vidObjLay->video_object_layer_width + 15) >> 4;
        uint16_t mbs_y = (vidObjLay->video_object_layer_height + 15) >> 4;
        uint32 length = vbp_macroblock_number_length_mp42(mbs_x * mbs_y);

        getbits = viddec_pm_get_bits(parent, &code, length);
        BREAK_GETBITS_FAIL(getbits, ret);

        _macroblock_number = code;

        // quant_scale
        if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY)
        {
            getbits = viddec_pm_get_bits(parent, &code, vidObjLay->quant_precision);
            BREAK_GETBITS_FAIL(getbits, ret);
            _quant_scale = code;
        }

        // header_extension_codes
        if (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_RECTANGULAR)
        {
            getbits = viddec_pm_get_bits(parent, &code, 1);
            BREAK_GETBITS_FAIL(getbits, ret);
            header_extension_codes = code;
        }

        if (header_extension_codes)
        {
            // modulo time base
            do
            {
                getbits = viddec_pm_get_bits(parent, &code, 1);
                BREAK_GETBITS_FAIL(getbits, ret);
            } while (code);

            // marker_bit
            getbits = viddec_pm_get_bits(parent, &code, 1);
            BREAK_GETBITS_FAIL(getbits, ret);

            // vop_time_increment
            uint32 numbits = 0;
            numbits = vidObjLay->vop_time_increment_resolution_bits;
            if (numbits == 0)
            {
                // ??
                numbits = 1;
            }
            getbits = viddec_pm_get_bits(parent, &code, numbits);
            BREAK_GETBITS_FAIL(getbits, ret);
            vidObjPlane->vop_time_increment = code;


            // marker_bit
            getbits = viddec_pm_get_bits(parent, &code, 1);
            BREAK_GETBITS_FAIL(getbits, ret);

            // vop_coding_type
            getbits = viddec_pm_get_bits(parent, &code, 2);
            BREAK_GETBITS_FAIL(getbits, ret);

            vop_coding_type = code & 0x3;
            vidObjPlane->vop_coding_type = vop_coding_type;


            if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY)
            {
                // intra_dc_vlc_thr
                getbits = viddec_pm_get_bits(parent, &code, 3);
                BREAK_GETBITS_FAIL(getbits, ret);

                vidObjPlane->intra_dc_vlc_thr = code;
                if ((vidObjLay->sprite_enable == MP4_SPRITE_GMC) &&
                    (vop_coding_type == MP4_VOP_TYPE_S) &&
                    (vidObjLay->sprite_info.no_of_sprite_warping_points> 0))
                {
                    if (vbp_sprite_trajectory_mp42(parent, vidObjLay, vidObjPlane) != VBP_OK)
                    {
                        break;
                    }
                }

                if (vidObjLay->reduced_resolution_vop_enable &&
                   (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_RECTANGULAR) &&
                   ((vop_coding_type == MP4_VOP_TYPE_I) ||
                    (vop_coding_type == MP4_VOP_TYPE_P)))
                {
                    // vop_reduced_resolution
                    getbits = viddec_pm_get_bits(parent, &code, 1);
                    BREAK_GETBITS_FAIL(getbits, ret);
                }

                if (vop_coding_type != MP4_VOP_TYPE_I)
                {
                    // vop_fcode_forward
                    getbits = viddec_pm_get_bits(parent, &code, 3);
                    BREAK_GETBITS_FAIL(getbits, ret);
                    vidObjPlane->vop_fcode_forward = code;
                }

                if (vop_coding_type == MP4_VOP_TYPE_B)
                {
                    // vop_fcode_backward
                    getbits = viddec_pm_get_bits(parent, &code, 3);
                    BREAK_GETBITS_FAIL(getbits, ret);
                    vidObjPlane->vop_fcode_backward = code;
                }
            }
        }

        if (vidObjLay->newpred_enable)
        {
            // New pred mode not supported in HW, but, does libva support this?
            ETRACE("New pred mode not supported in HW");
            ret = VBP_DATA;
            break;
        }

        *quant_scale = _quant_scale;
        *macroblock_number = _macroblock_number;

        ret = VBP_OK;
    }
    while (0);
    return ret;
}

uint32 vbp_resync_marker_Length_mp42(viddec_mp4_parser_t *parser_cxt)
{
    mp4_Info_t *pInfo = &(parser_cxt->info);
    mp4_VideoObjectPlane_t *vidObjPlane =
            &(pInfo->VisualObject.VideoObject.VideoObjectPlane);

    uint32 resync_marker_length = 0;
    if (vidObjPlane->vop_coding_type == MP4_VOP_TYPE_I)
    {
        resync_marker_length = 17;
    }
    else if (vidObjPlane->vop_coding_type == MP4_VOP_TYPE_B)
    {
        uint8 fcode_max = vidObjPlane->vop_fcode_forward;
        if (fcode_max < vidObjPlane->vop_fcode_backward)
        {
            fcode_max = vidObjPlane->vop_fcode_backward;
        }
        resync_marker_length = 16 + fcode_max;

        // resync_marker is max(15+fcode,17) zeros followed by a one
        if (resync_marker_length < 18)
            resync_marker_length = 18;
    }
    else
    {
        resync_marker_length = 16 + vidObjPlane->vop_fcode_forward;
    }
    return resync_marker_length;
}

uint32 vbp_process_slices_svh_mp42(vbp_context *pcontext, int list_index)
{
    uint32 ret = VBP_OK;

    vbp_data_mp42 *query_data = (vbp_data_mp42 *) pcontext->query_data;
    viddec_pm_cxt_t *parent = pcontext->parser_cxt;
    viddec_mp4_parser_t *parser_cxt =
            (viddec_mp4_parser_t *) &(parent->codec_data[0]);

    vbp_picture_data_mp42 *picture_data = vbp_get_mp42_picture_data(query_data);
    vbp_slice_data_mp42 *slice_data = &(picture_data->slice_data);
    VASliceParameterBufferMPEG4* slice_param = &(slice_data->slice_param);

    uint8 is_emul = 0;
    uint32 bit_offset = 0;
    uint32 byte_offset = 0;

    // The offsets are relative to parent->parse_cubby.buf
    viddec_pm_get_au_pos(parent, &bit_offset, &byte_offset, &is_emul);

    slice_data->buffer_addr = parent->parse_cubby.buf;

    slice_data->slice_offset =
            byte_offset + parent->list.data[list_index].stpos;
    slice_data->slice_size =
            parent->list.data[list_index].edpos - parent->list.data[list_index].stpos - byte_offset;

    slice_param->slice_data_size = slice_data->slice_size;
    slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
    slice_param->slice_data_offset = 0;
    slice_param->macroblock_offset = bit_offset;
    slice_param->macroblock_number = 0;
    slice_param->quant_scale
            = parser_cxt->info.VisualObject.VideoObject.VideoObjectPlaneH263.vop_quant;

    return ret;
}
#define SEARCH_SYNC_OPT
uint32 vbp_process_slices_mp42(vbp_context *pcontext, int list_index)
{
    vbp_data_mp42 *query_data = (vbp_data_mp42 *) pcontext->query_data;
    viddec_pm_cxt_t *parent = pcontext->parser_cxt;
    viddec_mp4_parser_t *parser_cxt = (viddec_mp4_parser_t *) &(parent->codec_data[0]);

    vbp_picture_data_mp42 *picture_data = NULL;
    vbp_slice_data_mp42 *slice_data = NULL;
    VASliceParameterBufferMPEG4* slice_param = NULL;

    uint32 ret = VBP_OK;

    uint8 is_emul = 0;
    uint32 bit_offset = 0;
    uint32 byte_offset = 0;

    uint32 code = 0;
    int32_t getbits = 0;
    uint32 resync_marker_length = 0;

    /* The offsets are relative to parent->parse_cubby.buf */
    viddec_pm_get_au_pos(parent, &bit_offset, &byte_offset, &is_emul);

    picture_data = vbp_get_mp42_picture_data(query_data);
    slice_data = &(picture_data->slice_data);
    slice_param = &(slice_data->slice_param);

    slice_data->buffer_addr = parent->parse_cubby.buf;

    slice_data->slice_offset = byte_offset + parent->list.data[list_index].stpos;
    slice_data->slice_size =
            parent->list.data[list_index].edpos - parent->list.data[list_index].stpos - byte_offset;

    slice_param->slice_data_size = slice_data->slice_size;
    slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
    slice_param->slice_data_offset = 0;
    slice_param->macroblock_offset = bit_offset;
    slice_param->macroblock_number = 0;
    slice_param->quant_scale
            = parser_cxt->info.VisualObject.VideoObject.VideoObjectPlane.vop_quant;

    if (parser_cxt->info.VisualObject.VideoObject.resync_marker_disable)
    {
        // no resync_marker
        VTRACE("resync marker is disabled");
        return VBP_OK;
    }

    // scan for resync_marker
    viddec_pm_get_au_pos(parent, &bit_offset, &byte_offset, &is_emul);
    if (bit_offset)
    {
        // byte-aligned
        getbits = viddec_pm_get_bits(parent, &code, 8 - bit_offset);
        if (getbits == -1)
        {
            WTRACE("FAILURE!!!! getbits %s : %d", __FUNCTION__, __LINE__);
            return VBP_DATA;
        }
    }

    // get resync_marker_length
    resync_marker_length = vbp_resync_marker_Length_mp42(parser_cxt);

    uint16_t quant_scale = 0;
    uint32 macroblock_number = 0;

    while (1)
    {
#ifndef SEARCH_SYNC_OPT
        getbits = viddec_pm_peek_bits(parent, &code, resync_marker_length);

        // return VBP_OK as resync_marker may not be present
        BREAK_GETBITS_FAIL(getbits, ret);

        if (code != 1)
        {
            getbits = viddec_pm_get_bits(parent, &code, 8);
            BREAK_GETBITS_FAIL(getbits, ret);
            continue;
        }
#else

        // read 3 bytes since resync_marker_length is between 17 bits and 23 bits
        if (parent->getbits.bstrm_buf.buf_index + 3 > parent->getbits.bstrm_buf.buf_end)
        {
            break;
        }

        code = parent->getbits.bstrm_buf.buf[parent->getbits.bstrm_buf.buf_index] << 16 |
                parent->getbits.bstrm_buf.buf[parent->getbits.bstrm_buf.buf_index+1] << 8 |
                parent->getbits.bstrm_buf.buf[parent->getbits.bstrm_buf.buf_index+2];

        if (code >> (24-resync_marker_length) != 1)
        {
            int byte0 = code & 0xff;
            int byte1 = (code >> 8) & 0xff;
            if (byte0 != 0)
            {
                parent->getbits.bstrm_buf.buf_index += 3;
            }
            else if (byte1 != 0)
            {
                parent->getbits.bstrm_buf.buf_index += 2;
            }
            else
            {
                parent->getbits.bstrm_buf.buf_index += 1;
            }
            continue;
        }
#endif
        // We found resync_marker
        viddec_pm_get_au_pos(parent, &bit_offset, &byte_offset, &is_emul);

        // update slice data as we found resync_marker
        slice_data->slice_size -=
                (parent->list.data[list_index].edpos - parent->list.data[list_index].stpos - byte_offset);
        slice_param->slice_data_size = slice_data->slice_size;

        // skip resync marker
        getbits = viddec_pm_get_bits(parent, &code, resync_marker_length);

        // return VBP_DATA, this should never happen!
        BREAK_GETBITS_FAIL(getbits, ret);

        // parse video_packet_header
        ret = vbp_parse_video_packet_header_mp42(parent, parser_cxt,
                &quant_scale, &macroblock_number);

        if (ret != VBP_OK)
        {
            ETRACE("Failed to parse video packet header.\n");
            return ret;
        }

        // new_picture_flag = 0, this is not the first slice of a picture
        vbp_fill_picture_param(pcontext, 0);

        picture_data = vbp_get_mp42_picture_data(query_data);
        slice_data = &(picture_data->slice_data);
        slice_param = &(slice_data->slice_param);


        viddec_pm_get_au_pos(parent, &bit_offset, &byte_offset, &is_emul);

        slice_data->buffer_addr = parent->parse_cubby.buf;

        slice_data->slice_offset =
                    byte_offset + parent->list.data[list_index].stpos;
        slice_data->slice_size =
                    parent->list.data[list_index].edpos - parent->list.data[list_index].stpos - byte_offset;

        slice_param->slice_data_size = slice_data->slice_size;
        slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
        slice_param->slice_data_offset = 0;
        slice_param->macroblock_offset = bit_offset;
        slice_param->macroblock_number = macroblock_number;
        slice_param->quant_scale = quant_scale;

        if (bit_offset)
        {
            // byte-align parsing position
            getbits = viddec_pm_skip_bits(parent,  8 - bit_offset);
            if (getbits == -1)
            {
                ETRACE("Failed to align parser to byte position.\n");
                return VBP_DATA;
            }
        }

    }

    return VBP_OK;
}

uint32 vbp_process_video_packet_mp42(vbp_context *pcontext)
{
    vbp_data_mp42 *query_data = (vbp_data_mp42 *) pcontext->query_data;
    viddec_pm_cxt_t *parent = pcontext->parser_cxt;
    viddec_mp4_parser_t *parser_cxt = (viddec_mp4_parser_t *) &(parent->codec_data[0]);
    uint32 code = 0;
    int32_t getbits = 0;

    uint32 ret = VBP_DATA;


    // setup bitstream parser
    parent->getbits.list = &(parent->list);

    parent->getbits.bstrm_buf.buf = parent->parse_cubby.buf;
    parent->getbits.bstrm_buf.buf_index = 0;
    parent->getbits.bstrm_buf.buf_st = 0;
    parent->getbits.bstrm_buf.buf_end = parent->parse_cubby.size;
    parent->getbits.bstrm_buf.buf_bitoff = 0;

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

    parent->list.start_offset = 0;
    parent->list.end_offset = parent->parse_cubby.size;
    parent->list.total_bytes = parent->parse_cubby.size;


    // skip leading zero-byte
    while (code == 0)
    {
        getbits = viddec_pm_get_bits(parent, &code, 8);
        BREAK_GETBITS_FAIL(getbits, ret);
        getbits = viddec_pm_peek_bits(parent, &code, 8);
        BREAK_GETBITS_FAIL(getbits, ret);
    }

    if (getbits != 0)
    {
        return VBP_DATA;
    }

    // resync-marker is represented as 17-23 bits. (16-22 bits of 0)
    // as 16-bit '0' has been skipped, we try to parse buffer bit by bit
    // until bit 1 is encounted or up to 7 bits are parsed.
    code = 0;
    uint8 count = 0;
    while (code == 0  && count < 7)
    {
        getbits = viddec_pm_get_bits(parent, &code, 1);
        BREAK_GETBITS_FAIL(getbits, ret);
        count++;
    }

    if (code == 0 || getbits != 0)
    {
        ETRACE("no resync-marker in the buffer.\n");
        return ret;
    }

    // resync marker is skipped
    uint16_t quant_scale = 0;
    uint32 macroblock_number = 0;

    // parse video_packet_header
    vbp_parse_video_packet_header_mp42(parent, parser_cxt, &quant_scale, &macroblock_number);

    // new_picture_flag = 0, this is not the first slice of a picture
    vbp_fill_picture_param(pcontext, 0);

    vbp_picture_data_mp42 *picture_data = NULL;
    vbp_slice_data_mp42 *slice_data = NULL;
    VASliceParameterBufferMPEG4* slice_param = NULL;

    picture_data = vbp_get_mp42_picture_data(query_data);
    slice_data = &(picture_data->slice_data);
    slice_param = &(slice_data->slice_param);

    ret = vbp_process_slices_mp42(pcontext, 0);

    // update slice's QP and macro_block number as it is set to 0 by default.
    slice_param->macroblock_number = macroblock_number;
    slice_param->quant_scale = quant_scale;

    // VOP must be coded!
    picture_data->vop_coded = 1;
    return ret;

}


static inline uint32 vbp_sprite_dmv_length_mp42(
    void * parent,
    int32_t *dmv_length)
{
    uint32 code, skip;
    int32_t getbits = 0;
    uint32 ret = VBP_DATA;
    *dmv_length = 0;
    skip = 3;
    do
    {
        getbits = viddec_pm_peek_bits(parent, &code, skip);
        BREAK_GETBITS_FAIL(getbits, ret);

        if (code == 7)
        {
            viddec_pm_skip_bits(parent, skip);
            getbits = viddec_pm_peek_bits(parent, &code, 9);
            BREAK_GETBITS_FAIL(getbits, ret);

            skip = 1;
            while ((code & 256) != 0)
            {
                // count number of 1 bits
                code <<= 1;
                skip++;
            }
            *dmv_length = 5 + skip;
        }
        else
        {
            skip = (code <= 1) ? 2 : 3;
            *dmv_length = code - 1;
        }
        viddec_pm_skip_bits(parent, skip);
        ret = VBP_OK;

    }
    while (0);
    return ret;
}


static inline uint32 vbp_sprite_trajectory_mp42(
    void *parent,
    mp4_VideoObjectLayer_t *vidObjLay,
    mp4_VideoObjectPlane_t *vidObjPlane)
{
    uint32 code, i;
    int32_t dmv_length = 0, dmv_code = 0, getbits = 0;
    uint32 ret = VBP_OK;
    for (i = 0; i < (uint32) vidObjLay->sprite_info.no_of_sprite_warping_points; i++)
    {
        ret = VBP_DATA;
        ret = vbp_sprite_dmv_length_mp42(parent, &dmv_length);
        if (ret != VBP_OK)
        {
            break;
        }
        if (dmv_length <= 0)
        {
            dmv_code = 0;
        }
        else
        {
            getbits = viddec_pm_get_bits(parent, &code, (uint32) dmv_length);
            BREAK_GETBITS_FAIL(getbits, ret);
            dmv_code = (int32_t) code;
            if ((dmv_code & (1 << (dmv_length - 1))) == 0)
            {
                dmv_code -= (1 << dmv_length) - 1;
            }
        }
        getbits = viddec_pm_get_bits(parent, &code, 1);
        BREAK_GETBITS_FAIL(getbits, ret);
        if (code != 1)
        {
            ret = VBP_DATA;
            break;
        }
        vidObjPlane->warping_mv_code_du[i] = dmv_code;
        // TODO: create another inline function to avoid code duplication
        ret = vbp_sprite_dmv_length_mp42(parent, &dmv_length);
        if (ret != VBP_OK)
        {
            break;
        }
        // reset return value in case early break
        ret = VBP_DATA;
        if (dmv_length <= 0)
        {
            dmv_code = 0;
        }
        else
        {
            getbits = viddec_pm_get_bits(parent, &code, (uint32) dmv_length);
            BREAK_GETBITS_FAIL(getbits, ret);
            dmv_code = (int32_t) code;
            if ((dmv_code & (1 << (dmv_length - 1))) == 0)
            {
                dmv_code -= (1 << dmv_length) - 1;
            }
        }
        getbits = viddec_pm_get_bits(parent, &code, 1);
        BREAK_GETBITS_FAIL(getbits, ret);
        if (code != 1)
        {
            break;
        }
        vidObjPlane->warping_mv_code_dv[i] = dmv_code;

        // set to VBP_OK
        ret = VBP_OK;

    }
    return ret;
}


/*
 * free memory of vbp_data_mp42 structure and its members
 */
uint32 vbp_free_query_data_mp42(vbp_context *pcontext)
{
    vbp_data_mp42 *query_data = (vbp_data_mp42 *) pcontext->query_data;
    vbp_picture_data_mp42* current = NULL;
    vbp_picture_data_mp42* next = NULL;

    if (pcontext->parser_private)
    {
        free(pcontext->parser_private);
        pcontext->parser_private = NULL;
    }
    if (query_data)
    {
        current = query_data->picture_data;
        while (current != NULL)
        {
            next = current->next_picture_data;
            free(current);
            current = next;
        }

        free(query_data);
    }

    pcontext->query_data = NULL;
    return VBP_OK;
}

/*
 * Allocate memory for vbp_data_mp42 structure and all its members.
 */
uint32 vbp_allocate_query_data_mp42(vbp_context *pcontext)
{
    vbp_data_mp42 *query_data;
    pcontext->query_data = NULL;

    query_data = vbp_malloc_set0(vbp_data_mp42, 1);
    if (query_data == NULL)
    {
        goto cleanup;
    }

    pcontext->query_data = (void *) query_data;
    query_data->picture_data = NULL;
    query_data->number_picture_data = 0;
    query_data->number_pictures = 0;

    pcontext->parser_private = NULL;
    vbp_mp42_parser_private *parser_private = NULL;

    parser_private = vbp_malloc_set0(vbp_mp42_parser_private, 1);
    if (NULL == parser_private)
    {
        goto cleanup;
    }

    /* assign the pointer */
    pcontext->parser_private = (void *)parser_private;

    /* init the pointer */
    parser_private->short_video_header = TRUE;
    return VBP_OK;

cleanup:

    vbp_free_query_data_mp42(pcontext);

    return VBP_MEM;
}
