162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2019-2020 Pengutronix, Michael Tretter <kernel@pengutronix.de>
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Convert NAL units between raw byte sequence payloads (RBSP) and C structs.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * The conversion is defined in "ITU-T Rec. H.265 (02/2018) high efficiency
862306a36Sopenharmony_ci * video coding". Decoder drivers may use the parser to parse RBSP from
962306a36Sopenharmony_ci * encoded streams and configure the hardware, if the hardware is not able to
1062306a36Sopenharmony_ci * parse RBSP itself. Encoder drivers may use the generator to generate the
1162306a36Sopenharmony_ci * RBSP for VPS/SPS/PPS nal units and add them to the encoded stream if the
1262306a36Sopenharmony_ci * hardware does not generate the units.
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/kernel.h>
1662306a36Sopenharmony_ci#include <linux/types.h>
1762306a36Sopenharmony_ci#include <linux/string.h>
1862306a36Sopenharmony_ci#include <linux/v4l2-controls.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include <linux/device.h>
2162306a36Sopenharmony_ci#include <linux/export.h>
2262306a36Sopenharmony_ci#include <linux/log2.h>
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include "nal-hevc.h"
2562306a36Sopenharmony_ci#include "nal-rbsp.h"
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/*
2862306a36Sopenharmony_ci * See Rec. ITU-T H.265 (02/2018) Table 7-1 - NAL unit type codes and NAL unit
2962306a36Sopenharmony_ci * type classes
3062306a36Sopenharmony_ci */
3162306a36Sopenharmony_cienum nal_unit_type {
3262306a36Sopenharmony_ci	VPS_NUT = 32,
3362306a36Sopenharmony_ci	SPS_NUT = 33,
3462306a36Sopenharmony_ci	PPS_NUT = 34,
3562306a36Sopenharmony_ci	FD_NUT = 38,
3662306a36Sopenharmony_ci};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistatic void nal_hevc_write_start_code_prefix(struct rbsp *rbsp)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	u8 *p = rbsp->data + DIV_ROUND_UP(rbsp->pos, 8);
4162306a36Sopenharmony_ci	int i = 4;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	if (DIV_ROUND_UP(rbsp->pos, 8) + i > rbsp->size) {
4462306a36Sopenharmony_ci		rbsp->error = -EINVAL;
4562306a36Sopenharmony_ci		return;
4662306a36Sopenharmony_ci	}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	p[0] = 0x00;
4962306a36Sopenharmony_ci	p[1] = 0x00;
5062306a36Sopenharmony_ci	p[2] = 0x00;
5162306a36Sopenharmony_ci	p[3] = 0x01;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	rbsp->pos += i * 8;
5462306a36Sopenharmony_ci}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cistatic void nal_hevc_read_start_code_prefix(struct rbsp *rbsp)
5762306a36Sopenharmony_ci{
5862306a36Sopenharmony_ci	u8 *p = rbsp->data + DIV_ROUND_UP(rbsp->pos, 8);
5962306a36Sopenharmony_ci	int i = 4;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	if (DIV_ROUND_UP(rbsp->pos, 8) + i > rbsp->size) {
6262306a36Sopenharmony_ci		rbsp->error = -EINVAL;
6362306a36Sopenharmony_ci		return;
6462306a36Sopenharmony_ci	}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	if (p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0x01) {
6762306a36Sopenharmony_ci		rbsp->error = -EINVAL;
6862306a36Sopenharmony_ci		return;
6962306a36Sopenharmony_ci	}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	rbsp->pos += i * 8;
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic void nal_hevc_write_filler_data(struct rbsp *rbsp)
7562306a36Sopenharmony_ci{
7662306a36Sopenharmony_ci	u8 *p = rbsp->data + DIV_ROUND_UP(rbsp->pos, 8);
7762306a36Sopenharmony_ci	int i;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	/* Keep 1 byte extra for terminating the NAL unit */
8062306a36Sopenharmony_ci	i = rbsp->size - DIV_ROUND_UP(rbsp->pos, 8) - 1;
8162306a36Sopenharmony_ci	memset(p, 0xff, i);
8262306a36Sopenharmony_ci	rbsp->pos += i * 8;
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistatic void nal_hevc_read_filler_data(struct rbsp *rbsp)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	u8 *p = rbsp->data + DIV_ROUND_UP(rbsp->pos, 8);
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	while (*p == 0xff) {
9062306a36Sopenharmony_ci		if (DIV_ROUND_UP(rbsp->pos, 8) > rbsp->size) {
9162306a36Sopenharmony_ci			rbsp->error = -EINVAL;
9262306a36Sopenharmony_ci			return;
9362306a36Sopenharmony_ci		}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci		p++;
9662306a36Sopenharmony_ci		rbsp->pos += 8;
9762306a36Sopenharmony_ci	}
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistatic void nal_hevc_rbsp_profile_tier_level(struct rbsp *rbsp,
10162306a36Sopenharmony_ci					     struct nal_hevc_profile_tier_level *ptl)
10262306a36Sopenharmony_ci{
10362306a36Sopenharmony_ci	unsigned int i;
10462306a36Sopenharmony_ci	unsigned int max_num_sub_layers_minus_1 = 0;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	rbsp_bits(rbsp, 2, &ptl->general_profile_space);
10762306a36Sopenharmony_ci	rbsp_bit(rbsp, &ptl->general_tier_flag);
10862306a36Sopenharmony_ci	rbsp_bits(rbsp, 5, &ptl->general_profile_idc);
10962306a36Sopenharmony_ci	for (i = 0; i < 32; i++)
11062306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_profile_compatibility_flag[i]);
11162306a36Sopenharmony_ci	rbsp_bit(rbsp, &ptl->general_progressive_source_flag);
11262306a36Sopenharmony_ci	rbsp_bit(rbsp, &ptl->general_interlaced_source_flag);
11362306a36Sopenharmony_ci	rbsp_bit(rbsp, &ptl->general_non_packed_constraint_flag);
11462306a36Sopenharmony_ci	rbsp_bit(rbsp, &ptl->general_frame_only_constraint_flag);
11562306a36Sopenharmony_ci	if (ptl->general_profile_idc == 4 ||
11662306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[4] ||
11762306a36Sopenharmony_ci	    ptl->general_profile_idc == 5 ||
11862306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[5] ||
11962306a36Sopenharmony_ci	    ptl->general_profile_idc == 6 ||
12062306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[6] ||
12162306a36Sopenharmony_ci	    ptl->general_profile_idc == 7 ||
12262306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[7] ||
12362306a36Sopenharmony_ci	    ptl->general_profile_idc == 8 ||
12462306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[8] ||
12562306a36Sopenharmony_ci	    ptl->general_profile_idc == 9 ||
12662306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[9] ||
12762306a36Sopenharmony_ci	    ptl->general_profile_idc == 10 ||
12862306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[10]) {
12962306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_max_12bit_constraint_flag);
13062306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_max_10bit_constraint_flag);
13162306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_max_8bit_constraint_flag);
13262306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_max_422chroma_constraint_flag);
13362306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_max_420chroma_constraint_flag);
13462306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_max_monochrome_constraint_flag);
13562306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_intra_constraint_flag);
13662306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_one_picture_only_constraint_flag);
13762306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_lower_bit_rate_constraint_flag);
13862306a36Sopenharmony_ci		if (ptl->general_profile_idc == 5 ||
13962306a36Sopenharmony_ci		    ptl->general_profile_compatibility_flag[5] ||
14062306a36Sopenharmony_ci		    ptl->general_profile_idc == 9 ||
14162306a36Sopenharmony_ci		    ptl->general_profile_compatibility_flag[9] ||
14262306a36Sopenharmony_ci		    ptl->general_profile_idc == 10 ||
14362306a36Sopenharmony_ci		    ptl->general_profile_compatibility_flag[10]) {
14462306a36Sopenharmony_ci			rbsp_bit(rbsp, &ptl->general_max_14bit_constraint_flag);
14562306a36Sopenharmony_ci			rbsp_bits(rbsp, 32, &ptl->general_reserved_zero_33bits);
14662306a36Sopenharmony_ci			rbsp_bits(rbsp, 33 - 32, &ptl->general_reserved_zero_33bits);
14762306a36Sopenharmony_ci		} else {
14862306a36Sopenharmony_ci			rbsp_bits(rbsp, 32, &ptl->general_reserved_zero_34bits);
14962306a36Sopenharmony_ci			rbsp_bits(rbsp, 34 - 2, &ptl->general_reserved_zero_34bits);
15062306a36Sopenharmony_ci		}
15162306a36Sopenharmony_ci	} else if (ptl->general_profile_idc == 2 ||
15262306a36Sopenharmony_ci		   ptl->general_profile_compatibility_flag[2]) {
15362306a36Sopenharmony_ci		rbsp_bits(rbsp, 7, &ptl->general_reserved_zero_7bits);
15462306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_one_picture_only_constraint_flag);
15562306a36Sopenharmony_ci		rbsp_bits(rbsp, 32, &ptl->general_reserved_zero_35bits);
15662306a36Sopenharmony_ci		rbsp_bits(rbsp, 35 - 32, &ptl->general_reserved_zero_35bits);
15762306a36Sopenharmony_ci	} else {
15862306a36Sopenharmony_ci		rbsp_bits(rbsp, 32, &ptl->general_reserved_zero_43bits);
15962306a36Sopenharmony_ci		rbsp_bits(rbsp, 43 - 32, &ptl->general_reserved_zero_43bits);
16062306a36Sopenharmony_ci	}
16162306a36Sopenharmony_ci	if ((ptl->general_profile_idc >= 1 && ptl->general_profile_idc <= 5) ||
16262306a36Sopenharmony_ci	    ptl->general_profile_idc == 9 ||
16362306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[1] ||
16462306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[2] ||
16562306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[3] ||
16662306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[4] ||
16762306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[5] ||
16862306a36Sopenharmony_ci	    ptl->general_profile_compatibility_flag[9])
16962306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_inbld_flag);
17062306a36Sopenharmony_ci	else
17162306a36Sopenharmony_ci		rbsp_bit(rbsp, &ptl->general_reserved_zero_bit);
17262306a36Sopenharmony_ci	rbsp_bits(rbsp, 8, &ptl->general_level_idc);
17362306a36Sopenharmony_ci	if (max_num_sub_layers_minus_1 > 0)
17462306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
17562306a36Sopenharmony_ci}
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_cistatic void nal_hevc_rbsp_vps(struct rbsp *rbsp, struct nal_hevc_vps *vps)
17862306a36Sopenharmony_ci{
17962306a36Sopenharmony_ci	unsigned int i, j;
18062306a36Sopenharmony_ci	unsigned int reserved_0xffff_16bits = 0xffff;
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	rbsp_bits(rbsp, 4, &vps->video_parameter_set_id);
18362306a36Sopenharmony_ci	rbsp_bit(rbsp, &vps->base_layer_internal_flag);
18462306a36Sopenharmony_ci	rbsp_bit(rbsp, &vps->base_layer_available_flag);
18562306a36Sopenharmony_ci	rbsp_bits(rbsp, 6, &vps->max_layers_minus1);
18662306a36Sopenharmony_ci	rbsp_bits(rbsp, 3, &vps->max_sub_layers_minus1);
18762306a36Sopenharmony_ci	rbsp_bits(rbsp, 1, &vps->temporal_id_nesting_flag);
18862306a36Sopenharmony_ci	rbsp_bits(rbsp, 16, &reserved_0xffff_16bits);
18962306a36Sopenharmony_ci	nal_hevc_rbsp_profile_tier_level(rbsp, &vps->profile_tier_level);
19062306a36Sopenharmony_ci	rbsp_bit(rbsp, &vps->sub_layer_ordering_info_present_flag);
19162306a36Sopenharmony_ci	for (i = vps->sub_layer_ordering_info_present_flag ? 0 : vps->max_sub_layers_minus1;
19262306a36Sopenharmony_ci	     i <= vps->max_sub_layers_minus1; i++) {
19362306a36Sopenharmony_ci		rbsp_uev(rbsp, &vps->max_dec_pic_buffering_minus1[i]);
19462306a36Sopenharmony_ci		rbsp_uev(rbsp, &vps->max_num_reorder_pics[i]);
19562306a36Sopenharmony_ci		rbsp_uev(rbsp, &vps->max_latency_increase_plus1[i]);
19662306a36Sopenharmony_ci	}
19762306a36Sopenharmony_ci	rbsp_bits(rbsp, 6, &vps->max_layer_id);
19862306a36Sopenharmony_ci	rbsp_uev(rbsp, &vps->num_layer_sets_minus1);
19962306a36Sopenharmony_ci	for (i = 0; i <= vps->num_layer_sets_minus1; i++)
20062306a36Sopenharmony_ci		for (j = 0; j <= vps->max_layer_id; j++)
20162306a36Sopenharmony_ci			rbsp_bit(rbsp, &vps->layer_id_included_flag[i][j]);
20262306a36Sopenharmony_ci	rbsp_bit(rbsp, &vps->timing_info_present_flag);
20362306a36Sopenharmony_ci	if (vps->timing_info_present_flag)
20462306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
20562306a36Sopenharmony_ci	rbsp_bit(rbsp, &vps->extension_flag);
20662306a36Sopenharmony_ci	if (vps->extension_flag)
20762306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
20862306a36Sopenharmony_ci}
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistatic void nal_hevc_rbsp_sub_layer_hrd_parameters(struct rbsp *rbsp,
21162306a36Sopenharmony_ci						   struct nal_hevc_sub_layer_hrd_parameters *hrd)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	unsigned int i;
21462306a36Sopenharmony_ci	unsigned int cpb_cnt = 1;
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci	for (i = 0; i < cpb_cnt; i++) {
21762306a36Sopenharmony_ci		rbsp_uev(rbsp, &hrd->bit_rate_value_minus1[i]);
21862306a36Sopenharmony_ci		rbsp_uev(rbsp, &hrd->cpb_size_value_minus1[i]);
21962306a36Sopenharmony_ci		rbsp_bit(rbsp, &hrd->cbr_flag[i]);
22062306a36Sopenharmony_ci	}
22162306a36Sopenharmony_ci}
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_cistatic void nal_hevc_rbsp_hrd_parameters(struct rbsp *rbsp,
22462306a36Sopenharmony_ci					 struct nal_hevc_hrd_parameters *hrd)
22562306a36Sopenharmony_ci{
22662306a36Sopenharmony_ci	unsigned int i;
22762306a36Sopenharmony_ci	unsigned int max_num_sub_layers_minus_1 = 0;
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	rbsp_bit(rbsp, &hrd->nal_hrd_parameters_present_flag);
23062306a36Sopenharmony_ci	rbsp_bit(rbsp, &hrd->vcl_hrd_parameters_present_flag);
23162306a36Sopenharmony_ci	if (hrd->nal_hrd_parameters_present_flag || hrd->vcl_hrd_parameters_present_flag) {
23262306a36Sopenharmony_ci		rbsp_bit(rbsp, &hrd->sub_pic_hrd_params_present_flag);
23362306a36Sopenharmony_ci		if (hrd->sub_pic_hrd_params_present_flag) {
23462306a36Sopenharmony_ci			rbsp_bits(rbsp, 8, &hrd->tick_divisor_minus2);
23562306a36Sopenharmony_ci			rbsp_bits(rbsp, 5, &hrd->du_cpb_removal_delay_increment_length_minus1);
23662306a36Sopenharmony_ci			rbsp_bit(rbsp, &hrd->sub_pic_cpb_params_in_pic_timing_sei_flag);
23762306a36Sopenharmony_ci			rbsp_bits(rbsp, 5, &hrd->dpb_output_delay_du_length_minus1);
23862306a36Sopenharmony_ci		}
23962306a36Sopenharmony_ci		rbsp_bits(rbsp, 4, &hrd->bit_rate_scale);
24062306a36Sopenharmony_ci		rbsp_bits(rbsp, 4, &hrd->cpb_size_scale);
24162306a36Sopenharmony_ci		if (hrd->sub_pic_hrd_params_present_flag)
24262306a36Sopenharmony_ci			rbsp_bits(rbsp, 4, &hrd->cpb_size_du_scale);
24362306a36Sopenharmony_ci		rbsp_bits(rbsp, 5, &hrd->initial_cpb_removal_delay_length_minus1);
24462306a36Sopenharmony_ci		rbsp_bits(rbsp, 5, &hrd->au_cpb_removal_delay_length_minus1);
24562306a36Sopenharmony_ci		rbsp_bits(rbsp, 5, &hrd->dpb_output_delay_length_minus1);
24662306a36Sopenharmony_ci	}
24762306a36Sopenharmony_ci	for (i = 0; i <= max_num_sub_layers_minus_1; i++) {
24862306a36Sopenharmony_ci		rbsp_bit(rbsp, &hrd->fixed_pic_rate_general_flag[i]);
24962306a36Sopenharmony_ci		if (!hrd->fixed_pic_rate_general_flag[i])
25062306a36Sopenharmony_ci			rbsp_bit(rbsp, &hrd->fixed_pic_rate_within_cvs_flag[i]);
25162306a36Sopenharmony_ci		if (hrd->fixed_pic_rate_within_cvs_flag[i])
25262306a36Sopenharmony_ci			rbsp_uev(rbsp, &hrd->elemental_duration_in_tc_minus1[i]);
25362306a36Sopenharmony_ci		else
25462306a36Sopenharmony_ci			rbsp_bit(rbsp, &hrd->low_delay_hrd_flag[i]);
25562306a36Sopenharmony_ci		if (!hrd->low_delay_hrd_flag[i])
25662306a36Sopenharmony_ci			rbsp_uev(rbsp, &hrd->cpb_cnt_minus1[i]);
25762306a36Sopenharmony_ci		if (hrd->nal_hrd_parameters_present_flag)
25862306a36Sopenharmony_ci			nal_hevc_rbsp_sub_layer_hrd_parameters(rbsp, &hrd->vcl_hrd[i]);
25962306a36Sopenharmony_ci		if (hrd->vcl_hrd_parameters_present_flag)
26062306a36Sopenharmony_ci			nal_hevc_rbsp_sub_layer_hrd_parameters(rbsp, &hrd->vcl_hrd[i]);
26162306a36Sopenharmony_ci	}
26262306a36Sopenharmony_ci}
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_cistatic void nal_hevc_rbsp_vui_parameters(struct rbsp *rbsp,
26562306a36Sopenharmony_ci					 struct nal_hevc_vui_parameters *vui)
26662306a36Sopenharmony_ci{
26762306a36Sopenharmony_ci	if (!vui) {
26862306a36Sopenharmony_ci		rbsp->error = -EINVAL;
26962306a36Sopenharmony_ci		return;
27062306a36Sopenharmony_ci	}
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	rbsp_bit(rbsp, &vui->aspect_ratio_info_present_flag);
27362306a36Sopenharmony_ci	if (vui->aspect_ratio_info_present_flag) {
27462306a36Sopenharmony_ci		rbsp_bits(rbsp, 8, &vui->aspect_ratio_idc);
27562306a36Sopenharmony_ci		if (vui->aspect_ratio_idc == 255) {
27662306a36Sopenharmony_ci			rbsp_bits(rbsp, 16, &vui->sar_width);
27762306a36Sopenharmony_ci			rbsp_bits(rbsp, 16, &vui->sar_height);
27862306a36Sopenharmony_ci		}
27962306a36Sopenharmony_ci	}
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	rbsp_bit(rbsp, &vui->overscan_info_present_flag);
28262306a36Sopenharmony_ci	if (vui->overscan_info_present_flag)
28362306a36Sopenharmony_ci		rbsp_bit(rbsp, &vui->overscan_appropriate_flag);
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci	rbsp_bit(rbsp, &vui->video_signal_type_present_flag);
28662306a36Sopenharmony_ci	if (vui->video_signal_type_present_flag) {
28762306a36Sopenharmony_ci		rbsp_bits(rbsp, 3, &vui->video_format);
28862306a36Sopenharmony_ci		rbsp_bit(rbsp, &vui->video_full_range_flag);
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci		rbsp_bit(rbsp, &vui->colour_description_present_flag);
29162306a36Sopenharmony_ci		if (vui->colour_description_present_flag) {
29262306a36Sopenharmony_ci			rbsp_bits(rbsp, 8, &vui->colour_primaries);
29362306a36Sopenharmony_ci			rbsp_bits(rbsp, 8, &vui->transfer_characteristics);
29462306a36Sopenharmony_ci			rbsp_bits(rbsp, 8, &vui->matrix_coeffs);
29562306a36Sopenharmony_ci		}
29662306a36Sopenharmony_ci	}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci	rbsp_bit(rbsp, &vui->chroma_loc_info_present_flag);
29962306a36Sopenharmony_ci	if (vui->chroma_loc_info_present_flag) {
30062306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->chroma_sample_loc_type_top_field);
30162306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->chroma_sample_loc_type_bottom_field);
30262306a36Sopenharmony_ci	}
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	rbsp_bit(rbsp, &vui->neutral_chroma_indication_flag);
30562306a36Sopenharmony_ci	rbsp_bit(rbsp, &vui->field_seq_flag);
30662306a36Sopenharmony_ci	rbsp_bit(rbsp, &vui->frame_field_info_present_flag);
30762306a36Sopenharmony_ci	rbsp_bit(rbsp, &vui->default_display_window_flag);
30862306a36Sopenharmony_ci	if (vui->default_display_window_flag) {
30962306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->def_disp_win_left_offset);
31062306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->def_disp_win_right_offset);
31162306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->def_disp_win_top_offset);
31262306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->def_disp_win_bottom_offset);
31362306a36Sopenharmony_ci	}
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	rbsp_bit(rbsp, &vui->vui_timing_info_present_flag);
31662306a36Sopenharmony_ci	if (vui->vui_timing_info_present_flag) {
31762306a36Sopenharmony_ci		rbsp_bits(rbsp, 32, &vui->vui_num_units_in_tick);
31862306a36Sopenharmony_ci		rbsp_bits(rbsp, 32, &vui->vui_time_scale);
31962306a36Sopenharmony_ci		rbsp_bit(rbsp, &vui->vui_poc_proportional_to_timing_flag);
32062306a36Sopenharmony_ci		if (vui->vui_poc_proportional_to_timing_flag)
32162306a36Sopenharmony_ci			rbsp_uev(rbsp, &vui->vui_num_ticks_poc_diff_one_minus1);
32262306a36Sopenharmony_ci		rbsp_bit(rbsp, &vui->vui_hrd_parameters_present_flag);
32362306a36Sopenharmony_ci		if (vui->vui_hrd_parameters_present_flag)
32462306a36Sopenharmony_ci			nal_hevc_rbsp_hrd_parameters(rbsp, &vui->nal_hrd_parameters);
32562306a36Sopenharmony_ci	}
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	rbsp_bit(rbsp, &vui->bitstream_restriction_flag);
32862306a36Sopenharmony_ci	if (vui->bitstream_restriction_flag) {
32962306a36Sopenharmony_ci		rbsp_bit(rbsp, &vui->tiles_fixed_structure_flag);
33062306a36Sopenharmony_ci		rbsp_bit(rbsp, &vui->motion_vectors_over_pic_boundaries_flag);
33162306a36Sopenharmony_ci		rbsp_bit(rbsp, &vui->restricted_ref_pic_lists_flag);
33262306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->min_spatial_segmentation_idc);
33362306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->max_bytes_per_pic_denom);
33462306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->max_bits_per_min_cu_denom);
33562306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->log2_max_mv_length_horizontal);
33662306a36Sopenharmony_ci		rbsp_uev(rbsp, &vui->log2_max_mv_length_vertical);
33762306a36Sopenharmony_ci	}
33862306a36Sopenharmony_ci}
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_cistatic void nal_hevc_rbsp_sps(struct rbsp *rbsp, struct nal_hevc_sps *sps)
34162306a36Sopenharmony_ci{
34262306a36Sopenharmony_ci	unsigned int i;
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci	rbsp_bits(rbsp, 4, &sps->video_parameter_set_id);
34562306a36Sopenharmony_ci	rbsp_bits(rbsp, 3, &sps->max_sub_layers_minus1);
34662306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->temporal_id_nesting_flag);
34762306a36Sopenharmony_ci	nal_hevc_rbsp_profile_tier_level(rbsp, &sps->profile_tier_level);
34862306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->seq_parameter_set_id);
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->chroma_format_idc);
35162306a36Sopenharmony_ci	if (sps->chroma_format_idc == 3)
35262306a36Sopenharmony_ci		rbsp_bit(rbsp, &sps->separate_colour_plane_flag);
35362306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->pic_width_in_luma_samples);
35462306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->pic_height_in_luma_samples);
35562306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->conformance_window_flag);
35662306a36Sopenharmony_ci	if (sps->conformance_window_flag) {
35762306a36Sopenharmony_ci		rbsp_uev(rbsp, &sps->conf_win_left_offset);
35862306a36Sopenharmony_ci		rbsp_uev(rbsp, &sps->conf_win_right_offset);
35962306a36Sopenharmony_ci		rbsp_uev(rbsp, &sps->conf_win_top_offset);
36062306a36Sopenharmony_ci		rbsp_uev(rbsp, &sps->conf_win_bottom_offset);
36162306a36Sopenharmony_ci	}
36262306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->bit_depth_luma_minus8);
36362306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->bit_depth_chroma_minus8);
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->log2_max_pic_order_cnt_lsb_minus4);
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->sub_layer_ordering_info_present_flag);
36862306a36Sopenharmony_ci	for (i = (sps->sub_layer_ordering_info_present_flag ? 0 : sps->max_sub_layers_minus1);
36962306a36Sopenharmony_ci	     i <= sps->max_sub_layers_minus1; i++) {
37062306a36Sopenharmony_ci		rbsp_uev(rbsp, &sps->max_dec_pic_buffering_minus1[i]);
37162306a36Sopenharmony_ci		rbsp_uev(rbsp, &sps->max_num_reorder_pics[i]);
37262306a36Sopenharmony_ci		rbsp_uev(rbsp, &sps->max_latency_increase_plus1[i]);
37362306a36Sopenharmony_ci	}
37462306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->log2_min_luma_coding_block_size_minus3);
37562306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->log2_diff_max_min_luma_coding_block_size);
37662306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->log2_min_luma_transform_block_size_minus2);
37762306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->log2_diff_max_min_luma_transform_block_size);
37862306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->max_transform_hierarchy_depth_inter);
37962306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->max_transform_hierarchy_depth_intra);
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->scaling_list_enabled_flag);
38262306a36Sopenharmony_ci	if (sps->scaling_list_enabled_flag)
38362306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->amp_enabled_flag);
38662306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->sample_adaptive_offset_enabled_flag);
38762306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->pcm_enabled_flag);
38862306a36Sopenharmony_ci	if (sps->pcm_enabled_flag) {
38962306a36Sopenharmony_ci		rbsp_bits(rbsp, 4, &sps->pcm_sample_bit_depth_luma_minus1);
39062306a36Sopenharmony_ci		rbsp_bits(rbsp, 4, &sps->pcm_sample_bit_depth_chroma_minus1);
39162306a36Sopenharmony_ci		rbsp_uev(rbsp, &sps->log2_min_pcm_luma_coding_block_size_minus3);
39262306a36Sopenharmony_ci		rbsp_uev(rbsp, &sps->log2_diff_max_min_pcm_luma_coding_block_size);
39362306a36Sopenharmony_ci		rbsp_bit(rbsp, &sps->pcm_loop_filter_disabled_flag);
39462306a36Sopenharmony_ci	}
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	rbsp_uev(rbsp, &sps->num_short_term_ref_pic_sets);
39762306a36Sopenharmony_ci	if (sps->num_short_term_ref_pic_sets > 0)
39862306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->long_term_ref_pics_present_flag);
40162306a36Sopenharmony_ci	if (sps->long_term_ref_pics_present_flag)
40262306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->sps_temporal_mvp_enabled_flag);
40562306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->strong_intra_smoothing_enabled_flag);
40662306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->vui_parameters_present_flag);
40762306a36Sopenharmony_ci	if (sps->vui_parameters_present_flag)
40862306a36Sopenharmony_ci		nal_hevc_rbsp_vui_parameters(rbsp, &sps->vui);
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci	rbsp_bit(rbsp, &sps->extension_present_flag);
41162306a36Sopenharmony_ci	if (sps->extension_present_flag) {
41262306a36Sopenharmony_ci		rbsp_bit(rbsp, &sps->sps_range_extension_flag);
41362306a36Sopenharmony_ci		rbsp_bit(rbsp, &sps->sps_multilayer_extension_flag);
41462306a36Sopenharmony_ci		rbsp_bit(rbsp, &sps->sps_3d_extension_flag);
41562306a36Sopenharmony_ci		rbsp_bit(rbsp, &sps->sps_scc_extension_flag);
41662306a36Sopenharmony_ci		rbsp_bits(rbsp, 5, &sps->sps_extension_4bits);
41762306a36Sopenharmony_ci	}
41862306a36Sopenharmony_ci	if (sps->sps_range_extension_flag)
41962306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
42062306a36Sopenharmony_ci	if (sps->sps_multilayer_extension_flag)
42162306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
42262306a36Sopenharmony_ci	if (sps->sps_3d_extension_flag)
42362306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
42462306a36Sopenharmony_ci	if (sps->sps_scc_extension_flag)
42562306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
42662306a36Sopenharmony_ci	if (sps->sps_extension_4bits)
42762306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
42862306a36Sopenharmony_ci}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_cistatic void nal_hevc_rbsp_pps(struct rbsp *rbsp, struct nal_hevc_pps *pps)
43162306a36Sopenharmony_ci{
43262306a36Sopenharmony_ci	unsigned int i;
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	rbsp_uev(rbsp, &pps->pps_pic_parameter_set_id);
43562306a36Sopenharmony_ci	rbsp_uev(rbsp, &pps->pps_seq_parameter_set_id);
43662306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->dependent_slice_segments_enabled_flag);
43762306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->output_flag_present_flag);
43862306a36Sopenharmony_ci	rbsp_bits(rbsp, 3, &pps->num_extra_slice_header_bits);
43962306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->sign_data_hiding_enabled_flag);
44062306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->cabac_init_present_flag);
44162306a36Sopenharmony_ci	rbsp_uev(rbsp, &pps->num_ref_idx_l0_default_active_minus1);
44262306a36Sopenharmony_ci	rbsp_uev(rbsp, &pps->num_ref_idx_l1_default_active_minus1);
44362306a36Sopenharmony_ci	rbsp_sev(rbsp, &pps->init_qp_minus26);
44462306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->constrained_intra_pred_flag);
44562306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->transform_skip_enabled_flag);
44662306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->cu_qp_delta_enabled_flag);
44762306a36Sopenharmony_ci	if (pps->cu_qp_delta_enabled_flag)
44862306a36Sopenharmony_ci		rbsp_uev(rbsp, &pps->diff_cu_qp_delta_depth);
44962306a36Sopenharmony_ci	rbsp_sev(rbsp, &pps->pps_cb_qp_offset);
45062306a36Sopenharmony_ci	rbsp_sev(rbsp, &pps->pps_cr_qp_offset);
45162306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->pps_slice_chroma_qp_offsets_present_flag);
45262306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->weighted_pred_flag);
45362306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->weighted_bipred_flag);
45462306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->transquant_bypass_enabled_flag);
45562306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->tiles_enabled_flag);
45662306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->entropy_coding_sync_enabled_flag);
45762306a36Sopenharmony_ci	if (pps->tiles_enabled_flag) {
45862306a36Sopenharmony_ci		rbsp_uev(rbsp, &pps->num_tile_columns_minus1);
45962306a36Sopenharmony_ci		rbsp_uev(rbsp, &pps->num_tile_rows_minus1);
46062306a36Sopenharmony_ci		rbsp_bit(rbsp, &pps->uniform_spacing_flag);
46162306a36Sopenharmony_ci		if (!pps->uniform_spacing_flag) {
46262306a36Sopenharmony_ci			for (i = 0; i < pps->num_tile_columns_minus1; i++)
46362306a36Sopenharmony_ci				rbsp_uev(rbsp, &pps->column_width_minus1[i]);
46462306a36Sopenharmony_ci			for (i = 0; i < pps->num_tile_rows_minus1; i++)
46562306a36Sopenharmony_ci				rbsp_uev(rbsp, &pps->row_height_minus1[i]);
46662306a36Sopenharmony_ci		}
46762306a36Sopenharmony_ci		rbsp_bit(rbsp, &pps->loop_filter_across_tiles_enabled_flag);
46862306a36Sopenharmony_ci	}
46962306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->pps_loop_filter_across_slices_enabled_flag);
47062306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->deblocking_filter_control_present_flag);
47162306a36Sopenharmony_ci	if (pps->deblocking_filter_control_present_flag) {
47262306a36Sopenharmony_ci		rbsp_bit(rbsp, &pps->deblocking_filter_override_enabled_flag);
47362306a36Sopenharmony_ci		rbsp_bit(rbsp, &pps->pps_deblocking_filter_disabled_flag);
47462306a36Sopenharmony_ci		if (!pps->pps_deblocking_filter_disabled_flag) {
47562306a36Sopenharmony_ci			rbsp_sev(rbsp, &pps->pps_beta_offset_div2);
47662306a36Sopenharmony_ci			rbsp_sev(rbsp, &pps->pps_tc_offset_div2);
47762306a36Sopenharmony_ci		}
47862306a36Sopenharmony_ci	}
47962306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->pps_scaling_list_data_present_flag);
48062306a36Sopenharmony_ci	if (pps->pps_scaling_list_data_present_flag)
48162306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
48262306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->lists_modification_present_flag);
48362306a36Sopenharmony_ci	rbsp_uev(rbsp, &pps->log2_parallel_merge_level_minus2);
48462306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->slice_segment_header_extension_present_flag);
48562306a36Sopenharmony_ci	rbsp_bit(rbsp, &pps->pps_extension_present_flag);
48662306a36Sopenharmony_ci	if (pps->pps_extension_present_flag) {
48762306a36Sopenharmony_ci		rbsp_bit(rbsp, &pps->pps_range_extension_flag);
48862306a36Sopenharmony_ci		rbsp_bit(rbsp, &pps->pps_multilayer_extension_flag);
48962306a36Sopenharmony_ci		rbsp_bit(rbsp, &pps->pps_3d_extension_flag);
49062306a36Sopenharmony_ci		rbsp_bit(rbsp, &pps->pps_scc_extension_flag);
49162306a36Sopenharmony_ci		rbsp_bits(rbsp, 4, &pps->pps_extension_4bits);
49262306a36Sopenharmony_ci	}
49362306a36Sopenharmony_ci	if (pps->pps_range_extension_flag)
49462306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
49562306a36Sopenharmony_ci	if (pps->pps_multilayer_extension_flag)
49662306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
49762306a36Sopenharmony_ci	if (pps->pps_3d_extension_flag)
49862306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
49962306a36Sopenharmony_ci	if (pps->pps_scc_extension_flag)
50062306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
50162306a36Sopenharmony_ci	if (pps->pps_extension_4bits)
50262306a36Sopenharmony_ci		rbsp_unsupported(rbsp);
50362306a36Sopenharmony_ci}
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci/**
50662306a36Sopenharmony_ci * nal_hevc_write_vps() - Write PPS NAL unit into RBSP format
50762306a36Sopenharmony_ci * @dev: device pointer
50862306a36Sopenharmony_ci * @dest: the buffer that is filled with RBSP data
50962306a36Sopenharmony_ci * @n: maximum size of @dest in bytes
51062306a36Sopenharmony_ci * @vps: &struct nal_hevc_vps to convert to RBSP
51162306a36Sopenharmony_ci *
51262306a36Sopenharmony_ci * Convert @vps to RBSP data and write it into @dest.
51362306a36Sopenharmony_ci *
51462306a36Sopenharmony_ci * The size of the VPS NAL unit is not known in advance and this function will
51562306a36Sopenharmony_ci * fail, if @dest does not hold sufficient space for the VPS NAL unit.
51662306a36Sopenharmony_ci *
51762306a36Sopenharmony_ci * Return: number of bytes written to @dest or negative error code
51862306a36Sopenharmony_ci */
51962306a36Sopenharmony_cissize_t nal_hevc_write_vps(const struct device *dev,
52062306a36Sopenharmony_ci			   void *dest, size_t n, struct nal_hevc_vps *vps)
52162306a36Sopenharmony_ci{
52262306a36Sopenharmony_ci	struct rbsp rbsp;
52362306a36Sopenharmony_ci	unsigned int forbidden_zero_bit = 0;
52462306a36Sopenharmony_ci	unsigned int nal_unit_type = VPS_NUT;
52562306a36Sopenharmony_ci	unsigned int nuh_layer_id = 0;
52662306a36Sopenharmony_ci	unsigned int nuh_temporal_id_plus1 = 1;
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	if (!dest)
52962306a36Sopenharmony_ci		return -EINVAL;
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci	rbsp_init(&rbsp, dest, n, &write);
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	nal_hevc_write_start_code_prefix(&rbsp);
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	/* NAL unit header */
53662306a36Sopenharmony_ci	rbsp_bit(&rbsp, &forbidden_zero_bit);
53762306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nal_unit_type);
53862306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nuh_layer_id);
53962306a36Sopenharmony_ci	rbsp_bits(&rbsp, 3, &nuh_temporal_id_plus1);
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci	nal_hevc_rbsp_vps(&rbsp, vps);
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci	rbsp_trailing_bits(&rbsp);
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	if (rbsp.error)
54662306a36Sopenharmony_ci		return rbsp.error;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	return DIV_ROUND_UP(rbsp.pos, 8);
54962306a36Sopenharmony_ci}
55062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nal_hevc_write_vps);
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci/**
55362306a36Sopenharmony_ci * nal_hevc_read_vps() - Read VPS NAL unit from RBSP format
55462306a36Sopenharmony_ci * @dev: device pointer
55562306a36Sopenharmony_ci * @vps: the &struct nal_hevc_vps to fill from the RBSP data
55662306a36Sopenharmony_ci * @src: the buffer that contains the RBSP data
55762306a36Sopenharmony_ci * @n: size of @src in bytes
55862306a36Sopenharmony_ci *
55962306a36Sopenharmony_ci * Read RBSP data from @src and use it to fill @vps.
56062306a36Sopenharmony_ci *
56162306a36Sopenharmony_ci * Return: number of bytes read from @src or negative error code
56262306a36Sopenharmony_ci */
56362306a36Sopenharmony_cissize_t nal_hevc_read_vps(const struct device *dev,
56462306a36Sopenharmony_ci			  struct nal_hevc_vps *vps, void *src, size_t n)
56562306a36Sopenharmony_ci{
56662306a36Sopenharmony_ci	struct rbsp rbsp;
56762306a36Sopenharmony_ci	unsigned int forbidden_zero_bit;
56862306a36Sopenharmony_ci	unsigned int nal_unit_type;
56962306a36Sopenharmony_ci	unsigned int nuh_layer_id;
57062306a36Sopenharmony_ci	unsigned int nuh_temporal_id_plus1;
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci	if (!src)
57362306a36Sopenharmony_ci		return -EINVAL;
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci	rbsp_init(&rbsp, src, n, &read);
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ci	nal_hevc_read_start_code_prefix(&rbsp);
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	rbsp_bit(&rbsp, &forbidden_zero_bit);
58062306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nal_unit_type);
58162306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nuh_layer_id);
58262306a36Sopenharmony_ci	rbsp_bits(&rbsp, 3, &nuh_temporal_id_plus1);
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	if (rbsp.error ||
58562306a36Sopenharmony_ci	    forbidden_zero_bit != 0 ||
58662306a36Sopenharmony_ci	    nal_unit_type != VPS_NUT)
58762306a36Sopenharmony_ci		return -EINVAL;
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci	nal_hevc_rbsp_vps(&rbsp, vps);
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_ci	rbsp_trailing_bits(&rbsp);
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci	if (rbsp.error)
59462306a36Sopenharmony_ci		return rbsp.error;
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	return DIV_ROUND_UP(rbsp.pos, 8);
59762306a36Sopenharmony_ci}
59862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nal_hevc_read_vps);
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_ci/**
60162306a36Sopenharmony_ci * nal_hevc_write_sps() - Write SPS NAL unit into RBSP format
60262306a36Sopenharmony_ci * @dev: device pointer
60362306a36Sopenharmony_ci * @dest: the buffer that is filled with RBSP data
60462306a36Sopenharmony_ci * @n: maximum size of @dest in bytes
60562306a36Sopenharmony_ci * @sps: &struct nal_hevc_sps to convert to RBSP
60662306a36Sopenharmony_ci *
60762306a36Sopenharmony_ci * Convert @sps to RBSP data and write it into @dest.
60862306a36Sopenharmony_ci *
60962306a36Sopenharmony_ci * The size of the SPS NAL unit is not known in advance and this function will
61062306a36Sopenharmony_ci * fail, if @dest does not hold sufficient space for the SPS NAL unit.
61162306a36Sopenharmony_ci *
61262306a36Sopenharmony_ci * Return: number of bytes written to @dest or negative error code
61362306a36Sopenharmony_ci */
61462306a36Sopenharmony_cissize_t nal_hevc_write_sps(const struct device *dev,
61562306a36Sopenharmony_ci			   void *dest, size_t n, struct nal_hevc_sps *sps)
61662306a36Sopenharmony_ci{
61762306a36Sopenharmony_ci	struct rbsp rbsp;
61862306a36Sopenharmony_ci	unsigned int forbidden_zero_bit = 0;
61962306a36Sopenharmony_ci	unsigned int nal_unit_type = SPS_NUT;
62062306a36Sopenharmony_ci	unsigned int nuh_layer_id = 0;
62162306a36Sopenharmony_ci	unsigned int nuh_temporal_id_plus1 = 1;
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci	if (!dest)
62462306a36Sopenharmony_ci		return -EINVAL;
62562306a36Sopenharmony_ci
62662306a36Sopenharmony_ci	rbsp_init(&rbsp, dest, n, &write);
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci	nal_hevc_write_start_code_prefix(&rbsp);
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci	/* NAL unit header */
63162306a36Sopenharmony_ci	rbsp_bit(&rbsp, &forbidden_zero_bit);
63262306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nal_unit_type);
63362306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nuh_layer_id);
63462306a36Sopenharmony_ci	rbsp_bits(&rbsp, 3, &nuh_temporal_id_plus1);
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci	nal_hevc_rbsp_sps(&rbsp, sps);
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci	rbsp_trailing_bits(&rbsp);
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	if (rbsp.error)
64162306a36Sopenharmony_ci		return rbsp.error;
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	return DIV_ROUND_UP(rbsp.pos, 8);
64462306a36Sopenharmony_ci}
64562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nal_hevc_write_sps);
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci/**
64862306a36Sopenharmony_ci * nal_hevc_read_sps() - Read SPS NAL unit from RBSP format
64962306a36Sopenharmony_ci * @dev: device pointer
65062306a36Sopenharmony_ci * @sps: the &struct nal_hevc_sps to fill from the RBSP data
65162306a36Sopenharmony_ci * @src: the buffer that contains the RBSP data
65262306a36Sopenharmony_ci * @n: size of @src in bytes
65362306a36Sopenharmony_ci *
65462306a36Sopenharmony_ci * Read RBSP data from @src and use it to fill @sps.
65562306a36Sopenharmony_ci *
65662306a36Sopenharmony_ci * Return: number of bytes read from @src or negative error code
65762306a36Sopenharmony_ci */
65862306a36Sopenharmony_cissize_t nal_hevc_read_sps(const struct device *dev,
65962306a36Sopenharmony_ci			  struct nal_hevc_sps *sps, void *src, size_t n)
66062306a36Sopenharmony_ci{
66162306a36Sopenharmony_ci	struct rbsp rbsp;
66262306a36Sopenharmony_ci	unsigned int forbidden_zero_bit;
66362306a36Sopenharmony_ci	unsigned int nal_unit_type;
66462306a36Sopenharmony_ci	unsigned int nuh_layer_id;
66562306a36Sopenharmony_ci	unsigned int nuh_temporal_id_plus1;
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	if (!src)
66862306a36Sopenharmony_ci		return -EINVAL;
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	rbsp_init(&rbsp, src, n, &read);
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	nal_hevc_read_start_code_prefix(&rbsp);
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_ci	rbsp_bit(&rbsp, &forbidden_zero_bit);
67562306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nal_unit_type);
67662306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nuh_layer_id);
67762306a36Sopenharmony_ci	rbsp_bits(&rbsp, 3, &nuh_temporal_id_plus1);
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	if (rbsp.error ||
68062306a36Sopenharmony_ci	    forbidden_zero_bit != 0 ||
68162306a36Sopenharmony_ci	    nal_unit_type != SPS_NUT)
68262306a36Sopenharmony_ci		return -EINVAL;
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	nal_hevc_rbsp_sps(&rbsp, sps);
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	rbsp_trailing_bits(&rbsp);
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	if (rbsp.error)
68962306a36Sopenharmony_ci		return rbsp.error;
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_ci	return DIV_ROUND_UP(rbsp.pos, 8);
69262306a36Sopenharmony_ci}
69362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nal_hevc_read_sps);
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci/**
69662306a36Sopenharmony_ci * nal_hevc_write_pps() - Write PPS NAL unit into RBSP format
69762306a36Sopenharmony_ci * @dev: device pointer
69862306a36Sopenharmony_ci * @dest: the buffer that is filled with RBSP data
69962306a36Sopenharmony_ci * @n: maximum size of @dest in bytes
70062306a36Sopenharmony_ci * @pps: &struct nal_hevc_pps to convert to RBSP
70162306a36Sopenharmony_ci *
70262306a36Sopenharmony_ci * Convert @pps to RBSP data and write it into @dest.
70362306a36Sopenharmony_ci *
70462306a36Sopenharmony_ci * The size of the PPS NAL unit is not known in advance and this function will
70562306a36Sopenharmony_ci * fail, if @dest does not hold sufficient space for the PPS NAL unit.
70662306a36Sopenharmony_ci *
70762306a36Sopenharmony_ci * Return: number of bytes written to @dest or negative error code
70862306a36Sopenharmony_ci */
70962306a36Sopenharmony_cissize_t nal_hevc_write_pps(const struct device *dev,
71062306a36Sopenharmony_ci			   void *dest, size_t n, struct nal_hevc_pps *pps)
71162306a36Sopenharmony_ci{
71262306a36Sopenharmony_ci	struct rbsp rbsp;
71362306a36Sopenharmony_ci	unsigned int forbidden_zero_bit = 0;
71462306a36Sopenharmony_ci	unsigned int nal_unit_type = PPS_NUT;
71562306a36Sopenharmony_ci	unsigned int nuh_layer_id = 0;
71662306a36Sopenharmony_ci	unsigned int nuh_temporal_id_plus1 = 1;
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci	if (!dest)
71962306a36Sopenharmony_ci		return -EINVAL;
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci	rbsp_init(&rbsp, dest, n, &write);
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci	nal_hevc_write_start_code_prefix(&rbsp);
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_ci	/* NAL unit header */
72662306a36Sopenharmony_ci	rbsp_bit(&rbsp, &forbidden_zero_bit);
72762306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nal_unit_type);
72862306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nuh_layer_id);
72962306a36Sopenharmony_ci	rbsp_bits(&rbsp, 3, &nuh_temporal_id_plus1);
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci	nal_hevc_rbsp_pps(&rbsp, pps);
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	rbsp_trailing_bits(&rbsp);
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_ci	if (rbsp.error)
73662306a36Sopenharmony_ci		return rbsp.error;
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_ci	return DIV_ROUND_UP(rbsp.pos, 8);
73962306a36Sopenharmony_ci}
74062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nal_hevc_write_pps);
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci/**
74362306a36Sopenharmony_ci * nal_hevc_read_pps() - Read PPS NAL unit from RBSP format
74462306a36Sopenharmony_ci * @dev: device pointer
74562306a36Sopenharmony_ci * @pps: the &struct nal_hevc_pps to fill from the RBSP data
74662306a36Sopenharmony_ci * @src: the buffer that contains the RBSP data
74762306a36Sopenharmony_ci * @n: size of @src in bytes
74862306a36Sopenharmony_ci *
74962306a36Sopenharmony_ci * Read RBSP data from @src and use it to fill @pps.
75062306a36Sopenharmony_ci *
75162306a36Sopenharmony_ci * Return: number of bytes read from @src or negative error code
75262306a36Sopenharmony_ci */
75362306a36Sopenharmony_cissize_t nal_hevc_read_pps(const struct device *dev,
75462306a36Sopenharmony_ci			  struct nal_hevc_pps *pps, void *src, size_t n)
75562306a36Sopenharmony_ci{
75662306a36Sopenharmony_ci	struct rbsp rbsp;
75762306a36Sopenharmony_ci	unsigned int forbidden_zero_bit;
75862306a36Sopenharmony_ci	unsigned int nal_unit_type;
75962306a36Sopenharmony_ci	unsigned int nuh_layer_id;
76062306a36Sopenharmony_ci	unsigned int nuh_temporal_id_plus1;
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci	if (!src)
76362306a36Sopenharmony_ci		return -EINVAL;
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci	rbsp_init(&rbsp, src, n, &read);
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci	nal_hevc_read_start_code_prefix(&rbsp);
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	/* NAL unit header */
77062306a36Sopenharmony_ci	rbsp_bit(&rbsp, &forbidden_zero_bit);
77162306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nal_unit_type);
77262306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nuh_layer_id);
77362306a36Sopenharmony_ci	rbsp_bits(&rbsp, 3, &nuh_temporal_id_plus1);
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ci	nal_hevc_rbsp_pps(&rbsp, pps);
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci	rbsp_trailing_bits(&rbsp);
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_ci	if (rbsp.error)
78062306a36Sopenharmony_ci		return rbsp.error;
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci	return DIV_ROUND_UP(rbsp.pos, 8);
78362306a36Sopenharmony_ci}
78462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nal_hevc_read_pps);
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci/**
78762306a36Sopenharmony_ci * nal_hevc_write_filler() - Write filler data RBSP
78862306a36Sopenharmony_ci * @dev: device pointer
78962306a36Sopenharmony_ci * @dest: buffer to fill with filler data
79062306a36Sopenharmony_ci * @n: size of the buffer to fill with filler data
79162306a36Sopenharmony_ci *
79262306a36Sopenharmony_ci * Write a filler data RBSP to @dest with a size of @n bytes and return the
79362306a36Sopenharmony_ci * number of written filler data bytes.
79462306a36Sopenharmony_ci *
79562306a36Sopenharmony_ci * Use this function to generate dummy data in an RBSP data stream that can be
79662306a36Sopenharmony_ci * safely ignored by hevc decoders.
79762306a36Sopenharmony_ci *
79862306a36Sopenharmony_ci * The RBSP format of the filler data is specified in Rec. ITU-T H.265
79962306a36Sopenharmony_ci * (02/2018) 7.3.2.8 Filler data RBSP syntax.
80062306a36Sopenharmony_ci *
80162306a36Sopenharmony_ci * Return: number of filler data bytes (including marker) or negative error
80262306a36Sopenharmony_ci */
80362306a36Sopenharmony_cissize_t nal_hevc_write_filler(const struct device *dev, void *dest, size_t n)
80462306a36Sopenharmony_ci{
80562306a36Sopenharmony_ci	struct rbsp rbsp;
80662306a36Sopenharmony_ci	unsigned int forbidden_zero_bit = 0;
80762306a36Sopenharmony_ci	unsigned int nal_unit_type = FD_NUT;
80862306a36Sopenharmony_ci	unsigned int nuh_layer_id = 0;
80962306a36Sopenharmony_ci	unsigned int nuh_temporal_id_plus1 = 1;
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_ci	if (!dest)
81262306a36Sopenharmony_ci		return -EINVAL;
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci	rbsp_init(&rbsp, dest, n, &write);
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci	nal_hevc_write_start_code_prefix(&rbsp);
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	rbsp_bit(&rbsp, &forbidden_zero_bit);
81962306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nal_unit_type);
82062306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nuh_layer_id);
82162306a36Sopenharmony_ci	rbsp_bits(&rbsp, 3, &nuh_temporal_id_plus1);
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci	nal_hevc_write_filler_data(&rbsp);
82462306a36Sopenharmony_ci	rbsp_trailing_bits(&rbsp);
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ci	if (rbsp.error)
82762306a36Sopenharmony_ci		return rbsp.error;
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_ci	return DIV_ROUND_UP(rbsp.pos, 8);
83062306a36Sopenharmony_ci}
83162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nal_hevc_write_filler);
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci/**
83462306a36Sopenharmony_ci * nal_hevc_read_filler() - Read filler data RBSP
83562306a36Sopenharmony_ci * @dev: device pointer
83662306a36Sopenharmony_ci * @src: buffer with RBSP data that is read
83762306a36Sopenharmony_ci * @n: maximum size of src that shall be read
83862306a36Sopenharmony_ci *
83962306a36Sopenharmony_ci * Read a filler data RBSP from @src up to a maximum size of @n bytes and
84062306a36Sopenharmony_ci * return the size of the filler data in bytes including the marker.
84162306a36Sopenharmony_ci *
84262306a36Sopenharmony_ci * This function is used to parse filler data and skip the respective bytes in
84362306a36Sopenharmony_ci * the RBSP data.
84462306a36Sopenharmony_ci *
84562306a36Sopenharmony_ci * The RBSP format of the filler data is specified in Rec. ITU-T H.265
84662306a36Sopenharmony_ci * (02/2018) 7.3.2.8 Filler data RBSP syntax.
84762306a36Sopenharmony_ci *
84862306a36Sopenharmony_ci * Return: number of filler data bytes (including marker) or negative error
84962306a36Sopenharmony_ci */
85062306a36Sopenharmony_cissize_t nal_hevc_read_filler(const struct device *dev, void *src, size_t n)
85162306a36Sopenharmony_ci{
85262306a36Sopenharmony_ci	struct rbsp rbsp;
85362306a36Sopenharmony_ci	unsigned int forbidden_zero_bit;
85462306a36Sopenharmony_ci	unsigned int nal_unit_type;
85562306a36Sopenharmony_ci	unsigned int nuh_layer_id;
85662306a36Sopenharmony_ci	unsigned int nuh_temporal_id_plus1;
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci	if (!src)
85962306a36Sopenharmony_ci		return -EINVAL;
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	rbsp_init(&rbsp, src, n, &read);
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci	nal_hevc_read_start_code_prefix(&rbsp);
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_ci	rbsp_bit(&rbsp, &forbidden_zero_bit);
86662306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nal_unit_type);
86762306a36Sopenharmony_ci	rbsp_bits(&rbsp, 6, &nuh_layer_id);
86862306a36Sopenharmony_ci	rbsp_bits(&rbsp, 3, &nuh_temporal_id_plus1);
86962306a36Sopenharmony_ci
87062306a36Sopenharmony_ci	if (rbsp.error)
87162306a36Sopenharmony_ci		return rbsp.error;
87262306a36Sopenharmony_ci	if (forbidden_zero_bit != 0 ||
87362306a36Sopenharmony_ci	    nal_unit_type != FD_NUT)
87462306a36Sopenharmony_ci		return -EINVAL;
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci	nal_hevc_read_filler_data(&rbsp);
87762306a36Sopenharmony_ci	rbsp_trailing_bits(&rbsp);
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci	if (rbsp.error)
88062306a36Sopenharmony_ci		return rbsp.error;
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ci	return DIV_ROUND_UP(rbsp.pos, 8);
88362306a36Sopenharmony_ci}
88462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nal_hevc_read_filler);
885