FFmpeg  4.0
dirac_vlc.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Open Broadcast Systems Ltd.
3  * Author 2016 Rostislav Pehlivanov <rpehlivanov@obe.tv>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "dirac_vlc.h"
23 
24 #define LUT_SIZE (1 << LUT_BITS)
25 #define RSIZE_BITS (CHAR_BIT*sizeof(residual))
26 
27 #define CONVERT_TO_RESIDUE(a, b) \
28  (((residual)(a)) << (RSIZE_BITS - (b)))
29 
30 #define INIT_RESIDUE(N) \
31  residual N = 0; \
32  av_unused int32_t N ## _bits = 0
33 
34 #define SET_RESIDUE(N, I, B) \
35  N = CONVERT_TO_RESIDUE(I, B); \
36  N ## _bits = B
37 
38 #define APPEND_RESIDUE(N, M) \
39  N |= M >> (N ## _bits); \
40  N ## _bits = (N ## _bits + (M ## _bits)) & 0x3F
41 
43  int bytes, uint8_t *_dst, int coeffs)
44 {
45  int i, b, c_idx = 0;
46  int32_t *dst = (int32_t *)_dst;
47  DiracGolombLUT *future[4], *l = &lut_ctx[2*LUT_SIZE + buf[0]];
48  INIT_RESIDUE(res);
49 
50  for (b = 1; b <= bytes; b++) {
51  future[0] = &lut_ctx[buf[b]];
52  future[1] = future[0] + 1*LUT_SIZE;
53  future[2] = future[0] + 2*LUT_SIZE;
54  future[3] = future[0] + 3*LUT_SIZE;
55 
56  if ((c_idx + 1) > coeffs)
57  return c_idx;
58 
59  /* res_bits is a hint for better branch prediction */
60  if (res_bits && l->sign) {
61  int32_t coeff = 1;
62  APPEND_RESIDUE(res, l->preamble);
63  for (i = 0; i < (res_bits >> 1) - 1; i++) {
64  coeff <<= 1;
65  coeff |= (res >> (RSIZE_BITS - 2*i - 2)) & 1;
66  }
67  dst[c_idx++] = l->sign * (coeff - 1);
68  res_bits = res = 0;
69  }
70 
71  memcpy(&dst[c_idx], l->ready, LUT_BITS*sizeof(int32_t));
72  c_idx += l->ready_num;
73 
74  APPEND_RESIDUE(res, l->leftover);
75 
76  l = future[l->need_s ? 3 : !res_bits ? 2 : res_bits & 1];
77  }
78 
79  return c_idx;
80 }
81 
83  int bytes, uint8_t *_dst, int coeffs)
84 {
85  int i, b, c_idx = 0;
86  int16_t *dst = (int16_t *)_dst;
87  DiracGolombLUT *future[4], *l = &lut_ctx[2*LUT_SIZE + buf[0]];
88  INIT_RESIDUE(res);
89 
90  for (b = 1; b <= bytes; b++) {
91  future[0] = &lut_ctx[buf[b]];
92  future[1] = future[0] + 1*LUT_SIZE;
93  future[2] = future[0] + 2*LUT_SIZE;
94  future[3] = future[0] + 3*LUT_SIZE;
95 
96  if ((c_idx + 1) > coeffs)
97  return c_idx;
98 
99  if (res_bits && l->sign) {
100  int32_t coeff = 1;
101  APPEND_RESIDUE(res, l->preamble);
102  for (i = 0; i < (res_bits >> 1) - 1; i++) {
103  coeff <<= 1;
104  coeff |= (res >> (RSIZE_BITS - 2*i - 2)) & 1;
105  }
106  dst[c_idx++] = l->sign * (coeff - 1);
107  res_bits = res = 0;
108  }
109 
110  for (i = 0; i < LUT_BITS; i++)
111  dst[c_idx + i] = l->ready[i];
112  c_idx += l->ready_num;
113 
114  APPEND_RESIDUE(res, l->leftover);
115 
116  l = future[l->need_s ? 3 : !res_bits ? 2 : res_bits & 1];
117  }
118 
119  return c_idx;
120 }
121 
122 /* Searches for golomb codes in a residue */
123 static inline void search_for_golomb(DiracGolombLUT *l, residual r, int bits)
124 {
125  int r_count = RSIZE_BITS - 1;
126  int bits_start, bits_tot = bits, need_sign = 0;
127 
128 #define READ_BIT(N) (((N) >> (N ## _count--)) & 1)
129 
130  while (1) {
131  int32_t coef = 1;
132  bits_start = (RSIZE_BITS - 1) - r_count;
133 
134  while (1) {
135  if (!bits--)
136  goto leftover;
137  if (READ_BIT(r))
138  break;
139 
140  coef <<= 1;
141 
142  if (!bits--)
143  goto leftover;
144  coef |= READ_BIT(r);
145  }
146 
147  l->ready[l->ready_num] = coef - 1;
148  if (l->ready[l->ready_num]) {
149  if (!bits--) {
150  need_sign = 1;
151  goto leftover;
152  }
153  l->ready[l->ready_num] *= READ_BIT(r) ? -1 : +1;
154  }
155  l->ready_num++;
156 
157  if (!bits)
158  return;
159  }
160 
161  leftover:
162  l->leftover = r << bits_start;
163  l->leftover_bits = bits_tot - bits_start;
164  l->need_s = need_sign;
165 }
166 
167 /* Parity LUTs - even and odd bit end positions */
169 {
170  int idx;
171  for (idx = 0; idx < LUT_SIZE; idx++) {
172  DiracGolombLUT *l = &lut[idx];
173  int symbol_end_loc = -1;
174  uint32_t code;
175  int i;
176 
177  INIT_RESIDUE(res);
178  SET_RESIDUE(res, idx, LUT_BITS);
179 
180  for (i = 0; i < LUT_BITS; i++) {
181  const int cond = even ? (i & 1) : !(i & 1);
182  if (((res >> (RSIZE_BITS - i - 1)) & 1) && cond) {
183  symbol_end_loc = i + 2;
184  break;
185  }
186  }
187 
188  if (symbol_end_loc < 0 || symbol_end_loc > LUT_BITS) {
189  l->preamble = 0;
190  l->preamble_bits = 0;
191  l->leftover_bits = LUT_BITS;
193  if (even)
194  l->need_s = idx & 1;
195  continue;
196  }
197 
198  /* Gets bits 0 through to (symbol_end_loc - 1) inclusive */
199  code = idx >> ((LUT_BITS - 1) - (symbol_end_loc - 1));
200  code &= ((1 << LUT_BITS) - 1) >> (LUT_BITS - symbol_end_loc);
201  l->preamble_bits = symbol_end_loc;
203  l->sign = ((l->preamble >> (RSIZE_BITS - l->preamble_bits)) & 1) ? -1 : +1;
204 
205  search_for_golomb(l, res << symbol_end_loc, LUT_BITS - symbol_end_loc);
206  }
207 }
208 
209 /* Reset (off == 0) and needs-one-more-bit (off == 1) LUTs */
210 static void generate_offset_lut(DiracGolombLUT *lut, int off)
211 {
212  int idx;
213  for (idx = 0; idx < LUT_SIZE; idx++) {
214  DiracGolombLUT *l = &lut[idx];
215 
216  INIT_RESIDUE(res);
217  SET_RESIDUE(res, idx, LUT_BITS);
218 
219  l->preamble_bits = off;
220  if (off) {
221  l->preamble = CONVERT_TO_RESIDUE(res >> (RSIZE_BITS - off), off);
222  l->sign = ((l->preamble >> (RSIZE_BITS - l->preamble_bits)) & 1) ? -1 : +1;
223  } else {
224  l->preamble = 0;
225  l->sign = 1;
226  }
227 
228  search_for_golomb(l, res << off, LUT_BITS - off);
229  }
230 }
231 
233 {
234  DiracGolombLUT *lut;
235 
236  if (!(lut = av_calloc(4*LUT_SIZE, sizeof(DiracGolombLUT))))
237  return AVERROR(ENOMEM);
238 
239  generate_parity_lut(&lut[0*LUT_SIZE], 0);
240  generate_parity_lut(&lut[1*LUT_SIZE], 1);
241  generate_offset_lut(&lut[2*LUT_SIZE], 0);
242  generate_offset_lut(&lut[3*LUT_SIZE], 1);
243 
244  *lut_ctx = lut;
245 
246  return 0;
247 }
248 
250 {
251  av_freep(lut_ctx);
252 }
int ff_dirac_golomb_read_32bit(DiracGolombLUT *lut_ctx, const uint8_t *buf, int bytes, uint8_t *_dst, int coeffs)
Definition: dirac_vlc.c:42
#define READ_BIT(N)
static void search_for_golomb(DiracGolombLUT *l, residual r, int bits)
Definition: dirac_vlc.c:123
const char * b
Definition: vf_curves.c:113
int ff_dirac_golomb_read_16bit(DiracGolombLUT *lut_ctx, const uint8_t *buf, int bytes, uint8_t *_dst, int coeffs)
Definition: dirac_vlc.c:82
#define SET_RESIDUE(N, I, B)
Definition: dirac_vlc.c:34
#define LUT_BITS
Definition: bgmc.c:38
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
uint8_t
#define av_cold
Definition: attributes.h:82
#define LUT_SIZE
Definition: dirac_vlc.c:24
av_cold int ff_dirac_golomb_reader_init(DiracGolombLUT **lut_ctx)
Definition: dirac_vlc.c:232
int32_t ready[LUT_BITS]
Definition: dirac_vlc.h:36
#define INIT_RESIDUE(N)
Definition: dirac_vlc.c:30
#define AVERROR(e)
Definition: error.h:43
const char * r
Definition: vf_curves.c:111
int32_t preamble_bits
Definition: dirac_vlc.h:37
uint64_t residual
Definition: dirac_vlc.h:29
int32_t ready_num
Definition: dirac_vlc.h:37
static void generate_offset_lut(DiracGolombLUT *lut, int off)
Definition: dirac_vlc.c:210
int32_t
av_cold void ff_dirac_golomb_reader_end(DiracGolombLUT **lut_ctx)
Definition: dirac_vlc.c:249
int8_t sign
Definition: dirac_vlc.h:38
static av_always_inline int even(uint64_t layout)
#define RSIZE_BITS
Definition: dirac_vlc.c:25
void * buf
Definition: avisynth_c.h:690
int32_t leftover_bits
Definition: dirac_vlc.h:37
#define CONVERT_TO_RESIDUE(a, b)
Definition: dirac_vlc.c:27
int(* cond)(enum AVPixelFormat pix_fmt)
Definition: pixdesc_query.c:28
#define APPEND_RESIDUE(N, M)
Definition: dirac_vlc.c:38
residual leftover
Definition: dirac_vlc.h:35
static const int16_t coeffs[]
residual preamble
Definition: dirac_vlc.h:35
static const double coeff[2][5]
Definition: vf_owdenoise.c:72
static void generate_parity_lut(DiracGolombLUT *lut, int even)
Definition: dirac_vlc.c:168
#define av_freep(p)
int8_t need_s
Definition: dirac_vlc.h:38