FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
apv.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/lfg.h"
20 #include "libavutil/random_seed.h"
21 
22 #include "libavcodec/apv_decode.h"
23 #include "libavcodec/apv_dsp.h"
24 #include "libavcodec/put_bits.h"
25 
26 
27 // Whole file included here to get internal symbols.
28 #include "libavcodec/apv_entropy.c"
29 
30 
31 // As defined in 7.1.4, for testing.
32 // Adds a check to limit loop after reading 16 zero bits to avoid
33 // getting stuck reading a stream of zeroes forever (this matches
34 // the behaviour of the faster version).
35 
36 static unsigned int apv_read_vlc_spec(GetBitContext *gbc, int k_param)
37 {
38  unsigned int symbol_value = 0;
39  int parse_exp_golomb = 1;
40  int k = k_param;
41  int stop_loop = 0;
42 
43  if(get_bits1(gbc) == 1) {
44  parse_exp_golomb = 0;
45  } else {
46  if (get_bits1(gbc) == 0) {
47  symbol_value += (1 << k);
48  parse_exp_golomb = 0;
49  } else {
50  symbol_value += (2 << k);
51  parse_exp_golomb = 1;
52  }
53  }
54  if (parse_exp_golomb) {
55  int read_limit = 0;
56  do {
57  if (get_bits1(gbc) == 1) {
58  stop_loop = 1;
59  } else {
60  if (++read_limit == 16)
61  break;
62  symbol_value += (1 << k);
63  k++;
64  }
65  } while (!stop_loop);
66  }
67  if (k > 0)
68  symbol_value += get_bits(gbc, k);
69 
70  return symbol_value;
71 }
72 
73 // As defined in 7.2.4, for testing.
74 
76  unsigned int symbol_val, int k_param)
77 {
78  int prefix_vlc_table[3][2] = {{1, 0}, {0, 0}, {0, 1}};
79 
80  unsigned int symbol_value = symbol_val;
81  int val_prefix_vlc = av_clip(symbol_val >> k_param, 0, 2);
82  int bit_count = 0;
83  int k = k_param;
84 
85  while (symbol_value >= (1 << k)) {
86  symbol_value -= (1 << k);
87  if (bit_count < 2)
88  put_bits(pbc, 1, prefix_vlc_table[val_prefix_vlc][bit_count]);
89  else
90  put_bits(pbc, 1, 0);
91  if (bit_count >= 2)
92  ++k;
93  ++bit_count;
94  }
95 
96  if(bit_count < 2)
97  put_bits(pbc, 1, prefix_vlc_table[val_prefix_vlc][bit_count]);
98  else
99  put_bits(pbc, 1, 1);
100 
101  if(k > 0)
102  put_bits(pbc, k, symbol_value);
103 }
104 
105 // Old version of ff_apv_entropy_decode_block, for test comparison.
106 
107 static int apv_entropy_decode_block(int16_t *restrict coeff,
108  GetBitContext *restrict gbc,
109  APVEntropyState *restrict state)
110 {
111  const APVVLCLUT *lut = state->decode_lut;
112 
113  // DC coefficient.
114  {
115  int abs_dc_coeff_diff;
116  int sign_dc_coeff_diff;
117  int dc_coeff;
118 
119  abs_dc_coeff_diff = apv_read_vlc(gbc, state->prev_k_dc, lut);
120 
121  if (abs_dc_coeff_diff > 0)
122  sign_dc_coeff_diff = get_bits1(gbc);
123  else
124  sign_dc_coeff_diff = 0;
125 
126  if (sign_dc_coeff_diff)
127  dc_coeff = state->prev_dc - abs_dc_coeff_diff;
128  else
129  dc_coeff = state->prev_dc + abs_dc_coeff_diff;
130 
131  if (dc_coeff < APV_MIN_TRANS_COEFF ||
132  dc_coeff > APV_MAX_TRANS_COEFF) {
133  av_log(state->log_ctx, AV_LOG_ERROR,
134  "Out-of-range DC coefficient value: %d "
135  "(from prev_dc %d abs_dc_coeff_diff %d sign_dc_coeff_diff %d)\n",
136  dc_coeff, state->prev_dc, abs_dc_coeff_diff, sign_dc_coeff_diff);
137  return AVERROR_INVALIDDATA;
138  }
139 
140  coeff[0] = dc_coeff;
141 
142  state->prev_dc = dc_coeff;
143  state->prev_k_dc = FFMIN(abs_dc_coeff_diff >> 1, 5);
144  }
145 
146  // AC coefficients.
147  {
148  int scan_pos = 1;
149  int first_ac = 1;
150  int k_run = 0;
151  int k_level = state->prev_k_level;
152 
153  do {
154  int coeff_zero_run;
155 
156  coeff_zero_run = apv_read_vlc(gbc, k_run, lut);
157 
158  if (coeff_zero_run > APV_BLK_COEFFS - scan_pos) {
159  av_log(state->log_ctx, AV_LOG_ERROR,
160  "Out-of-range zero-run value: %d (at scan pos %d)\n",
161  coeff_zero_run, scan_pos);
162  return AVERROR_INVALIDDATA;
163  }
164 
165  for (int i = 0; i < coeff_zero_run; i++) {
166  coeff[ff_zigzag_direct[scan_pos]] = 0;
167  ++scan_pos;
168  }
169  k_run = FFMIN(coeff_zero_run >> 2, 2);
170 
171  if (scan_pos < APV_BLK_COEFFS) {
172  int abs_ac_coeff_minus1;
173  int sign_ac_coeff;
174  int abs_level, level;
175 
176  abs_ac_coeff_minus1 = apv_read_vlc(gbc, k_level, lut);
177  sign_ac_coeff = get_bits(gbc, 1);
178 
179  abs_level = abs_ac_coeff_minus1 + 1;
180  if (sign_ac_coeff)
181  level = -abs_level;
182  else
183  level = abs_level;
184 
185  if (level < APV_MIN_TRANS_COEFF ||
187  av_log(state->log_ctx, AV_LOG_ERROR,
188  "Out-of-range AC coefficient value: %d "
189  "(from k_param %d abs_ac_coeff_minus1 %d sign_ac_coeff %d)\n",
190  level, k_level, abs_ac_coeff_minus1, sign_ac_coeff);
191  }
192 
193  coeff[ff_zigzag_direct[scan_pos]] = level;
194 
195  k_level = FFMIN(abs_level >> 2, 4);
196  if (first_ac) {
197  state->prev_k_level = k_level;
198  first_ac = 0;
199  }
200 
201  ++scan_pos;
202  }
203 
204  } while (scan_pos < APV_BLK_COEFFS);
205  }
206 
207  return 0;
208 }
209 
210 static void binary(char *buf, uint32_t value, int bits)
211 {
212  for (int i = 0; i < bits; i++)
213  buf[i] = (value >> (bits - i - 1) & 1) ? '1' : '0';
214  buf[bits] = '\0';
215 }
216 
217 static int test_apv_read_vlc(void)
218 {
219  APVVLCLUT lut;
220  int err = 0;
221 
223 
224  // Generate all possible 20 bit sequences (padded with zeroes), then
225  // verify that spec and improved parsing functions get the same result
226  // and consume the same number of bits for each possible k_param.
227 
228  for (int k = 0; k <= 5; k++) {
229  for (uint32_t b = 0; b < (1 << 20); b++) {
230  uint8_t buf[8] = {
231  b >> 12,
232  b >> 4,
233  b << 4,
234  0, 0, 0, 0, 0
235  };
236 
237  GetBitContext gbc_test, gbc_spec;
238  unsigned int res_test, res_spec;
239  int con_test, con_spec;
240 
241  init_get_bits8(&gbc_test, buf, 8);
242  init_get_bits8(&gbc_spec, buf, 8);
243 
244  res_test = apv_read_vlc (&gbc_test, k, &lut);
245  res_spec = apv_read_vlc_spec(&gbc_spec, k);
246 
247  con_test = get_bits_count(&gbc_test);
248  con_spec = get_bits_count(&gbc_spec);
249 
250  if (res_test != res_spec ||
251  con_test != con_spec) {
252  char str[21];
253  binary(str, b, 20);
255  "Mismatch reading %s (%d) with k=%d:\n", str, b, k);
257  "Test function result %d consumed %d bits.\n",
258  res_test, con_test);
260  "Spec function result %d consumed %d bits.\n",
261  res_spec, con_spec);
262  ++err;
263  if (err > 10)
264  return err;
265  }
266  }
267  }
268 
269  return err;
270 }
271 
272 static int random_coeff(AVLFG *lfg)
273 {
274  // Geometric distribution of code lengths (1-14 bits),
275  // uniform distribution within codes of the length,
276  // equal probability of either sign.
277  int length = (av_lfg_get(lfg) / (UINT_MAX / 14 + 1));
278  int random = av_lfg_get(lfg);
279  int value = (1 << length) + (random & (1 << length) - 1);
280  if (random & (1 << length))
281  return value;
282  else
283  return -value;
284 }
285 
286 static int random_run(AVLFG *lfg)
287 {
288  // Expoenential distrbution of run lengths.
289  unsigned int random = av_lfg_get(lfg);
290  for (int len = 0;; len++) {
291  if (random & (1 << len))
292  return len;
293  }
294  // You rolled zero on a 2^32 sided die; well done!
295  return 64;
296 }
297 
299 {
300  // Generate random entropy blocks, code them, then ensure they
301  // decode to the same block with both implementations.
302 
304  AVLFG lfg;
305  unsigned int seed = av_get_random_seed();
306  av_lfg_init(&lfg, seed);
307 
308  av_log(NULL, AV_LOG_INFO, "seed = %u\n", seed);
309 
311 
312  for (int t = 0; t < 100; t++) {
313  APVEntropyState state, save_state;
314  int16_t block[64];
315  int16_t block_test1[64];
316  int16_t block_test2[64];
317  uint8_t buffer[1024];
318  PutBitContext pbc;
319  GetBitContext gbc;
320  int bits_written;
321  int pos, run, coeff, level, err;
322  int k_dc, k_run, k_level;
323 
324  memset(block, 0, sizeof(block));
325  memset(buffer, 0, sizeof(buffer));
326  init_put_bits(&pbc, buffer, sizeof(buffer));
327 
328  // Randomly-constructed state.
329  memset(&state, 0, sizeof(state));
330  state.decode_lut = &decode_lut;
331  state.prev_dc = random_coeff(&lfg);
332  state.prev_k_dc = av_lfg_get(&lfg) % 5;
333  state.prev_k_level = av_lfg_get(&lfg) % 4;
334  save_state = state;
335 
336  k_dc = state.prev_k_dc;
337  k_run = 0;
338  k_level = state.prev_k_level;
339 
340  coeff = random_coeff(&lfg) / 2;
341  block[ff_zigzag_direct[0]] = state.prev_dc + coeff;
342  apv_write_vlc_spec(&pbc, FFABS(coeff), k_dc);
343  if (coeff != 0)
344  put_bits(&pbc, 1, coeff < 0);
345 
346  pos = 1;
347  while (pos < 64) {
348  run = random_run(&lfg);
349  if (pos + run > 64)
350  run = 64 - pos;
351  apv_write_vlc_spec(&pbc, run, k_run);
352  k_run = av_clip(run >> 2, 0, 2);
353  pos += run;
354  if (pos < 64) {
355  coeff = random_coeff(&lfg);
356  level = FFABS(coeff) - 1;
358  apv_write_vlc_spec(&pbc, level, k_level);
359  put_bits(&pbc, 1, coeff < 0);
360  k_level = av_clip((level + 1) >> 2, 0, 4);
361  ++pos;
362  }
363  }
364  bits_written = put_bits_count(&pbc);
365  flush_put_bits(&pbc);
366 
367  // Fill output block with a distinctive error value.
368  for (int i = 0; i < 64; i++)
369  block_test1[i] = -9999;
370  init_get_bits8(&gbc, buffer, sizeof(buffer));
371 
372  err = apv_entropy_decode_block(block_test1, &gbc, &state);
373  if (err < 0) {
374  av_log(NULL, AV_LOG_ERROR, "Entropy decode returned error.\n");
375  return 1;
376  } else {
377  int bits_read = get_bits_count(&gbc);
378  if (bits_written != bits_read) {
379  av_log(NULL, AV_LOG_ERROR, "Wrote %d bits but read %d.\n",
380  bits_written, bits_read);
381  return 1;
382  } else {
383  err = 0;
384  for (int i = 0; i < 64; i++) {
385  if (block[i] != block_test1[i])
386  ++err;
387  }
388  if (err > 0) {
389  av_log(NULL, AV_LOG_ERROR, "%d mismatches in output block.\n", err);
390  return err;
391  }
392  }
393  }
394 
395  init_get_bits8(&gbc, buffer, sizeof(buffer));
396  memset(block_test2, 0, 64 * sizeof(int16_t));
397 
398  err = ff_apv_entropy_decode_block(block_test2, &gbc, &save_state);
399  if (err < 0) {
400  av_log(NULL, AV_LOG_ERROR, "Entropy decode returned error.\n");
401  return 1;
402  } else {
403  int bits_read = get_bits_count(&gbc);
404  if (bits_written != bits_read) {
405  av_log(NULL, AV_LOG_ERROR, "Wrote %d bits but read %d.\n",
406  bits_written, bits_read);
407  return 1;
408  } else {
409  err = 0;
410  for (int i = 0; i < 64; i++) {
411  if (block[i] != block_test2[i])
412  ++err;
413  }
414  if (err > 0) {
415  av_log(NULL, AV_LOG_ERROR, "%d mismatches in output block.\n", err);
416  return err;
417  }
418  }
419  }
420 
421  if (state.prev_dc != save_state.prev_dc ||
422  state.prev_k_dc != save_state.prev_k_dc ||
423  state.prev_k_level != save_state.prev_k_level) {
424  av_log(NULL, AV_LOG_ERROR, "Entropy state mismatch.\n");
425  return 1;
426  }
427  }
428 
429  return 0;
430 }
431 
432 int main(void)
433 {
434  int err;
435 
436  err = test_apv_read_vlc();
437  if (err) {
438  av_log(NULL, AV_LOG_ERROR, "Read VLC test failed.\n");
439  return err;
440  }
441 
443  if (err) {
444  av_log(NULL, AV_LOG_ERROR, "Entropy decode block test failed.\n");
445  return err;
446  }
447 
448  return 0;
449 }
APV_BLK_COEFFS
@ APV_BLK_COEFFS
Definition: apv.h:55
level
uint8_t level
Definition: svq3.c:208
av_clip
#define av_clip
Definition: common.h:100
state
static struct @508 state
test_apv_entropy_decode_block
static int test_apv_entropy_decode_block(void)
Definition: apv.c:298
av_lfg_init
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:32
init_put_bits
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:62
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:249
apv_decode.h
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:223
b
#define b
Definition: input.c:42
bits_read
#define bits_read
Definition: bitstream.h:117
test_apv_read_vlc
static int test_apv_read_vlc(void)
Definition: apv.c:217
av_get_random_seed
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:196
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:318
apv_entropy_decode_block
static int apv_entropy_decode_block(int16_t *restrict coeff, GetBitContext *restrict gbc, APVEntropyState *restrict state)
Definition: apv.c:107
GetBitContext
Definition: get_bits.h:108
apv_entropy.c
decode_lut
static APVVLCLUT decode_lut
Definition: apv_decode.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:528
apv_dsp.h
av_lfg_get
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition: lfg.h:53
random_coeff
static int random_coeff(AVLFG *lfg)
Definition: apv.c:272
lfg.h
bits
uint8_t bits
Definition: vp3data.h:128
binary
static void binary(char *buf, uint32_t value, int bits)
Definition: apv.c:210
PutBitContext
Definition: put_bits.h:50
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:207
main
int main(void)
Definition: apv.c:432
APV_MAX_TRANS_COEFF
@ APV_MAX_TRANS_COEFF
Definition: apv.h:57
apv_read_vlc
static av_always_inline unsigned int apv_read_vlc(GetBitContext *restrict gbc, int k_param, const APVVLCLUT *restrict lut)
Definition: apv_entropy.c:26
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:371
ff_apv_entropy_build_decode_lut
void ff_apv_entropy_build_decode_lut(APVVLCLUT *decode_lut)
Build the decoder VLC look-up tables.
Definition: apv_entropy.c:62
seed
static unsigned int seed
Definition: videogen.c:78
random_run
static int random_run(AVLFG *lfg)
Definition: apv.c:286
AVLFG
Context structure for the Lagged Fibonacci PRNG.
Definition: lfg.h:33
APVEntropyState
Definition: apv_decode.h:71
APVEntropyState::prev_k_level
uint8_t prev_k_level
Definition: apv_decode.h:81
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
put_bits_count
static int put_bits_count(PutBitContext *s)
Definition: put_bits.h:90
APVEntropyState::prev_k_dc
uint8_t prev_k_dc
Definition: apv_decode.h:79
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
len
int len
Definition: vorbis_enc_data.h:426
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:137
APV_MIN_TRANS_COEFF
@ APV_MIN_TRANS_COEFF
Definition: apv.h:56
APVVLCLUT
Definition: apv_decode.h:59
pos
unsigned int pos
Definition: spdifenc.c:414
random_seed.h
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
apv_read_vlc_spec
static unsigned int apv_read_vlc_spec(GetBitContext *gbc, int k_param)
Definition: apv.c:36
flush_put_bits
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:153
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
coeff
static const double coeff[2][5]
Definition: vf_owdenoise.c:80
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_apv_entropy_decode_block
int ff_apv_entropy_decode_block(int16_t *restrict coeff, GetBitContext *restrict gbc, APVEntropyState *restrict state)
Entropy decode a single 8x8 block to coefficients.
Definition: apv_entropy.c:208
put_bits.h
apv_write_vlc_spec
static void apv_write_vlc_spec(PutBitContext *pbc, unsigned int symbol_val, int k_param)
Definition: apv.c:75
APVEntropyState::prev_dc
int16_t prev_dc
Definition: apv_decode.h:77