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 }
ff_dirac_golomb_read_32bit
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
generate_parity_lut
static void generate_parity_lut(DiracGolombLUT *lut, int even)
Definition: dirac_vlc.c:168
r
const char * r
Definition: vf_curves.c:114
AVERROR
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
DiracGolombLUT::preamble_bits
int32_t preamble_bits
Definition: dirac_vlc.h:37
SET_RESIDUE
#define SET_RESIDUE(N, I, B)
Definition: dirac_vlc.c:34
LUT_SIZE
#define LUT_SIZE
Definition: dirac_vlc.c:24
even
Tag MUST be even
Definition: snow.txt:206
b
#define b
Definition: input.c:41
ff_dirac_golomb_reader_init
av_cold int ff_dirac_golomb_reader_init(DiracGolombLUT **lut_ctx)
Definition: dirac_vlc.c:232
search_for_golomb
static void search_for_golomb(DiracGolombLUT *l, residual r, int bits)
Definition: dirac_vlc.c:123
LUT_BITS
#define LUT_BITS
Definition: bgmc.c:38
future
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
Definition: issue_tracker.txt:13
DiracGolombLUT::leftover_bits
int32_t leftover_bits
Definition: dirac_vlc.h:37
buf
void * buf
Definition: avisynth_c.h:766
av_cold
#define av_cold
Definition: attributes.h:84
DiracGolombLUT::ready_num
int32_t ready_num
Definition: dirac_vlc.h:37
bits
uint8_t bits
Definition: vp3data.h:202
generate_offset_lut
static void generate_offset_lut(DiracGolombLUT *lut, int off)
Definition: dirac_vlc.c:210
int32_t
int32_t
Definition: audio_convert.c:194
ff_dirac_golomb_reader_end
av_cold void ff_dirac_golomb_reader_end(DiracGolombLUT **lut_ctx)
Definition: dirac_vlc.c:249
DiracGolombLUT::leftover
residual leftover
Definition: dirac_vlc.h:35
DiracGolombLUT
Definition: dirac_vlc.h:34
RSIZE_BITS
#define RSIZE_BITS
Definition: dirac_vlc.c:25
dirac_vlc.h
residual
uint64_t residual
Definition: dirac_vlc.h:29
INIT_RESIDUE
#define INIT_RESIDUE(N)
Definition: dirac_vlc.c:30
CONVERT_TO_RESIDUE
#define CONVERT_TO_RESIDUE(a, b)
Definition: dirac_vlc.c:27
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
code
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
Definition: filter_design.txt:178
DiracGolombLUT::ready
int32_t ready[LUT_BITS]
Definition: dirac_vlc.h:36
uint8_t
uint8_t
Definition: audio_convert.c:194
DiracGolombLUT::preamble
residual preamble
Definition: dirac_vlc.h:35
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
APPEND_RESIDUE
#define APPEND_RESIDUE(N, M)
Definition: dirac_vlc.c:38
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
coeff
static const double coeff[2][5]
Definition: vf_owdenoise.c:72
DiracGolombLUT::sign
int8_t sign
Definition: dirac_vlc.h:38
DiracGolombLUT::need_s
int8_t need_s
Definition: dirac_vlc.h:38
cond
int(* cond)(enum AVPixelFormat pix_fmt)
Definition: pixdesc_query.c:28
READ_BIT
#define READ_BIT(N)
ff_dirac_golomb_read_16bit
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