FFmpeg
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
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 i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define INIT_RESIDUE(N)
Definition: dirac_vlc.c:30
const char * r
Definition: vf_curves.c:114
uint8_t bits
Definition: vp3data.h:202
int32_t preamble_bits
Definition: dirac_vlc.h:37
uint64_t residual
Definition: dirac_vlc.h:29
#define b
Definition: input.c:41
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
#define RSIZE_BITS
Definition: dirac_vlc.c:25
void * buf
Definition: avisynth_c.h:766
FFmpeg s bug feature request tracker new issues and changes to existing issues can be done through a web interface Issues can be different kinds of things we want to keep track of but that do not belong into the source tree itself This includes bug feature requests and license violations We might add more items to this list in the future
int32_t leftover_bits
Definition: dirac_vlc.h:37
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
#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
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
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
Tag MUST be even
Definition: snow.txt:206