// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
 * Copyright (c) 2020 MediaTek Inc.
 */
#include <linux/string.h>
#include <linux/printk.h>
#include "mtk_mvd_parser_header.h"
#include "mtk_mvd_parser_hal.h"
#ifdef ENABLE_REE_PARSE_HEADER

//Error handling
#define CHKPARAM(param, hbound)\
	({\
		int r = 0;\
		if (param > hbound) {\
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR, "Hdr err\n");\
			ret_value = (unsigned int)VDEC_HAL_RET_H264_INVALID_PARAM;\
			r = 1;\
		} \
		r;\
	})
//Error handling parse error
#define PSRERR()\
	({\
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR, "Hdr err\n");\
		ret_value = (unsigned int)VDEC_HAL_RET_H264_INVALID_PARAM;\
		1;\
	})

#define PAS_LOG_LEVEL_PARSE PAS_LOG_LEVEL_FRAMING

struct h264_sps_data g_h264_sps[H264_MAX_SPS_NUM];
struct h264_pps_data g_h264_pps[H264_MAX_PPS_NUM];

//struct h265_vps_data g_vps[H265_MAX_VPS_NUM];
struct h265_sps_data g_h265_sps[H265_MAX_SPS_NUM];
struct h265_sps_data active_h265_sps;
struct h265_pps_data g_h265_pps[H265_MAX_PPS_NUM];
struct h265_sei_data g_h265_sei;

void init_h264_seq_header(void)
{
	int i = 0;

	for (i = 0; i < H264_MAX_SPS_NUM; ++i)
		g_h264_sps[0].valid = 0;
	for (i = 0; i < H264_MAX_PPS_NUM; ++i)
		g_h265_pps[0].valid = 0;
}

void init_h265_seq_header(void)
{
	int i = 0;

	for (i = 0; i < H265_MAX_SPS_NUM; ++i)
		g_h265_sps[0].valid = 0;
	for (i = 0; i < H265_MAX_PPS_NUM; ++i)
		g_h265_pps[0].valid = 0;
}

void init_h265_sei_pic_struct(void)
{
	g_h265_sei.pic_tim_data.pic_struct = HEVC_SEI_FRAME_ONLY;
}


static int check_mpeg_pic_ext(
	unsigned char *p_vstart, unsigned char *p_vend,
	unsigned char *p_rstart, unsigned char *p_rend)
{
#define MPEG_NAL_HEADER_LEN 1
#define MPEG_EXT_HEADER 0xB5
	unsigned char *ptr = NULL, *start = p_rstart + START_CODE_LEN;
	// p_rend must > p_rstart
	int size = p_rend - p_rstart;

	if (size < START_CODE_LEN + MPEG_NAL_HEADER_LEN)
		return 0;

	if (start >= p_vend)
		ptr = p_vstart + (start-p_vend);
	else
		ptr = start;

	return (*ptr) == MPEG_EXT_HEADER;
}

signed int vdec_com_mpeg_sw_pic_ext(
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct MPEG_ES_UNIT *curCachedUnit)
{
	union mpeg2_pic_ext_hdr pic_ext_hdr;

	memset(&pic_ext_hdr, 0, sizeof(union mpeg2_pic_ext_hdr));

	pic_ext_hdr.reg[0] = vpas_readbits(rbsp_bitstream_inst, VALUE_32);
	// pic_ext_hdr.reg[1] = vpas_readbits(rbsp_bitstream_inst, 32);

	curCachedUnit->pic_struct = pic_ext_hdr.field.pic_structure;

	return VDEC_HAL_RET_OK;
}

// init rbsp's location
signed int vdec_rbsp_parser_init(
	struct rbsp_bitstream *p_rbsp_bitstream,
	unsigned char *p_vstart, // read nal start
	unsigned char *p_vend,   // read nal end (cannot read)
	unsigned char *p_rstart, // read start pointer move in byte
	unsigned char *p_rend,   // read end (cannot read)
	unsigned int codec,
	bool disable_emulation_prevention) // check emulation_prevention 03 or not
{
#define MPEG_NAL_HEADER_LEN 1
#define H264_NAL_HEADER_LEN 1
#define H265_NAL_HEADER_LEN 2

	unsigned int i = 0, nalu_header_len = 0;
	unsigned char *ptr = NULL;
	uintptr_t start = 0, end = 0, size = 0;

	if (codec == E_VES_PARSER_CODEC_AVC)
		nalu_header_len = H264_NAL_HEADER_LEN;
	else if (codec == E_VES_PARSER_CODEC_HEVC)
		nalu_header_len = H265_NAL_HEADER_LEN;
	else if (codec == E_VES_PARSER_CODEC_MPEG2) {
		if (check_mpeg_pic_ext(p_vstart, p_vend, p_rstart, p_rend))
			nalu_header_len = MPEG_NAL_HEADER_LEN;
		else
			return -1;
	}

	// check remain size can skip nalu header or not
	if (p_rend - p_rstart < START_CODE_LEN + nalu_header_len)
		return -1;

	p_rbsp_bitstream->p_vstart = p_vstart;
	p_rbsp_bitstream->p_vend = p_vend;
	p_rbsp_bitstream->p_rstart = p_rstart +
		START_CODE_LEN + nalu_header_len; // skip start code & nalu header type len

	if (p_rend - p_rbsp_bitstream->p_rstart >= CACHE_SIZE)
		p_rbsp_bitstream->p_rend = p_rbsp_bitstream->p_rstart + CACHE_SIZE;
	else
		p_rbsp_bitstream->p_rend = p_rend;

	p_rbsp_bitstream->stored_cache_size = size =
		(uintptr_t) p_rbsp_bitstream->p_rend -
		(uintptr_t) p_rbsp_bitstream->p_rstart;

	i = 0;

	p_rbsp_bitstream->bits_read = 0;
	p_rbsp_bitstream->bits_write = 0;
	p_rbsp_bitstream->remove_03 = 0;
	p_rbsp_bitstream->cont0 = 0;

	p_rbsp_bitstream->disable_emulation_prevention = disable_emulation_prevention;

	memset(p_rbsp_bitstream->cache, 0, sizeof(p_rbsp_bitstream->cache));
	// deal with wrap-around
	if (p_rbsp_bitstream->p_rstart >= p_rbsp_bitstream->p_vend) {
		start = (uintptr_t) p_rbsp_bitstream->p_vstart +
			((uintptr_t) p_rbsp_bitstream->p_rstart -
			(uintptr_t) p_rbsp_bitstream->p_vend);
		end = start + size;
	} else {
		if (p_rbsp_bitstream->p_rend <= p_rbsp_bitstream->p_vend) {
			start = (uintptr_t) p_rbsp_bitstream->p_rstart;
			end = (uintptr_t) p_rbsp_bitstream->p_rend;
		} else {
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE, "before wrap "
				"start: 0x%llx end: 0x%llx\n",
				(unsigned long long) p_rbsp_bitstream->p_rstart,
				(unsigned long long) p_rbsp_bitstream->p_vend);
			for (ptr = p_rbsp_bitstream->p_rstart;
				ptr != p_rbsp_bitstream->p_vend;
				i++, ptr++) {
				//PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR, "B[%02d]   %02x\n", i, *ptr);
				p_rbsp_bitstream->cache[i] = *ptr;
			}
			size = (uintptr_t) p_rbsp_bitstream->p_rend -
				(uintptr_t) p_rbsp_bitstream->p_vend;
			start = (uintptr_t) p_rbsp_bitstream->p_vstart;
			end = start + size;
		}
	}

	//printf("start: 0x%llx end: 0x%llx\n",
	//	(unsigned long long) start, (unsigned long long) end);

	for (ptr = (unsigned char *) start;
		ptr != (unsigned char *) end;
		i++, ptr++) {
		//printf("B[%02d]   %02x\n", i, *ptr);
		p_rbsp_bitstream->cache[i] = *ptr;
	}

	return 0;
}

unsigned int vdec_com_sw_psr_h264_pps(struct rbsp_bitstream *rbsp_bitstream_inst)
{
	signed int ret_value = VDEC_HAL_RET_OK;
	int pic_params_set_id = 0, seq_params_set_id = 0;
	struct h264_pps_data *p_pps = NULL;

	pic_params_set_id = vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
	if (CHKPARAM(pic_params_set_id, H264_MAX_PPS_NUM))
		return ret_value;

	seq_params_set_id = vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
	if (CHKPARAM(seq_params_set_id, H264_MAX_SPS_NUM))
		return ret_value;

	p_pps = &g_h264_pps[pic_params_set_id];
	p_pps->pic_params_set_id = pic_params_set_id;
	p_pps->seq_params_set_id = seq_params_set_id;
	p_pps->valid = 1;
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE, "valid pps: %d sps: %d\n",
		pic_params_set_id, seq_params_set_id);
	return VDEC_HAL_RET_OK;
}
static inline int h264_check_profile(struct h264_sps_data *p_SPS)
{
	if (p_SPS == NULL)
		return 0;

	return (p_SPS->profile_idc == FREXT_HP)
		|| (p_SPS->profile_idc == FREXT_Hi10P)
		|| (p_SPS->profile_idc == FREXT_Hi422)
		|| (p_SPS->profile_idc == FREXT_Hi444)
		|| (p_SPS->profile_idc == MVC_HIGH)
		|| (p_SPS->profile_idc == MVC_STEREO);
}
unsigned int vdec_com_sw_psr_h264_sps(struct rbsp_bitstream *rbsp_bitstream_inst)
{
#define VALUE_255 255
	signed int ret_value = VDEC_HAL_RET_OK;
	unsigned int index = 0;
	struct h264_sps_data sps_header;
	struct h264_sps_data *p_SPS = NULL;// = p_h264_hw_param->p_avc_paramset->p_SPS;

	memset(&sps_header, 0, sizeof(sps_header));

	sps_header.profile_idc =
		vpas_readbits(rbsp_bitstream_inst, VALUE_8);//u(8)
	sps_header.constrained_set0_flag =
		(bool)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	sps_header.constrained_set1_flag =
		(bool)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	sps_header.constrained_set2_flag =
		(bool)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	sps_header.constrained_set3_flag =
		(bool)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	sps_header.constrained_set4_flag =
		(bool)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	sps_header.constrained_set5_flag =
		(bool)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	vpas_readbits(rbsp_bitstream_inst, VALUE_2);//u(2)
	sps_header.level_idc =
		vpas_readbits(rbsp_bitstream_inst, VALUE_8);
	sps_header.seq_parameter_set_id =
		vpas_uecodenum(rbsp_bitstream_inst);
	if (CHKPARAM(sps_header.seq_parameter_set_id, H264_MAX_SPS_NUM))
		goto RETURN;

	// valid sps
	p_SPS = &g_h264_sps[sps_header.seq_parameter_set_id];
	*p_SPS = sps_header;

	if (h264_check_profile(p_SPS)) {
		p_SPS->chroma_format_idc =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		if (CHKPARAM(p_SPS->chroma_format_idc, VALUE_3))
			goto RETURN;
		if (p_SPS->chroma_format_idc == YUV444) { //YUV444 == 3
			vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
		}
		p_SPS->bitdepth_luma_minus8 =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		if (CHKPARAM(p_SPS->bitdepth_luma_minus8, VALUE_4))
			goto RETURN;
		p_SPS->bitdepth_chroma_minus8 =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		if (CHKPARAM(p_SPS->bitdepth_chroma_minus8, VALUE_4))
			goto RETURN;

		vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
		p_SPS->seqscaling_matrix_present_flag =
			(bool)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
		if (p_SPS->seqscaling_matrix_present_flag) {
			for (index = 0; index < VALUE_8; index++) {
				p_SPS->seqscalinglist_present_flag[index] =
					(bool)vpas_readbits(
						rbsp_bitstream_inst, 1);//u(1)
				// do not have to set calinglist
			}
		}
	}

	p_SPS->log2_max_framenum_minus4 =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	if (CHKPARAM(p_SPS->log2_max_framenum_minus4, VALUE_12))
		goto RETURN;
	p_SPS->max_framenum = VALUE_2 << (p_SPS->log2_max_framenum_minus4 + VALUE_4 - 1);
	p_SPS->picordercnt_type = vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	if (CHKPARAM(p_SPS->picordercnt_type, VALUE_2))
		goto RETURN;
	if (p_SPS->picordercnt_type == 0) {
		p_SPS->log2_max_picordercnt_lsb_minus4 =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		if (CHKPARAM(p_SPS->log2_max_picordercnt_lsb_minus4, VALUE_12))
			goto RETURN;
	} else if (p_SPS->picordercnt_type == 1) {
		p_SPS->delta_picorder_alwayszero_flag =
			(bool)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
		p_SPS->offset_for_non_refpic =
			vpas_secodenum(rbsp_bitstream_inst);//se(v)
		p_SPS->offset_for_top_to_bottom_field =
			vpas_secodenum(rbsp_bitstream_inst);//se(v)
		p_SPS->numref_frames_in_picordercnt_cycle =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		if (CHKPARAM(p_SPS->numref_frames_in_picordercnt_cycle, VALUE_255))
			goto RETURN;
		for (index = 0 ; index < p_SPS->numref_frames_in_picordercnt_cycle; index++) {
			p_SPS->offset_for_ref_frame[index] =
				vpas_secodenum(rbsp_bitstream_inst);//se(v)
		}
	}
	p_SPS->num_refframes = vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	if (CHKPARAM(p_SPS->num_refframes, VALUE_16))
		goto RETURN;
	p_SPS->gaps_in_framenum_value_allowed_flag =
		(bool)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	p_SPS->pic_width_in_mbs_minus1 =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	p_SPS->pic_height_in_mapunits_minus1 =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	p_SPS->frame_mbs_Only_flag =
		(bool)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	p_SPS->valid = 1;
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE, "valid sps: %d\n",
		p_SPS->seq_parameter_set_id);
	return VDEC_HAL_RET_OK;
RETURN:
	if (p_SPS != NULL)
		p_SPS->valid = 0;
	return ret_value;
}

// parse h264 i/p/b slice type
signed int vdec_com_h264_sw_parsenal(
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct AVC_ES_UNIT *curCachedUnit)
{
#define nal_ref_idc_mask 0x60
	unsigned int ret_value = (unsigned int)VDEC_HAL_RET_OK;
	unsigned char nal_unit_type = 0;
	unsigned char nal_ref_idc = 0;


	nal_ref_idc = curCachedUnit->unitType & nal_ref_idc_mask;
	nal_unit_type = curCachedUnit->unitType & 0x1f; // avc
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_INFO,
		"%s nal_type: %d\n", __func__, nal_unit_type);
	switch (nal_unit_type) {
	case NON_IDR_SLICE:
	case IDR_SLICE:
	case CODED_SLICE_EXT:
		ret_value = vdec_sw_psr_h264_slice_type(nal_unit_type,
			nal_ref_idc,
			rbsp_bitstream_inst, curCachedUnit);
		if (ret_value == 0) {
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_INFO,
				"%s h264 OK\n", __func__);
		}
		break;
	case PPS:
		ret_value = vdec_com_sw_psr_h264_pps(rbsp_bitstream_inst);
		break;
	case SPS:
		ret_value = vdec_com_sw_psr_h264_sps(rbsp_bitstream_inst);
		break;
	default:
		break;
	}

	return (signed int)ret_value;
}

//	Note : magic number
//	1. Sw parse header in logic flow and get bits by syntax spec
//	2. Confirm parsing value is reasonable by spec
unsigned int vdec_sw_psr_h264_slice_type(
	unsigned char nal_unit_type,
	unsigned char nal_ref_idc,
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct AVC_ES_UNIT *curCachedUnit)
{
#define VALID_SLICE_TYPE_VALUE 9
#define CODED_SLICE_EXT_SIZE 24
	unsigned int ret_value = (unsigned int)VDEC_HAL_RET_OK;
	struct h264_sps_data *p_SPS = NULL;
	struct h264_slice_data slice;

	memset(&slice, 0, sizeof(slice));

	if (nal_unit_type == CODED_SLICE_EXT)
		vpas_readbits(rbsp_bitstream_inst,
			CODED_SLICE_EXT_SIZE);   //arse ext code ,

	slice.is_ref = fgIsRefPic(nal_ref_idc);
	slice.first_mb_in_slice = vpas_uecodenum(rbsp_bitstream_inst);
	slice.slice_type = vpas_uecodenum(rbsp_bitstream_inst);
	if (CHKPARAM(slice.slice_type, VALID_SLICE_TYPE_VALUE))
		goto RETURN;
	slice.pic_params_set_id = vpas_uecodenum(rbsp_bitstream_inst);

	PAS_DEBUG_LOG(PAS_LOG_LEVEL_INFO,
		"slice_type: %d pps: %d\n", slice.slice_type, slice.pic_params_set_id);
	if (g_h264_pps[slice.pic_params_set_id].valid) {
		slice.seq_params_set_id = g_h264_pps[slice.pic_params_set_id].seq_params_set_id;
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_INFO,
			"sps: %d\n", g_h264_pps[slice.pic_params_set_id].seq_params_set_id);
		if (g_h264_sps[slice.seq_params_set_id].valid)
			p_SPS = &g_h264_sps[slice.seq_params_set_id];
		else {
			if (PSRERR())
				goto RETURN;
		}
	} else {
		if (PSRERR())
			goto RETURN;
	}

	// no support separte_colour_plane_flag == 1 it is for 4:4:4

	slice.frame_num = vpas_readbits(rbsp_bitstream_inst,
		p_SPS->log2_max_framenum_minus4+VALUE_4);

	if (!p_SPS->frame_mbs_Only_flag) {
		slice.field_pic_flag = vpas_readbits(rbsp_bitstream_inst, 1);
		if (slice.field_pic_flag)
			slice.bottom_field_flag = vpas_readbits(rbsp_bitstream_inst, 1);
	}

	// init unitInfo
	curCachedUnit->unitInfo.f.bIFrame = 0;
	curCachedUnit->unitInfo.f.field_pic_flag = slice.field_pic_flag;
	curCachedUnit->unitInfo.f.bottom_field_flag = slice.bottom_field_flag;
	curCachedUnit->unitInfo.f.is_ref = slice.is_ref;
	curCachedUnit->frame_num = slice.frame_num;

	if (IS_SLICE(slice.slice_type)) {
		curCachedUnit->unitInfo.f.bIFrame = 1;
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
		"%s I_SLICE first_mb_in_slice: %d, slice_type: %d\n",
		__func__, slice.first_mb_in_slice, slice.slice_type);
	} else if (IS_P_SLICE(slice.slice_type)) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_INFO,
		"%s P_SLICE first_mb_in_slice: %d, slice_type: %d\n",
		__func__, slice.first_mb_in_slice, slice.slice_type);
	} else if (IS_B_SLICE(slice.slice_type)) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_INFO,
		"%s B_SLICE first_mb_in_slice: %d, slice_type: %d\n",
		__func__, slice.first_mb_in_slice, slice.slice_type);
	}
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_INFO,
			"frame_num: %d is_ref: %d field_pic_flag: %d bottom_field_flag: %d\n",
			slice.frame_num, slice.is_ref,
			slice.field_pic_flag, slice.bottom_field_flag);

RETURN:
	return ret_value;
}

// do ue(v)
unsigned int vpas_uecodenum(
	struct rbsp_bitstream *p_rbsp_bitstream)
{
#define INT_BYTE_SIZE 32
	unsigned int uival = 0;
	unsigned int uicode = 0;
	unsigned int uilength = 0;

	uicode = vpas_readbits(p_rbsp_bitstream, 1);

	if (uicode == 0) {
		uilength = 0;

		while (!(uicode & 1)) {
			uicode = vpas_readbits(p_rbsp_bitstream, 1);
			uilength++;
			if (uilength >= INT_BYTE_SIZE) {
				PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR, "fail ue > 32 bits\n");
				return 0;
			}
		}

		uival = vpas_readbits(p_rbsp_bitstream, uilength);
		uival += (1 << uilength) - 1;
	}

	return uival;
}

// do se(v)
signed int vpas_secodenum(struct rbsp_bitstream *rbsp_bitstream_inst)
{
	unsigned int uibits = vpas_readbits(rbsp_bitstream_inst, 1);
	signed int v = 0;

	if (uibits == 0) {
		unsigned int uilength = 0;

		while (!(uibits & 1)) {
			uibits = vpas_readbits(rbsp_bitstream_inst, 1);
			uilength++;
			if (uilength >= VALUE_32) {
				PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR, "fail se > 32 bits\n");
				return 0;
			}
		}

		uibits = vpas_readbits(rbsp_bitstream_inst, uilength);

		uibits += (1 << uilength);
		v = (uibits & 1) ? -(signed int)(uibits >> 1) : (signed int)(uibits >> 1);
	}

	return v;
}

// read bits from es
unsigned int vpas_readbits(
	struct rbsp_bitstream *p_rbsp_bitstream,
	unsigned int bits)
{
	unsigned int value = 0;
	unsigned int bits_read = 0;
	signed int cont0 = 0;

	if (vpas_rawnextbits(p_rbsp_bitstream, bits, &value, &bits_read,
			&cont0))
		return 0;

	p_rbsp_bitstream->bits_read += bits_read;
	p_rbsp_bitstream->cont0 = cont0;

	return value;
}

signed int vpas_rawnextbits(
	struct rbsp_bitstream *p_rbsp_bitstream,
	unsigned int bits,
	unsigned int *p_value,
	unsigned int *p_bits_read,
	signed int *p_cont0)
{
	unsigned int bits_read = 0;
	unsigned int bits_want = 0;
	unsigned int bits_remain = 0;
	unsigned int idx = 0;
	unsigned int value = 0;
	unsigned int u4raw_byte = 0;
	unsigned int remove_03 = 0;
	signed int cont0 = 0;

	if (bits == 0)
		return 0;

	if (bits == 0 || bits > INT_BYTE_SIZE) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR, "error bits (0x%x)\n", bits);
		//ASSERT(bits > 0 && bits <= 32);
		return -1;
	}

	// remove 03

	bits_read = 0;
	bits_want = bits;
	bits_remain = BYTE_SIZE - (p_rbsp_bitstream->bits_read & (BYTE_SIZE-1));
	idx = (p_rbsp_bitstream->bits_read) >> BYTE_SHIFT;
	remove_03 = p_rbsp_bitstream->remove_03;
	cont0 = p_rbsp_bitstream->cont0;

	(void)remove_03;

	while (bits_want > 0) {
		if (idx >= p_rbsp_bitstream->stored_cache_size)
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR, "ERROR!! over stored_cache_size\n");

		u4raw_byte = p_rbsp_bitstream->cache[idx % CACHE_SIZE];

		if (p_rbsp_bitstream->disable_emulation_prevention)
			cont0 = 0;

		// skip remove 03 byte
		if (cont0 > 1 && u4raw_byte == EMULATION_PREVENTION_VALUE) {
			//ASSERT(bits_remain == 8);
			remove_03++;
			cont0 = 0;
			bits_read += bits_remain;
			idx++;
			continue;
		}

		// Check curret byte's remain bits
		if (bits_remain > bits_want) {
			value <<= bits_want;
			value |= ((u4raw_byte & ((1 << bits_remain) - 1))
				>> (bits_remain - bits_want));
			bits_read += bits_want;
			bits_want = 0;
			break;
		}
		// Current byte's bits has all been read
		value <<= bits_remain;
		value |= (u4raw_byte & ((1 << bits_remain) - 1));

		if (u4raw_byte == 0)
			cont0++;
		else
			cont0 = 0;


		bits_read += bits_remain;
		bits_want -= bits_remain;
		bits_remain = BYTE_SIZE;
		idx++;
	}

	//vdec_printf(p_rbsp_bitstream->p_comhal_handle, VDEC_HAL_LOGI, "value 0x%x\n", value);

	if (p_value)
		*p_value = value;

	if (p_cont0)
		*p_cont0 = cont0;

	if (p_bits_read)
		*p_bits_read = bits_read;

	p_rbsp_bitstream->remove_03 = remove_03;

	if (p_rbsp_bitstream->bits_read + bits_read > p_rbsp_bitstream->bits_write) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE,
			"read underflow write 0x%x read 0x%x want 0x%x actually read 0x%x, cont0 %u remove_03 %u\n",
		p_rbsp_bitstream->bits_write,
		p_rbsp_bitstream->bits_read,
		bits,
		bits_read,
		cont0,
		remove_03);
	}

	return 0;
}

// TODO get data from cur unit reserve0
static void h265_decoder_decode_nal_unit_header(
	struct h265_nal_unit_header *nal_unit_header,
	unsigned int nalu_val)
{
	//(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);
	nal_unit_header->forbidden_zero_bit = GET_BITS(nalu_val, VALUE_15, VALUE_1);
	//(unsigned char)vpas_readbits(rbsp_bitstream_inst, 6);
	nal_unit_header->nal_unit_type = GET_BITS(nalu_val, VALUE_9, VALUE_6);
	//(unsigned char)vpas_readbits(rbsp_bitstream_inst, 6);
	nal_unit_header->nuh_layer_id = GET_BITS(nalu_val, VALUE_3, VALUE_6);
	//(unsigned char)vpas_readbits(rbsp_bitstream_inst, 3);
	nal_unit_header->nuh_temporal_id_plus1 = GET_BITS(nalu_val, VALUE_0, VALUE_3);
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
						"nalu unit header %d, %d, %d, %d\n",
						nal_unit_header->forbidden_zero_bit,
						nal_unit_header->nal_unit_type,
						nal_unit_header->nuh_layer_id,
						nal_unit_header->nuh_temporal_id_plus1);
}

#define IsH265IRap(NalType) ((NalType) >= NAL_UNIT_CODED_SLICE_BLA && \
	(NalType) <= NAL_UNIT_RESERVED_IRAP_VCL23)
// TODO add function to parse  profile_present_flag
#define CHECK_GEN_PTL1 (p_PTL->general_PTL.profile_idc == H265_Format_Range_Extensions_Profiles \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_Format_Range_Extensions_Profiles] \
|| p_PTL->general_PTL.profile_idc == H265_High_Throughput_Profiles \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_High_Throughput_Profiles] \
|| p_PTL->general_PTL.profile_idc == VALUE_6 \
|| p_PTL->general_PTL.profile_compatibility_flag[VALUE_6] \
|| p_PTL->general_PTL.profile_idc == VALUE_7 \
|| p_PTL->general_PTL.profile_compatibility_flag[VALUE_7] \
|| p_PTL->general_PTL.profile_idc == VALUE_8 \
|| p_PTL->general_PTL.profile_compatibility_flag[VALUE_8] \
|| p_PTL->general_PTL.profile_idc == H265_Screen_Content_Coding_Extensions_Profiles \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_Screen_Content_Coding_Extensions_Profiles] \
|| p_PTL->general_PTL.profile_idc == VALUE_10 \
|| p_PTL->general_PTL.profile_compatibility_flag[VALUE_10])

#define CHECK_GEN_PTL2 (p_PTL->general_PTL.profile_idc == H265_High_Throughput_Profiles \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_High_Throughput_Profiles] \
|| p_PTL->general_PTL.profile_idc == H265_Screen_Content_Coding_Extensions_Profiles \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_Screen_Content_Coding_Extensions_Profiles] \
/*|| p_PTL->general_PTL.profile_idc == 10 || p_PTL->general_PTL.profile_compatibility_flag[10]*/)


static int vdec_com_h265_parse_general_ptl(
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct h265_ptl_data *p_PTL)
{
	if (CHECK_GEN_PTL1) {
		p_PTL->general_PTL.general_max_12bit_constraint_flag =
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.general_max_10bit_constraint_flag =
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.general_max_8bit_constraint_flag =
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.general_max_422_chroma_constraint_flag =
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.general_max_420_chroma_constraint_flag =
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.general_max_mono_chroma_constraint_flag =
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.general_intra_constraint_flag =
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.general_one_picture_only_constraint_flag =
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.general_lower_bit_rate_constraint_flag =
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		if (CHECK_GEN_PTL2) {
			p_PTL->general_PTL.general_max_14bit_constraint_flag =
				vpas_readbits(rbsp_bitstream_inst, VALUE_1);
			vpas_readbits(rbsp_bitstream_inst, VALUE_32);
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		} else {
			vpas_readbits(rbsp_bitstream_inst, VALUE_32);
			vpas_readbits(rbsp_bitstream_inst, VALUE_2);
		}
		return 1;
	}
	return 0;
}
#define H265_SCCEP H265_Screen_Content_Coding_Extensions_Profiles
#define CHECK_SUB_PTL1 ( \
p_PTL->sub_layer_PTL[i4Idx].profile_idc == H265_Format_Range_Extensions_Profiles \
|| p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[H265_Format_Range_Extensions_Profiles] \
|| p_PTL->sub_layer_PTL[i4Idx].profile_idc == H265_High_Throughput_Profiles \
|| p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[H265_High_Throughput_Profiles] \
|| p_PTL->sub_layer_PTL[i4Idx].profile_idc == VALUE_6 \
|| p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[VALUE_6] \
|| p_PTL->sub_layer_PTL[i4Idx].profile_idc == VALUE_7 \
|| p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[VALUE_7] \
|| p_PTL->sub_layer_PTL[i4Idx].profile_idc == VALUE_8 \
|| p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[VALUE_8] \
|| p_PTL->sub_layer_PTL[i4Idx].profile_idc == H265_SCCEP \
|| p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[H265_SCCEP] \
|| p_PTL->sub_layer_PTL[i4Idx].profile_idc == VALUE_10 \
|| p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[VALUE_10])

#define CHECK_SUB_PTL2 (p_PTL->sub_layer_PTL[i4Idx].profile_idc \
== H265_High_Throughput_Profiles \
|| p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[H265_High_Throughput_Profiles]  \
|| p_PTL->sub_layer_PTL[i4Idx].profile_idc == H265_SCCEP \
|| p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[H265_SCCEP] \
|| p_PTL->sub_layer_PTL[i4Idx].profile_idc == VALUE_10 \
|| p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[VALUE_10])

void vdec_com_h265_parse_sub_ptl(struct rbsp_bitstream *rbsp_bitstream_inst,
	struct h265_ptl_data *p_PTL, int i4Idx)
{
	int i;

	if (i4Idx < 0 || i4Idx >= VALUE_6)
		return;

	p_PTL->sub_layer_PTL[i4Idx].profile_space =
		vpas_readbits(rbsp_bitstream_inst, VALUE_2);  // u(2)
	p_PTL->sub_layer_PTL[i4Idx].tier_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst,
			VALUE_1);  // u(1)
	p_PTL->sub_layer_PTL[i4Idx].profile_idc =
		vpas_readbits(rbsp_bitstream_inst, VALUE_5);  // u(5)

	for (i = 0; i < VALUE_32; i++) {
		p_PTL->sub_layer_PTL[i4Idx].profile_compatibility_flag[i] =
			(unsigned char)vpas_readbits(
				rbsp_bitstream_inst, VALUE_1);  // u(1)
	}

	p_PTL->sub_layer_PTL[i4Idx].progressive_source_flag = (unsigned char)
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);  // u(1)
	p_PTL->sub_layer_PTL[i4Idx].interlaced_source_flag = (unsigned char)
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);  // u(1)
	p_PTL->sub_layer_PTL[i4Idx].non_packed_constraint_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);  // u(1)
	p_PTL->sub_layer_PTL[i4Idx].frame_only_constraint_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);  // u(1)

	if (CHECK_SUB_PTL1) {
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		if (CHECK_SUB_PTL2) {
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
			vpas_readbits(rbsp_bitstream_inst, VALUE_32);
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		} else {
			vpas_readbits(rbsp_bitstream_inst, VALUE_32);
			vpas_readbits(rbsp_bitstream_inst, VALUE_2);
		}
	} else {
		vpas_readbits(rbsp_bitstream_inst, VALUE_32);
		vpas_readbits(rbsp_bitstream_inst, VALUE_11);
	}

	// sub_layer_inbld_flag or sub_layer_reserved_zero_bit
	vpas_readbits(rbsp_bitstream_inst, VALUE_1);
}
#define CHECK_PTL_RBSP1 ((p_PTL->general_PTL.profile_idc >= H265_Main_Profile \
&& p_PTL->general_PTL.profile_idc <= H265_High_Throughput_Profiles) \
|| p_PTL->general_PTL.profile_idc == H265_Screen_Content_Coding_Extensions_Profiles \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_Main_Profile] \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_Main10_Profile] \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_Main_StillPic_Profile] \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_Format_Range_Extensions_Profiles] \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_High_Throughput_Profiles] \
|| p_PTL->general_PTL.profile_compatibility_flag[H265_Screen_Content_Coding_Extensions_Profiles])
static int vdec_com_h265_ptl_rbsp(
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct h265_ptl_data *p_PTL,
	int max_num_sub_layers_minus1)
{
	int i4tmp = 0;
	int i = 0;
	int i4Idx  = 0;

	if (max_num_sub_layers_minus1 > VALUE_6) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR, "%s max_num_sub_layers_minus1: %d\n",
			__func__, max_num_sub_layers_minus1);
		return SYNTAX_ERROR;
	}

	if (p_PTL->profile_present_flag) {
		p_PTL->general_PTL.profile_space =
			vpas_readbits(
			rbsp_bitstream_inst, VALUE_2);  // u(2)
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE, "profile_space: %d\n",
				p_PTL->general_PTL.profile_space);
		p_PTL->general_PTL.tier_flag =
			(unsigned char)vpas_readbits(
			rbsp_bitstream_inst, VALUE_1);  // u(1)
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE, "tier_flag: %d\n",
				p_PTL->general_PTL.tier_flag);
		p_PTL->general_PTL.profile_idc =
			vpas_readbits(
			rbsp_bitstream_inst, VALUE_5);  // u(5)
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE, "profile_idc: %d\n",
				p_PTL->general_PTL.profile_idc);
		for (i = 0; i < VALUE_32; i++) {
			p_PTL->general_PTL.profile_compatibility_flag[i] =
				(unsigned char)vpas_readbits(
					rbsp_bitstream_inst, VALUE_1);
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
				"p_PTL->general_PTL.profile_compatibility_flag[%d]: %d\n",
				i,
				p_PTL->general_PTL.profile_compatibility_flag[i]);
		}

		p_PTL->general_PTL.progressive_source_flag =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.interlaced_source_flag =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.non_packed_constraint_flag =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		p_PTL->general_PTL.frame_only_constraint_flag =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
						"p_PTL->general_PTL.progressive_source_flag: %d "
						"interlaced_source_flag: %d "
						"non_packed_constraint_flag: %d "
						"frame_only_constraint_flagL %d\n",
						p_PTL->general_PTL.progressive_source_flag,
						p_PTL->general_PTL.interlaced_source_flag,
						p_PTL->general_PTL.non_packed_constraint_flag,
						p_PTL->general_PTL.frame_only_constraint_flag);

		if (vdec_com_h265_parse_general_ptl(rbsp_bitstream_inst, p_PTL)) {
			// do nothing
			// have done in vdec_com_h265_parse_general_ptl for
			// character cannot over 100 in one line
		} else if (p_PTL->general_PTL.profile_idc == H265_Main10_Profile
		|| p_PTL->general_PTL.profile_compatibility_flag[H265_Main10_Profile]) {
			vpas_readbits(rbsp_bitstream_inst, VALUE_7);
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
			vpas_readbits(rbsp_bitstream_inst, VALUE_32);
			vpas_readbits(rbsp_bitstream_inst, VALUE_3);
		} else {
			vpas_readbits(rbsp_bitstream_inst, VALUE_32);
			vpas_readbits(rbsp_bitstream_inst, VALUE_11);
		}

		if (CHECK_PTL_RBSP1) {
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		} else {
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);
			//u4VDecGetBits("general_reserved_zero_bit", bs, 1);
		}

	}

	p_PTL->general_PTL.level_idc =
		vpas_readbits(rbsp_bitstream_inst, VALUE_8);  // u(8)
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE,
						"level_idc: %d\n",
						p_PTL->general_PTL.level_idc);

	// parse sub layer part for profile tier level (ptl)
	for (i4Idx = 0; i4Idx < max_num_sub_layers_minus1 && i4Idx < VALUE_6; i4Idx++) {
		p_PTL->sub_layer_profile_present_flag[i4Idx] =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst,
				VALUE_1);  // u(1)
		p_PTL->sub_layer_level_present_flag[i4Idx] =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst,
				VALUE_1);  // u(1)
	}

	if (max_num_sub_layers_minus1 > VALUE_0) {
		for (i4Idx = max_num_sub_layers_minus1; i4Idx < VALUE_8; i4Idx++) {
			i4tmp = vpas_readbits(rbsp_bitstream_inst, VALUE_2); // u(2)
			if (i4tmp) {
				PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
					"[VDEC-H265-ERR] Reserved 2bit conflict\n");
				return SYNTAX_ERROR;
			}
		}
	}

	// sub level
	for (i4Idx = 0; i4Idx < max_num_sub_layers_minus1 && i4Idx < VALUE_6; i4Idx++) {
		if (p_PTL->profile_present_flag
			&& p_PTL->sub_layer_profile_present_flag[i4Idx])
			vdec_com_h265_parse_sub_ptl(rbsp_bitstream_inst, p_PTL, i4Idx);

		if (p_PTL->sub_layer_level_present_flag[i4Idx]) {
			p_PTL->sub_layer_PTL[i4Idx].level_idc =
				vpas_readbits(rbsp_bitstream_inst, VALUE_8);  // u(8)
		}
	}

	return SYNTAX_OK;
}

static void vdec_com_h265_init_sps(struct h265_sps_data *p_sps)
{
	int i;
	//signed int ****pi4SPSScalingList = NULL;

	p_sps->max_cu_width = VALUE_32;
	p_sps->max_cu_height = VALUE_32;
	p_sps->u4MaxCUDepth = VALUE_3;
	p_sps->pcm_log2_luma_max_size = VALUE_5;
	p_sps->pcm_log2_luma_min_size_minus3 = VALUE_4;
	p_sps->chroma_format_idc = VALUE_1;
	p_sps->bit_depth_luma_minus8 = VALUE_0;
	p_sps->bit_depth_chroma_minus8 = VALUE_0;
	p_sps->pcm_bit_depth_luma_minus1 = VALUE_7;
	p_sps->pcm_bit_depth_chroma_minus1 = VALUE_7;
	p_sps->bit_depth_luma_minus8 = VALUE_0;
	p_sps->bit_depth_chroma_minus8 = VALUE_0;
	p_sps->log2_max_pic_order_cnt_lsb_minus4 = VALUE_4;
	p_sps->u4MaxTrSize = VALUE_32;
	p_sps->num_long_term_ref_pic_sps = VALUE_0;
	p_sps->num_short_term_ref_pic_sets = VALUE_0;
	//p_sps->u4NumRefFrames = 0;

	for (i = 0; i < MAX_TLAYER; i++) {
		p_sps->max_latency_increase[i] = 0;
		p_sps->max_dec_pic_buffering[i] = 1;
		p_sps->num_reorder_pics[i] = 0;
	}

	// init scaling list
	if (p_sps->sps_id >= H265_MAX_SPS_NUM) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
			"Sps ID too large, reallocate scaling list arry!\n");
	}
	p_sps->sl_init = VALUE_1;
}
static int parse_sps_pic_format(struct rbsp_bitstream *rbsp_bitstream_inst,
	struct h265_sps_data *p_sps)
{
	p_sps->update_rep_format_flag = false;
	p_sps->chroma_format_idc =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
						"chroma_format_idc %d\n",
						p_sps->chroma_format_idc);

	if (p_sps->chroma_format_idc != 1) {
		// support 4:2:0 only
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
			"[VDEC-H265-ERR] Unsupported chroma format idc %u\n",
			p_sps->chroma_format_idc);
		return SPS_CHROMA_FORMAT_IDC_NOT_SUPPORT;
	}

	if (p_sps->chroma_format_idc == 1) {
		p_sps->sub_width_c = VALUE_2;
		p_sps->sub_height_c = VALUE_2;
	} else {
		return SYNTAX_ERROR;
	}

	p_sps->pic_width_in_luma_samples =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	p_sps->pic_height_in_luma_samples =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	p_sps->conformance_window_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);
	if (p_sps->conformance_window_flag) {
		p_sps->conformance_win_left_offset =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		p_sps->conformance_win_right_offset =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		p_sps->conformance_win_top_offset =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		p_sps->conformance_win_bottom_offset =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	}
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE,
			"[VDEC-H265-ERR] width: %d, height: %d, conformance_window_flag: %d\n",
			p_sps->pic_width_in_luma_samples,
			p_sps->pic_height_in_luma_samples,
			p_sps->conformance_window_flag);
	p_sps->frame_crop_left_offset = p_sps->conformance_win_left_offset *
		p_sps->sub_width_c;
	p_sps->frame_crop_right_offset = p_sps->conformance_win_right_offset *
		p_sps->sub_width_c;
	p_sps->frame_crop_top_offset = p_sps->conformance_win_top_offset *
		p_sps->sub_height_c;
	p_sps->frame_crop_bottom_offset = p_sps->conformance_win_bottom_offset *
		p_sps->sub_height_c;

	if (p_sps->pic_width_in_luma_samples == 0
		|| p_sps->pic_height_in_luma_samples == 0
		|| (p_sps->frame_crop_left_offset + p_sps->frame_crop_right_offset
			>= p_sps->pic_width_in_luma_samples)
		|| (p_sps->frame_crop_top_offset + p_sps->frame_crop_bottom_offset
			>= p_sps->pic_height_in_luma_samples)) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE,
			"[VDEC-H265-ERR] W %u H %u L %u R %u T %u B %u\n",
			p_sps->pic_width_in_luma_samples,
			p_sps->pic_height_in_luma_samples,
			p_sps->frame_crop_left_offset,
			p_sps->frame_crop_right_offset,
			p_sps->frame_crop_top_offset,
			p_sps->frame_crop_bottom_offset);
		return SPS_RESOLUTION;
	}

	p_sps->bit_depth_luma_minus8 =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	p_sps->qpbd_offset_y =
		(unsigned int) VALUE_6 * (p_sps->bit_depth_luma_minus8+VALUE_8);

	p_sps->bit_depth_chroma_minus8 =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	p_sps->qpbd_offset_c =
		(unsigned int) VALUE_6 * (p_sps->bit_depth_chroma_minus8+VALUE_8);
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE,
				"[VDEC-H265-ERR] bit_depth_luma_minus8: %d, bit_depth_chroma_minus8: %d\n",
				p_sps->bit_depth_luma_minus8,
				p_sps->bit_depth_chroma_minus8);

	// only support 0, 2 (8,10 bit)
	if (p_sps->bit_depth_luma_minus8 == 0 && p_sps->bit_depth_chroma_minus8 == 0) {
		//prH265DecPrm->ucMain10Mode = HEVC_8BIT_MODE;
	} else if (p_sps->bit_depth_luma_minus8 == VALUE_2
		&& p_sps->bit_depth_chroma_minus8 == VALUE_2) {
		//LOG(0, "[VDEC-H265-ERR] bit depth not support\n");
		//return SPS_BITDEPTH_NOT_SUPPORT;
	} else {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
			"[VDEC-H265-ERR] bit depth not support\n");
		return SPS_BITDEPTH_NOT_SUPPORT;
	}
	return 0;
}
unsigned char *vdec_h265_get_sl_address(
	struct h265_sl_data *p_sl_data,
	unsigned int size,
	unsigned int list)
{
	if (size == SCALING_LIST_32x32 && list == VALUE_3) {
		// u4Size = SCALING_LIST_32x32;
		list = 1;
	}

	if ((size < SCALING_LIST_SIZE_NUM) &&
		(list < SCALING_LIST_NUM))
		return &p_sl_data->scaling_list_delta_coef[size][list][0];
	else
		return NULL;
}

unsigned char *vdec_h265_get_sl_default_address(int size_id, int list_id)
{
	unsigned char *src = 0;

	switch (size_id) {
	case SCALING_LIST_4x4:
		src = h265_quant_ts_default_4x4;
		break;
	case SCALING_LIST_8x8:
		src = (list_id < VALUE_3) ? h265_quant_intra_default_8x8 :
			h265_quant_inter_default_8x8;
		break;
	case SCALING_LIST_16x16:
		src = (list_id < VALUE_3) ? h265_quant_intra_default_8x8 :
			h265_quant_inter_default_8x8;
		break;
	case SCALING_LIST_32x32:
		src = (list_id < VALUE_1) ? h265_quant_intra_default_8x8 :
			h265_quant_inter_default_8x8;
		break;
	default:
		src = h265_quant_ts_default_4x4;
		break;
	}
	return src;
}
bool h265_rps_rbsp_condition1(struct h265_rps_data *p_rps)
{
	return p_rps->num_of_negative_pics > VALUE_16 ||
		p_rps->num_of_positive_pics > VALUE_16 ||
		((p_rps->num_of_negative_pics + p_rps->num_of_positive_pics) > VALUE_16);
}
unsigned int  vdec_h265_rps_rbsp(
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct h265_sps_data *p_sps,
	struct h265_rps_data *p_rps,
	unsigned int index)
{
	unsigned int code, bit, ref_idc;
	int ref_index;
	bool used;
	struct h265_rps_data *ref_rps = NULL;

	int k = 0;
	int k0 = 0;
	int k1 = 0;
	int delta_rps, delta_poc, i, j;
	int temp, num_neg_pics;
	int prev, poc;

	// reset p_rps
	p_rps->num_of_negative_pics = 0;
	p_rps->num_of_positive_pics = 0;
	p_rps->num_of_pics = 0;
	p_rps->num_of_long_term_pics = 0;
	//p_rps->u4DeltaRIdxMinus1 = 0;
	//p_rps->u4DeltaRPS = 0;
	p_rps->inter_rps_prediction = 0;
	p_rps->num_ref_idc = 0;


	if (index > 0)
		p_rps->inter_rps_prediction =
		(unsigned char) vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	else
		p_rps->inter_rps_prediction = 0;

	//inter_rps_pred = p_rps->bInterRPSPrediction;

	if (p_rps->inter_rps_prediction) {
		if (index ==  p_sps->num_short_term_ref_pic_sets)
			code = vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
		else
			code = 0;


		if (code > index - 1)
			return SPS_RPS_SYNTAX_ERROR;


		ref_index = index - 1 - code;
		if (ref_index > (signed int) (index - 1) || ref_index < 0)
			return SPS_RPS_SYNTAX_ERROR;

		ref_rps = &p_sps->short_term_ref_pic_sets[ref_index];

		if (ref_rps == NULL)
			return SPS_RPS_SYNTAX_ERROR;


		bit = vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
		code = vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
		delta_rps = (1 - (bit << 1)) * (code + 1);  // delta_RPS

		p_sps->str_num_delta_pocs = (signed int)(ref_rps->num_of_negative_pics +
				ref_rps->num_of_positive_pics);

		for (i = 0;
			i <= (signed int)(ref_rps->num_of_negative_pics +
				ref_rps->num_of_positive_pics); i++) {
			bit = vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
			ref_idc = bit;
			if (ref_idc == 0) {
				bit = vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
				// second bit is "1" if ref_idc is 2, "0" if ref_idc = 0.
				ref_idc = bit << 1;
			}
			if (ref_idc == 1 || ref_idc == VALUE_2) {
				delta_poc = delta_rps + ((i <
					(signed int)(ref_rps->num_of_negative_pics +
					ref_rps->num_of_positive_pics))
					? ref_rps->delta_poc[i] : 0);
				p_rps->delta_poc[k] = delta_poc;
				p_rps->used[k] = (ref_idc == 1);

				if (delta_poc < 0)
					k0++;
				else
					k1++;
				k++;
			}
			p_rps->ref_idc[i] = ref_idc;
		}

		p_rps->num_ref_idc = ref_rps->num_of_pics + 1;
		p_rps->num_of_pics = k;
		p_rps->num_of_negative_pics = k0;
		p_rps->num_of_positive_pics = k1;

		// sort in increasing order (smallest first)
		for (j = 1; j < (signed int) p_rps->num_of_pics; j++) {
			delta_poc = p_rps->delta_poc[j];
			used = p_rps->used[j];
			for (k = j-1; k >= 0; k--) {
				temp = p_rps->delta_poc[k];
				if (delta_poc < temp) {
					p_rps->delta_poc[k+1] = temp;
					p_rps->used[k+1] = p_rps->used[k];
					p_rps->delta_poc[k] = delta_poc;
					p_rps->used[k] = used;
				}
			}
		}
		// flip the negative values to largest first
		num_neg_pics = p_rps->num_of_negative_pics;
		for (j = 0, k = num_neg_pics - 1; j < num_neg_pics>>1; j++, k--) {
			delta_poc = p_rps->delta_poc[j];
			used = p_rps->used[j];
			p_rps->delta_poc[j] = p_rps->delta_poc[k];
			p_rps->used[j] = p_rps->used[k];
			p_rps->delta_poc[k] = delta_poc;
			p_rps->used[k] = used;
		}
	} else {
		p_rps->num_of_negative_pics =
			vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
		p_rps->num_of_positive_pics =
			vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)

		if (h265_rps_rbsp_condition1(p_rps)) {
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE,
				"%s %d num_of_negative_pics %u num_of_positive_pics %u\n",
				__func__, __LINE__,
				p_rps->num_of_negative_pics, p_rps->num_of_positive_pics);
			return SPS_RPS_SYNTAX_ERROR;
		}

		p_sps->str_num_negtive_pos_pics = p_rps->num_of_negative_pics +
			p_rps->num_of_positive_pics;
		p_sps->max_str_num_negtive_pos_pics = (p_sps->max_str_num_negtive_pos_pics <
				p_sps->str_num_negtive_pos_pics)
			? p_sps->str_num_negtive_pos_pics : p_sps->max_str_num_negtive_pos_pics;

		if (p_sps->str_num_negtive_pos_pics > VALUE_16)
			return SPS_RPS_SYNTAX_ERROR;


		prev = 0;
		for (j = 0; j < (signed int)p_rps->num_of_negative_pics; j++) {
			code = vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
			poc = prev-code-1;
			prev = poc;
			p_rps->delta_poc[j] = poc;
			p_rps->used[j] =
				(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
		}
		prev = 0;
		for (j = p_rps->num_of_negative_pics;
			j < (signed int)(p_rps->num_of_negative_pics + p_rps->num_of_positive_pics)
			&& j < MAX_NUM_REF_PICS + 1;
			j++) {
			code = vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
			poc = prev + code + 1;
			prev = poc;
			p_rps->delta_poc[j] = poc;
			p_rps->used[j] =
				(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
		}

		p_rps->num_of_pics = p_rps->num_of_negative_pics + p_rps->num_of_positive_pics;
	}

	return SPS_OK;
}

void vdec_h265_vui_rbsp(
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct h265_vui_data *vui,
	unsigned int max_t_layers)
{
	//ASSERT(vui != NULL);
	vui->aspect_ratio_present_flag =
		(unsigned char) vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
	if (vui->aspect_ratio_present_flag) {
		vui->aspect_ratio_idc = vpas_readbits(rbsp_bitstream_inst, VALUE_8);  // u(8)
		if (vui->aspect_ratio_idc == VALUE_255) {
			vui->sar_width =
				vpas_readbits(rbsp_bitstream_inst, VALUE_16);  // u(16)
			vui->sar_height =
				vpas_readbits(rbsp_bitstream_inst, VALUE_16);  // u(16)
		}
	}

	vui->overscan_info_present_flag = false;
	vui->overscan_appropriate_flag = false;
	vui->overscan_info_present_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
	if (vui->overscan_info_present_flag)
		vui->overscan_appropriate_flag =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)


	vui->video_signal_type_present_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
	if (vui->video_signal_type_present_flag) {
		vui->video_format =
			vpas_readbits(rbsp_bitstream_inst, VALUE_3);  // u(3)
		vui->video_full_range_flag =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
		vui->colour_description_present_flag =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst,
				1);  // u(1)
		if (vui->colour_description_present_flag) {
			vui->colour_primaries =
				vpas_readbits(rbsp_bitstream_inst, VALUE_8);  // u(8)
			vui->transfer_characteristics =
				vpas_readbits(rbsp_bitstream_inst, VALUE_8);  // u(8)
			vui->matrix_coeffcients =
				vpas_readbits(rbsp_bitstream_inst, VALUE_8);  // u(8)
		}
	}

	vui->chroma_loc_info_present_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst,
			1);  // u(1)
	if (vui->chroma_loc_info_present_flag) {
		vui->chroma_sample_loc_type_top_field =
			vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
		vui->chroma_sample_loc_type_bottom_field =
			vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
	}

	vui->neutral_chroma_indication_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst,
			1);  // u(1)
	vui->field_seq_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)

	vui->frame_field_info_present_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst,
			1);  // u(1)
	vui->default_display_window_enable_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst,
			1);  // u(1)

	if (vui->default_display_window_enable_flag) {
		vui->default_display_window_left_offset =
			vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
		vui->default_display_window_right_offset =
			vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
		vui->default_display_window_top_offset =
			vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
		vui->default_display_window_bottom_offset =
			vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
	}

	vui->timing_info_present_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
	if (vui->timing_info_present_flag) {
		vui->num_units_in_tick = vpas_readbits(rbsp_bitstream_inst, VALUE_32);  // u(32)
		vui->time_scale = vpas_readbits(rbsp_bitstream_inst, VALUE_32);  // u(32)
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE,
			"num_units_in_tick: %u time_scale: %u\n",
			vui->num_units_in_tick, vui->time_scale);
	}
}

unsigned int  vdec_h265_sl_rbsp(
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct h265_sl_data *scaling_list)
{
	unsigned int size_id, list_id;
	unsigned char scaling_list_pred_mode_flag;
	int code;
	unsigned int ref_list_id, list_size;

	// for each size
	for (size_id = 0; size_id < SCALING_LIST_SIZE_NUM; size_id++) {
		for (list_id = 0; list_id <  h265_scaling_list_num[size_id]; list_id++) {
			scaling_list_pred_mode_flag =
				(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);  // u(1)
			if (scaling_list_pred_mode_flag != 1) { // Copy Mode
				unsigned char *src = NULL, *dst = NULL;

				code  = (signed int)vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
				if ((signed int)list_id-code >= 0
					&& (signed int)list_id-code <
					(signed int)h265_scaling_list_num[size_id]) {
					ref_list_id = (unsigned int)((signed int)list_id-code);
				} else if ((signed int)list_id-code >= (signed int)
					h265_scaling_list_num[size_id]) {
					return SPS_SL_SYNTAX_ERROR;
				} else {
					return SPS_SL_SYNTAX_ERROR;
				}

				if (size_id > SCALING_LIST_8x8) {
					int s = size_id, r = ref_list_id;

					if (s > 0 && r > 0) {
						scaling_list->scaling_list_dc[s][list_id] =
							((list_id == r) ?
							VALUE_16 :
							scaling_list->scaling_list_dc[s][r]);
					}
				}

				//ref_list_id = scaling_list->u4RefMatrixId[size_id][list_id];
				list_size =
					(h265_scaling_list_size[size_id] > MAX_MATRIX_COEF_NUM) ?
					MAX_MATRIX_COEF_NUM : h265_scaling_list_size[size_id];
				dst = vdec_h265_get_sl_address(scaling_list, size_id, list_id);
				src = ((list_id == ref_list_id) ?
						vdec_h265_get_sl_default_address(size_id,
							ref_list_id) :
							vdec_h265_get_sl_address(
								scaling_list,
								size_id,
								ref_list_id));
				if (dst && src)
					memcpy(dst, src, sizeof(unsigned char) * list_size);
				else {
					PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
						"[VDEC-H265-ERR] %s %d\n", __func__, __LINE__);
					return SPS_SL_SYNTAX_ERROR;
				}
			} else {
				// DPCM Mode
				int i, coef_num = min_hevc(MAX_MATRIX_COEF_NUM,
						(signed int) h265_scaling_list_size[size_id]);
				unsigned char next_coef = SCALING_LIST_START_VALUE;
				unsigned int *scan  = (size_id == 0) ?
					h265_aui_sig_last_scan[SCAN_DIAG][1] :
					h265_sig_last_scan_cg32x32;
				unsigned char *dst =
					vdec_h265_get_sl_address(scaling_list, size_id, list_id);

				if (!dst || !scan) {
					PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
						"[VDEC-H265-ERR] %s %d\n", __func__, __LINE__);
					return SPS_SL_SYNTAX_ERROR;
				}

				if (size_id > SCALING_LIST_8x8) {
					code  = vpas_secodenum(rbsp_bitstream_inst);  // se(v)
					scaling_list->scaling_list_dc[size_id][list_id] =
						(unsigned char)(code + VALUE_8);
					next_coef = scaling_list->scaling_list_dc[size_id][list_id];
				}

				for (i = 0; i < coef_num; i++) {
					code = vpas_secodenum(rbsp_bitstream_inst);  // se(v)
					next_coef = (next_coef + code + VALUE_256) % VALUE_256;
					dst[scan[i]] = next_coef;
				}
			}
		}
	}

	return SPS_OK;
}
// to get p_sps->max_cu_[width|height] and p_sps->pic_[width|height]_in_luma_samples
// TODO nal unit header
static int vdec_com_h265_decode_sps(
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct h265_nal_unit_header *nal_unit_header)
{
	struct h265_sps_data *p_sps = NULL;
	struct h265_vui_data *p_vui = NULL;
	//struct h265_vps_data *p_vps = NULL;

	unsigned int add_cu_depth = 0;
	unsigned int code, i;
	unsigned int temp_max_t_layers_minus1, seq_params_set_id;
	unsigned char temp_temporal_id_nesting_flag = 0;
	unsigned int temp_vps_id = 0;
	struct h265_ptl_data ptl;
	unsigned int layer_id = nal_unit_header->nuh_layer_id;
	bool multi_layer_ext_sps_flag = false;
	unsigned int index;

	memset(&ptl, 0, sizeof(ptl));

	temp_vps_id = vpas_readbits(rbsp_bitstream_inst, VALUE_4);  //u(4)
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
						"temp_vps_id %d\n",
						temp_vps_id);

	if (layer_id == 0) {
		code = vpas_readbits(rbsp_bitstream_inst, VALUE_3);  //u(3)
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
						"code %d\n",
						temp_vps_id);
		if (code > VALUE_6) {
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
				"[VDEC-H265-ERR] sps_max_sub_layers_minus1 %u 0\n", code);
			return SPS_MAX_SUB_LAYER;
		}
		temp_max_t_layers_minus1 = code;
	} else {
		code = vpas_readbits(rbsp_bitstream_inst, VALUE_3);  //u(3)
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
						"code %d\n",
						code);
		if (code != VALUE_7)
			temp_max_t_layers_minus1 = code;
		else
			temp_max_t_layers_minus1 = 0;
	}
	multi_layer_ext_sps_flag = (layer_id != 0 && code == VALUE_7);
	if (!multi_layer_ext_sps_flag) {
		// temporal_id_nesting_flag
		temp_temporal_id_nesting_flag =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
					"temp_temporal_id_nesting_flag %d\n",
					temp_temporal_id_nesting_flag);
		if (temp_max_t_layers_minus1 == 0) {
			if (temp_temporal_id_nesting_flag != 1) {
				// sps_temporal_id_nesting_flag must be 1
				// when sps_max_sub_layers_minus1 is 0
				PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
					"[VDEC-H265-ERR] layer count conflict with temporal id 0\n");
				return SPS_LAYER_CONFLICT;
			}
		}

		ptl.profile_present_flag = 1;
		if (vdec_com_h265_ptl_rbsp(rbsp_bitstream_inst,
			&ptl, temp_max_t_layers_minus1) != 0) {
			return SPS_PTL;
		}
	}

	seq_params_set_id = vpas_uecodenum(rbsp_bitstream_inst);  //ue(v)
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
					"seq_params_set_id %d\n",
					seq_params_set_id);
	if (seq_params_set_id >= H265_MAX_SPS_NUM) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
			"[VDEC-H265-ERR] SPS ID invalid 0\n");
		return SPS_ID_INVLID;
	}

	p_sps = &g_h265_sps[seq_params_set_id];
	//p_vps = H265_VPS_PTR(decoder->vps[temp_vps_id]);

	if (!p_sps) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
			"[VDEC-H265-ERR]p_sps(%p) is NULL\n", p_sps);
		return SPS_ID_INVLID;
	}

	memset(p_sps, 0, sizeof(struct h265_sps_data));
	p_sps->valid = false;

	p_sps->sps_id = seq_params_set_id;
	p_sps->vps_id = temp_vps_id;
	p_sps->layer_id = layer_id;
	p_sps->layer_idx = 0;// no set h265_layer_id_2_lay_idx(p_vps, p_sps->layer_id);
	p_sps->max_t_layers_minus1 = temp_max_t_layers_minus1;
	p_sps->multi_layer_ext_sps_flag = multi_layer_ext_sps_flag;
	p_sps->temporal_id_nesting_flag = temp_temporal_id_nesting_flag;
	memcpy(&p_sps->sps_PTL, &ptl, sizeof(struct h265_ptl_data));

	vdec_com_h265_init_sps(p_sps);

	if (multi_layer_ext_sps_flag) {
		p_sps->update_rep_format_flag =
			(unsigned char) vpas_readbits(rbsp_bitstream_inst, VALUE_1);
		if (p_sps->update_rep_format_flag) {
			p_sps->sps_rep_format_idx =
				vpas_readbits(rbsp_bitstream_inst, VALUE_8);
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
					"sps_rep_format_idx %d\n",
					p_sps->sps_rep_format_idx);
		}
	} else {
		int ret = 0;

		ret = parse_sps_pic_format(rbsp_bitstream_inst, p_sps);
		if (ret != 0)
			return ret;
	}

	p_sps->log2_max_pic_order_cnt_lsb_minus4 =
		vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
					"log2_max_pic_order_cnt_lsb_minus4 %d\n",
					p_sps->log2_max_pic_order_cnt_lsb_minus4);
	if (p_sps->log2_max_pic_order_cnt_lsb_minus4 + VALUE_4 > VALUE_16) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
			"log2_max_pic_order_cnt_lsb_minus4 %u\n",
			p_sps->log2_max_pic_order_cnt_lsb_minus4);
		return SPS_MAX_POC_LSB_M4;
	}

	if (!multi_layer_ext_sps_flag) {
		unsigned int sub_layer_ordering_flag =
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);  // u(1)
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
						"sub_layer_ordering_flag %d\n",
						sub_layer_ordering_flag);

		for (i = 0; i <= p_sps->max_t_layers_minus1; i++) {
			p_sps->max_dec_pic_buffering[i] =
				vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
			p_sps->num_reorder_pics[i] =
				vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
			p_sps->max_latency_increase[i] =
				vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
				"max_dec_pic_buffering[%d] %d, %d, %d\n",
				i,
				p_sps->max_dec_pic_buffering[i],
				p_sps->num_reorder_pics[i],
				p_sps->max_latency_increase[i]);
			if  (sub_layer_ordering_flag != VALUE_1) {
				for (i++; i <= p_sps->max_t_layers_minus1; i++) {
					p_sps->max_dec_pic_buffering[i] =
						p_sps->max_dec_pic_buffering[0];
					p_sps->num_reorder_pics[i] =
						p_sps->num_reorder_pics[0];
					p_sps->max_latency_increase[i] =
						p_sps->max_latency_increase[0];
				}
				break;
			}
		}
	}
	p_sps->log2_min_coding_block_size_minus3 =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	p_sps->log2_diff_max_min_coding_block_size =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	p_sps->max_cu_width =
			1<<(p_sps->log2_min_coding_block_size_minus3 + VALUE_3 +
			p_sps->log2_diff_max_min_coding_block_size);
	p_sps->max_cu_height =
			1<<(p_sps->log2_min_coding_block_size_minus3 + VALUE_3 +
			p_sps->log2_diff_max_min_coding_block_size);
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
			"log2_min_coding_block_size_minus3 %d, "
			"log2_diff_max_min_coding_block_size %d\n",
			p_sps->log2_min_coding_block_size_minus3,
			p_sps->log2_diff_max_min_coding_block_size);
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
			"max_cu_width %d, max_cu_height %d\n",
			p_sps->max_cu_width,
			p_sps->max_cu_height);

	p_sps->log2_min_transform_blcok_size_minus2 =
		vpas_uecodenum(rbsp_bitstream_inst);    //ue(v)
	p_sps->log2_diff_max_min_t_transform_block_size =
		vpas_uecodenum(rbsp_bitstream_inst);  //ue(v)
	p_sps->u4MaxTrSize = (1<<(p_sps->log2_min_transform_blcok_size_minus2 + VALUE_2 +
				p_sps->log2_diff_max_min_t_transform_block_size));

	p_sps->quad_tree_tu_max_depth_inter =
		vpas_uecodenum(rbsp_bitstream_inst) + 1;  //ue(v)
	p_sps->quad_tree_tu_max_depth_intra =
		vpas_uecodenum(rbsp_bitstream_inst) + 1;  //ue(v)

	while ((p_sps->max_cu_width >> p_sps->log2_diff_max_min_coding_block_size) >
		(unsigned int)(1 <<
			(p_sps->log2_min_transform_blcok_size_minus2 +
			VALUE_2 + add_cu_depth))) {
		add_cu_depth++;
	}

	p_sps->u4MaxCUDepth = add_cu_depth + p_sps->log2_diff_max_min_coding_block_size;
	p_sps->scaling_list_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	p_sps->sps_infer_scaling_list_flag = 0;
	p_sps->sps_scaling_list_ref_layer_id = 0;

	if (p_sps->scaling_list_flag) {
		if (multi_layer_ext_sps_flag) {
			p_sps->sps_infer_scaling_list_flag =
				vpas_readbits(rbsp_bitstream_inst, 1);
		} else {
			p_sps->sps_infer_scaling_list_flag = 0;
		}

		if (p_sps->sps_infer_scaling_list_flag) {
			p_sps->sps_scaling_list_ref_layer_id =
				vpas_readbits(rbsp_bitstream_inst, VALUE_6);
			p_sps->scaling_list_present_flag = false;
		} else {
			p_sps->scaling_list_present_flag =
				(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
			if (p_sps->scaling_list_present_flag) {
				//parse scaling list
				if (vdec_h265_sl_rbsp(rbsp_bitstream_inst,
						&(p_sps->sps_scaling_list)) != SPS_OK) {
					return SPS_SL_SYNTAX_ERROR;
				}
			}
		}
	}

	p_sps->use_amp =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	p_sps->use_sao =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	p_sps->use_pcm =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	if (p_sps->use_pcm) {
		p_sps->pcm_bit_depth_luma_minus1 =
			vpas_readbits(rbsp_bitstream_inst, VALUE_4);//u(4)
		p_sps->pcm_bit_depth_chroma_minus1 =
			vpas_readbits(rbsp_bitstream_inst, VALUE_4);//u(4)

		p_sps->pcm_log2_luma_min_size_minus3 =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		p_sps->pcm_log2_luma_max_size =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		p_sps->pcm_log2_luma_max_size +=
			p_sps->pcm_log2_luma_min_size_minus3 + VALUE_3;

		p_sps->pcm_filter_disable_flag =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	}

	// parse short term RPS
	p_sps->num_short_term_ref_pic_sets =
		vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
	if (p_sps->num_short_term_ref_pic_sets > VALUE_64)
		p_sps->num_short_term_ref_pic_sets = VALUE_64;


	for (index = 0; index < p_sps->num_short_term_ref_pic_sets; index++) {
		if (vdec_h265_rps_rbsp(rbsp_bitstream_inst,
				p_sps,
				&p_sps->short_term_ref_pic_sets[index],
				index) != SPS_OK) {
			return SPS_RPS_SYNTAX_ERROR;
		}
	}

	// parse Long term RPS
	p_sps->long_term_refs_present =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	if (p_sps->long_term_refs_present) {
		p_sps->num_long_term_ref_pic_sps =
			vpas_uecodenum(rbsp_bitstream_inst);//ue(v)
		if (p_sps->num_long_term_ref_pic_sps > H265_MAX_LONG_TERM_REF_PIC_NUM)
			p_sps->num_long_term_ref_pic_sps = H265_MAX_LONG_TERM_REF_PIC_NUM;
		for (index = 0; index < p_sps->num_long_term_ref_pic_sps; index++) {
			p_sps->long_term_ref_pic_poc_lsb_sps[index] =
				vpas_readbits(rbsp_bitstream_inst,
					p_sps->log2_max_pic_order_cnt_lsb_minus4 + VALUE_4);
			p_sps->used_by_curr_pic_lt_sps_flag[index] =
				(unsigned char)vpas_readbits(rbsp_bitstream_inst,
					1);//u(1)
		}
	}


	p_sps->tmvp_flags_present =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	p_sps->use_strong_intra_smoothing =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)
	p_sps->vui_params_present_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);//u(1)

	if (p_sps->vui_params_present_flag) {
		p_vui = &p_sps->vui;
		vdec_h265_vui_rbsp(rbsp_bitstream_inst, p_vui, p_sps->max_t_layers_minus1 + 1);
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_INFO,
			"SPS color %d transfer %d matrix %d\n", p_vui->colour_primaries,
			p_vui->transfer_characteristics,
			p_vui->matrix_coeffcients);
	}

	p_sps->valid = 1;
	active_h265_sps = *p_sps;

	return 0;
}

static int vdec_com_h265_decode_pps(
		struct rbsp_bitstream *rbsp_bitstream_inst)
{
	unsigned int pic_params_set_id;
	struct h265_pps_data *p_pps = NULL;

	pic_params_set_id = vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)
	if (pic_params_set_id >= H265_MAX_PPS_NUM) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR, "PPS id [%d] invalid 0\n", pic_params_set_id);
			return -1;
	}

	p_pps = &g_h265_pps[pic_params_set_id];
	memset(p_pps, 0, sizeof(struct h265_pps_data));
	p_pps->valid = 0;


	p_pps->pic_params_set_id = pic_params_set_id;

	// no check whether sps[seq_params_set_id] exists or not
	p_pps->seq_params_set_id = vpas_uecodenum(rbsp_bitstream_inst);  //ue(v)
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
			"pic_params_set_id %d seq_params_set_id %d\n",
			p_pps->pic_params_set_id,
			p_pps->seq_params_set_id);
	if (p_pps->seq_params_set_id >= H265_MAX_SPS_NUM) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR, "PPS id [%d] invalid 0\n",
			p_pps->seq_params_set_id);
		return PPS_NO_SPS_INFO_ERROR;
	}
	if (g_h265_sps[p_pps->seq_params_set_id].valid == false) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
			"Get Wrong SPS[%d]\n",
			p_pps->seq_params_set_id);
		p_pps->valid = 0;
		return -1;
	}

	p_pps->dependent_slice_segments_enable_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);//u(1)
	p_pps->output_flag_present_flag =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);//u(1)
	p_pps->num_extra_slice_header_bits =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_3);//u(3)
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
			"dependent_slice_segments_enable_flag %d %d %d\n",
			p_pps->dependent_slice_segments_enable_flag,
			p_pps->output_flag_present_flag,
			p_pps->num_extra_slice_header_bits);
	p_pps->valid = 1;
	return 0;
}

/*
 * Function     : get_golomb_code_len
 * Parameter    : the syntax element value that has been done GolombEncode
 * Return       : @ret_len:the length of Encoded value which has been done GolombEncode
 * Note         : this function is for the syntax coded as se(v) not ue(v)
 */
int get_golomb_code_len(int value, bool is_ue)
{
	int code_num = 0;
	int count   = 0;
	int ret_len  = 0;
	int tmp_num  = 0;

	// mapping the syntax element value to code_num
	if (is_ue)
		code_num = value;
	else
		code_num = (value > 0) ? ((value<<1)-1) : ((-value)<<1);

	// Length = 2*M + 1 + k (k = 0)
	// M = zeroPrefixLength = floor(log2[code_num + 2^k])
	// to calculate the zeroPrefixLength of GolombEncode depending on code_num
	tmp_num = code_num + 1;
	while (tmp_num >> 1) {
		tmp_num = tmp_num >> 1;
		count++;
	}

	// to calculate the length of GolombEncode of the syntax element
	ret_len = VALUE_2 * count + 1;

	return ret_len;
}

int vdec_com_h265_decode_sei_pic_timing(
	struct rbsp_bitstream *rbsp_bitstream_inst)
{
	unsigned char   frame_field_info_present_flag = false;
	unsigned int    payload_size = 0;
	unsigned int    payload_size_offset_bits_count = 0;

	struct h265_sei_data    *p_h265_sei_data = &g_h265_sei;
	struct h265_sps_data    *p_sps = NULL;
	struct h265_pic_tim_data    *p_pic_tim_data = NULL;

	p_pic_tim_data = &(p_h265_sei_data->pic_tim_data);
	p_sps = &active_h265_sps;


	payload_size = p_h265_sei_data->payload_size;

	frame_field_info_present_flag = p_sps->vui.frame_field_info_present_flag;

	p_h265_sei_data->sei_timing_num++;
	p_h265_sei_data->sei_timing_num_sub++;
	p_h265_sei_data->delta_to_divisor = 1;
	p_pic_tim_data->pic_struct = HEVC_SEI_FRAME_ONLY;

	if (frame_field_info_present_flag) {
		p_pic_tim_data->pic_struct =
			vpas_readbits(rbsp_bitstream_inst, VALUE_4);  //u(4)
		p_pic_tim_data->source_scan_type =
			vpas_readbits(rbsp_bitstream_inst, VALUE_2);  //u(2)
		p_pic_tim_data->duplicate_flag   =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst, 1);  //u(1)
		payload_size_offset_bits_count += VALUE_7;

		PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE, "PicStruct %d SourType %d Duplicate %d\n",
			p_pic_tim_data->pic_struct,
			p_pic_tim_data->source_scan_type,
			p_pic_tim_data->duplicate_flag);
	}

	if (payload_size_offset_bits_count % VALUE_8) {
		vpas_readbits(rbsp_bitstream_inst, VALUE_8 - payload_size_offset_bits_count %
			VALUE_8);  // byte_aligned for the last byte
		p_h265_sei_data->payload_size = payload_size - payload_size_offset_bits_count /
			VALUE_8 - 1;
	} else {
		p_h265_sei_data->payload_size = payload_size - payload_size_offset_bits_count /
			VALUE_8;
	}

	return 0;
}
static int update_rest_byte(struct rbsp_bitstream *rbsp_bitstream_inst)
{
	if (rbsp_bitstream_inst->bits_read % VALUE_8 != 0)
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_VERBOSE,
			"Not align bits_read: %d\n",
			rbsp_bitstream_inst->bits_read);

	return rbsp_bitstream_inst->stored_cache_size -
		(rbsp_bitstream_inst->bits_read/VALUE_8);
}
static int vdec_com_h265_decode_sei(struct rbsp_bitstream *rbsp_bitstream_inst)
{
	unsigned int payload_type = 0, payload_size = 0, u4Byte = 0;
	int rest_bytes = 0, sei_payload_cnt = 0, byte_read = 0;
	struct h265_sei_data *p_h265_sei_data = &g_h265_sei;
	//struct vdec_hal_bs_fifo *p_bs_info = NULL;

	//p_bs_info = &decoder->bs_fifo;
	//p_h265_sei_data = &decoder->sei_content;
	p_h265_sei_data->active = true;
	p_h265_sei_data->tech_hdr_flag = false;
	p_h265_sei_data->bFilmMaker = false;
	p_h265_sei_data->u1AFD = SEI_AFD_UNKONWN;

	rest_bytes = update_rest_byte(rbsp_bitstream_inst);

	//vld_read_ptr_end maybe unreliable
	//need improvement later. such as pre-search to next start code .
	//nal_end_ptr = p_bs_info->vld_read_ptr_end;
	do {
		payload_type = 0;
		while ((u4Byte = (vpas_readbits(rbsp_bitstream_inst, VALUE_8))) == VALUE_255)
			payload_type += VALUE_255;

		payload_type += u4Byte;

		payload_size = 0;
		while ((u4Byte = (vpas_readbits(rbsp_bitstream_inst, VALUE_8))) == VALUE_255)
			payload_size += VALUE_255;

		payload_size += u4Byte;
		p_h265_sei_data->payload_size = payload_size;

		rest_bytes = update_rest_byte(rbsp_bitstream_inst);

		if (rest_bytes <= 0) {
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
				"invalid SEI payload, type %u size %u\n",
				payload_type, payload_size);
			break;
		}

		// no enough payload
		byte_read = rbsp_bitstream_inst->bits_read/VALUE_8;
		if (byte_read + p_h265_sei_data->payload_size >
				rbsp_bitstream_inst->stored_cache_size) {
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
				"no enough payload, type %u byte_read %d size %u\n",
				payload_type, byte_read, payload_size);
			break;
		}

		PAS_DEBUG_LOG(PAS_LOG_LEVEL_INFO,
				"SEI type %u size %u rest: %d\n",
				payload_type, payload_size, rest_bytes);

		// parse sei_payload
		switch (payload_type) {
		case SEI_PIC_TIMING:
			vdec_com_h265_decode_sei_pic_timing(rbsp_bitstream_inst);
			break;
		default:
			break;
		}

		// check underflow, avoid dead loop
		if (payload_size < p_h265_sei_data->payload_size) {
			PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
				"payload_size underflow 0x%x 0x%x payload_type %u\n",
				payload_size, p_h265_sei_data->payload_size, payload_type);
			p_h265_sei_data->active = false;
			// not ok ...
			return SEI_OK;
		}

		// remove sei remaining unprocessed payload
		// if the SEI TYPE do not support,
		// the whole SEI would be directly removed
		while (p_h265_sei_data->payload_size > 0) {
			vpas_readbits(rbsp_bitstream_inst, VALUE_8);
			p_h265_sei_data->payload_size--;
		}

		if (sei_payload_cnt++ > VALUE_10)
			rest_bytes = 0;
		else
			rest_bytes = update_rest_byte(rbsp_bitstream_inst);

	} while (rest_bytes > VALID_MIN_SEI_SIZE);

	return SEI_OK;
}

void _hevc_vpas_set_slice_info(
	struct h265_slice_hdr_data *slice_header,
	struct h265_nal_unit_header *nal_unit_header,
	struct HEVC_ES_UNIT *curCachedUnit,
	unsigned int pic_struct)
{
	if (slice_header->slice_type >= H265_SLICE_TYPE_MAX) {
		if (nal_unit_header->nal_unit_type >= VALUE_16 &&
			nal_unit_header->nal_unit_type <= VALUE_23) {
			slice_header->slice_type = HEVC_I_SLICE;
		} else {
			slice_header->slice_type = HEVC_B_SLICE;
		}
	}

	curCachedUnit->unitInfo.f.bIFrame = false;
	if (slice_header->slice_type == HEVC_I_SLICE)
		curCachedUnit->unitInfo.f.bIFrame = true;

	if (pic_struct == HEVC_SEI_FRAME_ONLY)
		curCachedUnit->unitInfo.f.field_flag = HEVC_FRAME;
	else
		curCachedUnit->unitInfo.f.field_flag =
			pic_struct == VALUE_1 ||
			pic_struct == VALUE_9 ||
			pic_struct == VALUE_11;
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_INFO,
		"bIFrame %d slice type %d field %d\n",
		curCachedUnit->unitInfo.f.bIFrame,
		slice_header->slice_type,
		curCachedUnit->unitInfo.f.field_flag);
}
// TODO elimiate useless part
// how to get u(v)
static int vdec_com_h265_decode_slice_header(
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct h265_slice_hdr_data *slice_header,
	struct HEVC_ES_UNIT *curCachedUnit,
	struct h265_nal_unit_header *nal_unit_header)
{
	int bits_slice_segment_address, num_ctus;
	signed int ret_value = 0;
	struct h265_sps_data *p_sps = NULL;
	struct h265_pps_data *p_pps = NULL;
	struct h265_sei_data *p_h265_sei_data = &g_h265_sei;
	struct h265_pic_tim_data *p_pic_tim_data = &(p_h265_sei_data->pic_tim_data);
	unsigned int pic_struct = p_pic_tim_data->pic_struct;

	slice_header->first_slice_segment_in_pic =
		(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1); // u(1)

	if (IsH265IRap(curCachedUnit->unitType)) {
		// no_output_of_prior_pics_flag
		//slice_no_output_of_prior_pics_flag u(1)
		vpas_readbits(rbsp_bitstream_inst, VALUE_1);
	}

	slice_header->pps_id = vpas_uecodenum(rbsp_bitstream_inst); // ue(v)
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
			"first_slice_segment_in_pic %d pps_id %d\n",
			slice_header->first_slice_segment_in_pic,
			slice_header->pps_id);
	// get PPS
	if (slice_header->pps_id < H265_MAX_PPS_NUM
		&& g_h265_pps[slice_header->pps_id].valid) {
		p_pps = &g_h265_pps[slice_header->pps_id];
	}
	if (!p_pps) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
			"[VDEC-H265-ERROR-%d] Slice Hdr PPS Num[%d] err\n", 0,
			slice_header->pps_id);
		return SLICE_PPS_ID_ERROR;
	}

	// get SPS
	if (p_pps->seq_params_set_id < H265_MAX_SPS_NUM
		&& g_h265_sps[p_pps->seq_params_set_id].valid) {
		p_sps = &g_h265_sps[p_pps->seq_params_set_id];
	}
	if (!p_sps) {
		PAS_DEBUG_LOG(PAS_LOG_LEVEL_ERROR,
			"[VDEC-H265-ERROR-%d] SPS Num[%d] err\n", 0, p_pps->seq_params_set_id);
		return SLICE_PPS_ID_ERROR;
	}

	if (slice_header->first_slice_segment_in_pic != 1
		&& p_pps->dependent_slice_segments_enable_flag) {
		slice_header->dependent_slice_segment_flag =
			(unsigned char)vpas_readbits(rbsp_bitstream_inst, VALUE_1);
	} else {
		slice_header->dependent_slice_segment_flag = 0;
	}
	PAS_DEBUG_LOG(PAS_LOG_LEVEL_PARSE,
				"dependent_slice_segments_enable_flag %d\n",
				slice_header->dependent_slice_segment_flag);

	num_ctus = ((p_sps->pic_width_in_luma_samples + p_sps->max_cu_width - 1) /
			p_sps->max_cu_width)
		* ((p_sps->pic_height_in_luma_samples + p_sps->max_cu_height - 1) /
			p_sps->max_cu_height);

	bits_slice_segment_address = 0;
	while (num_ctus > (1 << bits_slice_segment_address))
		bits_slice_segment_address++;

	if (slice_header->first_slice_segment_in_pic != 1) {
		slice_header->slice_segment_address = vpas_readbits(rbsp_bitstream_inst,
				bits_slice_segment_address);  // u(v)
	}

	if (slice_header->dependent_slice_segment_flag == 0) {
		unsigned int num_extra_slice_header_bits = p_pps->num_extra_slice_header_bits;
		int i4Indexer = 0, i = 0;

		if (num_extra_slice_header_bits > i4Indexer) {
			slice_header->discard_able_flag =
				vpas_readbits(rbsp_bitstream_inst, VALUE_1);
			i4Indexer++;
		}

		if (num_extra_slice_header_bits > i4Indexer) {
			slice_header->cross_layer_bla_flag =
				vpas_readbits(rbsp_bitstream_inst, VALUE_1);
			i4Indexer++;
		}
		for (i = i4Indexer; i < p_pps->num_extra_slice_header_bits; i++)
			vpas_readbits(rbsp_bitstream_inst, VALUE_1);  // u(1)

		slice_header->slice_type =
			vpas_uecodenum(rbsp_bitstream_inst);  // ue(v)

		_hevc_vpas_set_slice_info(slice_header,
			nal_unit_header, curCachedUnit, pic_struct);
	}

	return ret_value;
}
// TODO make read all avaialable nalu unit payload
// parse h265 pps & i/p/b slice type
signed int vdec_com_h265_sw_parsenal(
	struct rbsp_bitstream *rbsp_bitstream_inst,
	struct HEVC_ES_UNIT *curCachedUnit)
{
	unsigned int ret_value = (unsigned int)VDEC_HAL_RET_OK;
	unsigned char nal_unit_type = curCachedUnit->unitType; // already set in hevcGetUnitType
	struct h265_slice_hdr_data slice_header;
	struct h265_nal_unit_header nal_unit_header;
	VES_PARSER_ES_UNIT *pUnit = (VES_PARSER_ES_UNIT *) curCachedUnit;

	h265_decoder_decode_nal_unit_header(&nal_unit_header,
				(pUnit->reserve0 << BYTE_SIZE) + pUnit->reserve1);
	pUnit->reserve0 = pUnit->reserve1 = 0;

	switch (nal_unit_type) {
	case NAL_UNIT_CODED_SLICE_BLA:
	case NAL_UNIT_CODED_SLICE_BLANT:
	case NAL_UNIT_CODED_SLICE_BLA_N_LP:
	case NAL_UNIT_CODED_SLICE_IDR:
	case NAL_UNIT_CODED_SLICE_IDR_N_LP:
	case NAL_UNIT_CODED_SLICE_CRA:
	case NAL_UNIT_CODED_SLICE_TRAIL_R:
	case NAL_UNIT_CODED_SLICE_TRAIL_N:
	case NAL_UNIT_CODED_SLICE_TLA:
	case NAL_UNIT_CODED_SLICE_TSA_N:
	case NAL_UNIT_CODED_SLICE_STSA_R:
	case NAL_UNIT_CODED_SLICE_STSA_N:
	case NAL_UNIT_CODED_SLICE_RADL_N:
	case NAL_UNIT_CODED_SLICE_DLP:
	case NAL_UNIT_CODED_SLICE_RASL_N:
	case NAL_UNIT_CODED_SLICE_TFD:
		ret_value =
			vdec_com_h265_decode_slice_header(rbsp_bitstream_inst,
				&slice_header,
				(struct HEVC_ES_UNIT *) curCachedUnit,
				&nal_unit_header);
		break;
	case NAL_UNIT_SPS:
		ret_value = vdec_com_h265_decode_sps(rbsp_bitstream_inst, &nal_unit_header);
		break;
	case NAL_UNIT_PPS:
		ret_value = vdec_com_h265_decode_pps(rbsp_bitstream_inst);
		break;
	case NAL_UNIT_SEI:
		// origin from h265_decoder_decode_sei
		ret_value = vdec_com_h265_decode_sei(rbsp_bitstream_inst);
		break;
	default:
		break;
	}

	return (signed int) ret_value;
}
#endif
