Coverage Report

Created: 2026-09-14 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}