/*
 INTEL CONFIDENTIAL
 Copyright 2009 Intel Corporation All Rights Reserved.
 The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.

 No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
 */


#include <glib.h>
#include <dlfcn.h>

#include <string.h>
#include "vbp_loader.h"
#include "vbp_utils.h"
#include "vbp_mp42_parser.h"
#include "../codecs/mp4/parser/viddec_mp4_parse.h"



static bool short_video_header = TRUE;

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

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 = dlsym(pcontext->fd_parser, "viddec_parse_sc_mp4");
	if (pcontext->parser_ops->parse_sc == NULL)
	{
		ETRACE ("Failed to set entry point." );
		return VBP_LOAD;
	}

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

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

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

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

	
	// reset query data for the new sample buffer 
	query_data->number_picture_data= 0;
	query_data->number_pictures = 0;
	
	// emulation prevention byte is always present 
	cxt->getbits.is_emul_reqd = 1;

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

		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 (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);
	
	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 (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 = 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_picture_data_mp42*)g_try_new0(vbp_picture_data_mp42, 1);
            query_data->picture_data = picture_data;
        }            
        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 = g_try_new0(vbp_picture_data_mp42, 1);
        }

        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;

	VTRACE ("vop_coded = %d\n", picture_data->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 = quant_mat_info->load_intra_quant_mat;
	iq_matrix->load_non_intra_quant_mat
			= 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);
}

uint32 vbp_get_sc_pos_mp42(
	uint8 *buf, 
	uint32 length,
	uint32 *sc_end_pos,
	uint8 *is_normal_sc,
	uint8 *resync_marker) 
{
	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);
					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) 
	{
		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?
			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;
}

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;

#ifdef VBP_TRACE
	uint32 list_size_at_index = parent->list.data[list_index].edpos
	- parent->list.data[list_index].stpos;

	VTRACE ("list_index = %d list_size_at_index = %d\n", list_index,
			list_size_at_index);

	VTRACE ("list_index = %d edpos = %d stpos = %d\n", list_index,
			parent->list.data[list_index].edpos,
			parent->list.data[list_index].stpos);
#endif

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

#if 0
	if (is_emul) {
		g_print("*** emul != 0\n");
		/*byte_offset += 1;*/
	}
#endif


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

        // 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_get_bits(parent, &code, 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 (query_data) 
	{
	    current = query_data->picture_data;
	    while (current != NULL)
	    {
	        next = current->next_picture_data;
	        g_free(current);
	        current = next;
        }	       

		g_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 = g_try_new0(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;

	return VBP_OK;

cleanup:

    vbp_free_query_data_mp42(pcontext);
    
	return VBP_MEM;
}
