Commit message: fixed #1893
CVE: CVE-2021-40572
CWE: CWE-415
Vulnerability description: The binary MP4Box in Gpac 1.0.1 has a double-free bug in the av1dmx_finalize function in reframe_av1.c, which allows attackers to cause a denial of service.

Project: gpac
File: av_parsers.c

static void av1_parse_uncompressed_header(GF_BitStream *bs, AV1State *state)
{
	Bool error_resilient_mode = GF_FALSE, allow_screen_content_tools = GF_FALSE, force_integer_mv = GF_FALSE;
	Bool /*use_ref_frame_mvs = GF_FALSE,*/ FrameIsIntra = GF_FALSE, frame_size_override_flag = GF_FALSE;
	Bool disable_cdf_update = GF_FALSE;
	u8 showable_frame;
	u8 primary_ref_frame;
	u16 idLen = 0;
	u32 idx;
	s8 ref_frame_idx[AV1_REFS_PER_FRAME];
	AV1StateFrame *frame_state = &state->frame_state;

	if (state->frame_id_numbers_present_flag) {
		idLen = (state->additional_frame_id_length_minus_1 + state->delta_frame_id_length_minus_2 + 3);
	}
	frame_state->refresh_frame_flags = 0;

	showable_frame = 0;
	if (state->reduced_still_picture_header) {
		frame_state->key_frame = GF_TRUE;
		FrameIsIntra = GF_TRUE;
		frame_state->frame_type = AV1_KEY_FRAME;
		frame_state->show_frame = GF_TRUE;
		frame_state->show_existing_frame = 0;
	}
	else {
		frame_state->show_existing_frame = gf_bs_read_int_log(bs, 1, "show_existing_frame");
		if (frame_state->show_existing_frame == GF_TRUE) {
			frame_state->frame_to_show_map_idx = gf_bs_read_int_log(bs, 3, "frame_to_show_map_idx");
			frame_state->frame_type = state->RefFrameType[frame_state->frame_to_show_map_idx];

			if (state->decoder_model_info_present_flag && !state->equal_picture_interval) {
				gf_bs_read_int_log(bs, state->frame_presentation_time_length, "frame_presentation_time");
			}

			frame_state->refresh_frame_flags = 0;
			if (state->frame_id_numbers_present_flag) {
				gf_bs_read_int_log(bs, idLen, "display_frame_id");
			}
			if (frame_state->frame_type == AV1_KEY_FRAME) {
				frame_state->refresh_frame_flags = AV1_ALL_FRAMES;
			}
			/*
			if (film_grain_params_present) {
				load_grain_params(frame_to_show_map_idx)
			}*/
			return;
		}
		frame_state->frame_type = gf_bs_read_int_log(bs, 2, "frame_type");
		FrameIsIntra = (frame_state->frame_type == AV1_INTRA_ONLY_FRAME || frame_state->frame_type == AV1_KEY_FRAME);
		frame_state->show_frame = gf_bs_read_int_log(bs, 1, "show_frame");
		if (frame_state->is_first_frame) {
			frame_state->key_frame = frame_state->seen_seq_header && frame_state->show_frame && frame_state->frame_type == AV1_KEY_FRAME && frame_state->seen_frame_header;
		}
		if (frame_state->show_frame && state->decoder_model_info_present_flag && !state->equal_picture_interval) {
			gf_bs_read_int_log(bs, state->frame_presentation_time_length, "frame_presentation_time");
		}
		if (frame_state->show_frame) {
			showable_frame = frame_state->frame_type != AV1_KEY_FRAME;

		}
		else {
			showable_frame = gf_bs_read_int_log(bs, 1, "showable_frame");
		}
		if (frame_state->frame_type == AV1_SWITCH_FRAME || (frame_state->frame_type == AV1_KEY_FRAME && frame_state->show_frame))
			error_resilient_mode = GF_TRUE;
		else
			error_resilient_mode = gf_bs_read_int_log(bs, 1, "error_resilient_mode");
	}

	if ((frame_state->frame_type == AV1_KEY_FRAME) && frame_state->show_frame) {
		u32 i;
		for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
			state->RefValid[i] = 0;
			state->RefOrderHint[i] = 0;
		}
		for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
			state->OrderHints[AV1_LAST_FRAME + i] = 0;
		}
	}

	disable_cdf_update = gf_bs_read_int_log(bs, 1, "disable_cdf_update");
	if (state->seq_force_screen_content_tools == 2/*SELECT_SCREEN_CONTENT_TOOLS*/) {
		allow_screen_content_tools = gf_bs_read_int_log(bs, 1, "allow_screen_content_tools");
	}
	else {
		allow_screen_content_tools = state->seq_force_screen_content_tools;
	}
	if (allow_screen_content_tools) {
		if (state->seq_force_integer_mv == 2/*SELECT_INTEGER_MV*/) {
			force_integer_mv = gf_bs_read_int_log(bs, 1, "force_integer_mv");
		}
		else {
			force_integer_mv = state->seq_force_integer_mv;
		}
	}
	else {
		force_integer_mv = 0;
	}
	if (FrameIsIntra) {
		force_integer_mv = 1;
	}
	if (state->frame_id_numbers_present_flag) {
		gf_bs_read_int_log(bs, idLen, "current_frame_id");
	}
	if (frame_state->frame_type == AV1_SWITCH_FRAME)
		frame_size_override_flag = GF_TRUE;
	else if (state->reduced_still_picture_header)
		frame_size_override_flag = GF_FALSE;
	else
		frame_size_override_flag = gf_bs_read_int_log(bs, 1, "frame_size_override_flag");

	frame_state->order_hint = gf_bs_read_int_log(bs, state->OrderHintBits, "order_hint");
	if (FrameIsIntra || error_resilient_mode) {
		primary_ref_frame = AV1_PRIMARY_REF_NONE;
	}
	else {
		primary_ref_frame = gf_bs_read_int_log(bs, 3, "primary_ref_frame");
	}

	if (state->decoder_model_info_present_flag) {
		u8 buffer_removal_time_present_flag = gf_bs_read_int_log(bs, 1, "buffer_removal_time_present_flag");
		if (buffer_removal_time_present_flag) {
			u32 opNum;
			for (opNum = 0; opNum < state->operating_points_count; opNum++) {
				if (state->decoder_model_present_for_this_op[opNum]) {
					u8 opPtIdc = state->operating_point_idc[opNum];
					u8 inTemporalLayer = (opPtIdc >> state->temporal_id) & 1;
					u8 inSpatialLayer = (opPtIdc >> (state->spatial_id + 8)) & 1;
					if (opPtIdc == 0 || (inTemporalLayer && inSpatialLayer)) {
						gf_bs_read_int_log_idx(bs, state->buffer_removal_time_length, "buffer_removal_time", opNum);
					}
				}
			}
		}
	}

	if (frame_state->frame_type == AV1_SWITCH_FRAME || (frame_state->frame_type == AV1_KEY_FRAME && frame_state->show_frame)) {
		frame_state->refresh_frame_flags = AV1_ALL_FRAMES;
	}
	else {
		frame_state->refresh_frame_flags = gf_bs_read_int_log(bs, 8, "refresh_frame_flags");
	}
	if (!FrameIsIntra || frame_state->refresh_frame_flags != AV1_ALL_FRAMES) {
		if (error_resilient_mode && state->enable_order_hint) {
			u32 i = 0;
			for (i = 0; i < AV1_NUM_REF_FRAMES; i++) {
				u8 ref_order_hint = gf_bs_read_int_log_idx(bs, state->OrderHintBits, "ref_order_hint", i);
				if (ref_order_hint != state->RefOrderHint[i]) {
					state->RefValid[i] = 0;
				}
				state->RefOrderHint[i] = ref_order_hint;
			}
		}
	}

	u8 allow_intrabc = 0;
	if (frame_state->frame_type == AV1_KEY_FRAME) {
		av1_frame_size(bs, state, frame_size_override_flag);
		av1_render_size(bs);
		if (allow_screen_content_tools && state->UpscaledWidth == state->width) {
			allow_intrabc = gf_bs_read_int_log(bs, 1, "allow_intrabc");
		}
	}
	else {
		if (frame_state->frame_type == AV1_INTRA_ONLY_FRAME) {
			av1_frame_size(bs, state, frame_size_override_flag);
			av1_render_size(bs);
			if (allow_screen_content_tools && state->UpscaledWidth == state->width) {
				allow_intrabc = gf_bs_read_int_log(bs, 1, "allow_intrabc");
			}
		}
		else {
			u32 i = 0;
			Bool frame_refs_short_signaling = GF_FALSE;
			if (state->enable_order_hint) {
				frame_refs_short_signaling = gf_bs_read_int_log(bs, 1, "frame_refs_short_signaling");
				if (frame_refs_short_signaling) {
					u8 last_frame_idx = gf_bs_read_int_log(bs, 3, "last_frame_idx");
					u8 gold_frame_idx = gf_bs_read_int_log(bs, 3, "gold_frame_idx");
					av1_set_frame_refs(state, last_frame_idx, gold_frame_idx, ref_frame_idx);
				}
			}
			for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
				if (!frame_refs_short_signaling)
					ref_frame_idx[i] = gf_bs_read_int_log_idx(bs, 3, "ref_frame_idx", i);

				if (state->frame_id_numbers_present_flag) {
					u32 n = state->delta_frame_id_length_minus_2 + 2;
					/*delta_frame_id_minus_1 =*/ gf_bs_read_int_log_idx(bs, n, "delta_frame_id_minus1", i);
					//DeltaFrameId = delta_frame_id_minus_1 + 1;
					//expectedFrameId[i] = ((current_frame_id + (1 << idLen) - DeltaFrameId) % (1 << idLen));
				}
			}
			if (frame_size_override_flag && !error_resilient_mode) {
				frame_size_with_refs(bs, state, frame_size_override_flag, ref_frame_idx);
			}
			else {
				av1_frame_size(bs, state, frame_size_override_flag);
				av1_render_size(bs);
			}
			frame_state->allow_high_precision_mv = 0;
			if (!force_integer_mv) {
				frame_state->allow_high_precision_mv = gf_bs_read_int_log(bs, 1, "allow_high_precision_mv");
			}

			read_interpolation_filter(bs);

			gf_bs_read_int_log(bs, 1, "is_motion_mode_switchable");
			if (!(error_resilient_mode || !state->enable_ref_frame_mvs)) {
				gf_bs_read_int_log(bs, 1, "use_ref_frame_mvs");
			}
		}
	}

	if (!FrameIsIntra) {
		u32 i;
		for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
			u8 refFrame = AV1_LAST_FRAME + i;
			u8 ridx = ref_frame_idx[i];
			if (ridx >= 0) {
				u8 hint = state->RefOrderHint[ridx];
				state->OrderHints[refFrame] = hint;
				/*			if ( !enable_order_hint ) {
								RefFrameSignBias[ refFrame ] = 0;
							} else {
								RefFrameSignBias[ refFrame ] = get_relative_dist( hint, OrderHint) > 0;
							}
				*/
			}

		}
	}

	if (!(state->reduced_still_picture_header || disable_cdf_update))
		gf_bs_read_int_log(bs, 1, "disable_frame_end_update_cdf");

	if (primary_ref_frame == AV1_PRIMARY_REF_NONE) {
		//init_non_coeff_cdfs();
		av1_setup_past_independence(state);
	}
	else {
		//load_cdfs(ref_frame_idx[primary_ref_frame]);
		av1_load_previous(state, primary_ref_frame, ref_frame_idx);
	}

	av1_parse_tile_info(bs, state);
	//quantization_params( ):
	u8 base_q_idx = gf_bs_read_int_log(bs, 8, "base_q_idx");
	s32 DeltaQUDc = 0;
	s32 DeltaQUAc = 0;
	s32 DeltaQVDc = 0;
	s32 DeltaQVAc = 0;
	s32 DeltaQYDc = av1_delta_q(bs, "DeltaQYDc_coded", "DeltaQYDc");
	if (!state->config->monochrome) {
		u8 diff_uv_delta = 0;
		if (state->separate_uv_delta_q)
			diff_uv_delta = gf_bs_read_int_log(bs, 1, "diff_uv_delta");

		DeltaQUDc = av1_delta_q(bs, "DeltaQUDc_coded", "DeltaQUDc");
		DeltaQUAc = av1_delta_q(bs, "DeltaQUAc_coded", "DeltaQUAc");
		if (diff_uv_delta) {
			DeltaQVDc = av1_delta_q(bs, "DeltaQVDc_coded", "DeltaQVDc");
			DeltaQVAc = av1_delta_q(bs, "DeltaQVAc_coded", "DeltaQVAc");
		}
	}
	if (gf_bs_read_int_log(bs, 1, "using_qmatrix")) {
		gf_bs_read_int_log(bs, 4, "qm_y");
		gf_bs_read_int_log(bs, 4, "qm_u");
		if (!state->separate_uv_delta_q) {
			gf_bs_read_int_log(bs, 4, "qm_v");
		}
	}

	u8 seg_features_SEG_LVL_ALT_Q_enabled[8] = { 0,0,0,0,0,0,0,0 };
	s32 seg_features_SEG_LVL_ALT_Q[8] = { 0,0,0,0,0,0,0,0 };

	//segmentation_params( ):
	u8 segmentation_enabled = gf_bs_read_int_log(bs, 1, "segmentation_enabled");
	if (segmentation_enabled) {
		/*u8 segmentation_temporal_update = 0;*/
		u8 segmentation_update_data = 1;
		if (primary_ref_frame != AV1_PRIMARY_REF_NONE) {
			u8 segmentation_update_map = gf_bs_read_int_log(bs, 1, "segmentation_update_map");
			if (segmentation_update_map == 1)
				gf_bs_read_int_log(bs, 1, "segmentation_temporal_update");
			segmentation_update_data = gf_bs_read_int_log(bs, 1, "segmentation_update_data");
		}
		if (segmentation_update_data == 1) {
			u32 i, j;
			for (i = 0; i < 8/*=MAX_SEGMENTS*/; i++) {
				for (j = 0; j < 8 /*=SEG_LVL_MAX*/; j++) {
					if (/*feature_enabled = */gf_bs_read_int_log_idx2(bs, 1, "feature_enabled", i, j) == 1) {
						s32 val;
						u32 bitsToRead = Segmentation_Feature_Bits[j];
						//this is SEG_LVL_ALT_Q
						if (!j) seg_features_SEG_LVL_ALT_Q_enabled[i] = 1;

						if (Segmentation_Feature_Signed[j] == 1) {
							val = gf_bs_read_int_log_idx2(bs, 1 + bitsToRead, "signed_feature_value", i, j);
						}
						else {
							val = gf_bs_read_int_log_idx2(bs, bitsToRead, "feature_value", i, j);
						}
						if (!j) seg_features_SEG_LVL_ALT_Q[i] = val;
					}
				}
			}
			//ignore all init steps
		}

	}

	//delta_q_params():
	/*u8 delta_q_res = 0;*/
	u8 delta_q_present = 0;
	if (base_q_idx > 0) {
		delta_q_present = gf_bs_read_int_log(bs, 1, "delta_q_present");
	}
	if (delta_q_present) {
		gf_bs_read_int_log(bs, 2, "delta_q_res");
	}

	//delta_lf_params():
	u8 delta_lf_present = 0;
	/*u8 delta_lf_res = 0;
	u8 delta_lf_multi = 0;*/
	if (delta_q_present) {
		if (!allow_intrabc) {
			delta_lf_present = gf_bs_read_int_log(bs, 1, "delta_lf_present");
		}
		if (delta_lf_present) {
			gf_bs_read_int_log(bs, 2, "delta_lf_res");
			gf_bs_read_int_log(bs, 1, "delta_lf_multi");
		}
	}

	//init lossless stuff!
	u8 CodedLossless = 1;
	for (idx = 0; idx < 8; idx++) {
		u8 qindex = av1_get_qindex(GF_TRUE, idx, base_q_idx, delta_q_present, 0/*CurrentQIndex always ignored at this level of parsin*/, segmentation_enabled, seg_features_SEG_LVL_ALT_Q_enabled, seg_features_SEG_LVL_ALT_Q);
		Bool LosslessArray = (qindex == 0) && (DeltaQYDc == 0) && (DeltaQUAc == 0) && (DeltaQUDc == 0) && (DeltaQVAc == 0) && (DeltaQVDc == 0);
		if (!LosslessArray)
			CodedLossless = 0;
	}
	Bool AllLossless = CodedLossless && (state->width == state->UpscaledWidth);

	//loop_filter_params():
	if (!CodedLossless && !allow_intrabc) {
		u8 loop_filter_level_0 = gf_bs_read_int_log(bs, 6, "loop_filter_level_0");
		u8 loop_filter_level_1 = gf_bs_read_int_log(bs, 6, "loop_filter_level_1");
		if (!state->config->monochrome) {
			if (loop_filter_level_0 || loop_filter_level_1) {
				gf_bs_read_int_log(bs, 6, "loop_filter_level_2");
				gf_bs_read_int_log(bs, 6, "loop_filter_level_3");
			}
		}
		gf_bs_read_int_log(bs, 3, "loop_filter_sharpness");
		u8 loop_filter_delta_enabled = gf_bs_read_int_log(bs, 1, "loop_filter_delta_enabled");
		if (loop_filter_delta_enabled == 1) {
			u8 loop_filter_delta_update = gf_bs_read_int_log(bs, 1, "loop_filter_delta_update");
			if (loop_filter_delta_update) {
				u32 i;
				for (i = 0; i < 8/*TOTAL_REFS_PER_FRAME*/; i++) {
					u8 update_ref_delta = gf_bs_read_int_log_idx(bs, 1, "update_ref_delta", i);
					if (update_ref_delta == 1) {
						gf_bs_read_int_log_idx(bs, 1 + 6, "loop_filter_ref_deltas", i);
					}
				}
				for (i = 0; i < 2; i++) {
					u8 update_mode_delta = gf_bs_read_int_log_idx(bs, 1, "update_mode_delta", i);
					if (update_mode_delta) {
						gf_bs_read_int_log_idx(bs, 1 + 6, "loop_filter_mode_deltas", i);
					}
				}
			}
		}
	}
	//cdef_params( ):
	if (!CodedLossless && !allow_intrabc && state->enable_cdef) {
		gf_bs_read_int_log(bs, 2, "cdef_damping_minus_3");
		u8 cdef_bits = gf_bs_read_int_log(bs, 2, "cdef_bits");
		u32 i, num_cd = 1 << cdef_bits;
		for (i = 0; i < num_cd; i++) {
			gf_bs_read_int_log_idx(bs, 4, "cdef_y_pri_strength", i);
			gf_bs_read_int_log_idx(bs, 2, "cdef_y_sec_strength", i);
			if (!state->config->monochrome) {
				gf_bs_read_int_log_idx(bs, 4, "cdef_uv_pri_strength", i);
				gf_bs_read_int_log_idx(bs, 2, "cdef_uv_sec_strength", i);
			}
		}
	}

	//lr_params( ) :
	if (!AllLossless && !allow_intrabc && state->enable_restoration) {
		u32 i, nb_planes = state->config->monochrome ? 1 : 3;
		u8 UsesLr = 0;
		u8 usesChromaLr = 0;
		for (i = 0; i < nb_planes; i++) {
			u8 lr_type = gf_bs_read_int_log_idx(bs, 2, "lr_type", i);
			//FrameRestorationType[i] = Remap_Lr_Type[lr_type]
			if (lr_type != AV1_RESTORE_NONE) {
				UsesLr = 1;
				if (i > 0) {
					usesChromaLr = 1;
				}
			}
		}
		if (UsesLr) {
			if (state->use_128x128_superblock) {
				gf_bs_read_int_log(bs, 1, "lr_unit_shift_minus_1");
			}
			else {
				u8 lr_unit_shift = gf_bs_read_int_log(bs, 1, "lr_unit_shift");
				if (lr_unit_shift) {
					gf_bs_read_int_log(bs, 1, "lr_unit_extra_shift");
					//lr_unit_shift += lr_unit_extra_shift;
				}
			}
			if (state->config->chroma_subsampling_x && state->config->chroma_subsampling_y && usesChromaLr) {
				gf_bs_read_int_log(bs, 1, "lr_uv_shift");
			}
		}
	}
	//read_tx_mode():
	if (CodedLossless == 1) {
	}
	else {
		gf_bs_read_int_log(bs, 1, "tx_mode_select");
	}

	//frame_reference_mode( ):
	u8 reference_select = 0;
	if (FrameIsIntra) {
	}
	else {
		reference_select = gf_bs_read_int_log(bs, 1, "reference_select");
	}

	//skip_mode_params( ):
	u8 skipModeAllowed = 0;
	if (FrameIsIntra || !reference_select || !state->enable_order_hint) {
	}
	else {
		u32 i;
		s32 forwardIdx = -1;
		s32 backwardIdx = -1;
		s32 forwardHint = 0;
		s32 backwardHint = 0;
		for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
			u8 refHint = state->RefOrderHint[ref_frame_idx[i]];
			if (av1_get_relative_dist(refHint, frame_state->order_hint, state) < 0) {
				if (forwardIdx < 0 || av1_get_relative_dist(refHint, forwardHint, state) > 0) {
					forwardIdx = i;
					forwardHint = refHint;
				}
			}
			else if (av1_get_relative_dist(refHint, frame_state->order_hint, state) > 0) {
				if (backwardIdx < 0 || av1_get_relative_dist(refHint, backwardHint, state) < 0) {
					backwardIdx = i;
					backwardHint = refHint;
				}
			}
		}
		if (forwardIdx < 0) {
			skipModeAllowed = 0;
		}
		else if (backwardIdx >= 0) {
			skipModeAllowed = 1;
			//SkipModeFrame[0] = AV1_LAST_FRAME + MIN(forwardIdx, backwardIdx);
			//SkipModeFrame[1] = AV1_LAST_FRAME + MAX(forwardIdx, backwardIdx);
		}
		else {
			s32 secondForwardIdx = -1;
			s32 secondForwardHint = 0;
			for (i = 0; i < AV1_REFS_PER_FRAME; i++) {
				u8 refHint = state->RefOrderHint[ref_frame_idx[i]];
				if (av1_get_relative_dist(refHint, forwardHint, state) < 0) {
					if (secondForwardIdx < 0 || av1_get_relative_dist(refHint, secondForwardHint, state) > 0) {
						secondForwardIdx = i;
						secondForwardHint = refHint;
					}
				}
			}
			if (secondForwardIdx < 0) {
				skipModeAllowed = 0;
			}
			else {
				skipModeAllowed = 1;
				//SkipModeFrame[ 0 ] = LAST_FRAME + Min(forwardIdx, secondForwardIdx)
				//SkipModeFrame[ 1 ] = LAST_FRAME + Max(forwardIdx, secondForwardIdx)
			}
		}
	}
	if (skipModeAllowed) {
		gf_bs_read_int_log(bs, 1, "skip_mode_present");
	}


	if (FrameIsIntra || error_resilient_mode || !state->enable_warped_motion) {

	}
	else {
		gf_bs_read_int_log(bs, 1, "allow_warped_motion");
	}

	gf_bs_read_int_log(bs, 1, "reduced_tx");

	//global_motion_params( )
	u32 ref;
	for (ref = AV1_LAST_FRAME; ref <= AV1_ALTREF_FRAME; ref++) {
		u32 i;
		for (i = 0; i < 6; i++) {
			state->GmParams.coefs[ref][i] = ((i % 3 == 2) ? 1 << WARPEDMODEL_PREC_BITS : 0);
		}
	}
	if (!FrameIsIntra) {
		u32 refs;
		for (refs = AV1_LAST_FRAME; refs <= AV1_ALTREF_FRAME; refs++) {
			u8 type = AV1_GMC_IDENTITY;
			Bool is_global = gf_bs_read_int_log_idx(bs, 1, "is_global", refs);
			if (is_global) {
				Bool is_rot_zoom = gf_bs_read_int_log_idx(bs, 1, "is_rot_zoom", refs);
				if (is_rot_zoom) {
					type = AV1_GMC_ROTZOOM;
				}
				else {
					Bool is_trans = gf_bs_read_int_log_idx(bs, 1, "is_translation", refs);
					type = is_trans ? AV1_GMC_TRANSLATION : AV1_GMC_AFFINE;

				}
			}

			if (type >= AV1_GMC_ROTZOOM) {
				av1_read_global_param(state, bs, type, refs, 2);
				av1_read_global_param(state, bs, type, refs, 3);
				if (type == AV1_GMC_AFFINE) {
					av1_read_global_param(state, bs, type, refs, 4);
					av1_read_global_param(state, bs, type, refs, 5);
				}
				else {
					state->GmParams.coefs[refs][4] = -state->GmParams.coefs[refs][3];
					state->GmParams.coefs[refs][5] = state->GmParams.coefs[refs][2];

				}
			}
			if (type >= AV1_GMC_TRANSLATION) {
				av1_read_global_param(state, bs, type, refs, 0);
				av1_read_global_param(state, bs, type, refs, 1);
			}
		}
	}

	//film_grain_params()
	if (!state->film_grain_params_present || (!state->frame_state.show_frame && !showable_frame)) {
	}
	else {
		u8 apply_grain = gf_bs_read_int_log(bs, 1, "apply_grain");
		if (apply_grain) {
			gf_bs_read_int_log(bs, 16, "grain_seed");
			u8 update_grain = 1;
			if (state->frame_state.frame_type == AV1_INTER_FRAME) {
				update_grain = gf_bs_read_int_log(bs, 1, "update_grain");
			}
			if (!update_grain) {
				gf_bs_read_int_log(bs, 3, "film_grain_params_ref_idx");
			}
			else {
				u32 i, num_y_points = gf_bs_read_int_log(bs, 4, "num_y_points");
				for (i = 0; i < num_y_points; i++) {
					gf_bs_read_int_log_idx(bs, 8, "point_y_value", i);
					gf_bs_read_int_log_idx(bs, 8, "point_y_scaling", i);
				}
				u8 chroma_scaling_from_luma = 0;
				if (!state->config->monochrome)
					chroma_scaling_from_luma = gf_bs_read_int_log(bs, 1, "chroma_scaling_from_luma");

				u8 num_cb_points = 0;
				u8 num_cr_points = 0;
				if (state->config->monochrome || chroma_scaling_from_luma ||
					((state->config->chroma_subsampling_x == 1) && (state->config->chroma_subsampling_y == 1) && (num_y_points == 0))
					) {
				}
				else {
					num_cb_points = gf_bs_read_int_log(bs, 4, "num_cb_points");
					for (i = 0; i < num_cb_points; i++) {
						gf_bs_read_int_log_idx(bs, 8, "point_cb_value", i);
						gf_bs_read_int_log_idx(bs, 8, "point_cb_scaling", i);
					}
					num_cr_points = gf_bs_read_int_log(bs, 4, "num_cr_points");
					for (i = 0; i < num_cr_points; i++) {
						gf_bs_read_int_log_idx(bs, 8, "point_cr_value", i);
						gf_bs_read_int_log_idx(bs, 8, "point_cr_scaling", i);
					}
				}
				gf_bs_read_int_log(bs, 2, "grain_scaling_minus_8");
				u8 ar_coeff_lag = gf_bs_read_int_log(bs, 2, "ar_coeff_lag");
				u16 numPosLuma = 2 * ar_coeff_lag * (ar_coeff_lag + 1);
				u16 numPosChroma = numPosLuma;
				if (num_y_points) {
					numPosChroma = numPosLuma + 1;
					for (i = 0; i < numPosLuma; i++) {
						gf_bs_read_int_log_idx(bs, 8, "ar_coeffs_y_plus_128", i);
					}
				}
				if (chroma_scaling_from_luma || num_cb_points) {
					for (i = 0; i < numPosChroma; i++) {
						gf_bs_read_int_log_idx(bs, 8, "ar_coeffs_cb_plus_128", i);
					}
				}
				if (chroma_scaling_from_luma || num_cr_points) {
					for (i = 0; i < numPosChroma; i++) {
						gf_bs_read_int_log_idx(bs, 8, "ar_coeffs_cr_plus_128", i);
					}
				}
				gf_bs_read_int_log(bs, 2, "ar_coeff_shift_minus_6");
				gf_bs_read_int_log(bs, 2, "grain_scale_shift");
				if (num_cb_points) {
					gf_bs_read_int_log(bs, 8, "cb_mult");
					gf_bs_read_int_log(bs, 8, "cb_luma_mult");
					gf_bs_read_int_log(bs, 9, "cb_offset");
				}
				if (num_cr_points) {
					gf_bs_read_int_log(bs, 8, "cr_mult");
					gf_bs_read_int_log(bs, 8, "cr_luma_mult");
					gf_bs_read_int_log(bs, 9, "cr_offset");
				}
				gf_bs_read_int_log(bs, 1, "overlap_flag");
				gf_bs_read_int_log(bs, 1, "clip_to_restricted_range");
			}
		}
	}

	//end of uncompressed header !!
}

Project: gpac
File: av_parsers.c

s32 gf_avc_read_sps_ext(const char *spse_data, u32 spse_size)
{
	GF_BitStream *bs;
	s32 sps_id;

	bs = gf_bs_new(spse_data, spse_size, GF_BITSTREAM_READ);
	sps_id = gf_avc_read_sps_ext_bs(bs);

	gf_bs_del(bs);
	return sps_id;
}

Project: gpac
File: av_parsers.c

GF_Err gf_avc_get_sps_info(u8 *sps_data, u32 sps_size, u32 *sps_id, u32 *width, u32 *height, s32 *par_n, s32 *par_d)
{
	AVCState avc;
	s32 idx;
	memset(&avc, 0, sizeof(AVCState));
	avc.sps_active_idx = -1;

	idx = gf_avc_read_sps(sps_data, sps_size, &avc, 0, NULL);
	if (idx < 0) {
		return GF_NON_COMPLIANT_BITSTREAM;
	}
	if (sps_id) *sps_id = idx;

	if (width) *width = avc.sps[idx].width;
	if (height) *height = avc.sps[idx].height;
	if (par_n) *par_n = avc.sps[idx].vui.par_num ? avc.sps[idx].vui.par_num : (u32)-1;
	if (par_d) *par_d = avc.sps[idx].vui.par_den ? avc.sps[idx].vui.par_den : (u32)-1;

	return GF_OK;
}

Project: gpac
File: av_parsers.c

static Bool vvc_parse_nal_header(GF_BitStream *bs, u8 *nal_unit_type, u8 *temporal_id, u8 *layer_id)
{
	u32 val;
	val = gf_bs_read_int_log(bs, 1, "forbidden_zero");
	if (val) return GF_FALSE;
	val = gf_bs_read_int_log(bs, 1, "resevred0");
	if (val) return GF_FALSE;

	val = gf_bs_read_int_log(bs, 6, "layerID");
	if (layer_id) *layer_id = val;

	val = gf_bs_read_int_log(bs, 5, "nuh_type");
	if (nal_unit_type) *nal_unit_type = val;

	val = gf_bs_read_int_log(bs, 3, "temporalID");
	if (!val) return GF_FALSE;
	val -= 1;
	if (temporal_id) *temporal_id = val;
	return GF_TRUE;
}

Project: gpac
File: av_parsers.c

static s32 gf_media_vvc_read_sps_bs_internal(GF_BitStream *bs, VVCState *vvc, u8 layer_id, u32 *vui_flag_pos)
{
	s32 vps_id, sps_id;
	u32 i, CtbSizeY;
	VVC_SPS *sps;
	u8 sps_ptl_dpb_hrd_params_present_flag;

	if (vui_flag_pos) *vui_flag_pos = 0;

	sps_id = gf_bs_read_int_log(bs, 4, "sps_id");
	if ((sps_id<0) || (sps_id >= 16)) {
		return -1;
	}
	vps_id = gf_bs_read_int_log(bs, 4, "vps_id");
	if ((vps_id<0) || (vps_id >= 16)) {
		return -1;
	}
	if (!vps_id && !vvc->vps[0].state) {
		vvc->vps[0].state = 1;
		vvc->vps[0].num_ptl = 1;
		vvc->vps[0].max_layers = 1;
		vvc->vps[0].all_layers_independent = 1;
	}

	sps = &vvc->sps[sps_id];
	if (!sps->state) {
		sps->state = 1;
		sps->id = sps_id;
		sps->vps_id = vps_id;
	}
	sps->max_sublayers = 1 + gf_bs_read_int_log(bs, 3, "max_sublayers_minus1");
	sps->chroma_format_idc = gf_bs_read_int_log(bs, 2, "chroma_format_idc");
	sps->log2_ctu_size = 5 + gf_bs_read_int_log(bs, 2, "log2_ctu_size_minus5");
	CtbSizeY = 1<<sps->log2_ctu_size;

	sps_ptl_dpb_hrd_params_present_flag = gf_bs_read_int_log(bs, 1, "sps_ptl_dpb_hrd_params_present_flag");
	if (sps_ptl_dpb_hrd_params_present_flag) {
		VVC_ProfileTierLevel ptl, *p_ptl;
		if (sps->vps_id) {
			p_ptl = &ptl;
		} else {
			p_ptl = &vvc->vps[0].ptl[0];
		}
		memset(p_ptl, 0, sizeof(VVC_ProfileTierLevel));
		p_ptl->pt_present = 1;
		p_ptl->ptl_max_tid = sps->max_sublayers-1;
		vvc_profile_tier_level(bs, p_ptl, 0);
	}
	sps->gdr_enabled = gf_bs_read_int_log(bs, 1, "gdr_enabled");
	sps->ref_pic_resampling = gf_bs_read_int_log(bs, 1, "ref_pic_resampling");
	if (sps->ref_pic_resampling)
		sps->res_change_in_clvs = gf_bs_read_int_log(bs, 1, "res_change_in_clvs");
	sps->width = gf_bs_read_ue_log(bs, "width");
	sps->height = gf_bs_read_ue_log(bs, "height");
	sps->conf_window = gf_bs_read_int_log(bs, 1, "conformance_window_present_flag");
	if (sps->conf_window) {
		sps->cw_left = gf_bs_read_ue_log(bs, "conformance_window_left");
		sps->cw_right = gf_bs_read_ue_log(bs, "conformance_window_right");
		sps->cw_top = gf_bs_read_ue_log(bs, "conformance_window_top");
		sps->cw_bottom = gf_bs_read_ue_log(bs, "conformance_window_bottom");
	}
	sps->subpic_info_present = gf_bs_read_int_log(bs, 1, "subpic_info_present");
	if (sps->subpic_info_present) {
		sps->nb_subpics = 1 + gf_bs_read_ue_log(bs, "nb_subpics_minus1");
		if (sps->nb_subpics>1) {
			u32 tmpWidthVal, tmpHeightVal;
			sps->independent_subpic_flags = gf_bs_read_int_log(bs, 1, "independent_subpic_flags");
			sps->subpic_same_size = gf_bs_read_int_log(bs, 1, "subpic_same_size");

			tmpWidthVal = (sps->width + CtbSizeY-1) / CtbSizeY;
			tmpWidthVal = gf_get_bit_size(tmpWidthVal);
			tmpHeightVal = (sps->height + CtbSizeY-1) / CtbSizeY;
			tmpHeightVal = gf_get_bit_size(tmpHeightVal);

			for (i=0; i<sps->nb_subpics; i++) {
				if( !sps->subpic_same_size || !i) {
					if (i && (sps->width > CtbSizeY))
						gf_bs_read_int_log(bs, tmpWidthVal, "subpic_ctu_top_left_x");
					if (i && (sps->height > CtbSizeY))
						gf_bs_read_int_log(bs, tmpHeightVal, "subpic_ctu_top_left_y");
					if ((i+1 < sps->nb_subpics) && (sps->width > CtbSizeY))
						gf_bs_read_int_log(bs, tmpWidthVal, "subpic_width_minus1");
					if ((i+1 < sps->nb_subpics) && (sps->height > CtbSizeY))
						gf_bs_read_int_log(bs, tmpHeightVal, "subpic_height_minus1");
				}
				if (!sps->independent_subpic_flags) {
					gf_bs_read_int_log(bs, 1, "subpic_treated_as_pic_flag");
					gf_bs_read_int_log(bs, 1, "loop_filter_across_subpic_enabled_flag");
				}
			}
			sps->subpicid_len = gf_bs_read_ue_log(bs, "subpic_id_len_minus1") + 1;
			sps->subpicid_mapping_explicit = gf_bs_read_int_log(bs, 1, "subpic_id_mapping_explicitly_signalled_flag");
			if (sps->subpicid_mapping_explicit) {
				sps->subpicid_mapping_present = gf_bs_read_int_log(bs, 1, "subpic_id_mapping_present_flag");
				if (sps->subpicid_mapping_present) {
					for (i=0; i<sps->nb_subpics; i++) {
						gf_bs_read_ue_log(bs, "subpic_id");
					}
				}
			}
		}
	}
	sps->bitdepth = gf_bs_read_ue_log(bs, "bitdepth_minus8") + 8;
	gf_bs_read_int_log(bs, 1, "entropy_coding_sync_enabled_flag");
	gf_bs_read_int_log(bs, 1, "entry_point_offsets_present_flag");
	sps->log2_max_poc_lsb = 4 + gf_bs_read_int_log(bs, 4, "log2_max_poc_lsb_minus4");
	if ((sps->poc_msb_cycle_flag = gf_bs_read_int_log(bs, 1, "poc_msb_cycle_flag")))
		sps->poc_msb_cycle_len = 1 + gf_bs_read_ue_log(bs, "poc_msb_cycle_len_minus1");

	u8 sps_num_extra_ph_bits = 8 * gf_bs_read_int_log(bs, 2, "sps_num_extra_ph_bytes");
	for (i=0; i<sps_num_extra_ph_bits; i++) {
		if (gf_bs_read_int_log_idx(bs, 1, "extra_ph_bit_present_flag", 1))
			sps->ph_num_extra_bits++;
	}
	u8 sps_num_extra_sh_bits = 8 * gf_bs_read_int_log(bs, 2, "num_extra_sh_bytes");
	for (i=0; i<sps_num_extra_sh_bits; i++) {
		if (gf_bs_read_int_log_idx(bs, 1, "extra_sh_bit_present_flag", i))
			sps->sh_num_extra_bits++;
	}

	if (sps_ptl_dpb_hrd_params_present_flag) {
		u8 sps_sublayer_dpb_params_flag = 0;
		if (sps->max_sublayers>1) {
			sps_sublayer_dpb_params_flag = gf_bs_read_int_log(bs, 1, "sps_sublayer_dpb_params_flag");
		}
		for (i=(sps_sublayer_dpb_params_flag ? 0 : sps->max_sublayers-1); i < sps->max_sublayers; i++ ) {
			gf_bs_read_ue_log_idx(bs, "dpb_max_dec_pic_buffering_minus1", i);
			gf_bs_read_ue_log_idx(bs, "dpb_max_num_reorder_pics", i);
			gf_bs_read_ue_log_idx(bs, "dpb_max_latency_increase_plus1", i);
		}
	}
	gf_bs_read_ue_log(bs, "sps_log2_min_luma_coding_block_size_minus2");
	gf_bs_read_int_log(bs, 1, "sps_partition_constraints_override_enabled_flag");
	gf_bs_read_ue_log(bs, "sps_log2_min_luma_coding_block_size_minus2");
	u8 sps_max_mtt_hierarchy_depth_intra_slice_luma = gf_bs_read_ue_log(bs, "sps_max_mtt_hierarchy_depth_intra_slice_luma");
	if (sps_max_mtt_hierarchy_depth_intra_slice_luma != 0) {
		gf_bs_read_ue_log(bs, "sps_log2_diff_max_bt_min_qt_intra_slice_luma");
		gf_bs_read_ue_log(bs, "sps_log2_diff_max_tt_min_qt_intra_slice_luma");
	}
	u8 sps_qtbtt_dual_tree_intra_flag = 0;
	if (sps->chroma_format_idc) {
		sps_qtbtt_dual_tree_intra_flag = gf_bs_read_int_log(bs, 1, "sps_qtbtt_dual_tree_intra_flag");
	}
	if (sps_qtbtt_dual_tree_intra_flag) {
		gf_bs_read_ue_log(bs, "sps_log2_diff_min_qt_min_cb_intra_slice_chroma");
		u8 sps_max_mtt_hierarchy_depth_intra_slice_chroma = gf_bs_read_ue_log(bs, "sps_max_mtt_hierarchy_depth_intra_slice_chroma");
		if( sps_max_mtt_hierarchy_depth_intra_slice_chroma != 0) {
			gf_bs_read_ue_log(bs, "sps_log2_diff_max_bt_min_qt_intra_slice_chroma");
			gf_bs_read_ue_log(bs, "sps_log2_diff_max_tt_min_qt_intra_slice_chroma");
		}
	}

	gf_bs_read_ue_log(bs, "sps_log2_diff_min_qt_min_cb_inter_slice");
	u8 sps_max_mtt_hierarchy_depth_inter_slice = gf_bs_read_ue_log(bs, "sps_max_mtt_hierarchy_depth_inter_slice");
	if (sps_max_mtt_hierarchy_depth_inter_slice != 0) {
		gf_bs_read_ue_log(bs, "sps_log2_diff_max_bt_min_qt_inter_slice");
		gf_bs_read_ue_log(bs, "sps_log2_diff_max_tt_min_qt_inter_slice");
	}
	//u8 sps_max_luma_transform_size_64_flag = 0;
	if (CtbSizeY > 32) {
		/*sps_max_luma_transform_size_64_flag = */gf_bs_read_int_log(bs, 1, "sps_max_luma_transform_size_64_flag");
	}
	u8 sps_transform_skip_enabled_flag = gf_bs_read_int_log(bs, 1, "sps_transform_skip_enabled_flag");

	if (sps_transform_skip_enabled_flag) {
		gf_bs_read_ue_log(bs, "sps_log2_transform_skip_max_size_minus2");
		gf_bs_read_int_log(bs, 1, "sps_bdpcm_enabled_flag");
	}
	if (gf_bs_read_int_log(bs, 1, "sps_mts_enabled_flag")) {
		gf_bs_read_int_log(bs, 1, "sps_explicit_mts_intra_enabled_flag");
		gf_bs_read_int_log(bs, 1, "sps_explicit_mts_inter_enabled_flag");
	}
	gf_bs_read_int_log(bs, 1, "sps_lfnst_enabled_flag");
	if (sps->chroma_format_idc) {
		u8 sps_joint_cbcr_enabled_flag = gf_bs_read_int_log(bs, 1, "sps_joint_cbcr_enabled_flag");
		u8 sps_same_qp_table_for_chroma_flag = gf_bs_read_int_log(bs, 1, "sps_same_qp_table_for_chroma_flag");
		u32 numQpTables = sps_same_qp_table_for_chroma_flag ? 1 : (sps_joint_cbcr_enabled_flag ? 3 : 2);
		for (i=0; i<numQpTables; i++) {
			gf_bs_read_se_log_idx(bs, "sps_qp_table_start_minus26", i);
			u32 j, sps_num_points_in_qp_table = 1 + gf_bs_read_ue_log_idx(bs, "sps_num_points_in_qp_table_minus1", i);
			for (j=0; j<sps_num_points_in_qp_table; j++) {
				gf_bs_read_ue_log_idx2(bs, "sps_delta_qp_in_val_minus1", i, j);
				gf_bs_read_ue_log_idx2(bs, "sps_delta_qp_diff_val", i, j);
			}
		}
	}
	gf_bs_read_int_log(bs, 1, "sps_sao_enabled_flag");
	sps->alf_enabled_flag = gf_bs_read_int_log(bs, 1, "sps_alf_enabled_flag");
	if (sps->alf_enabled_flag && sps->chroma_format_idc) {
		gf_bs_read_int_log(bs, 1, "sps_ccalf_enabled_flag");
	}
	/*! TODO parse the rest !*/

	return sps_id;
}

Project: gpac
File: av_parsers.c

static void av1_load_previous(AV1State *state, u8 primary_ref_frame, s8 *ref_frame_idx)
{
	s8 prevFrame = ref_frame_idx[primary_ref_frame];
	if (prevFrame < 0) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] load_previous: prevFrame reference index %d is invalid\n", prevFrame));
	}
	else {
		state->PrevGmParams = state->SavedGmParams[prevFrame];
		// load_loop_filter_params( prevFrame )
		// load_segmentation_params( prevFrame )
	}
}

Project: gpac
File: av_parsers.c

u32 gf_media_nalu_add_emulation_bytes(const u8 *buffer_src, u8 *buffer_dst, u32 nal_size)
{
	u32 i = 0, emulation_bytes_count = 0;
	u8 num_zero = 0;

	while (i < nal_size) {
		/*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003
		other than the following sequences shall not occur at any byte-aligned position:
		0x00000300
		0x00000301
		0x00000302
		0x00000303"
		*/
		if (num_zero == 2 && (u8)buffer_src[i] < 0x04) {
			/*add emulation code*/
			num_zero = 0;
			buffer_dst[i + emulation_bytes_count] = 0x03;
			emulation_bytes_count++;
			if (!buffer_src[i])
				num_zero = 1;
		}
		else {
			if (!buffer_src[i])
				num_zero++;
			else
				num_zero = 0;
		}
		buffer_dst[i + emulation_bytes_count] = buffer_src[i];
		i++;
	}
	return nal_size + emulation_bytes_count;
}

Project: gpac
File: av_parsers.c

static s32 gf_hevc_read_vps_bs_internal(GF_BitStream *bs, HEVCState *hevc, Bool stop_at_vps_ext)
{
	u8 vps_sub_layer_ordering_info_present_flag, vps_extension_flag;
	u32 i, j;
	s32 vps_id;
	HEVC_VPS *vps;
	u8 layer_id_included_flag[MAX_LHVC_LAYERS][64];

	//nalu header already parsed
	vps_id = gf_bs_read_int_log(bs, 4, "vps_id");

	if ((vps_id<0) || (vps_id >= 16)) return -1;

	vps = &hevc->vps[vps_id];
	vps->bit_pos_vps_extensions = -1;
	if (!vps->state) {
		vps->id = vps_id;
		vps->state = 1;
	}

	vps->base_layer_internal_flag = gf_bs_read_int_log(bs, 1, "base_layer_internal_flag");
	vps->base_layer_available_flag = gf_bs_read_int_log(bs, 1, "base_layer_available_flag");
	vps->max_layers = 1 + gf_bs_read_int_log(bs, 6, "max_layers_minus1");
	if (vps->max_layers > MAX_LHVC_LAYERS) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] sorry, %d layers in VPS but only %d supported\n", vps->max_layers, MAX_LHVC_LAYERS));
		return -1;
	}
	vps->max_sub_layers = gf_bs_read_int_log(bs, 3, "max_sub_layers_minus1") + 1;
	vps->temporal_id_nesting = gf_bs_read_int_log(bs, 1, "temporal_id_nesting");
	gf_bs_read_int_log(bs, 16, "vps_reserved_ffff_16bits");
	hevc_profile_tier_level(bs, 1, vps->max_sub_layers - 1, &vps->ptl, 0);

	vps_sub_layer_ordering_info_present_flag = gf_bs_read_int_log(bs, 1, "vps_sub_layer_ordering_info_present_flag");
	for (i = (vps_sub_layer_ordering_info_present_flag ? 0 : vps->max_sub_layers - 1); i < vps->max_sub_layers; i++) {
		gf_bs_read_ue_log_idx(bs, "vps_max_dec_pic_buffering_minus1", i);
		gf_bs_read_ue_log_idx(bs, "vps_max_num_reorder_pics", i);
		gf_bs_read_ue_log_idx(bs, "vps_max_latency_increase_plus1", i);
	}
	vps->max_layer_id = gf_bs_read_int_log(bs, 6, "max_layer_id");
	if (vps->max_layer_id > MAX_LHVC_LAYERS) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] VPS max layer ID %u but GPAC only supports %u\n", vps->max_layer_id, MAX_LHVC_LAYERS));
		return -1;
	}
	vps->num_layer_sets = gf_bs_read_ue_log(bs, "num_layer_sets_minus1") + 1;
	if (vps->num_layer_sets > MAX_LHVC_LAYERS) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] Wrong number of layer sets in VPS %d\n", vps->num_layer_sets));
		return -1;
	}
	for (i = 1; i < vps->num_layer_sets; i++) {
		for (j = 0; j <= vps->max_layer_id; j++) {
			layer_id_included_flag[i][j] = gf_bs_read_int_log_idx2(bs, 1, "layer_id_included_flag", i, j);
		}
	}
	vps->num_layers_in_id_list[0] = 1;
	for (i = 1; i < vps->num_layer_sets; i++) {
		u32 n, m;
		n = 0;
		for (m = 0; m <= vps->max_layer_id; m++) {
			if (layer_id_included_flag[i][m]) {
				vps->LayerSetLayerIdList[i][n++] = m;
				if (vps->LayerSetLayerIdListMax[i] < m)
					vps->LayerSetLayerIdListMax[i] = m;
			}
		}
		vps->num_layers_in_id_list[i] = n;
	}
	if (gf_bs_read_int_log(bs, 1, "vps_timing_info_present_flag")) {
		u32 vps_num_hrd_parameters;
		gf_bs_read_int_log(bs, 32, "vps_num_units_in_tick");
		gf_bs_read_int_log(bs, 32, "vps_time_scale");
		if (gf_bs_read_int_log(bs, 1, "vps_poc_proportional_to_timing_flag")) {
			gf_bs_read_ue_log(bs, "vps_num_ticks_poc_diff_one_minus1");
		}
		vps_num_hrd_parameters = gf_bs_read_ue_log(bs, "vps_num_hrd_parameters");
		for (i = 0; i < vps_num_hrd_parameters; i++) {
			Bool cprms_present_flag = GF_TRUE;
			gf_bs_read_ue_log_idx(bs, "hrd_layer_set_idx", i);
			if (i > 0)
				cprms_present_flag = gf_bs_read_int_log(bs, 1, "cprms_present_flag");
			hevc_parse_hrd_parameters(bs, cprms_present_flag, vps->max_sub_layers - 1, i);
		}
	}
	if (stop_at_vps_ext) {
		return vps_id;
	}

	vps_extension_flag = gf_bs_read_int_log(bs, 1, "vps_extension_flag");
	if (vps_extension_flag) {
		Bool res;
		gf_bs_align(bs);
		res = hevc_parse_vps_extension(vps, bs);
		if (res != GF_TRUE) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] Failed to parse VPS extensions\n"));
			return -1;
		}
		if (gf_bs_read_int_log(bs, 1, "vps_extension2_flag")) {
#if 0
			while (gf_bs_available(bs)) {
				/*vps_extension_data_flag */ gf_bs_read_int(bs, 1);
			}
#endif

		}
	}
	return vps_id;
}

Project: gpac
File: av_parsers.c

u32 gf_opus_check_frame(GF_OpusParser *op, u8 *data, u32 data_length)
{
	u32 block_size;

	if (!memcmp(data, "OpusHead", sizeof(char)*8))
		return 0;
	if (!memcmp(data, "OpusTags", sizeof(char)*8))
		return 0;

	/*consider the whole packet as Ogg packets and ISOBMFF samples for Opus are framed similarly*/
	static const int OpusFrameDurIn48k[] = { 480, 960, 1920, 2880, 480, 960, 1920, 2880, 480, 960, 1920, 2880,
		480, 960, 480, 960,
		120, 240, 480, 960, 120, 240, 480, 960, 120, 240, 480, 960, 120, 240, 480, 960,
	};
	int TOC_config = (data[0] & 0xf8) >> 3;
	//int s = (data[0] & 0x04) >> 2;
	block_size = OpusFrameDurIn48k[TOC_config];

	int c = data[0] & 0x03;
	if (c == 1 || c == 2) {
		block_size *= 2;
	} else if (c == 3) {
		/*unknown number of frames*/
		int num_frames = data[1] & 0x3f;
		block_size *= num_frames;
	}
	return block_size;
}

Project: gpac
File: av_parsers.c

s32 gf_bs_read_se(GF_BitStream *bs)
{
	u32 v = gf_bs_read_ue(bs);
	if ((v & 0x1) == 0) return (s32)(0 - (v >> 1));
	return (v + 1) >> 1;
}

Project: gpac
File: av_parsers.c

static GF_Err M4V_Reset(GF_M4VParser *m4v, u64 start)
{
	gf_bs_seek(m4v->bs, start);

	assert(start < (u64)1<<31);
	m4v->current_object_start = (u32)start;
	m4v->current_object_type = 0;
	return GF_OK;
}

Project: gpac
File: av_parsers.c

static void hevc_parse_hrd_parameters(GF_BitStream *bs, Bool commonInfPresentFlag, int maxNumSubLayersMinus1, u32 idx)
{
	int i;
	Bool nal_hrd_parameters_present_flag = GF_FALSE;
	Bool vcl_hrd_parameters_present_flag = GF_FALSE;
	Bool sub_pic_hrd_params_present_flag = GF_FALSE;

	if (commonInfPresentFlag) {
		nal_hrd_parameters_present_flag = gf_bs_read_int_log_idx(bs, 1, "nal_hrd_parameters_present_flag", idx);
		vcl_hrd_parameters_present_flag = gf_bs_read_int_log_idx(bs, 1, "vcl_hrd_parameters_present_flag", idx);
		if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {
			sub_pic_hrd_params_present_flag = gf_bs_read_int_log_idx(bs, 1, "sub_pic_hrd_params_present_flag", idx);
			if (sub_pic_hrd_params_present_flag) {
				gf_bs_read_int_log_idx(bs, 8, "tick_divisor_minus2", idx);
				gf_bs_read_int_log_idx(bs, 5, "du_cpb_removal_delay_increment_length_minus1", idx);
				gf_bs_read_int_log_idx(bs, 1, "sub_pic_cpb_params_in_pic_timing_sei_flag", idx);
				gf_bs_read_int_log_idx(bs, 5, "dpb_output_delay_du_length_minus1", idx);
			}
			gf_bs_read_int_log_idx(bs, 4, "bit_rate_scale", idx);
			gf_bs_read_int_log_idx(bs, 4, "cpb_size_scale", idx);
			if (sub_pic_hrd_params_present_flag) {
				gf_bs_read_int_log_idx(bs, 4, "cpb_size_du_scale", idx);
			}
			gf_bs_read_int_log_idx(bs, 5, "initial_cpb_removal_delay_length_minus1", idx);
			gf_bs_read_int_log_idx(bs, 5, "au_cpb_removal_delay_length_minus1", idx);
			gf_bs_read_int_log_idx(bs, 5, "dpb_output_delay_length_minus1", idx);
		}
	}
	for (i = 0; i <= maxNumSubLayersMinus1; i++) {
		Bool fixed_pic_rate_general_flag_i = gf_bs_read_int_log_idx(bs, 1, "fixed_pic_rate_general_flag", idx);
		Bool fixed_pic_rate_within_cvs_flag_i = GF_TRUE;
		Bool low_delay_hrd_flag_i = GF_FALSE;
		u32 cpb_cnt_minus1_i = 0;
		if (!fixed_pic_rate_general_flag_i) {
			fixed_pic_rate_within_cvs_flag_i = gf_bs_read_int_log_idx(bs, 1, "fixed_pic_rate_within_cvs_flag", idx);
		}
		if (fixed_pic_rate_within_cvs_flag_i)
			gf_bs_read_ue_log_idx(bs, "elemental_duration_in_tc_minus1", idx);
		else
			low_delay_hrd_flag_i = gf_bs_read_int_log_idx(bs, 1, "low_delay_hrd_flag", idx);
		if (!low_delay_hrd_flag_i) {
			cpb_cnt_minus1_i = gf_bs_read_ue_log_idx(bs, "cpb_cnt_minus1", idx);
		}
		if (nal_hrd_parameters_present_flag) {
			sub_layer_hrd_parameters(bs, i, cpb_cnt_minus1_i, sub_pic_hrd_params_present_flag, idx, i);
		}
		if (vcl_hrd_parameters_present_flag) {
			sub_layer_hrd_parameters(bs, i, cpb_cnt_minus1_i, sub_pic_hrd_params_present_flag, idx, i);
		}
	}
}

Project: gpac
File: av_parsers.c

s32 gf_avc_read_pps_bs(GF_BitStream *bs, AVCState *avc)
{
	return gf_avc_read_pps_bs_internal(bs, avc, 0);
}

Project: gpac
File: av_parsers.c

GF_Err gf_media_avc_change_par(GF_AVCConfig *avcc, s32 ar_n, s32 ar_d)
{
	GF_VUIInfo vuii;
	memset(&vuii, 0, sizeof(GF_VUIInfo));
	vuii.ar_num = ar_n;
	vuii.ar_den = ar_d;
	vuii.fullrange = -1;
	vuii.video_format = -1;
	vuii.color_prim = -1;
	vuii.color_tfc = -1;
	vuii.color_matrix = -1;
	return gf_avc_change_vui(avcc, &vuii);
}

Project: gpac
File: av_parsers.c

static u32 av1_uvlc(GF_BitStream *bs, const char *fname)
{
	u32 res;
	u8 leadingZeros = 0;
	while (1) {
		Bool done = gf_bs_read_int(bs, 1);
		if (done)
			break;
		leadingZeros++;
	}
	if (leadingZeros >= 32) {
		return 0xFFFFFFFF;
	}
	res = gf_bs_read_int(bs, leadingZeros) + (1 << leadingZeros) - 1;
	gf_bs_log(bs, 2*leadingZeros, fname, res);
	return res;
}

Project: gpac
File: av_parsers.c

s32 gf_media_vvc_parse_nalu_bs(GF_BitStream *bs, VVCState *vvc, u8 *nal_unit_type, u8 *temporal_id, u8 *layer_id)
{
	Bool is_slice = GF_FALSE;
	s32 ret = -1;
	Bool poc_reset = GF_FALSE;
	VVCSliceInfo n_state;

	gf_bs_enable_emulation_byte_removal(bs, GF_TRUE);

	memcpy(&n_state, &vvc->s_info, sizeof(VVCSliceInfo));
	if (!vvc_parse_nal_header(bs, nal_unit_type, temporal_id, layer_id)) return -1;

	n_state.nal_unit_type = *nal_unit_type;

	switch (n_state.nal_unit_type) {
	case GF_VVC_NALU_ACCESS_UNIT:
	case GF_VVC_NALU_END_OF_SEQ:
	case GF_VVC_NALU_END_OF_STREAM:
		ret = 1;
		break;

	case GF_VVC_NALU_SLICE_IDR_W_RADL:
	case GF_VVC_NALU_SLICE_IDR_N_LP:
		poc_reset = GF_TRUE;
	case GF_VVC_NALU_SLICE_TRAIL:
	case GF_VVC_NALU_SLICE_STSA:
	case GF_VVC_NALU_SLICE_RADL:
	case GF_VVC_NALU_SLICE_RASL:
	case GF_VVC_NALU_SLICE_CRA:
	case GF_VVC_NALU_SLICE_GDR:
		/* slice - read the info and compare.*/
		ret = vvc_parse_slice(bs, vvc, &n_state);
		if (ret < 0) return ret;

		ret = 0;
		if (n_state.compute_poc_defer || n_state.picture_header_in_slice_header_flag) {
			is_slice = GF_TRUE;
			n_state.compute_poc_defer = 0;
			if (poc_reset) {
				n_state.poc_lsb_prev = 0;
				n_state.poc_msb_prev = 0;
			}

			vvc_compute_poc(&n_state);
			if (vvc->s_info.poc != n_state.poc) {
				ret = 1;
				break;
			}
			if (!(*layer_id) || (n_state.prev_layer_id_plus1 && ((*layer_id) <= n_state.prev_layer_id_plus1 - 1))) {
				ret = 1;
				break;
			}
		}
		break;

	case GF_VVC_NALU_PIC_HEADER:
		if (vvc_parse_picture_header(bs, vvc, &n_state)<0) {
			ret = -1;
			break;
		}
		is_slice = GF_TRUE;

		/*POC reset for IDR frames, NOT for CRA*/
		if (n_state.irap_or_gdr_pic && !n_state.gdr_pic) {
			n_state.poc_lsb_prev = 0;
			n_state.poc_msb_prev = 0;
			vvc_compute_poc(&n_state);
		} else {
			//we cannot compute poc until we know the first picture unit type, since IDR will reset poc count
			//and irap_or_gdr_pic=0 does not prevent IDR from following
			n_state.compute_poc_defer = 1;
		}

		if (!(*layer_id) || (n_state.prev_layer_id_plus1 && ((*layer_id) <= n_state.prev_layer_id_plus1 - 1))) {
			ret = 1;
		}
		break;
	case GF_VVC_NALU_SEQ_PARAM:
		vvc->last_parsed_sps_id = gf_media_vvc_read_sps_bs_internal(bs, vvc, *layer_id, NULL);
		ret = (vvc->last_parsed_sps_id>=0) ? 0 : -1;
		break;
	case GF_VVC_NALU_PIC_PARAM:
		vvc->last_parsed_pps_id = gf_media_vvc_read_pps_bs_internal(bs, vvc);
		ret = (vvc->last_parsed_pps_id>=0) ? 0 : -1;
		break;
	case GF_VVC_NALU_VID_PARAM:
		vvc->last_parsed_vps_id = gf_media_vvc_read_vps_bs_internal(bs, vvc, GF_FALSE);
		ret = (vvc->last_parsed_vps_id>=0) ? 0 : -1;
		break;
	case GF_VVC_NALU_DEC_PARAM:
		ret = 0;
		break;
	case GF_VVC_NALU_APS_PREFIX:
		//we use the mix aps type + aps id (first 8 bits) as unique identifier
		vvc->last_parsed_aps_id = gf_bs_read_int_log(bs, 8, "aps_id");
		ret = 0;
		break;
	default:
		ret = 0;
		break;
	}

	/* save _prev values */
	if ((ret>0) && vvc->s_info.sps) {
//		n_state.frame_num_offset_prev = vvc->s_info.frame_num_offset;
//		n_state.frame_num_prev = vvc->s_info.frame_num;

		n_state.poc_lsb_prev = vvc->s_info.poc_lsb;
		n_state.poc_msb_prev = vvc->s_info.poc_msb;
		if (is_slice)
			n_state.prev_layer_id_plus1 = *layer_id + 1;
	}

	memcpy(&vvc->s_info, &n_state, sizeof(VVCSliceInfo));

	return ret;
}

Project: gpac
File: av_parsers.c

s32 gf_avc_read_sps_bs(GF_BitStream *bs, AVCState *avc, u32 subseq_sps, u32 *vui_flag_pos)
{
	return gf_avc_read_sps_bs_internal(bs, avc, subseq_sps, vui_flag_pos, 0);
}

Project: gpac
File: av_parsers.c

Bool gf_ac3_parser(u8 *buf, u32 buflen, u32 *pos, GF_AC3Config *hdr, Bool full_parse)
{
	GF_BitStream *bs;
	Bool ret;

	if (buflen < 6) return GF_FALSE;
	(*pos) = AC3_FindSyncCode(buf, buflen);
	if (*pos >= buflen) return GF_FALSE;

	bs = gf_bs_new((const char*)(buf + *pos), buflen, GF_BITSTREAM_READ);
	ret = gf_ac3_parser_bs(bs, hdr, full_parse);
	gf_bs_del(bs);

	return ret;
}

Project: gpac
File: av_parsers.c

u32 gf_id3_read_size(GF_BitStream *bs)
{
	u32 size = 0;
	gf_bs_read_int(bs, 1);
	size |= gf_bs_read_int(bs, 7);
	size<<=7;
	gf_bs_read_int(bs, 1);
	size |= gf_bs_read_int(bs, 7);
	size<<=7;
	gf_bs_read_int(bs, 1);
	size |= gf_bs_read_int(bs, 7);
	size<<=7;
	gf_bs_read_int(bs, 1);
	size |= gf_bs_read_int(bs, 7);
	return size;
}

Project: gpac
File: av_parsers.c

static void dec_ref_pic_marking(GF_BitStream *bs, Bool IdrPicFlag) {
	if (IdrPicFlag) {
		gf_bs_read_int_log(bs, 1, "no_output_of_prior_pics_flag");
		gf_bs_read_int_log(bs, 1, "long_term_reference_flag");
	}
	else {
		if (gf_bs_read_int_log(bs, 1, "adaptive_ref_pic_marking_mode_flag")) {
			u32 idx=0, memory_management_control_operation;
			do {
				memory_management_control_operation = gf_bs_read_ue_log_idx(bs, "memory_management_control_operation", idx);
				if (memory_management_control_operation == 1 || memory_management_control_operation == 3)
					gf_bs_read_ue_log_idx(bs, "difference_of_pic_nums_minus1", idx);
				if (memory_management_control_operation == 2)
					gf_bs_read_ue_log_idx(bs, "long_term_pic_num", idx);
				if (memory_management_control_operation == 3 || memory_management_control_operation == 6)
					gf_bs_read_ue_log_idx(bs, "long_term_frame_idx", idx);
				if (memory_management_control_operation == 4)
					gf_bs_read_ue_log_idx(bs, "max_long_term_frame_idx_plus1", idx);
				idx++;
			} while (memory_management_control_operation != 0);
		}
	}
}

Project: gpac
File: av_parsers.c

s32 gf_hevc_read_vps(u8 *data, u32 size, HEVCState *hevc)
{
	return gf_hevc_read_vps_ex(data, &size, hevc, GF_FALSE);
}

Project: gpac
File: av_parsers.c

GF_Err gf_av1_parse_obu(GF_BitStream *bs, ObuType *obu_type, u64 *obu_size, u32 *obu_hdr_size, AV1State *state)
{
	GF_Err e = GF_OK;
	u32 i, hdr_size;
	u64 pos = gf_bs_get_position(bs);

	if (!bs || !obu_type || !state)
		return GF_BAD_PARAM;

	state->bs_overread = GF_FALSE;
	gf_bs_set_eos_callback(bs, on_aom_av1_eos, state);

	state->obu_extension_flag = state->obu_has_size_field = 0;
	state->temporal_id = state->spatial_id = 0;
	state->frame_state.uncompressed_header_bytes = 0;
	e = gf_av1_parse_obu_header(bs, obu_type, &state->obu_extension_flag, &state->obu_has_size_field, &state->temporal_id, &state->spatial_id);
	if (e)
		return e;

	if (state->obu_has_size_field) {
		*obu_size = (u32)gf_av1_leb128_read(bs, NULL);
	}
	else {
		if (*obu_size >= 1 + state->obu_extension_flag) {
			*obu_size = *obu_size - 1 - state->obu_extension_flag;
		}
		else {
			GF_LOG(state->config ? GF_LOG_WARNING : GF_LOG_DEBUG, GF_LOG_CODING, ("[AV1] computed OBU size "LLD" (input value = "LLU"). Skipping.\n", *obu_size - 1 - state->obu_extension_flag, *obu_size));
			return GF_NON_COMPLIANT_BITSTREAM;
		}
	}
	hdr_size = (u32)(gf_bs_get_position(bs) - pos);
	if ((gf_bs_available(bs) < *obu_size) || state->bs_overread) {
		gf_bs_seek(bs, pos);
		return GF_BUFFER_TOO_SMALL;
	}
	*obu_size += hdr_size;
	if (obu_hdr_size) *obu_hdr_size = hdr_size;


	if (*obu_type != OBU_SEQUENCE_HEADER && *obu_type != OBU_TEMPORAL_DELIMITER &&
		state->OperatingPointIdc != 0 && state->obu_extension_flag == 1)
	{
		u32 inTemporalLayer = (state->OperatingPointIdc >> state->temporal_id) & 1;
		u32 inSpatialLayer = (state->OperatingPointIdc >> (state->spatial_id + 8)) & 1;
		if (!inTemporalLayer || !inSpatialLayer) {
			*obu_type = -1;
			gf_bs_seek(bs, pos + *obu_size);
			return GF_OK;
		}
	}

	e = GF_OK;

	/* for AVIF a1lx */
	for (i = state->spatial_id; i < 4; i++) {
		state->layer_size[i] = (u32) (pos + *obu_size);
	}

	switch (*obu_type) {
	case OBU_SEQUENCE_HEADER:
		av1_parse_sequence_header_obu(bs, state);
		if (gf_bs_get_position(bs) > pos + *obu_size) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] Sequence header parsing consumed too many bytes !\n"));
			e = GF_NON_COMPLIANT_BITSTREAM;
		}
		gf_bs_seek(bs, pos + *obu_size);
		break;

	case OBU_METADATA:
#if 0
		//TODO + sample groups
		const ObuMetadataType metadata_type = (u32)read_leb128(bs, NULL); we should check for 16 bits limit(AV1MetadataSampleGroupEntry) for ISOBMFF bindings, see https ://github.com/AOMediaCodec/av1-isobmff/pull/86#issuecomment-416659538
		if (metadata_type == OBU_METADATA_TYPE_ITUT_T35) {
		}
		else if (metadata_type == OBU_METADATA_TYPE_HDR_CLL) {
		}
		else if (metadata_type == OBU_METADATA_TYPE_HDR_MDCV) {
		}
		else if (metadata_type == OBU_METADATA_TYPE_SCALABILITY) {
		}
		else if (metadata_type == METADATA_TYPE_TIMECODE) {
		}
#endif
		GF_LOG(GF_LOG_INFO, GF_LOG_CODING, ("[AV1] parsing for metadata is not implemented. Forwarding.\n"));

		if (gf_bs_get_position(bs) > pos + *obu_size) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] Metadata parsing consumed too many bytes !\n"));
			e = GF_NON_COMPLIANT_BITSTREAM;
		}
		gf_bs_seek(bs, pos + *obu_size);
		break;

	case OBU_FRAME_HEADER:
	case OBU_REDUNDANT_FRAME_HEADER:
		if (state->config) {
			av1_parse_frame_header(bs, state);
			if (gf_bs_get_position(bs) > pos + *obu_size) {
				GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] Frame header parsing consumed too many bytes !\n"));
				e = GF_NON_COMPLIANT_BITSTREAM;
			}
		}
		gf_bs_seek(bs, pos + *obu_size);
		break;
	case OBU_FRAME:
		e = av1_parse_frame(bs, state, pos, *obu_size);
		if (gf_bs_get_position(bs) != pos + *obu_size) {
			GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] Frame parsing did not consume the right number of bytes !\n"));
			e = GF_NON_COMPLIANT_BITSTREAM;
		}
		gf_bs_seek(bs, pos + *obu_size);
		break;
	case OBU_TILE_GROUP:
		if (state->config) {
			e = av1_parse_tile_group(bs, state, pos, *obu_size);
			if (gf_bs_get_position(bs) != pos + *obu_size) {
				GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] Tile group parsing did not consume the right number of bytes !\n"));
				e = GF_NON_COMPLIANT_BITSTREAM;
			}
		}
		gf_bs_seek(bs, pos + *obu_size);
		break;
	case OBU_TEMPORAL_DELIMITER:
		state->frame_state.seen_frame_header = GF_FALSE;
	case OBU_PADDING:
		gf_bs_seek(bs, pos + *obu_size);
		break;
	default:
		GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] unknown OBU type %u (size "LLU"). Skipping.\n", *obu_type, *obu_size));
		gf_bs_seek(bs, pos + *obu_size);
		break;
	}
	return e;
}

Project: gpac
File: av_parsers.c

static u32 gf_media_nalu_locate_start_code_bs(GF_BitStream *bs, Bool locate_trailing)
{
	u32 v, bpos, nb_cons_zeros = 0;
	char avc_cache[AVC_CACHE_SIZE];
	u64 end, cache_start, load_size;
	u64 start = gf_bs_get_position(bs);
	if (start < 3) return 0;

	load_size = 0;
	bpos = 0;
	cache_start = 0;
	end = 0;
	v = 0xffffffff;
	while (!end) {
		/*refill cache*/
		if (bpos == (u32)load_size) {
			if (!gf_bs_available(bs)) break;
			load_size = gf_bs_available(bs);
			if (load_size > AVC_CACHE_SIZE) load_size = AVC_CACHE_SIZE;
			bpos = 0;
			cache_start = gf_bs_get_position(bs);
			gf_bs_read_data(bs, avc_cache, (u32)load_size);
		}
		v = ( (v<<8) & 0xFFFFFF00) | ((u32) avc_cache[bpos]);
		bpos++;

		if (locate_trailing) {
			if ((v & 0x000000FF) == 0) nb_cons_zeros++;
			else nb_cons_zeros = 0;
		}

		if (v == 0x00000001) end = cache_start + bpos - 4;
		else if ((v & 0x00FFFFFF) == 0x00000001) end = cache_start + bpos - 3;
	}

	gf_bs_seek(bs, start);
	if (!end) end = gf_bs_get_size(bs);
	if (locate_trailing) {
		if (nb_cons_zeros >= 3)
			return (u32)(end - start - nb_cons_zeros);
	}
	return (u32)(end - start);
}

Project: gpac
File: av_parsers.c

void hevc_pred_weight_table(GF_BitStream *bs, HEVCState *hevc, HEVCSliceInfo *si, HEVC_PPS *pps, HEVC_SPS *sps, u32 num_ref_idx_l0_active, u32 num_ref_idx_l1_active)
{
	u32 i, num_ref_idx;
	Bool first_pass = GF_TRUE;
	u8 luma_weights[20], chroma_weights[20];
	u32 ChromaArrayType = sps->separate_colour_plane_flag ? 0 : sps->chroma_format_idc;

	num_ref_idx = num_ref_idx_l0_active;

	gf_bs_read_ue_log(bs, "luma_log2_weight_denom");
	if (ChromaArrayType != 0)
		gf_bs_read_se_log(bs, "delta_chroma_log2_weight_denom");

parse_weights:
	for (i = 0; i < num_ref_idx; i++) {
		luma_weights[i] = gf_bs_read_int_log_idx(bs, 1, "luma_weights", i);
		//infered to be 0 if not present
		chroma_weights[i] = 0;
	}
	if (ChromaArrayType != 0) {
		for (i = 0; i < num_ref_idx; i++) {
			chroma_weights[i] = gf_bs_read_int_log_idx(bs, 1, "chroma_weights", i);
		}
	}
	for (i = 0; i < num_ref_idx; i++) {
		if (luma_weights[i]) {
			gf_bs_read_se_log_idx(bs, "delta_luma_weight_l0", i);
			gf_bs_read_se_log_idx(bs, "luma_offset_l0", i);
		}
		if (chroma_weights[i]) {
			gf_bs_read_se_log_idx(bs, "delta_chroma_weight_l0_0", i);
			gf_bs_read_se_log_idx(bs, "delta_chroma_offset_l0_0", i);

			gf_bs_read_se_log_idx(bs, "delta_chroma_weight_l0_1", i);
			gf_bs_read_se_log_idx(bs, "delta_chroma_offset_l0_1", i);
		}
	}

	if (si->slice_type == GF_HEVC_SLICE_TYPE_B) {
		if (!first_pass) return;
		first_pass = GF_FALSE;
		num_ref_idx = num_ref_idx_l1_active;
		goto parse_weights;
	}
}

Project: gpac
File: av_parsers.c

static u32 lhvc_get_scalability_id(HEVC_VPS *vps, u32 layer_id_in_vps, u32 scalability_type)
{
	u32 idx;
	if (!vps->scalability_mask[scalability_type]) return 0;
	idx = scalability_type_to_idx(vps, scalability_type);
	return vps->dimension_id[layer_id_in_vps][idx];
}

Project: gpac
File: av_parsers.c

GF_Err gf_media_parse_ivf_frame_header(GF_BitStream *bs, u64 *frame_size, u64 *pts)
{
	if (!frame_size) return GF_BAD_PARAM;
	if (gf_bs_available(bs) < 12)
		return GF_BUFFER_TOO_SMALL;

	*frame_size = gf_bs_read_u32_le(bs);
	if (*frame_size > 256 * 1024 * 1024) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IVF] Wrong frame size %u\n", *frame_size));
		*frame_size = 0;
		return GF_NON_COMPLIANT_BITSTREAM;
	}

	*pts = gf_bs_read_u64_le(bs);

	return GF_OK;
}

Project: gpac
File: av_parsers.c

static void av1_parse_frame_header(GF_BitStream *bs, AV1State *state)
{
	AV1StateFrame *frame_state = &state->frame_state;
	if (frame_state->seen_frame_header == GF_FALSE) {
		u64 pos = gf_bs_get_position(bs);
		state->frame_state.show_existing_frame = GF_FALSE;
		frame_state->seen_frame_header = GF_TRUE;
		av1_parse_uncompressed_header(bs, state);
		state->frame_state.is_first_frame = GF_FALSE;
		state->frame_state.uncompressed_header_bytes = (u32) (gf_bs_get_position(bs) - pos);

		if (state->frame_state.show_existing_frame) {
			av1_decode_frame_wrapup(state);
			frame_state->seen_frame_header = GF_FALSE;
		}
		else {
			//TileNum = 0;
			frame_state->seen_frame_header = GF_TRUE;
		}
	}
}

Project: gpac
File: av_parsers.c

static s32 gf_avc_read_pps_bs_internal(GF_BitStream *bs, AVCState *avc, u32 nal_hdr)
{
	s32 pps_id;
	AVC_PPS *pps;

	gf_bs_enable_emulation_byte_removal(bs, GF_TRUE);

	if (!nal_hdr) {
		gf_bs_read_int_log(bs, 1, "forbidden_zero_bit");
		gf_bs_read_int_log(bs, 2, "nal_ref_idc");
		gf_bs_read_int_log(bs, 5, "nal_unit_type");
	}
	pps_id = gf_bs_read_ue_log(bs, "pps_id");
	if ((pps_id<0) || (pps_id >= 255)) {
		return -1;
	}
	pps = &avc->pps[pps_id];
	pps->id = pps_id;

	if (!pps->status) pps->status = 1;
	pps->sps_id = gf_bs_read_ue_log(bs, "sps_id");
	if ((pps->sps_id<0) || (pps->sps_id >= 32)) {
		pps->sps_id = 0;
		return -1;
	}
	/*sps_id may be refer to regular SPS or subseq sps, depending on the coded slice referring to the pps*/
	if (!avc->sps[pps->sps_id].state && !avc->sps[pps->sps_id + GF_SVC_SSPS_ID_SHIFT].state) {
		return -1;
	}
	avc->pps_active_idx = pps->id; /*set active sps*/
	avc->sps_active_idx = pps->sps_id; /*set active sps*/
	pps->entropy_coding_mode_flag = gf_bs_read_int_log(bs, 1, "entropy_coding_mode_flag");
	pps->pic_order_present = gf_bs_read_int_log(bs, 1, "pic_order_present");
	pps->slice_group_count = gf_bs_read_ue_log(bs, "slice_group_count_minus1") + 1;
	if (pps->slice_group_count > 1) {
		u32 iGroup;
		pps->mb_slice_group_map_type = gf_bs_read_ue_log(bs, "mb_slice_group_map_type");
		if (pps->mb_slice_group_map_type == 0) {
			for (iGroup = 0; iGroup <= pps->slice_group_count - 1; iGroup++)
				gf_bs_read_ue_log_idx(bs, "run_length_minus1", iGroup);
		}
		else if (pps->mb_slice_group_map_type == 2) {
			for (iGroup = 0; iGroup < pps->slice_group_count - 1; iGroup++) {
				gf_bs_read_ue_log_idx(bs, "top_left", iGroup);
				gf_bs_read_ue_log_idx(bs, "bottom_right", iGroup);
			}
		}
		else if (pps->mb_slice_group_map_type == 3 || pps->mb_slice_group_map_type == 4 || pps->mb_slice_group_map_type == 5) {
			gf_bs_read_int_log(bs, 1, "slice_group_change_direction_flag");
			gf_bs_read_ue_log(bs, "slice_group_change_rate_minus1");
		}
		else if (pps->mb_slice_group_map_type == 6) {
			u32 i;
			pps->pic_size_in_map_units_minus1 = gf_bs_read_ue_log(bs, "pic_size_in_map_units_minus1");
			for (i = 0; i <= pps->pic_size_in_map_units_minus1; i++) {
				gf_bs_read_int_log_idx(bs, (u32)ceil(log(pps->slice_group_count) / log(2)), "slice_group_id", i);
			}
		}
	}
	pps->num_ref_idx_l0_default_active_minus1 = gf_bs_read_ue_log(bs, "num_ref_idx_l0_default_active_minus1");
	pps->num_ref_idx_l1_default_active_minus1 = gf_bs_read_ue_log(bs, "num_ref_idx_l1_default_active_minus1");

	/*
	if ((pps->ref_count[0] > 32) || (pps->ref_count[1] > 32)) goto exit;
	*/

	pps->weighted_pred_flag = gf_bs_read_int_log(bs, 1, "weighted_pred_flag");
	gf_bs_read_int_log(bs, 2, "weighted_bipred_idc");
	gf_bs_read_se_log(bs, "init_qp_minus26");
	gf_bs_read_se_log(bs, "init_qs_minus26");
	gf_bs_read_se_log(bs, "chroma_qp_index_offset");
	pps->deblocking_filter_control_present_flag = gf_bs_read_int_log(bs, 1, "deblocking_filter_control_present_flag");
	gf_bs_read_int_log(bs, 1, "constrained_intra_pred");
	pps->redundant_pic_cnt_present = gf_bs_read_int_log(bs, 1, "redundant_pic_cnt_present");

	return pps_id;
}

Project: gpac
File: av_parsers.c

void gf_bs_write_ue(GF_BitStream *bs, u32 num) {
	s32 length = 1;
	s32 temp = ++num;

	while (temp != 1) {
		temp >>= 1;
		length += 2;
	}

	gf_bs_write_int(bs, 0, length >> 1);
	gf_bs_write_int(bs, num, (length + 1) >> 1);
}

Project: gpac
File: av_parsers.c

u32 gf_mp3_bit_rate(u32 hdr)
{
	u8 version = gf_mp3_version(hdr);
	u8 layer = gf_mp3_layer(hdr);
	u8 bitRateIndex = (hdr >> 12) & 0xF;
	u32 lidx;
	/*MPEG-1*/
	if (version & 1) {
		if (!layer) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[MPEG-1/2 Audio] layer index not valid\n"));
			return 0;
		}
		lidx = layer - 1;
	}
	/*MPEG-2/2.5*/
	else {
		lidx = 3 + (layer >> 1);
	}
	if (lidx>4) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[MPEG-1/2 Audio] layer index not valid\n"));
		return 0;
	}
	return bitrate_table[lidx][bitRateIndex];
}

Project: gpac
File: av_parsers.c

static s32 av1_delta_q(GF_BitStream *bs, const char *name_flag, const char *name)
{
	Bool delta_coded = gf_bs_read_int_log(bs, 1, name_flag);
	s32 delta_q = 0;
	if (delta_coded) {
		u32 signMask = 1 << (7 - 1);
		delta_q = gf_bs_read_int_log(bs, 7, name);
		if (delta_q & signMask)
			delta_q = delta_q - 2 * signMask;
	}
	return delta_q;
}

Project: gpac
File: av_parsers.c

static Bool hevc_parse_short_term_ref_pic_set(GF_BitStream *bs, HEVC_SPS *sps, u32 idx_rps)
{
	u32 i;
	Bool inter_ref_pic_set_prediction_flag = 0;
	if (idx_rps != 0)
		inter_ref_pic_set_prediction_flag = gf_bs_read_int_log_idx(bs, 1, "inter_ref_pic_set_prediction_flag", idx_rps);

	if (inter_ref_pic_set_prediction_flag) {
		HEVC_ReferencePictureSets *ref_ps, *rps;
		u32 delta_idx_minus1 = 0;
		u32 ref_idx;
		u32 delta_rps_sign;
		u32 abs_delta_rps_minus1, nb_ref_pics;
		s32 deltaRPS;
		u32 k = 0, k0 = 0, k1 = 0;
		if (idx_rps == sps->num_short_term_ref_pic_sets)
			delta_idx_minus1 = gf_bs_read_ue_log_idx(bs, "delta_idx_minus1", idx_rps);

		assert(delta_idx_minus1 <= idx_rps - 1);
		ref_idx = idx_rps - 1 - delta_idx_minus1;
		delta_rps_sign = gf_bs_read_int_log_idx(bs, 1, "delta_rps_sign", idx_rps);
		abs_delta_rps_minus1 = gf_bs_read_ue_log_idx(bs, "abs_delta_rps_minus1", idx_rps);
		deltaRPS = (1 - (delta_rps_sign << 1)) * (abs_delta_rps_minus1 + 1);

		rps = &sps->rps[idx_rps];
		ref_ps = &sps->rps[ref_idx];
		nb_ref_pics = ref_ps->num_negative_pics + ref_ps->num_positive_pics;
		for (i = 0; i <= nb_ref_pics; i++) {
			s32 ref_idc;
			s32 used_by_curr_pic_flag = gf_bs_read_int_log_idx2(bs, 1, "used_by_curr_pic_flag", idx_rps, i);
			ref_idc = used_by_curr_pic_flag ? 1 : 0;
			if (!used_by_curr_pic_flag) {
				used_by_curr_pic_flag = gf_bs_read_int_log_idx2(bs, 1, "used_by_curr_pic_flag", idx_rps, i);
				ref_idc = used_by_curr_pic_flag << 1;
			}
			if ((ref_idc == 1) || (ref_idc == 2)) {
				s32 deltaPOC = deltaRPS;
				if (i < nb_ref_pics)
					deltaPOC += ref_ps->delta_poc[i];

				rps->delta_poc[k] = deltaPOC;

				if (deltaPOC < 0)  k0++;
				else k1++;

				k++;
			}
		}
		rps->num_negative_pics = k0;
		rps->num_positive_pics = k1;
	}
	else {
		s32 prev = 0, poc;
		sps->rps[idx_rps].num_negative_pics = gf_bs_read_ue_log_idx(bs, "num_negative_pics", idx_rps);
		sps->rps[idx_rps].num_positive_pics = gf_bs_read_ue_log_idx(bs, "num_positive_pics", idx_rps);
		if (sps->rps[idx_rps].num_negative_pics > 16)
			return GF_FALSE;
		if (sps->rps[idx_rps].num_positive_pics > 16)
			return GF_FALSE;
		for (i = 0; i < sps->rps[idx_rps].num_negative_pics; i++) {
			u32 delta_poc_s0_minus1 = gf_bs_read_ue_log_idx2(bs, "delta_poc_s0_minus1", idx_rps, i);
			poc = prev - delta_poc_s0_minus1 - 1;
			prev = poc;
			sps->rps[idx_rps].delta_poc[i] = poc;
			gf_bs_read_int_log_idx2(bs, 1, "delta_poc_s0_minus1", idx_rps, i);
		}
		for (i = 0; i < sps->rps[idx_rps].num_positive_pics; i++) {
			u32 delta_poc_s1_minus1 = gf_bs_read_ue_log_idx2(bs, "delta_poc_s1_minus1" , idx_rps, i);
			poc = prev + delta_poc_s1_minus1 + 1;
			prev = poc;
			sps->rps[idx_rps].delta_poc[i] = poc;
			gf_bs_read_int_log_idx2(bs, 1, "used_by_curr_pic_s1_flag", idx_rps, i);
		}
	}
	return GF_TRUE;
}

Project: gpac
File: av_parsers.c

static u32 av1_read_ns(GF_BitStream *bs, u32 n, const char *fname)
{
	u32 v, res;
	Bool extra_bit;
	int w = (u32)(log(n) / log(2)) + 1;
	u32 m = (1 << w) - n;
	assert(w < 32);
	v = gf_bs_read_int(bs, w - 1);
	if (v < m) {
		if (fname) {
			gf_bs_log(bs, w-1, fname, v);
		}
		return v;
	}
	extra_bit = gf_bs_read_int(bs, 1);
	res = (v << 1) - m + extra_bit;
	if (fname) {
		gf_bs_log(bs, w, fname, res);
	}
	return res;
}

Project: gpac
File: av_parsers.c

const char *gf_m4a_get_profile_name(u8 audio_pl)
{
	u32 i, count = GF_ARRAY_LENGTH(M4AProfiles);
	for (i=0; i<count; i++) {
		if ((u32) audio_pl==M4AProfiles[i].value)
			return M4AProfiles[i].name;
	}
	return "ISO Reserved / User Private";
}

Project: gpac
File: av_parsers.c

u32 gf_latm_get_value(GF_BitStream *bs)
{
	u32 i, tmp, value = 0;
	u32 bytesForValue = gf_bs_read_int(bs, 2);
	for (i = 0; i <= bytesForValue; i++) {
		value <<= 8;
		tmp = gf_bs_read_int(bs, 8);
		value += tmp;
	}
	return value;
}

Project: gpac
File: av_parsers.c

static void avc_hevc_rewrite_vui(GF_VUIInfo *vui_info, GF_BitStream *orig, GF_BitStream *mod)
{
	/* VUI present flag*/
	Bool vui_present_flag = gf_bs_read_int(orig, 1);

	/*setup default values*/
	Bool aspect_ratio_info_present_flag = 0;
	s32 aspect_ratio_idc = -1;
	u32 ar_n=0, ar_d=0;
	Bool overscan_info_present_flag = 0;
	u32 overscan_info=0;
	u32 video_signal_type_present_flag=0;
	u32 video_format = 5;
	u32 video_full_range_flag = 0;
	u32 colour_description_present_flag = 0;
	u32 colour_primaries = 2;
	u32 transfer_characteristics = 2;
	u32 matrix_coefficients = 2;

	//if VUI is present, read all SAR and overscan values
	if (vui_present_flag) { /* VUI found in input bitstream */
		aspect_ratio_info_present_flag = gf_bs_read_int(orig, 1);
		if (aspect_ratio_info_present_flag) {
			aspect_ratio_idc = gf_bs_read_int(orig, 8); /*aspect_ratio_idc*/
			if (aspect_ratio_idc == 255) {
				ar_n = gf_bs_read_int(orig, 16); /*sar_width*/
				ar_d = gf_bs_read_int(orig, 16); /*sar_height*/
			}
		}

		/*overscan_info_present_flag */
		overscan_info_present_flag = gf_bs_read_int(orig, 1);
		if(overscan_info_present_flag) {
			overscan_info = gf_bs_read_int(orig, 1);
		}

		/* read all video signal related flags first */
		video_signal_type_present_flag = gf_bs_read_int(orig, 1);
		if(video_signal_type_present_flag) {
			video_format = gf_bs_read_int(orig, 3);
			video_full_range_flag = gf_bs_read_int(orig, 1);
			colour_description_present_flag = gf_bs_read_int(orig, 1);
			if(colour_description_present_flag) {
				colour_primaries = gf_bs_read_int(orig, 8);
				transfer_characteristics = gf_bs_read_int(orig, 8);
				matrix_coefficients = gf_bs_read_int(orig, 8);
			}
		}
	}

	//recompute values
	//no change
	if ((vui_info->ar_num<0) || (vui_info->ar_den<0)) {
	}
	//remove par
	else if ((vui_info->ar_num==0) || (vui_info->ar_den==0)) {
		aspect_ratio_info_present_flag = 0;
	}
	//set par
	else {
		aspect_ratio_info_present_flag = 1;
		ar_n = vui_info->ar_num;
		ar_d = vui_info->ar_den;
		aspect_ratio_idc = avc_hevc_get_sar_idx((u32) ar_n, (u32) ar_d);
	}

	if (vui_info->remove_video_info) {
		video_signal_type_present_flag = 0;
	}
	/* correct the values of each flags */
	else if ((vui_info->fullrange==0) && (vui_info->video_format==5) && (vui_info->color_prim==2) && (vui_info->color_tfc==2) && (vui_info->color_matrix==2)) {
		video_signal_type_present_flag = 0; /* all default, nothing to write*/
	} else {
		video_signal_type_present_flag = 1;
		video_format = (vui_info->video_format < 0) ? video_format : vui_info->video_format;
		video_full_range_flag = (vui_info->fullrange < 0) ? video_full_range_flag : vui_info->fullrange;
		if ((vui_info->color_prim==2) && (vui_info->color_tfc==2) && (vui_info->color_matrix==2)) {
			colour_description_present_flag = 0;
		} else {
			colour_description_present_flag = 1;
			colour_primaries = (vui_info->color_prim < 0) ? colour_primaries : vui_info->color_prim;
			transfer_characteristics = (vui_info->color_tfc < 0) ? transfer_characteristics : vui_info->color_tfc;
			matrix_coefficients = (vui_info->color_matrix < 0) ? matrix_coefficients : vui_info->color_matrix;
		}
		if ((colour_primaries==2) && (transfer_characteristics==2) && (matrix_coefficients==2)) {
			colour_description_present_flag = 0;
			if ((video_format==5) && (video_full_range_flag==0))
				video_signal_type_present_flag = 0;
		}
	}

	//always rewrite VUI
	gf_bs_write_int(mod, 1, 1);
	gf_bs_write_int(mod, aspect_ratio_info_present_flag, 1);
	if (aspect_ratio_info_present_flag) {
		gf_bs_write_int(mod, aspect_ratio_idc, 8);
		if (aspect_ratio_idc == 255) {
			gf_bs_write_int(mod, ar_n, 16);
			gf_bs_write_int(mod, ar_d, 16);
		}
		if (vui_info->update) {
			vui_info->ar_num = ar_n;
			vui_info->ar_den = ar_d;
		}
	}
	gf_bs_write_int(mod, overscan_info_present_flag, 1);
	if (overscan_info_present_flag) {
		gf_bs_write_int(mod, overscan_info, 1);
	}

	gf_bs_write_int(mod, video_signal_type_present_flag, 1);
	if (video_signal_type_present_flag) {
		gf_bs_write_int(mod, video_format, 3);
		gf_bs_write_int(mod, video_full_range_flag, 1);
		gf_bs_write_int(mod, colour_description_present_flag, 1);

		if (colour_description_present_flag) {
			gf_bs_write_int(mod, colour_primaries, 8);
			gf_bs_write_int(mod, transfer_characteristics, 8);
			gf_bs_write_int(mod, matrix_coefficients, 8);
		}

		if (vui_info->update) {
			vui_info->video_format = video_format;
			vui_info->fullrange = video_full_range_flag;
			if (colour_description_present_flag) {
				vui_info->color_prim = colour_primaries;
				vui_info->color_tfc = transfer_characteristics;
				vui_info->color_matrix = matrix_coefficients;
			}
		}
	}

	/*no VUI in input bitstream but we just inserted one, set all remaining vui flags to 0*/
	if (!vui_present_flag) {
		gf_bs_write_int(mod, 0, 1);		/*chroma_location_info_present_flag */
		gf_bs_write_int(mod, 0, 1);		/*timing_info_present_flag*/
		gf_bs_write_int(mod, 0, 1);		/*nal_hrd_parameters_present*/
		gf_bs_write_int(mod, 0, 1);		/*vcl_hrd_parameters_present*/
		gf_bs_write_int(mod, 0, 1);		/*pic_struct_present*/
		gf_bs_write_int(mod, 0, 1);		/*bitstream_restriction*/
	}
	/*otherwise we copy over th bits from the input bitrate*/
}

Project: gpac
File: av_parsers.c

GF_Err gf_m4a_write_config(GF_M4ADecSpecInfo *cfg, u8 **dsi, u32 *dsi_size)
{
	GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
	gf_m4a_write_config_bs(bs, cfg);
	gf_bs_get_content(bs, dsi, dsi_size);
	gf_bs_del(bs);
	return GF_OK;
}

Project: gpac
File: av_parsers.c

GF_Err aom_av1_parse_temporal_unit_from_annexb(GF_BitStream *bs, AV1State *state)
{
	GF_Err e;
	u64 tupos;
	u64 tusize, sz;
	if (!bs || !state) return GF_BAD_PARAM;

	state->bs_overread = GF_FALSE;
	tusize = sz = gf_av1_leb128_read(bs, NULL);
	tupos = gf_bs_get_position(bs);
	if (!sz) {
		GF_LOG(GF_LOG_INFO, GF_LOG_CODING, ("[AV1] temporal unit size is 0, likely not annex B\n"));
		return GF_NON_COMPLIANT_BITSTREAM;
	}

	GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] Annex B temporal unit detected (size "LLU") ***** \n", sz));
	while (sz > 0) {
		u8 Leb128Bytes = 0;
		u64 frame_unit_size = gf_av1_leb128_read(bs, &Leb128Bytes);

		if (state->bs_overread) {
			return GF_BUFFER_TOO_SMALL;
		}
		if (sz < Leb128Bytes + frame_unit_size) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] Annex B sz("LLU") < Leb128Bytes("LLU") + frame_unit_size("LLU")\n", sz, Leb128Bytes, frame_unit_size));
			return GF_NON_COMPLIANT_BITSTREAM;
		}
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] Annex B frame unit detected (size "LLU")\n", frame_unit_size));
		sz -= Leb128Bytes + frame_unit_size;

		while (frame_unit_size > 0) {
			u64 pos, obu_length = gf_av1_leb128_read(bs, &Leb128Bytes);

			if (state->bs_overread) {
				return GF_BUFFER_TOO_SMALL;
			}
			if (frame_unit_size < Leb128Bytes + obu_length) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] Annex B frame_unit_size("LLU") < Leb128Bytes("LLU") + obu_length("LLU")\n", frame_unit_size, Leb128Bytes, obu_length));
				return GF_NON_COMPLIANT_BITSTREAM;
			}
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] Annex B OBU detected (size "LLU")\n", obu_length));
			pos = gf_bs_get_position(bs);
			frame_unit_size -= Leb128Bytes;

			e = gf_av1_parse_obu(bs, &state->obu_type, &obu_length, NULL, state);
			if (e) return e;

			if (obu_length != gf_bs_get_position(bs) - pos) {
				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[AV1] Annex B frame size "LLU" different from consumed bytes "LLU".\n", obu_length, gf_bs_get_position(bs) - pos));
				return GF_NON_COMPLIANT_BITSTREAM;
			}

			av1_populate_state_from_obu(bs, pos, obu_length, state->obu_type, state);
			if (frame_unit_size < obu_length) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] Annex B frame_unit_size("LLU") < OBU size ("LLU")\n", frame_unit_size, obu_length));
				return GF_NON_COMPLIANT_BITSTREAM;
			}
			frame_unit_size -= obu_length;
		}
	}
	assert(sz == 0);
	if (tusize != gf_bs_get_position(bs) - tupos) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[AV1] Annex B TU size "LLU" different from consumed bytes "LLU".\n", tusize, gf_bs_get_position(bs) - tupos));
		return GF_NON_COMPLIANT_BITSTREAM;
	}
	return GF_OK;
}

Project: gpac
File: av_parsers.c

static void av1_setup_past_independence(AV1State *state)
{
	u32 ref, i;
	for (ref = AV1_LAST_FRAME; ref <= AV1_ALTREF_FRAME; ref++) {
		for (i = 0; i <= 5; i++) {
			state->PrevGmParams.coefs[ref][i] = ((i % 3 == 2) ? 1 << WARPEDMODEL_PREC_BITS : 0);
		}
	}
}

Project: gpac
File: av_parsers.c

static u32 lhvc_get_num_views(HEVC_VPS *vps)
{
	u32 numViews = 1, i;
	for (i = 0; i < vps->max_layers; i++) {
		u32 layer_id = vps->layer_id_in_nuh[i];
		if (i > 0 && (lhvc_get_view_index(vps, layer_id) != lhvc_get_scalability_id(vps, i - 1, LHVC_VIEW_ORDER_INDEX))) {
			numViews++;
		}
	}
	return numViews;
}

Project: gpac
File: av_parsers.c

void gf_hevc_parse_sei(char *buffer, u32 nal_size, HEVCState *hevc)
{
	gf_hevc_vvc_parse_sei(buffer, nal_size, hevc, NULL);
}

Project: gpac
File: av_parsers.c

static GF_Err gf_m4v_parse_config_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi)
{
	unsigned char p[4];
	u32 ext_type;
	s32 o_type;
	u8 go, par;

	if (!m4v || !dsi) return GF_BAD_PARAM;

	memset(dsi, 0, sizeof(GF_M4VDecSpecInfo));
	dsi->VideoPL = 0;

	go = 1;
	while (go) {
		o_type = M4V_LoadObject(m4v);
		switch (o_type) {
		case M2V_SEQ_START_CODE:
			dsi->RAP_stream = 1;
			gf_bs_read_data(m4v->bs, (char *)p, 4);
			dsi->width = (p[0] << 4) | ((p[1] >> 4) & 0xf);
			dsi->height = ((p[1] & 0xf) << 8) | p[2];

			dsi->VideoPL = GF_CODECID_MPEG1;
			par = (p[3] >> 4) & 0xf;
			switch (par) {
			case 2:
				dsi->par_num = dsi->height / 3;
				dsi->par_den = dsi->width / 4;
				break;
			case 3:
				dsi->par_num = dsi->height / 9;
				dsi->par_den = dsi->width / 16;
				break;
			case 4:
				dsi->par_num = dsi->height / 2;
				dsi->par_den = dsi->width / 21;
				break;
			default:
				dsi->par_den = dsi->par_num = 0;
				break;
			}
			switch (p[3] & 0xf) {
			case 0:
				break;
			case 1:
				dsi->fps = 24000.0 / 1001.0;
				break;
			case 2:
				dsi->fps = 24.0;
				break;
			case 3:
				dsi->fps = 25.0;
				break;
			case 4:
				dsi->fps = 30000.0 / 1001.0;
				break;
			case 5:
				dsi->fps = 30.0;
				break;
			case 6:
				dsi->fps = 50.0;
				break;
			case 7:
				dsi->fps = ((60.0*1000.0) / 1001.0);
				break;
			case 8:
				dsi->fps = 60.0;
				break;
			case 9:
				dsi->fps = 1;
				break;
			case 10:
				dsi->fps = 5;
				break;
			case 11:
				dsi->fps = 10;
				break;
			case 12:
				dsi->fps = 12;
				break;
			case 13:
				dsi->fps = 15;
				break;
			}
			break;
		case M2V_EXT_START_CODE:
			gf_bs_read_data(m4v->bs, (char *)p, 4);
			ext_type = ((p[0] >> 4) & 0xf);
			if (ext_type == 1) {
				dsi->VideoPL = 0x65;
				dsi->height = ((p[1] & 0x1) << 13) | ((p[2] & 0x80) << 5) | (dsi->height & 0x0fff);
				dsi->width = (((p[2] >> 5) & 0x3) << 12) | (dsi->width & 0x0fff);
			}
			break;
		case M2V_PIC_START_CODE:
			if (dsi->width) go = 0;
			break;
		default:
			break;
			/*EOS*/
		case -1:
			go = 0;
			m4v->current_object_start = gf_bs_get_position(m4v->bs);
			break;
		}
	}
	M4V_Reset(m4v, 0);
	return GF_OK;
}

Project: gpac
File: av_parsers.c

Bool gf_media_avc_slice_is_intra(AVCState *avc)
{
	switch (avc->s_info.slice_type) {
	case GF_AVC_TYPE_I:
	case GF_AVC_TYPE2_I:
	case GF_AVC_TYPE_SI:
	case GF_AVC_TYPE2_SI:
		return 1;
	default:
		return 0;
	}
}

Project: gpac
File: av_parsers.c

u16 gf_mp3_frame_size(u32 hdr)
{
	u8 version = gf_mp3_version(hdr);
	u8 layer = gf_mp3_layer(hdr);
	u32 pad = ((hdr >> 9) & 0x1) ? 1 : 0;
	u32 bitrate = gf_mp3_bit_rate(hdr);
	u32 samplerate = gf_mp3_sampling_rate(hdr);

	u32 frameSize = 0;
	if (!samplerate || !bitrate) return 0;

	if (layer == 1) {
		frameSize = ((12 * bitrate / samplerate) + pad) * 4;
	}
	else {
		u32 slots_per_frame = 144;
		if ((layer == 3) && !(version & 1)) slots_per_frame = 72;
		frameSize = (slots_per_frame * bitrate / samplerate) + pad;
	}
	return (u16)frameSize;
}

Project: gpac
File: av_parsers.c

static u64 aom_av1_le(GF_BitStream *bs, u32 n, const char *name) {
	u32 i = 0;
	u64 t = 0;
	for (i = 0; i < n; i++) {
		u8 byte = gf_bs_read_int(bs, 8);
		t += (byte << (i * 8));
	}
	gf_bs_log(bs, n*8, name, t);
	return t;
}

Project: gpac
File: av_parsers.c

u32 gf_bs_read_ue(GF_BitStream *bs)
{
	return gf_bs_read_ue_log(bs, NULL);
}

Project: gpac
File: av_parsers.c

void gf_bs_write_se(GF_BitStream *bs, s32 num)
{
	u32 v;
	if (num <= 0)
		v = (-1 * num) << 1;
	else
		v = (num << 1) - 1;

	gf_bs_write_ue(bs, v);
}

Project: gpac
File: av_parsers.c

void gf_media_get_reduced_frame_rate(u32 *timescale, u32 *sample_dur)
{
	u32 res;
	if (!*sample_dur) return;
	res = *timescale / *sample_dur;
	if (res * (*sample_dur) == *timescale) {
		*timescale = res;
		*sample_dur = 1;
	}
	else if ((double)(*timescale * 1001 - (res + 1) * *sample_dur * 1000) / ((res + 1) * *sample_dur * 1000) < 0.001) {
		*timescale = (res + 1) * 1000;
		*sample_dur = 1001;
	}
}

Project: gpac
File: av_parsers.c

s32 gf_mpegh_get_mhas_pl(u8 *ptr, u32 size, u64 *ch_layout)
{
	s32 PL = -1;
	GF_BitStream *bs;
	u32 i;
	s32 sync_pos=-1;

	if (!ptr || !size) return 0;
	
	for (i=0; i<size-3; i++) {
		if ((ptr[i]==0xC0) && (ptr[i+1]== 0x01) && (ptr[i+2]==0xA5)) {
			sync_pos = i;
			break;
		}
	}
	if (sync_pos<0) return 0;
	if (ch_layout) *ch_layout = 0;
	bs = gf_bs_new(ptr, size, GF_BITSTREAM_READ);
	gf_bs_skip_bytes(bs, sync_pos);

	while (gf_bs_available(bs)) {
		u32 type = (u32) gf_mpegh_escaped_value(bs, 3, 8, 8);
		/*u64 label = */gf_mpegh_escaped_value(bs, 2, 8, 32);
		u64 mh_size = gf_mpegh_escaped_value(bs, 11, 24, 24);
		if (mh_size > gf_bs_available(bs))
			break;
		//MHAS config
		if (type==1) {
			PL = gf_bs_read_int(bs, 8);
			if (ch_layout) {
				u32 idx = gf_bs_read_int(bs, 5);
				if (idx==0x1f)
					gf_bs_read_int(bs, 24);
				/*idx = */gf_bs_read_int(bs, 3);
				gf_bs_read_int(bs, 1);
				gf_bs_read_int(bs, 1);

				//speaker config
				idx = gf_bs_read_int(bs, 2);
				if (idx == 0) {
					*ch_layout = gf_audio_fmt_get_layout_from_cicp( gf_bs_read_int(bs, 6) );
				}
			}
			break;
		}
		gf_bs_skip_bytes(bs, mh_size);
	}
	gf_bs_del(bs);
	return PL;
}

Project: gpac
File: av_parsers.c

GF_Err gf_media_vp9_parse_superframe(GF_BitStream *bs, u64 ivf_frame_size, u32 *num_frames_in_superframe, u32 frame_sizes[VP9_MAX_FRAMES_IN_SUPERFRAME], u32 *superframe_index_size)
{
	u32 byte, bytes_per_framesize;
	u64 pos = gf_bs_get_position(bs), i = 0;
	GF_Err e;

	assert(bs && num_frames_in_superframe);

	/*initialize like there is no superframe*/
	memset(frame_sizes, 0, VP9_MAX_FRAMES_IN_SUPERFRAME * sizeof(frame_sizes[0]));
	*num_frames_in_superframe = 1;
	frame_sizes[0] = (u32)ivf_frame_size;
	*superframe_index_size = 0;

	e = gf_bs_seek(bs, pos + ivf_frame_size - 1);
	if (e) return e;

	byte = gf_bs_read_u8(bs);
	if ((byte & 0xe0) != 0xc0)
		goto exit; /*no superframe*/

	bytes_per_framesize = 1 + ((byte & 0x18) >> 3);
	*num_frames_in_superframe = (u32)(1 + (byte & 0x7));

	/*superframe_index()*/
	*superframe_index_size = 2 + bytes_per_framesize * *num_frames_in_superframe;
	gf_bs_seek(bs, pos + ivf_frame_size - *superframe_index_size);
	byte = gf_bs_read_u8(bs);
	if ((byte & 0xe0) != 0xc0)
		goto exit; /*no superframe*/

	frame_sizes[0] = 0;
	for (i = 0; i < *num_frames_in_superframe; ++i) {
		gf_bs_read_data(bs, (char*)(frame_sizes + i), bytes_per_framesize);
	}

exit:
	gf_bs_seek(bs, pos);
	return e;
}

Project: gpac
File: av_parsers.c

static s32 gf_media_vvc_read_pps_bs_internal(GF_BitStream *bs, VVCState *vvc)
{
	u32 i;
	s32 pps_id;
	VVC_PPS *pps;

	//NAL header already read
	pps_id = gf_bs_read_int_log(bs, 6, "pps_id");

	if ((pps_id < 0) || (pps_id >= 64)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VVC] wrong PPS ID %d in PPS\n", pps_id));
		return -1;
	}
	pps = &vvc->pps[pps_id];

	if (!pps->state) {
		pps->id = pps_id;
		pps->state = 1;
	}
	pps->sps_id = gf_bs_read_int_log(bs, 4, "sps_id");
	if (((s32)pps->sps_id<0) || (pps->sps_id >= 16)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VVC] wrong SPS ID %d in PPS\n", pps->sps_id));
		pps->sps_id=0;
		return -1;
	}
	vvc->sps_active_idx = pps->sps_id; /*set active sps*/
	pps->mixed_nal_types = gf_bs_read_int_log(bs, 1, "mixed_nal_types");
	pps->width = gf_bs_read_ue_log(bs, "width");
	pps->height = gf_bs_read_ue_log(bs, "height");
	pps->conf_window = gf_bs_read_int_log(bs, 1, "conformance_window_flag");
	if (pps->conf_window) {
		pps->cw_left = gf_bs_read_ue_log(bs, "conf_win_left_offset");
		pps->cw_right = gf_bs_read_ue_log(bs, "conf_win_right_offset");
		pps->cw_top = gf_bs_read_ue_log(bs, "conf_win_top_offset");
		pps->cw_bottom = gf_bs_read_ue_log(bs, "conf_win_bottom_offset");
	}
	//scaling window
	if (gf_bs_read_int_log(bs, 1, "scaling_window_explicit_signaling_flag")) {
		gf_bs_read_se_log(bs, "scaling_win_left_offset");
		gf_bs_read_se_log(bs, "scaling_win_right_offset");
		gf_bs_read_se_log(bs, "scaling_win_top_offset");
		gf_bs_read_se_log(bs, "scaling_win_bottom_offset");
	}
	pps->output_flag_present_flag = gf_bs_read_int_log(bs, 1, "output_flag_present_flag");
	pps->no_pic_partition_flag = gf_bs_read_int_log(bs, 1, "no_pic_partition_flag");
	pps->subpic_id_mapping_present_flag = gf_bs_read_int_log(bs, 1, "subpic_id_mapping_present_flag");
	if (pps->subpic_id_mapping_present_flag) {
		u32 pps_subpic_id_len, pps_num_subpics=0;
		if (!pps->no_pic_partition_flag) {
			pps_num_subpics = 1+gf_bs_read_ue_log(bs, "pps_num_subpics_minus1");
		}
		pps_subpic_id_len = 1 + gf_bs_read_ue(bs);
		for (i=0; i<pps_num_subpics; i++) {
			gf_bs_read_int_log_idx(bs, pps_subpic_id_len, "subpic_id", i);
		}
	}
	if (!pps->no_pic_partition_flag) {
		gf_bs_read_int_log(bs, 2, "pps_log2_ctu_size_minus5");
		u32 num_exp_tile_columns = 1 + gf_bs_read_ue_log(bs, "num_exp_tile_columns_minus1");
		u32 num_exp_tile_rows = 1 + gf_bs_read_ue_log(bs, "num_exp_tile_rows_minus1");
		for (i=0; i<num_exp_tile_columns; i++)
			gf_bs_read_ue_log_idx(bs, "tile_column_width_minus1", i);
		for (i=0; i<num_exp_tile_rows; i++)
			gf_bs_read_ue_log_idx(bs, "tile_row_height_minus1", i);

		//todo parse the rest
		return pps_id;
	}


	//todo parse the rest

	return pps_id;
}

Project: gpac
File: av_parsers.c

static GF_Err vp9_color_config(GF_BitStream *bs, GF_VPConfig *vp9_cfg)
{
	VP9_color_space color_space;

	if (vp9_cfg->profile >= 2) {
		Bool ten_or_twelve_bit = gf_bs_read_int_log(bs, 1, "ten_or_twelve_bit");
		vp9_cfg->bit_depth = ten_or_twelve_bit ? 12 : 10;
	}
	else {
		vp9_cfg->bit_depth = 8;
	}

	color_space = gf_bs_read_int_log(bs, 3, "color_space");
	vp9_cfg->colour_primaries = VP9_CS_to_23001_8_colour_primaries[color_space];
	vp9_cfg->transfer_characteristics = VP9_CS_to_23001_8_transfer_characteristics[color_space];
	vp9_cfg->matrix_coefficients = VP9_CS_to_23001_8_matrix_coefficients[color_space];
	if (color_space != CS_RGB) {
		vp9_cfg->video_fullRange_flag = gf_bs_read_int_log(bs, 1, "video_fullRange_flag");
		if (vp9_cfg->profile == 1 || vp9_cfg->profile == 3) {
			u8 subsampling_x, subsampling_y, subsampling_xy_to_chroma_subsampling[2][2] = { {3, 0}, {2, 0} };
			subsampling_x = gf_bs_read_int_log(bs, 1, "subsampling_x");
			subsampling_y = gf_bs_read_int_log(bs, 1, "subsampling_x");
			vp9_cfg->chroma_subsampling = subsampling_xy_to_chroma_subsampling[subsampling_x][subsampling_y];
			Bool reserved_zero = gf_bs_read_int_log(bs, 1, "reserved_zero");
			if (reserved_zero) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VP9] color config reserved zero (1) is not zero.\n"));
				return GF_NON_COMPLIANT_BITSTREAM;
			}
		}
		else {
			vp9_cfg->chroma_subsampling = 0;
		}
	}
	else {
		vp9_cfg->video_fullRange_flag = GF_TRUE;
		if (vp9_cfg->profile == 1 || vp9_cfg->profile == 3) {
			vp9_cfg->chroma_subsampling = 3;
			Bool reserved_zero = gf_bs_read_int_log(bs, 1, "reserved_zero");
			if (reserved_zero) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VP9] color config reserved zero (2) is not zero.\n"));
				return GF_NON_COMPLIANT_BITSTREAM;
			}
		}
	}

	return GF_OK;
}

Project: gpac
File: av_parsers.c

static u32 av1_decode_subexp(GF_BitStream *bs, s32 numSyms)
{
	s32 i = 0;
	s32 mk = 0;
	s32 k = 3;
	while (1) {
		s32 b2 = i ? k + i - 1 : k;
		s32 a = 1 << b2;
		if (numSyms <= mk + 3 * a) {
			s32 subexp_final_bits = av1_read_ns(bs, numSyms - mk, NULL);
			return subexp_final_bits + mk;
		}
		else {
			s32 subexp_more_bits = gf_bs_read_int(bs, 1);
			if (subexp_more_bits) {
				i++;
				mk += a;
			}
			else {
				s32 subexp_bits = gf_bs_read_int(bs, b2);
				return subexp_bits + mk;
			}
		}
	}
}

Project: gpac
File: av_parsers.c

u32 gf_mp3_get_next_header_mem(const u8 *buffer, u32 size, u32 *pos)
{
	u32 cur;
	u8 b, state = 0;
	u32 dropped = 0;
	unsigned char bytes[4];
	bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0;

	cur = 0;
	*pos = 0;
	while (cur < size) {
		b = (u8)buffer[cur];
		cur++;

		if (state == 3) {
			u32 val;
			bytes[state] = b;
			val = GF_4CC((u32)bytes[0], bytes[1], bytes[2], bytes[3]);
			if (gf_mp3_frame_size(val)) {
				*pos = dropped;
				return val;
			}
			state = 0;
			dropped = cur;
		}
		if (state == 2) {
			if (((b & 0xF0) == 0) || ((b & 0xF0) == 0xF0) || ((b & 0x0C) == 0x0C)) {
				if (bytes[1] == 0xFF) {
					state = 1;
					dropped += 1;
				}
				else {
					state = 0;
					dropped = cur;
				}
			}
			else {
				bytes[state] = b;
				state = 3;
			}
		}
		if (state == 1) {
			if (((b & 0xE0) == 0xE0) && ((b & 0x18) != 0x08) && ((b & 0x06) != 0)) {
				bytes[state] = b;
				state = 2;
			}
			else {
				state = 0;
				dropped = cur;
			}
		}

		if (state == 0) {
			if (b == 0xFF) {
				bytes[state] = b;
				state = 1;
			}
			else {
				dropped++;
			}
		}
	}
	return 0;
}

Project: gpac
File: av_parsers.c

s32 gf_hevc_read_pps(u8 *data, u32 size, HEVCState *hevc)
{
	GF_BitStream *bs;
	s32 pps_id = -1;

	bs = gf_bs_new(data, size, GF_BITSTREAM_READ);
	if (!bs) goto exit;
	gf_bs_enable_emulation_byte_removal(bs, GF_TRUE);

	if (!hevc_parse_nal_header(bs, NULL, NULL, NULL)) goto exit;

	pps_id = gf_hevc_read_pps_bs_internal(bs, hevc);

exit:
	if (bs) gf_bs_del(bs);
	return pps_id;
}

Project: gpac
File: av_parsers.c

s32 gf_avc_read_pps(const u8 *pps_data, u32 pps_size, AVCState *avc)
{
	GF_BitStream *bs;
	s32 pps_id;

	/*PPS still contains emulation bytes*/
	bs = gf_bs_new(pps_data, pps_size, GF_BITSTREAM_READ);
	if (!bs) {
		return -1;
	}
	gf_bs_enable_emulation_byte_removal(bs, GF_TRUE);
	pps_id = gf_avc_read_pps_bs(bs, avc);
	gf_bs_del(bs);
	return pps_id;
}

Project: gpac
File: av_parsers.c

const char *gf_avc_get_profile_name(u8 video_prof)
{
	switch (video_prof) {
	case 0x42:
		return "Baseline";
	case 0x4D:
		return "Main";
	case 0x53:
		return "Scalable Baseline";
	case 0x56:
		return "Scalable High";
	case 0x58:
		return "Extended";
	case 0x64:
		return "High";
	case 0x6E:
		return "High 10";
	case 0x7A:
		return "High 4:2:2";
	case 0x90:
	case 0xF4:
		return "High 4:4:4";
	default:
		return "Unknown";
	}
}

Project: gpac
File: av_parsers.c

static s64 vp9_s(GF_BitStream *bs, int n, const char *fname, u32 idx) {
	s64 value = gf_bs_read_int(bs, n);
	Bool sign = gf_bs_read_int(bs, 1);
	if (sign) value = -value;
	gf_bs_log_idx(bs, n+1, fname, value, idx, -1, -1);
	return value;
}

Project: gpac
File: av_parsers.c

static Bool AC3_FindSyncCodeBS(GF_BitStream *bs)
{
	u8 b1;
	u64 pos = gf_bs_get_position(bs);
	u64 end = gf_bs_get_size(bs);

	pos += 1;
	b1 = gf_bs_read_u8(bs);
	while (pos + 1 <= end) {
		u8 b2 = gf_bs_read_u8(bs);
		if ((b1 == 0x0b) && (b2 == 0x77)) {
			gf_bs_seek(bs, pos - 1);
			return GF_TRUE;
		}
		pos++;
		b1 = b2;
	}
	return GF_FALSE;
}

Project: gpac
File: av_parsers.c

s32 hevc_parse_slice_segment(GF_BitStream *bs, HEVCState *hevc, HEVCSliceInfo *si)
{
	u32 i, j;
	u32 num_ref_idx_l0_active = 0, num_ref_idx_l1_active = 0;
	HEVC_PPS *pps;
	HEVC_SPS *sps;
	s32 pps_id;
	Bool RapPicFlag = GF_FALSE;
	Bool IDRPicFlag = GF_FALSE;

	si->first_slice_segment_in_pic_flag = gf_bs_read_int_log(bs, 1, "first_slice_segment_in_pic_flag");

	switch (si->nal_unit_type) {
	case GF_HEVC_NALU_SLICE_IDR_W_DLP:
	case GF_HEVC_NALU_SLICE_IDR_N_LP:
		IDRPicFlag = GF_TRUE;
		RapPicFlag = GF_TRUE;
		break;
	case GF_HEVC_NALU_SLICE_BLA_W_LP:
	case GF_HEVC_NALU_SLICE_BLA_W_DLP:
	case GF_HEVC_NALU_SLICE_BLA_N_LP:
	case GF_HEVC_NALU_SLICE_CRA:
		RapPicFlag = GF_TRUE;
		break;
	}

	if (RapPicFlag) {
		gf_bs_read_int_log(bs, 1, "no_output_of_prior_pics_flag");
	}

	pps_id = gf_bs_read_ue_log(bs, "pps_id");
	if ((pps_id<0) || (pps_id >= 64))
		return -1;

	pps = &hevc->pps[pps_id];
	sps = &hevc->sps[pps->sps_id];
	si->sps = sps;
	si->pps = pps;

	if (!si->first_slice_segment_in_pic_flag && pps->dependent_slice_segments_enabled_flag) {
		si->dependent_slice_segment_flag = gf_bs_read_int_log(bs, 1, "dependent_slice_segment_flag");
	}
	else {
		si->dependent_slice_segment_flag = GF_FALSE;
	}

	if (!si->first_slice_segment_in_pic_flag) {
		si->slice_segment_address = gf_bs_read_int_log(bs, sps->bitsSliceSegmentAddress, "slice_segment_address");
	}
	else {
		si->slice_segment_address = 0;
	}

	if (!si->dependent_slice_segment_flag) {
		Bool deblocking_filter_override_flag = 0;
		Bool slice_temporal_mvp_enabled_flag = 0;
		Bool slice_sao_luma_flag = 0;
		Bool slice_sao_chroma_flag = 0;
		Bool slice_deblocking_filter_disabled_flag = 0;

		//"slice_reserved_undetermined_flag[]"
		gf_bs_read_int_log(bs, pps->num_extra_slice_header_bits, "slice_reserved_undetermined_flag");

		si->slice_type = gf_bs_read_ue_log(bs, "slice_type");

		if (pps->output_flag_present_flag)
			gf_bs_read_int_log(bs, 1, "pic_output_flag");

		if (sps->separate_colour_plane_flag == 1)
			gf_bs_read_int_log(bs, 2, "colour_plane_id");

		if (IDRPicFlag) {
			si->poc_lsb = 0;

			//if not asked to parse full header, abort since we know the poc
			if (!hevc->full_slice_header_parse) return 0;

		}
		else {
			si->poc_lsb = gf_bs_read_int_log(bs, sps->log2_max_pic_order_cnt_lsb, "poc_lsb");

			//if not asked to parse full header, abort once we have the poc
			if (!hevc->full_slice_header_parse) return 0;

			if (gf_bs_read_int_log(bs, 1, "short_term_ref_pic_set_sps_flag") == 0) {
				Bool ret = hevc_parse_short_term_ref_pic_set(bs, sps, sps->num_short_term_ref_pic_sets);
				if (!ret)
					return -1;
			}
			else if (sps->num_short_term_ref_pic_sets > 1) {
				u32 numbits = 0;

				while ((u32)(1 << numbits) < sps->num_short_term_ref_pic_sets)
					numbits++;
				if (numbits > 0)
					gf_bs_read_int_log(bs, numbits, "short_term_ref_pic_set_idx");
				/*else
					short_term_ref_pic_set_idx = 0;*/
			}
			if (sps->long_term_ref_pics_present_flag) {
				u8 DeltaPocMsbCycleLt[32];
				u32 num_long_term_sps = 0;
				u32 num_long_term_pics = 0;

				memset(DeltaPocMsbCycleLt, 0, sizeof(u8) * 32);
				
				if (sps->num_long_term_ref_pic_sps > 0) {
					num_long_term_sps = gf_bs_read_ue_log(bs, "num_long_term_sps");
				}
				num_long_term_pics = gf_bs_read_ue_log(bs, "num_long_term_pics");

				for (i = 0; i < num_long_term_sps + num_long_term_pics; i++) {
					if (i < num_long_term_sps) {
						if (sps->num_long_term_ref_pic_sps > 1)
							gf_bs_read_int_log_idx(bs, gf_get_bit_size(sps->num_long_term_ref_pic_sps), "lt_idx_sps", i);
					}
					else {
						gf_bs_read_int_log_idx(bs, sps->log2_max_pic_order_cnt_lsb, "PocLsbLt", i);
						gf_bs_read_int_log_idx(bs, 1, "UsedByCurrPicLt", i);
					}
					if (gf_bs_read_int_log_idx(bs, 1, "delta_poc_msb_present_flag", i)) {
						if (i == 0 || i == num_long_term_sps)
							DeltaPocMsbCycleLt[i] = gf_bs_read_ue_log_idx(bs, "DeltaPocMsbCycleLt", i);
						else
							DeltaPocMsbCycleLt[i] = gf_bs_read_ue_log_idx(bs, "DeltaPocMsbCycleLt", i) + DeltaPocMsbCycleLt[i - 1];
					}
				}
			}
			if (sps->temporal_mvp_enable_flag)
				slice_temporal_mvp_enabled_flag = gf_bs_read_int_log(bs, 1, "slice_temporal_mvp_enabled_flag");
		}
		if (sps->sample_adaptive_offset_enabled_flag) {
			u32 ChromaArrayType = sps->separate_colour_plane_flag ? 0 : sps->chroma_format_idc;
			slice_sao_luma_flag = gf_bs_read_int_log(bs, 1, "slice_sao_luma_flag");
			if (ChromaArrayType != 0)
				slice_sao_chroma_flag = gf_bs_read_int_log(bs, 1, "slice_sao_chroma_flag");
		}

		if (si->slice_type == GF_HEVC_SLICE_TYPE_P || si->slice_type == GF_HEVC_SLICE_TYPE_B) {
			//u32 NumPocTotalCurr;
			num_ref_idx_l0_active = pps->num_ref_idx_l0_default_active;
			num_ref_idx_l1_active = 0;
			if (si->slice_type == GF_HEVC_SLICE_TYPE_B)
				num_ref_idx_l1_active = pps->num_ref_idx_l1_default_active;

			if (gf_bs_read_int_log(bs, 1, "num_ref_idx_active_override_flag")) {
				num_ref_idx_l0_active = 1 + gf_bs_read_ue_log(bs, "num_ref_idx_l0_active");
				if (si->slice_type == GF_HEVC_SLICE_TYPE_B)
					num_ref_idx_l1_active = 1 + gf_bs_read_ue_log(bs, "num_ref_idx_l1_active");
			}

			if (pps->lists_modification_present_flag /*TODO: && NumPicTotalCurr > 1*/) {
				if (!ref_pic_lists_modification(bs, si->slice_type, num_ref_idx_l0_active, num_ref_idx_l1_active)) {
					GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[hevc] ref_pic_lists_modification( ) not implemented\n"));
					return -1;
				}
			}

			if (si->slice_type == GF_HEVC_SLICE_TYPE_B)
				gf_bs_read_int_log(bs, 1, "mvd_l1_zero_flag");
			if (pps->cabac_init_present_flag)
				gf_bs_read_int_log(bs, 1, "cabac_init_flag");

			if (slice_temporal_mvp_enabled_flag) {
				// When collocated_from_l0_flag is not present, it is inferred to be equal to 1.
				Bool collocated_from_l0_flag = 1;
				if (si->slice_type == GF_HEVC_SLICE_TYPE_B)
					collocated_from_l0_flag = gf_bs_read_int_log(bs, 1, "collocated_from_l0_flag");

				if ((collocated_from_l0_flag && (num_ref_idx_l0_active > 1))
					|| (!collocated_from_l0_flag && (num_ref_idx_l1_active > 1))
				) {
					gf_bs_read_ue_log(bs, "collocated_ref_idx");
				}
			}

			if ((pps->weighted_pred_flag && si->slice_type == GF_HEVC_SLICE_TYPE_P)
				|| (pps->weighted_bipred_flag && si->slice_type == GF_HEVC_SLICE_TYPE_B)
				) {
				hevc_pred_weight_table(bs, hevc, si, pps, sps, num_ref_idx_l0_active, num_ref_idx_l1_active);
			}
			gf_bs_read_ue_log(bs, "five_minus_max_num_merge_cand");
		}
		si->slice_qp_delta_start_bits = (s32) (gf_bs_get_position(bs) - 1) * 8 + gf_bs_get_bit_position(bs);
		si->slice_qp_delta = gf_bs_read_se_log(bs, "slice_qp_delta");

		if (pps->slice_chroma_qp_offsets_present_flag) {
			gf_bs_read_se_log(bs, "slice_cb_qp_offset");
			gf_bs_read_se_log(bs, "slice_cr_qp_offset");
		}
		if (pps->deblocking_filter_override_enabled_flag) {
			deblocking_filter_override_flag = gf_bs_read_int_log(bs, 1, "deblocking_filter_override_flag");
		}

		if (deblocking_filter_override_flag) {
			slice_deblocking_filter_disabled_flag = gf_bs_read_int_log(bs, 1, "slice_deblocking_filter_disabled_flag");
			if (!slice_deblocking_filter_disabled_flag) {
				gf_bs_read_se_log(bs, "slice_beta_offset_div2");
				gf_bs_read_se_log(bs, "slice_tc_offset_div2");
			}
		}
		if (pps->loop_filter_across_slices_enabled_flag
			&& (slice_sao_luma_flag || slice_sao_chroma_flag || !slice_deblocking_filter_disabled_flag)
		) {
			gf_bs_read_int_log(bs, 1, "slice_loop_filter_across_slices_enabled_flag");
		}
	}
	//dependent slice segment
	else {
		//if not asked to parse full header, abort
		if (!hevc->full_slice_header_parse) return 0;
	}

	si->entry_point_start_bits = ((u32)gf_bs_get_position(bs) - 1) * 8 + gf_bs_get_bit_position(bs);

	if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
		u32 num_entry_point_offsets = gf_bs_read_ue_log(bs, "num_entry_point_offsets");
		if (num_entry_point_offsets > 0) {
			u32 offset = gf_bs_read_ue_log(bs, "offset") + 1;
			u32 segments = offset >> 4;
			s32 remain = (offset & 15);

			for (i = 0; i < num_entry_point_offsets; i++) {
				//u32 res = 0;
				for (j = 0; j < segments; j++) {
					//res <<= 16;
					/*res +=*/ gf_bs_read_int(bs, 16);
				}
				if (remain) {
					//res <<= remain;
					/* res += */ gf_bs_read_int(bs, remain);
				}
				// entry_point_offset = val + 1; // +1; // +1 to get the size
			}
		}
	}

	if (pps->slice_segment_header_extension_present_flag) {
		u32 size_ext = gf_bs_read_ue_log(bs, "size_ext");
		while (size_ext) {
			gf_bs_read_int(bs, 8);
			size_ext--;
		}
	}

	si->header_size_bits = (gf_bs_get_position(bs) - 1) * 8 + gf_bs_get_bit_position(bs); // av_parser.c modified on 16 jan. 2019 

	if (gf_bs_read_int_log(bs, 1, "byte_align") == 0) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("Error parsing slice header: byte_align not found at end of header !\n"));
	}

	gf_bs_align(bs);
	si->payload_start_offset = (s32)gf_bs_get_position(bs);
	return 0;
}

Project: gpac
File: av_parsers.c

s32 gf_media_vvc_parse_nalu(u8 *data, u32 size, VVCState *vvc, u8 *nal_unit_type, u8 *temporal_id, u8 *layer_id)
{
	GF_BitStream *bs = NULL;
	s32 ret;

	if (!vvc) {
		if (nal_unit_type) (*nal_unit_type) = data[1] >> 3;
		if (layer_id) (*layer_id) = data[0] & 0x3f;
		if (temporal_id) (*temporal_id) = (data[1] & 0x7);
		return -1;
	}
	bs = gf_bs_new(data, size, GF_BITSTREAM_READ);
	if (!bs) return -1;
	gf_bs_enable_emulation_byte_removal(bs, GF_TRUE);

	ret = gf_media_vvc_parse_nalu_bs(bs, vvc, nal_unit_type, temporal_id, layer_id);
	gf_bs_del(bs);
	return ret;
}

Project: gpac
File: av_parsers.c

static void vp9_render_size(GF_BitStream *bs, int FrameWidth, int FrameHeight, int *renderWidth, int *renderHeight)
{
	Bool render_and_frame_size_different = gf_bs_read_int_log(bs, 1, "render_and_frame_size_different");
	if (render_and_frame_size_different == 1) {
		int render_width_minus_1 = gf_bs_read_int_log(bs, 16, "render_width_minus_1");
		int render_height_minus_1 = gf_bs_read_int_log(bs, 16, "render_height_minus_1");
		*renderWidth = render_width_minus_1 + 1;
		*renderHeight = render_height_minus_1 + 1;
	}
	else {
		*renderWidth = FrameWidth;
		*renderHeight = FrameHeight;
	}
}

Project: gpac
File: av_parsers.c

GF_Err gf_av1_parse_obu_header(GF_BitStream *bs, ObuType *obu_type, Bool *obu_extension_flag, Bool *obu_has_size_field, u8 *temporal_id, u8 *spatial_id)
{
	Bool forbidden = gf_bs_read_int(bs, 1);
	if (forbidden) {
		return GF_NON_COMPLIANT_BITSTREAM;
	}

	*obu_type = gf_bs_read_int(bs, 4);
	*obu_extension_flag = gf_bs_read_int(bs, 1);
	*obu_has_size_field = gf_bs_read_int(bs, 1);
	if (gf_bs_read_int(bs, 1) /*obu_reserved_1bit*/) {
		return GF_NON_COMPLIANT_BITSTREAM;
	}
	if (*obu_extension_flag) {
		*temporal_id = gf_bs_read_int(bs, 3);
		*spatial_id = gf_bs_read_int(bs, 2);
		/*extension_header_reserved_3bits = */gf_bs_read_int(bs, 3);
	}

	return GF_OK;
}

Project: gpac
File: av_parsers.c

u32 gf_media_nalu_is_start_code(GF_BitStream *bs)
{
	u8 s1, s2, s3, s4;
	Bool is_sc = 0;
	u64 pos = gf_bs_get_position(bs);
	s1 = gf_bs_read_int(bs, 8);
	s2 = gf_bs_read_int(bs, 8);
	if (!s1 && !s2) {
		s3 = gf_bs_read_int(bs, 8);
		if (s3 == 0x01) is_sc = 3;
		else if (!s3) {
			s4 = gf_bs_read_int(bs, 8);
			if (s4 == 0x01) is_sc = 4;
		}
	}
	gf_bs_seek(bs, pos + is_sc);
	return is_sc;
}

Project: gpac
File: av_parsers.c

void gf_m4v_rewrite_pl(u8 **o_data, u32 *o_dataLen, u8 PL)
{
	u32 pos = 0;
	unsigned char *data = (unsigned char *)*o_data;
	u32 dataLen = *o_dataLen;

	while (pos + 4 < dataLen) {
		if (!data[pos] && !data[pos + 1] && (data[pos + 2] == 0x01) && (data[pos + 3] == M4V_VOS_START_CODE)) {
			data[pos + 4] = PL;
			return;
		}
		pos++;
	}
	/*emulate VOS at beggining*/
	(*o_data) = (char *)gf_malloc(sizeof(char)*(dataLen + 5));
	(*o_data)[0] = 0;
	(*o_data)[1] = 0;
	(*o_data)[2] = 1;
	(*o_data)[3] = (char)M4V_VOS_START_CODE;
	(*o_data)[4] = PL;
	memcpy((*o_data + 5), data, sizeof(char)*dataLen);
	gf_free(data);
	(*o_dataLen) = dataLen + 5;
}

Project: gpac
File: av_parsers.c

u32 gf_media_nalu_emulation_bytes_add_count(u8 *buffer, u32 nal_size)
{
	u32 i = 0, emulation_bytes_count = 0;
	u8 num_zero = 0;

	while (i < nal_size) {
		/*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003
		other than the following sequences shall not occur at any byte-aligned position:
		\96 0x00000300
		\96 0x00000301
		\96 0x00000302
		\96 0x00000303"
		*/
		if (num_zero == 2 && (u8)buffer[i] < 0x04) {
			/*emulation code found*/
			num_zero = 0;
			emulation_bytes_count++;
			if (!buffer[i])
				num_zero = 1;
		}
		else {
			if (!buffer[i])
				num_zero++;
			else
				num_zero = 0;
		}
		i++;
	}
	return emulation_bytes_count;
}