/src/avm/av2/decoder/obu_ops.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2025, Alliance for Open Media. All rights reserved |
3 | | * |
4 | | * This source code is subject to the terms of the BSD 3-Clause Clear License |
5 | | * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear |
6 | | * License was not distributed with this source code in the LICENSE file, you |
7 | | * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/. If the |
8 | | * Alliance for Open Media Patent License 1.0 was not distributed with this |
9 | | * source code in the PATENTS file, you can obtain it at |
10 | | * aomedia.org/license/patent-license/. |
11 | | */ |
12 | | |
13 | | #include <assert.h> |
14 | | |
15 | | #include "config/avm_config.h" |
16 | | #include "avm_dsp/bitreader_buffer.h" |
17 | | #include "av2/common/common.h" |
18 | | #include "av2/common/obu_util.h" |
19 | | #include "av2/decoder/decoder.h" |
20 | | #include "av2/decoder/decodeframe.h" |
21 | | #include "av2/decoder/obu.h" |
22 | | |
23 | | static void read_ops_mlayer_info(int xLId, |
24 | | struct OpsMLayerInfo *ops_mlayer_info, |
25 | 48 | struct avm_read_bit_buffer *rb) { |
26 | | // mlayer map |
27 | 48 | ops_mlayer_info->ops_mlayer_map[xLId] = |
28 | 48 | avm_rb_read_literal(rb, MAX_NUM_MLAYERS); |
29 | 48 | int mCount = 0; |
30 | 417 | for (int j = 0; j < MAX_NUM_MLAYERS; j++) { |
31 | 369 | if ((ops_mlayer_info->ops_mlayer_map[xLId] & (1 << j))) { |
32 | | // tlayer map |
33 | 160 | ops_mlayer_info->ops_tlayer_map[xLId][j] = |
34 | 160 | avm_rb_read_literal(rb, MAX_NUM_TLAYERS); |
35 | 160 | int tCount = 0; |
36 | 788 | for (int k = 0; k < MAX_NUM_TLAYERS; k++) { |
37 | 628 | if ((ops_mlayer_info->ops_tlayer_map[xLId][j] & (1 << k))) { |
38 | 299 | tCount++; |
39 | 299 | } |
40 | 628 | } |
41 | 160 | ops_mlayer_info->OPTLayerCount[xLId][j] = tCount; |
42 | 160 | mCount++; |
43 | 160 | } |
44 | 369 | } |
45 | 48 | ops_mlayer_info->OPMLayerCount[xLId] = mCount; |
46 | 48 | } |
47 | | |
48 | | static void read_ops_color_info(struct OpsColorInfo *opsColInfo, |
49 | 29 | struct avm_read_bit_buffer *rb) { |
50 | 29 | av2_read_color_info(&opsColInfo->ops_color_description_idc, |
51 | 29 | &opsColInfo->ops_color_primaries, |
52 | 29 | &opsColInfo->ops_transfer_characteristics, |
53 | 29 | &opsColInfo->ops_matrix_coefficients, |
54 | 29 | &opsColInfo->ops_full_range_flag, rb); |
55 | 29 | } |
56 | | |
57 | | static void read_ops_decoder_model_info( |
58 | | struct OpsDecoderModelInfo *ops_decoder_model_info, |
59 | 27 | struct avm_read_bit_buffer *rb) { |
60 | 27 | ops_decoder_model_info->ops_decoder_buffer_delay = |
61 | 27 | avm_rb_read_uvlc(rb); // decoder delay |
62 | 27 | ops_decoder_model_info->ops_encoder_buffer_delay = |
63 | 27 | avm_rb_read_uvlc(rb); // encoder delay |
64 | 27 | ops_decoder_model_info->ops_low_delay_mode_flag = |
65 | 27 | avm_rb_read_bit(rb); // low-delay mode flag |
66 | 27 | } |
67 | | |
68 | | uint32_t av2_read_operating_point_set_obu(struct AV2Decoder *pbi, |
69 | | int obu_xlayer_id, |
70 | 71 | struct avm_read_bit_buffer *rb) { |
71 | 71 | const uint32_t saved_bit_offset = rb->bit_offset; |
72 | | |
73 | 71 | int ops_reset_flag = avm_rb_read_bit(rb); |
74 | 71 | const int ops_id = avm_rb_read_literal(rb, OPS_ID_BITS); |
75 | 71 | const int ops_cnt = avm_rb_read_literal(rb, OPS_COUNT_BITS); |
76 | | |
77 | | // Apply reset semantics before writing to any slot (spec |
78 | | // #ops_general_semantics): |
79 | | // Case 1: reset_flag=1, cnt=0 -> reset all OPS for this layer |
80 | | // Case 2: reset_flag=1, cnt=N>0 -> reset all OPS for this layer, then |
81 | | // define OPS x |
82 | | // Case 3: reset_flag=0, cnt=0 -> reset only OPS x |
83 | | // Case 4: reset_flag=0, cnt=N>0 -> update OPS x only (no reset) |
84 | 71 | if (ops_reset_flag) { |
85 | 11 | if (obu_xlayer_id == GLOBAL_XLAYER_ID) { |
86 | | // Cases 1 & 2 (global): clear all slots across all extended layers |
87 | 0 | for (int x = 0; x < MAX_NUM_XLAYERS; x++) |
88 | 0 | for (int k = 0; k < MAX_NUM_OPS_ID; k++) |
89 | 0 | memset(&pbi->ops_list[x][k], 0, sizeof(pbi->ops_list[x][k])); |
90 | 11 | } else { |
91 | | // Cases 1 & 2 (local): clear all slots for this extended layer only |
92 | 187 | for (int k = 0; k < MAX_NUM_OPS_ID; k++) |
93 | 176 | memset(&pbi->ops_list[obu_xlayer_id][k], 0, |
94 | 176 | sizeof(pbi->ops_list[obu_xlayer_id][k])); |
95 | 11 | } |
96 | 60 | } else if (ops_cnt == 0) { |
97 | | // Case 3: clear only the targeted OPS slot |
98 | 8 | memset(&pbi->ops_list[obu_xlayer_id][ops_id], 0, |
99 | 8 | sizeof(pbi->ops_list[obu_xlayer_id][ops_id])); |
100 | 8 | } |
101 | | |
102 | 71 | OperatingPointSet *ops = &pbi->ops_list[obu_xlayer_id][ops_id]; |
103 | 71 | ops->obu_xlayer_id = obu_xlayer_id; |
104 | 71 | ops->ops_reset_flag = ops_reset_flag; |
105 | 71 | ops->ops_id = ops_id; |
106 | 71 | ops->ops_cnt = ops_cnt; |
107 | | |
108 | 71 | if (ops->ops_cnt > 0) { |
109 | 61 | ops->ops_priority = avm_rb_read_literal(rb, 4); |
110 | 61 | ops->ops_intent = avm_rb_read_literal(rb, 7); |
111 | 61 | ops->ops_intent_present_flag = avm_rb_read_bit(rb); |
112 | 61 | ops->ops_ptl_present_flag = avm_rb_read_bit(rb); |
113 | 61 | ops->ops_color_info_present_flag = avm_rb_read_bit(rb); |
114 | | |
115 | 61 | if (obu_xlayer_id == GLOBAL_XLAYER_ID) { |
116 | 0 | ops->ops_mlayer_info_idc = avm_rb_read_literal(rb, 2); |
117 | 0 | if (ops->ops_mlayer_info_idc >= 3) { |
118 | 0 | avm_internal_error( |
119 | 0 | &pbi->common.error, AVM_CODEC_UNSUP_BITSTREAM, |
120 | 0 | "value of ops_mlayer_info_idc should be smaller than 3."); |
121 | 0 | } |
122 | 61 | } else { |
123 | 61 | ops->ops_mlayer_info_idc = 1; |
124 | 61 | (void)avm_rb_read_literal(rb, 2); // ops_reserved_2bits |
125 | 61 | } |
126 | | |
127 | 126 | for (int i = 0; i < ops->ops_cnt; i++) { |
128 | 65 | OperatingPoint *op = &ops->op[i]; |
129 | | // Read ops_data_size (ULEB128 encoded) |
130 | 65 | op->ops_data_size = avm_rb_read_uleb(rb); |
131 | 65 | const uint32_t max_reasonable_size = 1024 * 1024; // Set a max size |
132 | 65 | if (op->ops_data_size > max_reasonable_size) { |
133 | 11 | avm_internal_error(&pbi->common.error, AVM_CODEC_CORRUPT_FRAME, |
134 | 11 | "ops_data_size value %u exceeds reasonable limit in " |
135 | 11 | "av2_read_operating_point_set_obu()", |
136 | 11 | op->ops_data_size); |
137 | 11 | } |
138 | | |
139 | 65 | const uint32_t op_start_bit_offset = rb->bit_offset; |
140 | | |
141 | 65 | if (ops->ops_intent_present_flag) |
142 | 34 | op->ops_intent_op = avm_rb_read_literal(rb, 7); |
143 | | |
144 | 65 | if (ops->ops_ptl_present_flag) { |
145 | 34 | if (obu_xlayer_id == GLOBAL_XLAYER_ID) { |
146 | 0 | op->ops_config_idc = avm_rb_read_literal(rb, MULTI_SEQ_CONFIG_BITS); |
147 | 0 | op->ops_aggregate_level_idx = avm_rb_read_literal(rb, LEVEL_BITS); |
148 | 0 | op->ops_max_tier_flag = avm_rb_read_bit(rb); |
149 | 0 | op->ops_max_interop = avm_rb_read_literal(rb, INTEROP_BITS); |
150 | 34 | } else { |
151 | 34 | op->ops_seq_profile_idc[obu_xlayer_id] = |
152 | 34 | avm_rb_read_literal(rb, PROFILE_BITS); |
153 | 34 | op->ops_level_idx[obu_xlayer_id] = |
154 | 34 | avm_rb_read_literal(rb, LEVEL_BITS); |
155 | 34 | op->ops_tier_flag[obu_xlayer_id] = avm_rb_read_bit(rb); |
156 | 34 | op->ops_mlayer_count[obu_xlayer_id] = avm_rb_read_literal(rb, 3); |
157 | 34 | (void)avm_rb_read_literal(rb, 2); // ops_ptl_reserved_2bits |
158 | 34 | } |
159 | 34 | } |
160 | 65 | if (ops->ops_color_info_present_flag) { |
161 | 29 | read_ops_color_info(&op->color_info, rb); |
162 | 36 | } else { |
163 | 36 | op->color_info.ops_color_description_idc = AVM_COLOR_DESC_IDC_EXPLICIT; |
164 | 36 | op->color_info.ops_color_primaries = AVM_CICP_CP_UNSPECIFIED; |
165 | 36 | op->color_info.ops_transfer_characteristics = AVM_CICP_TC_UNSPECIFIED; |
166 | 36 | op->color_info.ops_matrix_coefficients = AVM_CICP_MC_UNSPECIFIED; |
167 | 36 | op->color_info.ops_full_range_flag = 0; |
168 | 36 | } |
169 | 65 | op->ops_decoder_model_info_for_this_op_present_flag = avm_rb_read_bit(rb); |
170 | 65 | if (op->ops_decoder_model_info_for_this_op_present_flag) { |
171 | 27 | read_ops_decoder_model_info(&op->decoder_model_info, rb); |
172 | 27 | } |
173 | 65 | int ops_initial_display_delay_present_flag = avm_rb_read_bit(rb); |
174 | 65 | if (ops_initial_display_delay_present_flag) { |
175 | 22 | int ops_initial_display_delay_minus_1 = avm_rb_read_literal(rb, 4); |
176 | 22 | op->ops_initial_display_delay = ops_initial_display_delay_minus_1 + 1; |
177 | 43 | } else { |
178 | 43 | op->ops_initial_display_delay = BUFFER_POOL_MAX_SIZE; |
179 | 43 | } |
180 | | |
181 | 65 | if (obu_xlayer_id == GLOBAL_XLAYER_ID) { |
182 | 0 | op->ops_xlayer_map = avm_rb_read_literal(rb, MAX_NUM_XLAYERS - 1); |
183 | 0 | int k = 0; |
184 | 0 | for (int j = 0; j < MAX_NUM_XLAYERS - 1; j++) { |
185 | 0 | if ((op->ops_xlayer_map & (1 << j))) { |
186 | 0 | op->OpsxLayerID[k] = j; |
187 | 0 | k++; |
188 | |
|
189 | 0 | if (ops->ops_ptl_present_flag) { |
190 | 0 | op->ops_seq_profile_idc[j] = |
191 | 0 | avm_rb_read_literal(rb, PROFILE_BITS); |
192 | 0 | op->ops_level_idx[j] = avm_rb_read_literal(rb, LEVEL_BITS); |
193 | 0 | op->ops_tier_flag[j] = avm_rb_read_bit(rb); |
194 | 0 | op->ops_mlayer_count[j] = avm_rb_read_literal(rb, 3); |
195 | 0 | (void)avm_rb_read_literal(rb, 2); // ops_ptl_reserved_2bits |
196 | 0 | } |
197 | | // The ops_mlayer_indo_idc = 0, specifies that mlayer information |
198 | | // syntax structure is not present in the current OPS. |
199 | 0 | if (ops->ops_mlayer_info_idc == 1) { |
200 | 0 | read_ops_mlayer_info(j, &op->mlayer_info, rb); |
201 | 0 | } else if (ops->ops_mlayer_info_idc == 2) { |
202 | 0 | op->ops_mlayer_explicit_info_flag[j] = avm_rb_read_bit(rb); |
203 | 0 | if (op->ops_mlayer_explicit_info_flag[j]) { |
204 | 0 | read_ops_mlayer_info(j, &op->mlayer_info, rb); |
205 | 0 | } else { |
206 | 0 | op->ops_embedded_ops_id[j] = avm_rb_read_literal(rb, 4); |
207 | 0 | op->ops_embedded_op_index[j] = avm_rb_read_literal(rb, 3); |
208 | 0 | if (op->ops_embedded_op_index[j] > 6) { |
209 | 0 | avm_internal_error( |
210 | 0 | &pbi->common.error, AVM_CODEC_UNSUP_BITSTREAM, |
211 | 0 | "value of ops_embedded_op_index shall not be " |
212 | 0 | "larger than 6."); |
213 | 0 | } |
214 | | // Inherit mlayer_info from the referenced operating point. |
215 | 0 | const int ref_ops_id = op->ops_embedded_ops_id[j]; |
216 | 0 | const int ref_op_index = op->ops_embedded_op_index[j]; |
217 | 0 | const OperatingPointSet *ref_ops = |
218 | 0 | &pbi->ops_list[obu_xlayer_id][ref_ops_id]; |
219 | 0 | if (ref_op_index >= ref_ops->ops_cnt) { |
220 | 0 | avm_internal_error( |
221 | 0 | &pbi->common.error, AVM_CODEC_UNSUP_BITSTREAM, |
222 | 0 | "ops_embedded_op_index[%d] value %d exceeds ops_cnt %d " |
223 | 0 | "of referenced OPS %d.", |
224 | 0 | j, ref_op_index, ref_ops->ops_cnt, ref_ops_id); |
225 | 0 | } |
226 | 0 | if (ref_ops_id == ops_id && ref_op_index >= i) { |
227 | 0 | avm_internal_error( |
228 | 0 | &pbi->common.error, AVM_CODEC_UNSUP_BITSTREAM, |
229 | 0 | "ops_embedded_ops_id[%d] references current OPS %d " |
230 | 0 | "with op_index %d >= current op_index %d.", |
231 | 0 | j, ops_id, ref_op_index, i); |
232 | 0 | } |
233 | 0 | const OperatingPoint *ref_op = &ref_ops->op[ref_op_index]; |
234 | 0 | op->mlayer_info.ops_mlayer_map[j] = |
235 | 0 | ref_op->mlayer_info.ops_mlayer_map[j]; |
236 | 0 | op->mlayer_info.OPMLayerCount[j] = |
237 | 0 | ref_op->mlayer_info.OPMLayerCount[j]; |
238 | 0 | for (int m = 0; m < MAX_NUM_MLAYERS; m++) { |
239 | 0 | op->mlayer_info.ops_tlayer_map[j][m] = |
240 | 0 | ref_op->mlayer_info.ops_tlayer_map[j][m]; |
241 | 0 | op->mlayer_info.OPTLayerCount[j][m] = |
242 | 0 | ref_op->mlayer_info.OPTLayerCount[j][m]; |
243 | 0 | } |
244 | 0 | } |
245 | 0 | } |
246 | 0 | } |
247 | 0 | } |
248 | 0 | op->XCount = k; |
249 | 65 | } else { |
250 | 65 | op->XCount = 1; |
251 | 65 | op->OpsxLayerID[0] = obu_xlayer_id; |
252 | 65 | assert(ops->ops_mlayer_info_idc == 1); |
253 | 65 | read_ops_mlayer_info(obu_xlayer_id, &op->mlayer_info, rb); |
254 | 65 | } |
255 | | |
256 | | // Byte alignment at end of each operating point iteration |
257 | 65 | if (av2_check_byte_alignment(&pbi->common, rb) != 0) { |
258 | 19 | avm_internal_error(&pbi->common.error, AVM_CODEC_CORRUPT_FRAME, |
259 | 19 | "Byte alignment error at end of operating point in " |
260 | 19 | "av2_read_operating_point_set_obu()"); |
261 | 19 | } |
262 | | |
263 | 65 | const uint32_t op_end_bit_offset = rb->bit_offset; |
264 | 65 | const uint32_t actual_bits_read = op_end_bit_offset - op_start_bit_offset; |
265 | 65 | assert(actual_bits_read % 8 == 0); |
266 | 65 | const uint32_t actual_bytes_read = actual_bits_read / 8; |
267 | | |
268 | 65 | if (op->ops_data_size != actual_bytes_read) { |
269 | 21 | avm_internal_error( |
270 | 21 | &pbi->common.error, AVM_CODEC_CORRUPT_FRAME, |
271 | 21 | "ops_data_size mismatch in av2_read_operating_point_set_obu()"); |
272 | 21 | } |
273 | 65 | } |
274 | 61 | } |
275 | 71 | size_t bits_before_ext = rb->bit_offset - saved_bit_offset; |
276 | 71 | ops->ops_extension_present_flag = avm_rb_read_bit(rb); |
277 | 71 | if (ops->ops_extension_present_flag) { |
278 | | // Extension data bits = total - bits_read_before_extension -1 (ext flag) - |
279 | | // trailing bits |
280 | 6 | int extension_bits = read_obu_extension_bits( |
281 | 6 | rb->bit_buffer, rb->bit_buffer_end - rb->bit_buffer, bits_before_ext, |
282 | 6 | &pbi->common.error); |
283 | 6 | if (extension_bits > 0) { |
284 | 6 | rb->bit_offset += extension_bits; // skip over the extension bits |
285 | 6 | } else { |
286 | | // No extension data present |
287 | 0 | } |
288 | 6 | } |
289 | | |
290 | 71 | if (av2_check_trailing_bits(pbi, rb) != 0) { |
291 | 4 | return 0; |
292 | 4 | } |
293 | 67 | ops->valid = 1; |
294 | 67 | return ((rb->bit_offset - saved_bit_offset + 7) >> 3); |
295 | 71 | } |