/src/avm/av2/decoder/obu_fgm.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 "config/avm_scale_rtcd.h" |
17 | | |
18 | | #include "avm/avm_codec.h" |
19 | | #include "avm_dsp/bitreader_buffer.h" |
20 | | #include "avm_ports/mem_ops.h" |
21 | | |
22 | | #include "av2/common/common.h" |
23 | | #include "av2/common/obu_util.h" |
24 | | #include "av2/common/timing.h" |
25 | | #include "av2/decoder/decoder.h" |
26 | | #include "av2/decoder/decodeframe.h" |
27 | | #include "av2/decoder/obu.h" |
28 | | |
29 | | void copy_fgm_from_list(AV2_COMMON *cm, avm_film_grain_t *pars, |
30 | 0 | const struct film_grain_model *fgm) { |
31 | 0 | const SequenceHeader *const seq_params = &cm->seq_params; |
32 | 0 | pars->bit_depth = seq_params->bit_depth; |
33 | 0 | for (int c = 0; c < 3; c++) { |
34 | 0 | pars->fgm_points[c] = fgm->fgm_points[c]; |
35 | 0 | } |
36 | |
|
37 | 0 | for (int i = 0; i < 14; i++) { |
38 | 0 | for (int j = 0; j < 2; j++) { |
39 | 0 | pars->fgm_scaling_points_0[i][j] = fgm->fgm_scaling_points[0][i][j]; |
40 | 0 | pars->fgm_scaling_points_1[i][j] = fgm->fgm_scaling_points[1][i][j]; |
41 | 0 | pars->fgm_scaling_points_2[i][j] = fgm->fgm_scaling_points[2][i][j]; |
42 | 0 | } |
43 | 0 | } |
44 | |
|
45 | 0 | pars->scaling_shift = fgm->scaling_shift; |
46 | 0 | pars->ar_coeff_lag = fgm->ar_coeff_lag; |
47 | | |
48 | | // 8 bit values |
49 | 0 | for (int i = 0; i < 24; i++) pars->ar_coeffs_y[i] = fgm->ar_coeffs_y[i]; |
50 | 0 | for (int i = 0; i < 25; i++) { |
51 | 0 | pars->ar_coeffs_cb[i] = fgm->ar_coeffs_cb[i]; |
52 | 0 | pars->ar_coeffs_cr[i] = fgm->ar_coeffs_cr[i]; |
53 | 0 | } |
54 | 0 | pars->ar_coeff_shift = fgm->ar_coeff_shift; |
55 | 0 | pars->cb_mult = fgm->cb_mult; |
56 | 0 | pars->cb_luma_mult = fgm->cb_luma_mult; |
57 | 0 | pars->cb_offset = fgm->cb_offset; |
58 | 0 | pars->cr_mult = fgm->cr_mult; |
59 | 0 | pars->cr_luma_mult = fgm->cr_luma_mult; |
60 | 0 | pars->cr_offset = fgm->cr_offset; |
61 | 0 | pars->overlap_flag = fgm->overlap_flag; |
62 | 0 | pars->clip_to_restricted_range = fgm->clip_to_restricted_range; |
63 | 0 | pars->mc_identity = fgm->mc_identity; |
64 | 0 | pars->fgm_scale_from_channel0_flag = fgm->fgm_scale_from_channel0_flag; |
65 | 0 | pars->grain_scale_shift = fgm->grain_scale_shift; |
66 | 0 | pars->block_size = fgm->block_size; |
67 | 0 | } |
68 | | |
69 | | static void read_film_grain_model(struct film_grain_model *fgm, int chroma_idc, |
70 | | struct avm_read_bit_buffer *rb, |
71 | 254 | struct avm_internal_error_info *error_info) { |
72 | 254 | int monochrome = chroma_idc == CHROMA_FORMAT_400; |
73 | 254 | int subsampling_x = chroma_idc == CHROMA_FORMAT_444 ? 0 : 1; |
74 | 254 | int subsampling_y = |
75 | 254 | (chroma_idc == CHROMA_FORMAT_422 || chroma_idc == CHROMA_FORMAT_444) ? 0 |
76 | 254 | : 1; |
77 | | |
78 | | // Scaling functions parameters |
79 | 254 | int fgmNumChannels = monochrome ? 1 : 3; |
80 | | |
81 | 254 | if (fgmNumChannels > 1) { |
82 | 173 | fgm->fgm_scale_from_channel0_flag = avm_rb_read_bit(rb); |
83 | 173 | } else { |
84 | 81 | fgm->fgm_scale_from_channel0_flag = 0; |
85 | 81 | } |
86 | | |
87 | 254 | int fgmNumScalingChannels = |
88 | 254 | fgm->fgm_scale_from_channel0_flag ? 1 : fgmNumChannels; |
89 | 672 | for (int c = 0; c < fgmNumScalingChannels; c++) { |
90 | 418 | fgm->fgm_points[c] = avm_rb_read_literal(rb, 4); // max 14 |
91 | 418 | if (fgm->fgm_points[c] > 14) { |
92 | 6 | avm_internal_error(error_info, AVM_CODEC_UNSUP_BITSTREAM, |
93 | 6 | "Number of points for film grain %s scaling " |
94 | 6 | "function exceeds the maximum value.", |
95 | 6 | c == 0 ? "y" |
96 | 6 | : c == 1 ? "cb" |
97 | 2 | : "cr"); |
98 | 6 | } |
99 | 418 | if (fgm->fgm_points[c]) { |
100 | 199 | int point_value_increment_bits_minus1 = avm_rb_read_literal(rb, 3); |
101 | 199 | int point_scaling_bits_minus5 = avm_rb_read_literal(rb, 2); |
102 | 199 | int bitsIncr = point_value_increment_bits_minus1 + 1; |
103 | 199 | int bitsScal = point_scaling_bits_minus5 + 5; |
104 | 1.53k | for (int i = 0; i < fgm->fgm_points[c]; i++) { |
105 | 1.33k | int fgm_value_increment = avm_rb_read_literal(rb, bitsIncr); |
106 | 1.33k | if (i == 0) |
107 | 191 | fgm->fgm_scaling_points[c][i][0] = fgm_value_increment; |
108 | 1.14k | else |
109 | 1.14k | fgm->fgm_scaling_points[c][i][0] = |
110 | 1.14k | fgm->fgm_scaling_points[c][i - 1][0] + fgm_value_increment; |
111 | | |
112 | 1.33k | if (i && fgm->fgm_scaling_points[c][i - 1][0] >= |
113 | 1.14k | fgm->fgm_scaling_points[c][i][0]) { |
114 | 26 | avm_internal_error(error_info, AVM_CODEC_UNSUP_BITSTREAM, |
115 | 26 | "First coordinate of the %s scaling function " |
116 | 26 | "points shall be increasing.", |
117 | 26 | c == 0 ? "y" |
118 | 26 | : c == 1 ? "cb" |
119 | 4 | : "cr"); |
120 | 26 | } |
121 | 1.33k | fgm->fgm_scaling_points[c][i][1] = avm_rb_read_literal(rb, bitsScal); |
122 | 1.33k | } |
123 | 199 | } |
124 | 418 | } |
125 | | |
126 | | // Initialize unsignaled values to zero |
127 | 518 | for (int c = fgmNumScalingChannels; c < 3; c++) fgm->fgm_points[c] = 0; |
128 | | |
129 | 254 | if ((subsampling_x == 1) && (subsampling_y == 1) && |
130 | 170 | (((fgm->fgm_points[1] == 0) && (fgm->fgm_points[2] != 0)) || |
131 | 169 | ((fgm->fgm_points[1] != 0) && (fgm->fgm_points[2] == 0)))) { |
132 | 3 | avm_internal_error(error_info, AVM_CODEC_UNSUP_BITSTREAM, |
133 | 3 | "In YCbCr 4:2:0, film grain shall be applied " |
134 | 3 | "to both chroma components or neither."); |
135 | 3 | } |
136 | 254 | fgm->scaling_shift = avm_rb_read_literal(rb, 2) + 8; // 8 + value |
137 | | |
138 | | // AR coefficients |
139 | | // Only sent if the corresponsing scaling function has |
140 | | // more than 0 points |
141 | | |
142 | 254 | fgm->ar_coeff_lag = avm_rb_read_literal(rb, 2); |
143 | | |
144 | 254 | int num_pos_luma = 2 * fgm->ar_coeff_lag * (fgm->ar_coeff_lag + 1); |
145 | 254 | int num_pos_chroma = num_pos_luma; |
146 | | |
147 | 254 | if (fgm->fgm_points[0]) { |
148 | 114 | ++num_pos_chroma; |
149 | 114 | int bits_per_ar_coeff_y_minus5 = avm_rb_read_literal(rb, 2); |
150 | 114 | int BitsArY = bits_per_ar_coeff_y_minus5 + 5; |
151 | 114 | int midPointY = 1 << (BitsArY - 1); |
152 | 989 | for (int i = 0; i < num_pos_luma; i++) |
153 | 875 | fgm->ar_coeffs_y[i] = avm_rb_read_literal(rb, BitsArY) - midPointY; |
154 | 114 | } |
155 | | |
156 | 254 | if (fgm->fgm_points[1] || fgm->fgm_scale_from_channel0_flag) { |
157 | 82 | int bits_per_ar_coeff_cb_minus5 = avm_rb_read_literal(rb, 2); |
158 | 82 | int BitsArCb = bits_per_ar_coeff_cb_minus5 + 5; |
159 | 82 | int midPointCb = 1 << (BitsArCb - 1); |
160 | 575 | for (int i = 0; i < num_pos_chroma; i++) |
161 | 493 | fgm->ar_coeffs_cb[i] = avm_rb_read_literal(rb, BitsArCb) - midPointCb; |
162 | 82 | } |
163 | | |
164 | 254 | if (fgm->fgm_points[2] || fgm->fgm_scale_from_channel0_flag) { |
165 | 75 | int bits_per_ar_coeff_cr_minus5 = avm_rb_read_literal(rb, 2); |
166 | 75 | int BitsArCr = bits_per_ar_coeff_cr_minus5 + 5; |
167 | 75 | int midPointCr = 1 << (BitsArCr - 1); |
168 | 465 | for (int i = 0; i < num_pos_chroma; i++) |
169 | 390 | fgm->ar_coeffs_cr[i] = avm_rb_read_literal(rb, BitsArCr) - midPointCr; |
170 | 75 | } |
171 | | |
172 | 254 | fgm->ar_coeff_shift = avm_rb_read_literal(rb, 2) + 6; // 6 + value |
173 | | |
174 | 254 | fgm->grain_scale_shift = avm_rb_read_literal(rb, 2); |
175 | 254 | if (fgm->fgm_points[1] > 0) { |
176 | 15 | fgm->cb_mult = avm_rb_read_literal(rb, 8); |
177 | 15 | fgm->cb_luma_mult = avm_rb_read_literal(rb, 8); |
178 | 15 | fgm->cb_offset = avm_rb_read_literal(rb, 9); |
179 | 15 | } |
180 | 254 | if (fgm->fgm_points[2] > 0) { |
181 | 12 | fgm->cr_mult = avm_rb_read_literal(rb, 8); |
182 | 12 | fgm->cr_luma_mult = avm_rb_read_literal(rb, 8); |
183 | 12 | fgm->cr_offset = avm_rb_read_literal(rb, 9); |
184 | 12 | } |
185 | | |
186 | 254 | fgm->overlap_flag = avm_rb_read_bit(rb); |
187 | | |
188 | 254 | fgm->clip_to_restricted_range = avm_rb_read_bit(rb); |
189 | | |
190 | 254 | if (fgm->clip_to_restricted_range) |
191 | 62 | fgm->mc_identity = avm_rb_read_bit(rb); |
192 | 192 | else |
193 | 192 | fgm->mc_identity = 0; |
194 | | |
195 | 254 | fgm->block_size = avm_rb_read_bit(rb); |
196 | 254 | } |
197 | | |
198 | | // acc_fgm_id_bitmap is an in/out parameter. The caller should set |
199 | | // *acc_fgm_id_bitmap to 0 before the first call to read_fgm_obu(). Each |
200 | | // read_fgm_obu() call updates *acc_fgm_id_bitmap by bitwise-ORing the |
201 | | // fgm_bit_map from the FGM OBU with *acc_fgm_id_bitmap. |
202 | | uint32_t read_fgm_obu(AV2Decoder *pbi, const int obu_tlayer_id, |
203 | | const int obu_mlayer_id, uint32_t *acc_fgm_id_bitmap, |
204 | 108 | struct avm_read_bit_buffer *rb) { |
205 | 108 | const uint32_t saved_bit_offset = rb->bit_offset; |
206 | 108 | int fgm_bit_map = avm_rb_read_literal(rb, MAX_FGM_NUM); |
207 | 108 | if (*acc_fgm_id_bitmap & (uint32_t)fgm_bit_map) { |
208 | 0 | avm_internal_error( |
209 | 0 | &pbi->common.error, AVM_CODEC_INVALID_PARAM, |
210 | 0 | "fgm_bit_map(%d) overlaps the accumulated fgm_bit_map(%d)", fgm_bit_map, |
211 | 0 | acc_fgm_id_bitmap); |
212 | 108 | } else { |
213 | 108 | *acc_fgm_id_bitmap |= fgm_bit_map; |
214 | 108 | } |
215 | 108 | int fgm_chroma_idc = avm_rb_read_uvlc(rb); |
216 | 108 | if (fgm_chroma_idc >= NUM_CHROMA_FORMATS) { |
217 | 15 | avm_internal_error(&pbi->common.error, AVM_CODEC_UNSUP_BITSTREAM, |
218 | 15 | "Invalid fgm_chroma_idc [%d].", fgm_chroma_idc); |
219 | 15 | } |
220 | 526 | for (int j = 0; j < MAX_FGM_NUM; j++) { |
221 | | // This process overwrites the position(pbi->fg_list[fgm_id]) if the fgm_id |
222 | | // is the same. |
223 | 418 | if (fgm_bit_map & (1 << j)) { |
224 | 254 | int fgm_id = j; |
225 | 254 | memset(&pbi->fgm_list[fgm_id], 0, sizeof(pbi->fgm_list[fgm_id])); |
226 | 254 | pbi->fgm_list[fgm_id].fgm_id = fgm_id; |
227 | 254 | pbi->fgm_list[fgm_id].fgm_mlayer_id = obu_mlayer_id; |
228 | 254 | pbi->fgm_list[fgm_id].fgm_tlayer_id = obu_tlayer_id; |
229 | 254 | pbi->fgm_list[fgm_id].fgm_chroma_idc = fgm_chroma_idc; |
230 | 254 | read_film_grain_model(&pbi->fgm_list[fgm_id], fgm_chroma_idc, rb, |
231 | 254 | &pbi->common.error); |
232 | 254 | } |
233 | 418 | } |
234 | 108 | if (av2_check_trailing_bits(pbi, rb) != 0) { |
235 | | // cm->error.error_code is already set. |
236 | 15 | return 0; |
237 | 15 | } |
238 | 93 | return ((rb->bit_offset - saved_bit_offset + 7) >> 3); |
239 | 108 | } |