/*
 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);
		
		VTRACE("buf=%x, bytes_parsed=%d, unparsed=%d", (uint32)buf, bytes_parsed, size- bytes_parsed);
		VTRACE("found_sc=%d, cxt->list.num_items=%d, resync_marker=%d, ",
			found_sc, cxt->list.num_items, 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;
}
