1 |
|
|
/* |
2 |
|
|
* Copyright (C) 2016 Open Broadcast Systems Ltd. |
3 |
|
|
* Author 2016 Rostislav Pehlivanov <atomnuker@gmail.com> |
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 "libavutil/pixdesc.h" |
23 |
|
|
#include "libavutil/opt.h" |
24 |
|
|
#include "dirac.h" |
25 |
|
|
#include "put_bits.h" |
26 |
|
|
#include "internal.h" |
27 |
|
|
#include "version.h" |
28 |
|
|
|
29 |
|
|
#include "vc2enc_dwt.h" |
30 |
|
|
#include "diractab.h" |
31 |
|
|
|
32 |
|
|
/* The limited size resolution of each slice forces us to do this */ |
33 |
|
|
#define SSIZE_ROUND(b) (FFALIGN((b), s->size_scaler) + 4 + s->prefix_bytes) |
34 |
|
|
|
35 |
|
|
/* Decides the cutoff point in # of slices to distribute the leftover bytes */ |
36 |
|
|
#define SLICE_REDIST_TOTAL 150 |
37 |
|
|
|
38 |
|
|
typedef struct VC2BaseVideoFormat { |
39 |
|
|
enum AVPixelFormat pix_fmt; |
40 |
|
|
AVRational time_base; |
41 |
|
|
int width, height, interlaced, level; |
42 |
|
|
const char *name; |
43 |
|
|
} VC2BaseVideoFormat; |
44 |
|
|
|
45 |
|
|
static const VC2BaseVideoFormat base_video_fmts[] = { |
46 |
|
|
{ 0 }, /* Custom format, here just to make indexing equal to base_vf */ |
47 |
|
|
{ AV_PIX_FMT_YUV420P, { 1001, 15000 }, 176, 120, 0, 1, "QSIF525" }, |
48 |
|
|
{ AV_PIX_FMT_YUV420P, { 2, 25 }, 176, 144, 0, 1, "QCIF" }, |
49 |
|
|
{ AV_PIX_FMT_YUV420P, { 1001, 15000 }, 352, 240, 0, 1, "SIF525" }, |
50 |
|
|
{ AV_PIX_FMT_YUV420P, { 2, 25 }, 352, 288, 0, 1, "CIF" }, |
51 |
|
|
{ AV_PIX_FMT_YUV420P, { 1001, 15000 }, 704, 480, 0, 1, "4SIF525" }, |
52 |
|
|
{ AV_PIX_FMT_YUV420P, { 2, 25 }, 704, 576, 0, 1, "4CIF" }, |
53 |
|
|
|
54 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1001, 30000 }, 720, 480, 1, 2, "SD480I-60" }, |
55 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1, 25 }, 720, 576, 1, 2, "SD576I-50" }, |
56 |
|
|
|
57 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1001, 60000 }, 1280, 720, 0, 3, "HD720P-60" }, |
58 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1, 50 }, 1280, 720, 0, 3, "HD720P-50" }, |
59 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1001, 30000 }, 1920, 1080, 1, 3, "HD1080I-60" }, |
60 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1, 25 }, 1920, 1080, 1, 3, "HD1080I-50" }, |
61 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1001, 60000 }, 1920, 1080, 0, 3, "HD1080P-60" }, |
62 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1, 50 }, 1920, 1080, 0, 3, "HD1080P-50" }, |
63 |
|
|
|
64 |
|
|
{ AV_PIX_FMT_YUV444P12, { 1, 24 }, 2048, 1080, 0, 4, "DC2K" }, |
65 |
|
|
{ AV_PIX_FMT_YUV444P12, { 1, 24 }, 4096, 2160, 0, 5, "DC4K" }, |
66 |
|
|
|
67 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1001, 60000 }, 3840, 2160, 0, 6, "UHDTV 4K-60" }, |
68 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1, 50 }, 3840, 2160, 0, 6, "UHDTV 4K-50" }, |
69 |
|
|
|
70 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1001, 60000 }, 7680, 4320, 0, 7, "UHDTV 8K-60" }, |
71 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1, 50 }, 7680, 4320, 0, 7, "UHDTV 8K-50" }, |
72 |
|
|
|
73 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1001, 24000 }, 1920, 1080, 0, 3, "HD1080P-24" }, |
74 |
|
|
{ AV_PIX_FMT_YUV422P10, { 1001, 30000 }, 720, 486, 1, 2, "SD Pro486" }, |
75 |
|
|
}; |
76 |
|
|
static const int base_video_fmts_len = FF_ARRAY_ELEMS(base_video_fmts); |
77 |
|
|
|
78 |
|
|
enum VC2_QM { |
79 |
|
|
VC2_QM_DEF = 0, |
80 |
|
|
VC2_QM_COL, |
81 |
|
|
VC2_QM_FLAT, |
82 |
|
|
|
83 |
|
|
VC2_QM_NB |
84 |
|
|
}; |
85 |
|
|
|
86 |
|
|
typedef struct SubBand { |
87 |
|
|
dwtcoef *buf; |
88 |
|
|
ptrdiff_t stride; |
89 |
|
|
int width; |
90 |
|
|
int height; |
91 |
|
|
} SubBand; |
92 |
|
|
|
93 |
|
|
typedef struct Plane { |
94 |
|
|
SubBand band[MAX_DWT_LEVELS][4]; |
95 |
|
|
dwtcoef *coef_buf; |
96 |
|
|
int width; |
97 |
|
|
int height; |
98 |
|
|
int dwt_width; |
99 |
|
|
int dwt_height; |
100 |
|
|
ptrdiff_t coef_stride; |
101 |
|
|
} Plane; |
102 |
|
|
|
103 |
|
|
typedef struct SliceArgs { |
104 |
|
|
PutBitContext pb; |
105 |
|
|
int cache[DIRAC_MAX_QUANT_INDEX]; |
106 |
|
|
void *ctx; |
107 |
|
|
int x; |
108 |
|
|
int y; |
109 |
|
|
int quant_idx; |
110 |
|
|
int bits_ceil; |
111 |
|
|
int bits_floor; |
112 |
|
|
int bytes; |
113 |
|
|
} SliceArgs; |
114 |
|
|
|
115 |
|
|
typedef struct TransformArgs { |
116 |
|
|
void *ctx; |
117 |
|
|
Plane *plane; |
118 |
|
|
void *idata; |
119 |
|
|
ptrdiff_t istride; |
120 |
|
|
int field; |
121 |
|
|
VC2TransformContext t; |
122 |
|
|
} TransformArgs; |
123 |
|
|
|
124 |
|
|
typedef struct VC2EncContext { |
125 |
|
|
AVClass *av_class; |
126 |
|
|
PutBitContext pb; |
127 |
|
|
Plane plane[3]; |
128 |
|
|
AVCodecContext *avctx; |
129 |
|
|
DiracVersionInfo ver; |
130 |
|
|
|
131 |
|
|
SliceArgs *slice_args; |
132 |
|
|
TransformArgs transform_args[3]; |
133 |
|
|
|
134 |
|
|
/* For conversion from unsigned pixel values to signed */ |
135 |
|
|
int diff_offset; |
136 |
|
|
int bpp; |
137 |
|
|
int bpp_idx; |
138 |
|
|
|
139 |
|
|
/* Picture number */ |
140 |
|
|
uint32_t picture_number; |
141 |
|
|
|
142 |
|
|
/* Base video format */ |
143 |
|
|
int base_vf; |
144 |
|
|
int level; |
145 |
|
|
int profile; |
146 |
|
|
|
147 |
|
|
/* Quantization matrix */ |
148 |
|
|
uint8_t quant[MAX_DWT_LEVELS][4]; |
149 |
|
|
int custom_quant_matrix; |
150 |
|
|
|
151 |
|
|
/* Division LUT */ |
152 |
|
|
uint32_t qmagic_lut[116][2]; |
153 |
|
|
|
154 |
|
|
int num_x; /* #slices horizontally */ |
155 |
|
|
int num_y; /* #slices vertically */ |
156 |
|
|
int prefix_bytes; |
157 |
|
|
int size_scaler; |
158 |
|
|
int chroma_x_shift; |
159 |
|
|
int chroma_y_shift; |
160 |
|
|
|
161 |
|
|
/* Rate control stuff */ |
162 |
|
|
int frame_max_bytes; |
163 |
|
|
int slice_max_bytes; |
164 |
|
|
int slice_min_bytes; |
165 |
|
|
int q_ceil; |
166 |
|
|
int q_avg; |
167 |
|
|
|
168 |
|
|
/* Options */ |
169 |
|
|
double tolerance; |
170 |
|
|
int wavelet_idx; |
171 |
|
|
int wavelet_depth; |
172 |
|
|
int strict_compliance; |
173 |
|
|
int slice_height; |
174 |
|
|
int slice_width; |
175 |
|
|
int interlaced; |
176 |
|
|
enum VC2_QM quant_matrix; |
177 |
|
|
|
178 |
|
|
/* Parse code state */ |
179 |
|
|
uint32_t next_parse_offset; |
180 |
|
|
enum DiracParseCodes last_parse_code; |
181 |
|
|
} VC2EncContext; |
182 |
|
|
|
183 |
|
35739495 |
static av_always_inline void put_vc2_ue_uint(PutBitContext *pb, uint32_t val) |
184 |
|
|
{ |
185 |
|
|
int i; |
186 |
|
35739495 |
int pbits = 0, bits = 0, topbit = 1, maxval = 1; |
187 |
|
|
|
188 |
✓✓ |
35739495 |
if (!val++) { |
189 |
|
3422589 |
put_bits(pb, 1, 1); |
190 |
|
3422589 |
return; |
191 |
|
|
} |
192 |
|
|
|
193 |
✓✓ |
155685392 |
while (val > maxval) { |
194 |
|
123368486 |
topbit <<= 1; |
195 |
|
123368486 |
maxval <<= 1; |
196 |
|
123368486 |
maxval |= 1; |
197 |
|
|
} |
198 |
|
|
|
199 |
|
32316906 |
bits = ff_log2(topbit); |
200 |
|
|
|
201 |
✓✓ |
155685392 |
for (i = 0; i < bits; i++) { |
202 |
|
123368486 |
topbit >>= 1; |
203 |
|
123368486 |
pbits <<= 2; |
204 |
✓✓ |
123368486 |
if (val & topbit) |
205 |
|
55341066 |
pbits |= 0x1; |
206 |
|
|
} |
207 |
|
|
|
208 |
|
32316906 |
put_bits(pb, bits*2 + 1, (pbits << 1) | 1); |
209 |
|
|
} |
210 |
|
|
|
211 |
|
35735040 |
static av_always_inline int count_vc2_ue_uint(uint32_t val) |
212 |
|
|
{ |
213 |
|
35735040 |
int topbit = 1, maxval = 1; |
214 |
|
|
|
215 |
✓✓ |
35735040 |
if (!val++) |
216 |
|
3420429 |
return 1; |
217 |
|
|
|
218 |
✓✓ |
155675552 |
while (val > maxval) { |
219 |
|
123360941 |
topbit <<= 1; |
220 |
|
123360941 |
maxval <<= 1; |
221 |
|
123360941 |
maxval |= 1; |
222 |
|
|
} |
223 |
|
|
|
224 |
|
32314611 |
return ff_log2(topbit)*2 + 1; |
225 |
|
|
} |
226 |
|
|
|
227 |
|
|
/* VC-2 10.4 - parse_info() */ |
228 |
|
660 |
static void encode_parse_info(VC2EncContext *s, enum DiracParseCodes pcode) |
229 |
|
|
{ |
230 |
|
|
uint32_t cur_pos, dist; |
231 |
|
|
|
232 |
|
660 |
align_put_bits(&s->pb); |
233 |
|
|
|
234 |
|
660 |
cur_pos = put_bits_count(&s->pb) >> 3; |
235 |
|
|
|
236 |
|
|
/* Magic string */ |
237 |
|
660 |
ff_put_string(&s->pb, "BBCD", 0); |
238 |
|
|
|
239 |
|
|
/* Parse code */ |
240 |
|
660 |
put_bits(&s->pb, 8, pcode); |
241 |
|
|
|
242 |
|
|
/* Next parse offset */ |
243 |
|
660 |
dist = cur_pos - s->next_parse_offset; |
244 |
|
660 |
AV_WB32(s->pb.buf + s->next_parse_offset + 5, dist); |
245 |
|
660 |
s->next_parse_offset = cur_pos; |
246 |
✓✓ |
660 |
put_bits32(&s->pb, pcode == DIRAC_PCODE_END_SEQ ? 13 : 0); |
247 |
|
|
|
248 |
|
|
/* Last parse offset */ |
249 |
✓✗ |
660 |
put_bits32(&s->pb, s->last_parse_code == DIRAC_PCODE_END_SEQ ? 13 : dist); |
250 |
|
|
|
251 |
|
660 |
s->last_parse_code = pcode; |
252 |
|
660 |
} |
253 |
|
|
|
254 |
|
|
/* VC-2 11.1 - parse_parameters() |
255 |
|
|
* The level dictates what the decoder should expect in terms of resolution |
256 |
|
|
* and allows it to quickly reject whatever it can't support. Remember, |
257 |
|
|
* this codec kinda targets cheapo FPGAs without much memory. Unfortunately |
258 |
|
|
* it also limits us greatly in our choice of formats, hence the flag to disable |
259 |
|
|
* strict_compliance */ |
260 |
|
165 |
static void encode_parse_params(VC2EncContext *s) |
261 |
|
|
{ |
262 |
|
165 |
put_vc2_ue_uint(&s->pb, s->ver.major); /* VC-2 demands this to be 2 */ |
263 |
|
165 |
put_vc2_ue_uint(&s->pb, s->ver.minor); /* ^^ and this to be 0 */ |
264 |
|
165 |
put_vc2_ue_uint(&s->pb, s->profile); /* 3 to signal HQ profile */ |
265 |
|
165 |
put_vc2_ue_uint(&s->pb, s->level); /* 3 - 1080/720, 6 - 4K */ |
266 |
|
165 |
} |
267 |
|
|
|
268 |
|
|
/* VC-2 11.3 - frame_size() */ |
269 |
|
165 |
static void encode_frame_size(VC2EncContext *s) |
270 |
|
|
{ |
271 |
|
165 |
put_bits(&s->pb, 1, !s->strict_compliance); |
272 |
✓✗ |
165 |
if (!s->strict_compliance) { |
273 |
|
165 |
AVCodecContext *avctx = s->avctx; |
274 |
|
165 |
put_vc2_ue_uint(&s->pb, avctx->width); |
275 |
|
165 |
put_vc2_ue_uint(&s->pb, avctx->height); |
276 |
|
|
} |
277 |
|
165 |
} |
278 |
|
|
|
279 |
|
|
/* VC-2 11.3.3 - color_diff_sampling_format() */ |
280 |
|
165 |
static void encode_sample_fmt(VC2EncContext *s) |
281 |
|
|
{ |
282 |
|
165 |
put_bits(&s->pb, 1, !s->strict_compliance); |
283 |
✓✗ |
165 |
if (!s->strict_compliance) { |
284 |
|
|
int idx; |
285 |
✓✓✓✓
|
165 |
if (s->chroma_x_shift == 1 && s->chroma_y_shift == 0) |
286 |
|
75 |
idx = 1; /* 422 */ |
287 |
✓✓✓✗
|
90 |
else if (s->chroma_x_shift == 1 && s->chroma_y_shift == 1) |
288 |
|
45 |
idx = 2; /* 420 */ |
289 |
|
|
else |
290 |
|
45 |
idx = 0; /* 444 */ |
291 |
|
165 |
put_vc2_ue_uint(&s->pb, idx); |
292 |
|
|
} |
293 |
|
165 |
} |
294 |
|
|
|
295 |
|
|
/* VC-2 11.3.4 - scan_format() */ |
296 |
|
165 |
static void encode_scan_format(VC2EncContext *s) |
297 |
|
|
{ |
298 |
|
165 |
put_bits(&s->pb, 1, !s->strict_compliance); |
299 |
✓✗ |
165 |
if (!s->strict_compliance) |
300 |
|
165 |
put_vc2_ue_uint(&s->pb, s->interlaced); |
301 |
|
165 |
} |
302 |
|
|
|
303 |
|
|
/* VC-2 11.3.5 - frame_rate() */ |
304 |
|
165 |
static void encode_frame_rate(VC2EncContext *s) |
305 |
|
|
{ |
306 |
|
165 |
put_bits(&s->pb, 1, !s->strict_compliance); |
307 |
✓✗ |
165 |
if (!s->strict_compliance) { |
308 |
|
165 |
AVCodecContext *avctx = s->avctx; |
309 |
|
165 |
put_vc2_ue_uint(&s->pb, 0); |
310 |
|
165 |
put_vc2_ue_uint(&s->pb, avctx->time_base.den); |
311 |
|
165 |
put_vc2_ue_uint(&s->pb, avctx->time_base.num); |
312 |
|
|
} |
313 |
|
165 |
} |
314 |
|
|
|
315 |
|
|
/* VC-2 11.3.6 - aspect_ratio() */ |
316 |
|
165 |
static void encode_aspect_ratio(VC2EncContext *s) |
317 |
|
|
{ |
318 |
|
165 |
put_bits(&s->pb, 1, !s->strict_compliance); |
319 |
✓✗ |
165 |
if (!s->strict_compliance) { |
320 |
|
165 |
AVCodecContext *avctx = s->avctx; |
321 |
|
165 |
put_vc2_ue_uint(&s->pb, 0); |
322 |
|
165 |
put_vc2_ue_uint(&s->pb, avctx->sample_aspect_ratio.num); |
323 |
|
165 |
put_vc2_ue_uint(&s->pb, avctx->sample_aspect_ratio.den); |
324 |
|
|
} |
325 |
|
165 |
} |
326 |
|
|
|
327 |
|
|
/* VC-2 11.3.7 - clean_area() */ |
328 |
|
165 |
static void encode_clean_area(VC2EncContext *s) |
329 |
|
|
{ |
330 |
|
165 |
put_bits(&s->pb, 1, 0); |
331 |
|
165 |
} |
332 |
|
|
|
333 |
|
|
/* VC-2 11.3.8 - signal_range() */ |
334 |
|
165 |
static void encode_signal_range(VC2EncContext *s) |
335 |
|
|
{ |
336 |
|
165 |
put_bits(&s->pb, 1, !s->strict_compliance); |
337 |
✓✗ |
165 |
if (!s->strict_compliance) |
338 |
|
165 |
put_vc2_ue_uint(&s->pb, s->bpp_idx); |
339 |
|
165 |
} |
340 |
|
|
|
341 |
|
|
/* VC-2 11.3.9 - color_spec() */ |
342 |
|
165 |
static void encode_color_spec(VC2EncContext *s) |
343 |
|
|
{ |
344 |
|
165 |
AVCodecContext *avctx = s->avctx; |
345 |
|
165 |
put_bits(&s->pb, 1, !s->strict_compliance); |
346 |
✓✗ |
165 |
if (!s->strict_compliance) { |
347 |
|
|
int val; |
348 |
|
165 |
put_vc2_ue_uint(&s->pb, 0); |
349 |
|
|
|
350 |
|
|
/* primaries */ |
351 |
|
165 |
put_bits(&s->pb, 1, 1); |
352 |
✗✓ |
165 |
if (avctx->color_primaries == AVCOL_PRI_BT470BG) |
353 |
|
|
val = 2; |
354 |
✗✓ |
165 |
else if (avctx->color_primaries == AVCOL_PRI_SMPTE170M) |
355 |
|
|
val = 1; |
356 |
✗✓ |
165 |
else if (avctx->color_primaries == AVCOL_PRI_SMPTE240M) |
357 |
|
|
val = 1; |
358 |
|
|
else |
359 |
|
165 |
val = 0; |
360 |
|
165 |
put_vc2_ue_uint(&s->pb, val); |
361 |
|
|
|
362 |
|
|
/* color matrix */ |
363 |
|
165 |
put_bits(&s->pb, 1, 1); |
364 |
✗✓ |
165 |
if (avctx->colorspace == AVCOL_SPC_RGB) |
365 |
|
|
val = 3; |
366 |
✗✓ |
165 |
else if (avctx->colorspace == AVCOL_SPC_YCOCG) |
367 |
|
|
val = 2; |
368 |
✗✓ |
165 |
else if (avctx->colorspace == AVCOL_SPC_BT470BG) |
369 |
|
|
val = 1; |
370 |
|
|
else |
371 |
|
165 |
val = 0; |
372 |
|
165 |
put_vc2_ue_uint(&s->pb, val); |
373 |
|
|
|
374 |
|
|
/* transfer function */ |
375 |
|
165 |
put_bits(&s->pb, 1, 1); |
376 |
✗✓ |
165 |
if (avctx->color_trc == AVCOL_TRC_LINEAR) |
377 |
|
|
val = 2; |
378 |
✗✓ |
165 |
else if (avctx->color_trc == AVCOL_TRC_BT1361_ECG) |
379 |
|
|
val = 1; |
380 |
|
|
else |
381 |
|
165 |
val = 0; |
382 |
|
165 |
put_vc2_ue_uint(&s->pb, val); |
383 |
|
|
} |
384 |
|
165 |
} |
385 |
|
|
|
386 |
|
|
/* VC-2 11.3 - source_parameters() */ |
387 |
|
165 |
static void encode_source_params(VC2EncContext *s) |
388 |
|
|
{ |
389 |
|
165 |
encode_frame_size(s); |
390 |
|
165 |
encode_sample_fmt(s); |
391 |
|
165 |
encode_scan_format(s); |
392 |
|
165 |
encode_frame_rate(s); |
393 |
|
165 |
encode_aspect_ratio(s); |
394 |
|
165 |
encode_clean_area(s); |
395 |
|
165 |
encode_signal_range(s); |
396 |
|
165 |
encode_color_spec(s); |
397 |
|
165 |
} |
398 |
|
|
|
399 |
|
|
/* VC-2 11 - sequence_header() */ |
400 |
|
165 |
static void encode_seq_header(VC2EncContext *s) |
401 |
|
|
{ |
402 |
|
165 |
align_put_bits(&s->pb); |
403 |
|
165 |
encode_parse_params(s); |
404 |
|
165 |
put_vc2_ue_uint(&s->pb, s->base_vf); |
405 |
|
165 |
encode_source_params(s); |
406 |
|
165 |
put_vc2_ue_uint(&s->pb, s->interlaced); /* Frames or fields coding */ |
407 |
|
165 |
} |
408 |
|
|
|
409 |
|
|
/* VC-2 12.1 - picture_header() */ |
410 |
|
165 |
static void encode_picture_header(VC2EncContext *s) |
411 |
|
|
{ |
412 |
|
165 |
align_put_bits(&s->pb); |
413 |
|
165 |
put_bits32(&s->pb, s->picture_number++); |
414 |
|
165 |
} |
415 |
|
|
|
416 |
|
|
/* VC-2 12.3.4.1 - slice_parameters() */ |
417 |
|
165 |
static void encode_slice_params(VC2EncContext *s) |
418 |
|
|
{ |
419 |
|
165 |
put_vc2_ue_uint(&s->pb, s->num_x); |
420 |
|
165 |
put_vc2_ue_uint(&s->pb, s->num_y); |
421 |
|
165 |
put_vc2_ue_uint(&s->pb, s->prefix_bytes); |
422 |
|
165 |
put_vc2_ue_uint(&s->pb, s->size_scaler); |
423 |
|
165 |
} |
424 |
|
|
|
425 |
|
|
/* 1st idx = LL, second - vertical, third - horizontal, fourth - total */ |
426 |
|
|
static const uint8_t vc2_qm_col_tab[][4] = { |
427 |
|
|
{20, 9, 15, 4}, |
428 |
|
|
{ 0, 6, 6, 4}, |
429 |
|
|
{ 0, 3, 3, 5}, |
430 |
|
|
{ 0, 3, 5, 1}, |
431 |
|
|
{ 0, 11, 10, 11} |
432 |
|
|
}; |
433 |
|
|
|
434 |
|
|
static const uint8_t vc2_qm_flat_tab[][4] = { |
435 |
|
|
{ 0, 0, 0, 0}, |
436 |
|
|
{ 0, 0, 0, 0}, |
437 |
|
|
{ 0, 0, 0, 0}, |
438 |
|
|
{ 0, 0, 0, 0}, |
439 |
|
|
{ 0, 0, 0, 0} |
440 |
|
|
}; |
441 |
|
|
|
442 |
|
165 |
static void init_quant_matrix(VC2EncContext *s) |
443 |
|
|
{ |
444 |
|
|
int level, orientation; |
445 |
|
|
|
446 |
✓✗✓✗
|
165 |
if (s->wavelet_depth <= 4 && s->quant_matrix == VC2_QM_DEF) { |
447 |
|
165 |
s->custom_quant_matrix = 0; |
448 |
✓✓ |
825 |
for (level = 0; level < s->wavelet_depth; level++) { |
449 |
|
660 |
s->quant[level][0] = ff_dirac_default_qmat[s->wavelet_idx][level][0]; |
450 |
|
660 |
s->quant[level][1] = ff_dirac_default_qmat[s->wavelet_idx][level][1]; |
451 |
|
660 |
s->quant[level][2] = ff_dirac_default_qmat[s->wavelet_idx][level][2]; |
452 |
|
660 |
s->quant[level][3] = ff_dirac_default_qmat[s->wavelet_idx][level][3]; |
453 |
|
|
} |
454 |
|
165 |
return; |
455 |
|
|
} |
456 |
|
|
|
457 |
|
|
s->custom_quant_matrix = 1; |
458 |
|
|
|
459 |
|
|
if (s->quant_matrix == VC2_QM_DEF) { |
460 |
|
|
for (level = 0; level < s->wavelet_depth; level++) { |
461 |
|
|
for (orientation = 0; orientation < 4; orientation++) { |
462 |
|
|
if (level <= 3) |
463 |
|
|
s->quant[level][orientation] = ff_dirac_default_qmat[s->wavelet_idx][level][orientation]; |
464 |
|
|
else |
465 |
|
|
s->quant[level][orientation] = vc2_qm_col_tab[level][orientation]; |
466 |
|
|
} |
467 |
|
|
} |
468 |
|
|
} else if (s->quant_matrix == VC2_QM_COL) { |
469 |
|
|
for (level = 0; level < s->wavelet_depth; level++) { |
470 |
|
|
for (orientation = 0; orientation < 4; orientation++) { |
471 |
|
|
s->quant[level][orientation] = vc2_qm_col_tab[level][orientation]; |
472 |
|
|
} |
473 |
|
|
} |
474 |
|
|
} else { |
475 |
|
|
for (level = 0; level < s->wavelet_depth; level++) { |
476 |
|
|
for (orientation = 0; orientation < 4; orientation++) { |
477 |
|
|
s->quant[level][orientation] = vc2_qm_flat_tab[level][orientation]; |
478 |
|
|
} |
479 |
|
|
} |
480 |
|
|
} |
481 |
|
|
} |
482 |
|
|
|
483 |
|
|
/* VC-2 12.3.4.2 - quant_matrix() */ |
484 |
|
165 |
static void encode_quant_matrix(VC2EncContext *s) |
485 |
|
|
{ |
486 |
|
|
int level; |
487 |
|
165 |
put_bits(&s->pb, 1, s->custom_quant_matrix); |
488 |
✗✓ |
165 |
if (s->custom_quant_matrix) { |
489 |
|
|
put_vc2_ue_uint(&s->pb, s->quant[0][0]); |
490 |
|
|
for (level = 0; level < s->wavelet_depth; level++) { |
491 |
|
|
put_vc2_ue_uint(&s->pb, s->quant[level][1]); |
492 |
|
|
put_vc2_ue_uint(&s->pb, s->quant[level][2]); |
493 |
|
|
put_vc2_ue_uint(&s->pb, s->quant[level][3]); |
494 |
|
|
} |
495 |
|
|
} |
496 |
|
165 |
} |
497 |
|
|
|
498 |
|
|
/* VC-2 12.3 - transform_parameters() */ |
499 |
|
165 |
static void encode_transform_params(VC2EncContext *s) |
500 |
|
|
{ |
501 |
|
165 |
put_vc2_ue_uint(&s->pb, s->wavelet_idx); |
502 |
|
165 |
put_vc2_ue_uint(&s->pb, s->wavelet_depth); |
503 |
|
|
|
504 |
|
165 |
encode_slice_params(s); |
505 |
|
165 |
encode_quant_matrix(s); |
506 |
|
165 |
} |
507 |
|
|
|
508 |
|
|
/* VC-2 12.2 - wavelet_transform() */ |
509 |
|
165 |
static void encode_wavelet_transform(VC2EncContext *s) |
510 |
|
|
{ |
511 |
|
165 |
encode_transform_params(s); |
512 |
|
165 |
align_put_bits(&s->pb); |
513 |
|
165 |
} |
514 |
|
|
|
515 |
|
|
/* VC-2 12 - picture_parse() */ |
516 |
|
165 |
static void encode_picture_start(VC2EncContext *s) |
517 |
|
|
{ |
518 |
|
165 |
align_put_bits(&s->pb); |
519 |
|
165 |
encode_picture_header(s); |
520 |
|
165 |
align_put_bits(&s->pb); |
521 |
|
165 |
encode_wavelet_transform(s); |
522 |
|
165 |
} |
523 |
|
|
|
524 |
|
|
#define QUANT(c, mul, add, shift) (((mul) * (c) + (add)) >> (shift)) |
525 |
|
|
|
526 |
|
|
/* VC-2 13.5.5.2 - slice_band() */ |
527 |
|
1274130 |
static void encode_subband(VC2EncContext *s, PutBitContext *pb, int sx, int sy, |
528 |
|
|
SubBand *b, int quant) |
529 |
|
|
{ |
530 |
|
|
int x, y; |
531 |
|
|
|
532 |
|
1274130 |
const int left = b->width * (sx+0) / s->num_x; |
533 |
|
1274130 |
const int right = b->width * (sx+1) / s->num_x; |
534 |
|
1274130 |
const int top = b->height * (sy+0) / s->num_y; |
535 |
|
1274130 |
const int bottom = b->height * (sy+1) / s->num_y; |
536 |
|
|
|
537 |
|
1274130 |
dwtcoef *coeff = b->buf + top * b->stride; |
538 |
|
1274130 |
const uint64_t q_m = ((uint64_t)(s->qmagic_lut[quant][0])) << 2; |
539 |
|
1274130 |
const uint64_t q_a = s->qmagic_lut[quant][1]; |
540 |
|
1274130 |
const int q_s = av_log2(ff_dirac_qscale_tab[quant]) + 32; |
541 |
|
|
|
542 |
✓✓ |
5372730 |
for (y = top; y < bottom; y++) { |
543 |
✓✓ |
39833640 |
for (x = left; x < right; x++) { |
544 |
✓✓ |
35735040 |
uint32_t c_abs = QUANT(FFABS(coeff[x]), q_m, q_a, q_s); |
545 |
|
35735040 |
put_vc2_ue_uint(pb, c_abs); |
546 |
✓✓ |
35735040 |
if (c_abs) |
547 |
|
32314611 |
put_bits(pb, 1, coeff[x] < 0); |
548 |
|
|
} |
549 |
|
4098600 |
coeff += b->stride; |
550 |
|
|
} |
551 |
|
1274130 |
} |
552 |
|
|
|
553 |
|
130680 |
static int count_hq_slice(SliceArgs *slice, int quant_idx) |
554 |
|
|
{ |
555 |
|
|
int x, y; |
556 |
|
|
uint8_t quants[MAX_DWT_LEVELS][4]; |
557 |
|
130680 |
int bits = 0, p, level, orientation; |
558 |
|
130680 |
VC2EncContext *s = slice->ctx; |
559 |
|
|
|
560 |
✓✓ |
130680 |
if (slice->cache[quant_idx]) |
561 |
|
98010 |
return slice->cache[quant_idx]; |
562 |
|
|
|
563 |
|
32670 |
bits += 8*s->prefix_bytes; |
564 |
|
32670 |
bits += 8; /* quant_idx */ |
565 |
|
|
|
566 |
✓✓ |
163350 |
for (level = 0; level < s->wavelet_depth; level++) |
567 |
✓✓ |
555390 |
for (orientation = !!level; orientation < 4; orientation++) |
568 |
|
424710 |
quants[level][orientation] = FFMAX(quant_idx - s->quant[level][orientation], 0); |
569 |
|
|
|
570 |
✓✓ |
130680 |
for (p = 0; p < 3; p++) { |
571 |
|
|
int bytes_start, bytes_len, pad_s, pad_c; |
572 |
|
98010 |
bytes_start = bits >> 3; |
573 |
|
98010 |
bits += 8; |
574 |
✓✓ |
490050 |
for (level = 0; level < s->wavelet_depth; level++) { |
575 |
✓✓ |
1666170 |
for (orientation = !!level; orientation < 4; orientation++) { |
576 |
|
1274130 |
SubBand *b = &s->plane[p].band[level][orientation]; |
577 |
|
|
|
578 |
|
1274130 |
const int q_idx = quants[level][orientation]; |
579 |
|
1274130 |
const uint64_t q_m = ((uint64_t)s->qmagic_lut[q_idx][0]) << 2; |
580 |
|
1274130 |
const uint64_t q_a = s->qmagic_lut[q_idx][1]; |
581 |
|
1274130 |
const int q_s = av_log2(ff_dirac_qscale_tab[q_idx]) + 32; |
582 |
|
|
|
583 |
|
1274130 |
const int left = b->width * slice->x / s->num_x; |
584 |
|
1274130 |
const int right = b->width *(slice->x+1) / s->num_x; |
585 |
|
1274130 |
const int top = b->height * slice->y / s->num_y; |
586 |
|
1274130 |
const int bottom = b->height *(slice->y+1) / s->num_y; |
587 |
|
|
|
588 |
|
1274130 |
dwtcoef *buf = b->buf + top * b->stride; |
589 |
|
|
|
590 |
✓✓ |
5372730 |
for (y = top; y < bottom; y++) { |
591 |
✓✓ |
39833640 |
for (x = left; x < right; x++) { |
592 |
✓✓ |
35735040 |
uint32_t c_abs = QUANT(FFABS(buf[x]), q_m, q_a, q_s); |
593 |
|
35735040 |
bits += count_vc2_ue_uint(c_abs); |
594 |
|
35735040 |
bits += !!c_abs; |
595 |
|
|
} |
596 |
|
4098600 |
buf += b->stride; |
597 |
|
|
} |
598 |
|
|
} |
599 |
|
|
} |
600 |
|
98010 |
bits += FFALIGN(bits, 8) - bits; |
601 |
|
98010 |
bytes_len = (bits >> 3) - bytes_start - 1; |
602 |
|
98010 |
pad_s = FFALIGN(bytes_len, s->size_scaler)/s->size_scaler; |
603 |
|
98010 |
pad_c = (pad_s*s->size_scaler) - bytes_len; |
604 |
|
98010 |
bits += pad_c*8; |
605 |
|
|
} |
606 |
|
|
|
607 |
|
32670 |
slice->cache[quant_idx] = bits; |
608 |
|
|
|
609 |
|
32670 |
return bits; |
610 |
|
|
} |
611 |
|
|
|
612 |
|
|
/* Approaches the best possible quantizer asymptotically, its kinda exaustive |
613 |
|
|
* but we have a LUT to get the coefficient size in bits. Guaranteed to never |
614 |
|
|
* overshoot, which is apparently very important when streaming */ |
615 |
|
32670 |
static int rate_control(AVCodecContext *avctx, void *arg) |
616 |
|
|
{ |
617 |
|
32670 |
SliceArgs *slice_dat = arg; |
618 |
|
32670 |
VC2EncContext *s = slice_dat->ctx; |
619 |
|
32670 |
const int top = slice_dat->bits_ceil; |
620 |
|
32670 |
const int bottom = slice_dat->bits_floor; |
621 |
|
32670 |
int quant_buf[2] = {-1, -1}; |
622 |
|
32670 |
int quant = slice_dat->quant_idx, step = 1; |
623 |
|
32670 |
int bits_last, bits = count_hq_slice(slice_dat, quant); |
624 |
✗✓✓✗
|
98010 |
while ((bits > top) || (bits < bottom)) { |
625 |
✓✗ |
98010 |
const int signed_step = bits > top ? +step : -step; |
626 |
|
98010 |
quant = av_clip(quant + signed_step, 0, s->q_ceil-1); |
627 |
|
98010 |
bits = count_hq_slice(slice_dat, quant); |
628 |
✓✓ |
98010 |
if (quant_buf[1] == quant) { |
629 |
|
32670 |
quant = FFMAX(quant_buf[0], quant); |
630 |
✓✗ |
32670 |
bits = quant == quant_buf[0] ? bits_last : bits; |
631 |
|
32670 |
break; |
632 |
|
|
} |
633 |
|
65340 |
step = av_clip(step/2, 1, (s->q_ceil-1)/2); |
634 |
|
65340 |
quant_buf[1] = quant_buf[0]; |
635 |
|
65340 |
quant_buf[0] = quant; |
636 |
|
65340 |
bits_last = bits; |
637 |
|
|
} |
638 |
|
32670 |
slice_dat->quant_idx = av_clip(quant, 0, s->q_ceil-1); |
639 |
|
32670 |
slice_dat->bytes = SSIZE_ROUND(bits >> 3); |
640 |
|
32670 |
return 0; |
641 |
|
|
} |
642 |
|
|
|
643 |
|
165 |
static int calc_slice_sizes(VC2EncContext *s) |
644 |
|
|
{ |
645 |
|
165 |
int i, j, slice_x, slice_y, bytes_left = 0; |
646 |
|
165 |
int bytes_top[SLICE_REDIST_TOTAL] = {0}; |
647 |
|
165 |
int64_t total_bytes_needed = 0; |
648 |
|
165 |
int slice_redist_range = FFMIN(SLICE_REDIST_TOTAL, s->num_x*s->num_y); |
649 |
|
165 |
SliceArgs *enc_args = s->slice_args; |
650 |
|
165 |
SliceArgs *top_loc[SLICE_REDIST_TOTAL] = {NULL}; |
651 |
|
|
|
652 |
|
165 |
init_quant_matrix(s); |
653 |
|
|
|
654 |
✓✓ |
3135 |
for (slice_y = 0; slice_y < s->num_y; slice_y++) { |
655 |
✓✓ |
35640 |
for (slice_x = 0; slice_x < s->num_x; slice_x++) { |
656 |
|
32670 |
SliceArgs *args = &enc_args[s->num_x*slice_y + slice_x]; |
657 |
|
32670 |
args->ctx = s; |
658 |
|
32670 |
args->x = slice_x; |
659 |
|
32670 |
args->y = slice_y; |
660 |
|
32670 |
args->bits_ceil = s->slice_max_bytes << 3; |
661 |
|
32670 |
args->bits_floor = s->slice_min_bytes << 3; |
662 |
|
32670 |
memset(args->cache, 0, s->q_ceil*sizeof(*args->cache)); |
663 |
|
|
} |
664 |
|
|
} |
665 |
|
|
|
666 |
|
|
/* First pass - determine baseline slice sizes w.r.t. max_slice_size */ |
667 |
|
165 |
s->avctx->execute(s->avctx, rate_control, enc_args, NULL, s->num_x*s->num_y, |
668 |
|
|
sizeof(SliceArgs)); |
669 |
|
|
|
670 |
✓✓ |
32835 |
for (i = 0; i < s->num_x*s->num_y; i++) { |
671 |
|
32670 |
SliceArgs *args = &enc_args[i]; |
672 |
|
32670 |
bytes_left += args->bytes; |
673 |
✓✗ |
1155403 |
for (j = 0; j < slice_redist_range; j++) { |
674 |
✓✓ |
1155403 |
if (args->bytes > bytes_top[j]) { |
675 |
|
32670 |
bytes_top[j] = args->bytes; |
676 |
|
32670 |
top_loc[j] = args; |
677 |
|
32670 |
break; |
678 |
|
|
} |
679 |
|
|
} |
680 |
|
|
} |
681 |
|
|
|
682 |
|
165 |
bytes_left = s->frame_max_bytes - bytes_left; |
683 |
|
|
|
684 |
|
|
/* Second pass - distribute leftover bytes */ |
685 |
✓✗ |
165 |
while (bytes_left > 0) { |
686 |
|
165 |
int distributed = 0; |
687 |
✓✗ |
165 |
for (i = 0; i < slice_redist_range; i++) { |
688 |
|
|
SliceArgs *args; |
689 |
|
|
int bits, bytes, diff, prev_bytes, new_idx; |
690 |
✗✓ |
165 |
if (bytes_left <= 0) |
691 |
|
|
break; |
692 |
✓✗✗✓
|
165 |
if (!top_loc[i] || !top_loc[i]->quant_idx) |
693 |
|
|
break; |
694 |
|
|
args = top_loc[i]; |
695 |
|
|
prev_bytes = args->bytes; |
696 |
|
|
new_idx = FFMAX(args->quant_idx - 1, 0); |
697 |
|
|
bits = count_hq_slice(args, new_idx); |
698 |
|
|
bytes = SSIZE_ROUND(bits >> 3); |
699 |
|
|
diff = bytes - prev_bytes; |
700 |
|
|
if ((bytes_left - diff) > 0) { |
701 |
|
|
args->quant_idx = new_idx; |
702 |
|
|
args->bytes = bytes; |
703 |
|
|
bytes_left -= diff; |
704 |
|
|
distributed++; |
705 |
|
|
} |
706 |
|
|
} |
707 |
✓✗ |
165 |
if (!distributed) |
708 |
|
165 |
break; |
709 |
|
|
} |
710 |
|
|
|
711 |
✓✓ |
32835 |
for (i = 0; i < s->num_x*s->num_y; i++) { |
712 |
|
32670 |
SliceArgs *args = &enc_args[i]; |
713 |
|
32670 |
total_bytes_needed += args->bytes; |
714 |
|
32670 |
s->q_avg = (s->q_avg + args->quant_idx)/2; |
715 |
|
|
} |
716 |
|
|
|
717 |
|
165 |
return total_bytes_needed; |
718 |
|
|
} |
719 |
|
|
|
720 |
|
|
/* VC-2 13.5.3 - hq_slice */ |
721 |
|
32670 |
static int encode_hq_slice(AVCodecContext *avctx, void *arg) |
722 |
|
|
{ |
723 |
|
32670 |
SliceArgs *slice_dat = arg; |
724 |
|
32670 |
VC2EncContext *s = slice_dat->ctx; |
725 |
|
32670 |
PutBitContext *pb = &slice_dat->pb; |
726 |
|
32670 |
const int slice_x = slice_dat->x; |
727 |
|
32670 |
const int slice_y = slice_dat->y; |
728 |
|
32670 |
const int quant_idx = slice_dat->quant_idx; |
729 |
|
32670 |
const int slice_bytes_max = slice_dat->bytes; |
730 |
|
|
uint8_t quants[MAX_DWT_LEVELS][4]; |
731 |
|
|
int p, level, orientation; |
732 |
|
|
|
733 |
|
|
/* The reference decoder ignores it, and its typical length is 0 */ |
734 |
|
32670 |
memset(put_bits_ptr(pb), 0, s->prefix_bytes); |
735 |
|
32670 |
skip_put_bytes(pb, s->prefix_bytes); |
736 |
|
|
|
737 |
|
32670 |
put_bits(pb, 8, quant_idx); |
738 |
|
|
|
739 |
|
|
/* Slice quantization (slice_quantizers() in the specs) */ |
740 |
✓✓ |
163350 |
for (level = 0; level < s->wavelet_depth; level++) |
741 |
✓✓ |
555390 |
for (orientation = !!level; orientation < 4; orientation++) |
742 |
|
424710 |
quants[level][orientation] = FFMAX(quant_idx - s->quant[level][orientation], 0); |
743 |
|
|
|
744 |
|
|
/* Luma + 2 Chroma planes */ |
745 |
✓✓ |
130680 |
for (p = 0; p < 3; p++) { |
746 |
|
|
int bytes_start, bytes_len, pad_s, pad_c; |
747 |
|
98010 |
bytes_start = put_bits_count(pb) >> 3; |
748 |
|
98010 |
put_bits(pb, 8, 0); |
749 |
✓✓ |
490050 |
for (level = 0; level < s->wavelet_depth; level++) { |
750 |
✓✓ |
1666170 |
for (orientation = !!level; orientation < 4; orientation++) { |
751 |
|
1274130 |
encode_subband(s, pb, slice_x, slice_y, |
752 |
|
|
&s->plane[p].band[level][orientation], |
753 |
|
1274130 |
quants[level][orientation]); |
754 |
|
|
} |
755 |
|
|
} |
756 |
|
98010 |
align_put_bits(pb); |
757 |
|
98010 |
bytes_len = (put_bits_count(pb) >> 3) - bytes_start - 1; |
758 |
✓✓ |
98010 |
if (p == 2) { |
759 |
|
32670 |
int len_diff = slice_bytes_max - (put_bits_count(pb) >> 3); |
760 |
|
32670 |
pad_s = FFALIGN((bytes_len + len_diff), s->size_scaler)/s->size_scaler; |
761 |
|
32670 |
pad_c = (pad_s*s->size_scaler) - bytes_len; |
762 |
|
|
} else { |
763 |
|
65340 |
pad_s = FFALIGN(bytes_len, s->size_scaler)/s->size_scaler; |
764 |
|
65340 |
pad_c = (pad_s*s->size_scaler) - bytes_len; |
765 |
|
|
} |
766 |
|
98010 |
pb->buf[bytes_start] = pad_s; |
767 |
|
98010 |
flush_put_bits(pb); |
768 |
|
|
/* vc2-reference uses that padding that decodes to '0' coeffs */ |
769 |
|
98010 |
memset(put_bits_ptr(pb), 0xFF, pad_c); |
770 |
|
98010 |
skip_put_bytes(pb, pad_c); |
771 |
|
|
} |
772 |
|
|
|
773 |
|
32670 |
return 0; |
774 |
|
|
} |
775 |
|
|
|
776 |
|
|
/* VC-2 13.5.1 - low_delay_transform_data() */ |
777 |
|
165 |
static int encode_slices(VC2EncContext *s) |
778 |
|
|
{ |
779 |
|
|
uint8_t *buf; |
780 |
|
165 |
int slice_x, slice_y, skip = 0; |
781 |
|
165 |
SliceArgs *enc_args = s->slice_args; |
782 |
|
|
|
783 |
|
165 |
flush_put_bits(&s->pb); |
784 |
|
165 |
buf = put_bits_ptr(&s->pb); |
785 |
|
|
|
786 |
✓✓ |
3135 |
for (slice_y = 0; slice_y < s->num_y; slice_y++) { |
787 |
✓✓ |
35640 |
for (slice_x = 0; slice_x < s->num_x; slice_x++) { |
788 |
|
32670 |
SliceArgs *args = &enc_args[s->num_x*slice_y + slice_x]; |
789 |
|
32670 |
init_put_bits(&args->pb, buf + skip, args->bytes+s->prefix_bytes); |
790 |
|
32670 |
skip += args->bytes; |
791 |
|
|
} |
792 |
|
|
} |
793 |
|
|
|
794 |
|
165 |
s->avctx->execute(s->avctx, encode_hq_slice, enc_args, NULL, s->num_x*s->num_y, |
795 |
|
|
sizeof(SliceArgs)); |
796 |
|
|
|
797 |
|
165 |
skip_put_bytes(&s->pb, skip); |
798 |
|
|
|
799 |
|
165 |
return 0; |
800 |
|
|
} |
801 |
|
|
|
802 |
|
|
/* |
803 |
|
|
* Transform basics for a 3 level transform |
804 |
|
|
* |---------------------------------------------------------------------| |
805 |
|
|
* | LL-0 | HL-0 | | | |
806 |
|
|
* |--------|-------| HL-1 | | |
807 |
|
|
* | LH-0 | HH-0 | | | |
808 |
|
|
* |----------------|-----------------| HL-2 | |
809 |
|
|
* | | | | |
810 |
|
|
* | LH-1 | HH-1 | | |
811 |
|
|
* | | | | |
812 |
|
|
* |----------------------------------|----------------------------------| |
813 |
|
|
* | | | |
814 |
|
|
* | | | |
815 |
|
|
* | | | |
816 |
|
|
* | LH-2 | HH-2 | |
817 |
|
|
* | | | |
818 |
|
|
* | | | |
819 |
|
|
* | | | |
820 |
|
|
* |---------------------------------------------------------------------| |
821 |
|
|
* |
822 |
|
|
* DWT transforms are generally applied by splitting the image in two vertically |
823 |
|
|
* and applying a low pass transform on the left part and a corresponding high |
824 |
|
|
* pass transform on the right hand side. This is known as the horizontal filter |
825 |
|
|
* stage. |
826 |
|
|
* After that, the same operation is performed except the image is divided |
827 |
|
|
* horizontally, with the high pass on the lower and the low pass on the higher |
828 |
|
|
* side. |
829 |
|
|
* Therefore, you're left with 4 subdivisions - known as low-low, low-high, |
830 |
|
|
* high-low and high-high. They're referred to as orientations in the decoder |
831 |
|
|
* and encoder. |
832 |
|
|
* |
833 |
|
|
* The LL (low-low) area contains the original image downsampled by the amount |
834 |
|
|
* of levels. The rest of the areas can be thought as the details needed |
835 |
|
|
* to restore the image perfectly to its original size. |
836 |
|
|
*/ |
837 |
|
495 |
static int dwt_plane(AVCodecContext *avctx, void *arg) |
838 |
|
|
{ |
839 |
|
495 |
TransformArgs *transform_dat = arg; |
840 |
|
495 |
VC2EncContext *s = transform_dat->ctx; |
841 |
|
495 |
const void *frame_data = transform_dat->idata; |
842 |
|
495 |
const ptrdiff_t linesize = transform_dat->istride; |
843 |
|
495 |
const int field = transform_dat->field; |
844 |
|
495 |
const Plane *p = transform_dat->plane; |
845 |
|
495 |
VC2TransformContext *t = &transform_dat->t; |
846 |
|
495 |
dwtcoef *buf = p->coef_buf; |
847 |
|
495 |
const int idx = s->wavelet_idx; |
848 |
|
495 |
const int skip = 1 + s->interlaced; |
849 |
|
|
|
850 |
|
|
int x, y, level, offset; |
851 |
|
495 |
ptrdiff_t pix_stride = linesize >> (s->bpp - 1); |
852 |
|
|
|
853 |
✗✓ |
495 |
if (field == 1) { |
854 |
|
|
offset = 0; |
855 |
|
|
pix_stride <<= 1; |
856 |
✗✓ |
495 |
} else if (field == 2) { |
857 |
|
|
offset = pix_stride; |
858 |
|
|
pix_stride <<= 1; |
859 |
|
|
} else { |
860 |
|
495 |
offset = 0; |
861 |
|
|
} |
862 |
|
|
|
863 |
✓✓ |
495 |
if (s->bpp == 1) { |
864 |
|
135 |
const uint8_t *pix = (const uint8_t *)frame_data + offset; |
865 |
✓✓ |
34695 |
for (y = 0; y < p->height*skip; y+=skip) { |
866 |
✓✓ |
9918720 |
for (x = 0; x < p->width; x++) { |
867 |
|
9884160 |
buf[x] = pix[x] - s->diff_offset; |
868 |
|
|
} |
869 |
|
34560 |
memset(&buf[x], 0, (p->coef_stride - p->width)*sizeof(dwtcoef)); |
870 |
|
34560 |
buf += p->coef_stride; |
871 |
|
34560 |
pix += pix_stride; |
872 |
|
|
} |
873 |
|
|
} else { |
874 |
|
360 |
const uint16_t *pix = (const uint16_t *)frame_data + offset; |
875 |
✓✓ |
95400 |
for (y = 0; y < p->height*skip; y+=skip) { |
876 |
✓✓ |
25945920 |
for (x = 0; x < p->width; x++) { |
877 |
|
25850880 |
buf[x] = pix[x] - s->diff_offset; |
878 |
|
|
} |
879 |
|
95040 |
memset(&buf[x], 0, (p->coef_stride - p->width)*sizeof(dwtcoef)); |
880 |
|
95040 |
buf += p->coef_stride; |
881 |
|
95040 |
pix += pix_stride; |
882 |
|
|
} |
883 |
|
|
} |
884 |
|
|
|
885 |
|
495 |
memset(buf, 0, p->coef_stride * (p->dwt_height - p->height) * sizeof(dwtcoef)); |
886 |
|
|
|
887 |
✓✓ |
2475 |
for (level = s->wavelet_depth-1; level >= 0; level--) { |
888 |
|
1980 |
const SubBand *b = &p->band[level][0]; |
889 |
|
1980 |
t->vc2_subband_dwt[idx](t, p->coef_buf, p->coef_stride, |
890 |
|
|
b->width, b->height); |
891 |
|
|
} |
892 |
|
|
|
893 |
|
495 |
return 0; |
894 |
|
|
} |
895 |
|
|
|
896 |
|
165 |
static int encode_frame(VC2EncContext *s, AVPacket *avpkt, const AVFrame *frame, |
897 |
|
|
const char *aux_data, const int header_size, int field) |
898 |
|
|
{ |
899 |
|
|
int i, ret; |
900 |
|
|
int64_t max_frame_bytes; |
901 |
|
|
|
902 |
|
|
/* Threaded DWT transform */ |
903 |
✓✓ |
660 |
for (i = 0; i < 3; i++) { |
904 |
|
495 |
s->transform_args[i].ctx = s; |
905 |
|
495 |
s->transform_args[i].field = field; |
906 |
|
495 |
s->transform_args[i].plane = &s->plane[i]; |
907 |
|
495 |
s->transform_args[i].idata = frame->data[i]; |
908 |
|
495 |
s->transform_args[i].istride = frame->linesize[i]; |
909 |
|
|
} |
910 |
|
165 |
s->avctx->execute(s->avctx, dwt_plane, s->transform_args, NULL, 3, |
911 |
|
|
sizeof(TransformArgs)); |
912 |
|
|
|
913 |
|
|
/* Calculate per-slice quantizers and sizes */ |
914 |
|
165 |
max_frame_bytes = header_size + calc_slice_sizes(s); |
915 |
|
|
|
916 |
✓✗ |
165 |
if (field < 2) { |
917 |
|
165 |
ret = ff_alloc_packet2(s->avctx, avpkt, |
918 |
|
165 |
max_frame_bytes << s->interlaced, |
919 |
|
165 |
max_frame_bytes << s->interlaced); |
920 |
✗✓ |
165 |
if (ret) { |
921 |
|
|
av_log(s->avctx, AV_LOG_ERROR, "Error getting output packet.\n"); |
922 |
|
|
return ret; |
923 |
|
|
} |
924 |
|
165 |
init_put_bits(&s->pb, avpkt->data, avpkt->size); |
925 |
|
|
} |
926 |
|
|
|
927 |
|
|
/* Sequence header */ |
928 |
|
165 |
encode_parse_info(s, DIRAC_PCODE_SEQ_HEADER); |
929 |
|
165 |
encode_seq_header(s); |
930 |
|
|
|
931 |
|
|
/* Encoder version */ |
932 |
✓✗ |
165 |
if (aux_data) { |
933 |
|
165 |
encode_parse_info(s, DIRAC_PCODE_AUX); |
934 |
|
165 |
ff_put_string(&s->pb, aux_data, 1); |
935 |
|
|
} |
936 |
|
|
|
937 |
|
|
/* Picture header */ |
938 |
|
165 |
encode_parse_info(s, DIRAC_PCODE_PICTURE_HQ); |
939 |
|
165 |
encode_picture_start(s); |
940 |
|
|
|
941 |
|
|
/* Encode slices */ |
942 |
|
165 |
encode_slices(s); |
943 |
|
|
|
944 |
|
|
/* End sequence */ |
945 |
|
165 |
encode_parse_info(s, DIRAC_PCODE_END_SEQ); |
946 |
|
|
|
947 |
|
165 |
return 0; |
948 |
|
|
} |
949 |
|
|
|
950 |
|
165 |
static av_cold int vc2_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, |
951 |
|
|
const AVFrame *frame, int *got_packet) |
952 |
|
|
{ |
953 |
|
165 |
int ret = 0; |
954 |
|
165 |
int slice_ceil, sig_size = 256; |
955 |
|
165 |
VC2EncContext *s = avctx->priv_data; |
956 |
|
165 |
const int bitexact = avctx->flags & AV_CODEC_FLAG_BITEXACT; |
957 |
✓✗ |
165 |
const char *aux_data = bitexact ? "Lavc" : LIBAVCODEC_IDENT; |
958 |
✓✗ |
165 |
const int aux_data_size = bitexact ? sizeof("Lavc") : sizeof(LIBAVCODEC_IDENT); |
959 |
|
165 |
const int header_size = 100 + aux_data_size; |
960 |
|
165 |
int64_t r_bitrate = avctx->bit_rate >> (s->interlaced); |
961 |
|
|
|
962 |
|
165 |
s->avctx = avctx; |
963 |
|
165 |
s->size_scaler = 2; |
964 |
|
165 |
s->prefix_bytes = 0; |
965 |
|
165 |
s->last_parse_code = 0; |
966 |
|
165 |
s->next_parse_offset = 0; |
967 |
|
|
|
968 |
|
|
/* Rate control */ |
969 |
|
165 |
s->frame_max_bytes = (av_rescale(r_bitrate, s->avctx->time_base.num, |
970 |
|
165 |
s->avctx->time_base.den) >> 3) - header_size; |
971 |
|
165 |
s->slice_max_bytes = slice_ceil = av_rescale(s->frame_max_bytes, 1, s->num_x*s->num_y); |
972 |
|
|
|
973 |
|
|
/* Find an appropriate size scaler */ |
974 |
✓✓ |
1155 |
while (sig_size > 255) { |
975 |
|
990 |
int r_size = SSIZE_ROUND(s->slice_max_bytes); |
976 |
✓✓ |
990 |
if (r_size > slice_ceil) { |
977 |
|
825 |
s->slice_max_bytes -= r_size - slice_ceil; |
978 |
|
825 |
r_size = SSIZE_ROUND(s->slice_max_bytes); |
979 |
|
|
} |
980 |
|
990 |
sig_size = r_size/s->size_scaler; /* Signalled slize size */ |
981 |
|
990 |
s->size_scaler <<= 1; |
982 |
|
|
} |
983 |
|
|
|
984 |
|
165 |
s->slice_min_bytes = s->slice_max_bytes - s->slice_max_bytes*(s->tolerance/100.0f); |
985 |
|
|
|
986 |
|
165 |
ret = encode_frame(s, avpkt, frame, aux_data, header_size, s->interlaced); |
987 |
✗✓ |
165 |
if (ret) |
988 |
|
|
return ret; |
989 |
✗✓ |
165 |
if (s->interlaced) { |
990 |
|
|
ret = encode_frame(s, avpkt, frame, aux_data, header_size, 2); |
991 |
|
|
if (ret) |
992 |
|
|
return ret; |
993 |
|
|
} |
994 |
|
|
|
995 |
|
165 |
flush_put_bits(&s->pb); |
996 |
|
165 |
avpkt->size = put_bits_count(&s->pb) >> 3; |
997 |
|
|
|
998 |
|
165 |
*got_packet = 1; |
999 |
|
|
|
1000 |
|
165 |
return 0; |
1001 |
|
|
} |
1002 |
|
|
|
1003 |
|
33 |
static av_cold int vc2_encode_end(AVCodecContext *avctx) |
1004 |
|
|
{ |
1005 |
|
|
int i; |
1006 |
|
33 |
VC2EncContext *s = avctx->priv_data; |
1007 |
|
|
|
1008 |
|
33 |
av_log(avctx, AV_LOG_INFO, "Qavg: %i\n", s->q_avg); |
1009 |
|
|
|
1010 |
✓✓ |
132 |
for (i = 0; i < 3; i++) { |
1011 |
|
99 |
ff_vc2enc_free_transforms(&s->transform_args[i].t); |
1012 |
|
99 |
av_freep(&s->plane[i].coef_buf); |
1013 |
|
|
} |
1014 |
|
|
|
1015 |
|
33 |
av_freep(&s->slice_args); |
1016 |
|
|
|
1017 |
|
33 |
return 0; |
1018 |
|
|
} |
1019 |
|
|
|
1020 |
|
33 |
static av_cold int vc2_encode_init(AVCodecContext *avctx) |
1021 |
|
|
{ |
1022 |
|
|
Plane *p; |
1023 |
|
|
SubBand *b; |
1024 |
|
|
int i, level, o, shift, ret; |
1025 |
|
33 |
const AVPixFmtDescriptor *fmt = av_pix_fmt_desc_get(avctx->pix_fmt); |
1026 |
|
33 |
const int depth = fmt->comp[0].depth; |
1027 |
|
33 |
VC2EncContext *s = avctx->priv_data; |
1028 |
|
|
|
1029 |
|
33 |
s->picture_number = 0; |
1030 |
|
|
|
1031 |
|
|
/* Total allowed quantization range */ |
1032 |
|
33 |
s->q_ceil = DIRAC_MAX_QUANT_INDEX; |
1033 |
|
|
|
1034 |
|
33 |
s->ver.major = 2; |
1035 |
|
33 |
s->ver.minor = 0; |
1036 |
|
33 |
s->profile = 3; |
1037 |
|
33 |
s->level = 3; |
1038 |
|
|
|
1039 |
|
33 |
s->base_vf = -1; |
1040 |
|
33 |
s->strict_compliance = 1; |
1041 |
|
|
|
1042 |
|
33 |
s->q_avg = 0; |
1043 |
|
33 |
s->slice_max_bytes = 0; |
1044 |
|
33 |
s->slice_min_bytes = 0; |
1045 |
|
|
|
1046 |
|
|
/* Mark unknown as progressive */ |
1047 |
✓✗ |
66 |
s->interlaced = !((avctx->field_order == AV_FIELD_UNKNOWN) || |
1048 |
✗✓ |
33 |
(avctx->field_order == AV_FIELD_PROGRESSIVE)); |
1049 |
|
|
|
1050 |
✓✓ |
792 |
for (i = 0; i < base_video_fmts_len; i++) { |
1051 |
|
759 |
const VC2BaseVideoFormat *fmt = &base_video_fmts[i]; |
1052 |
✓✓ |
759 |
if (avctx->pix_fmt != fmt->pix_fmt) |
1053 |
|
606 |
continue; |
1054 |
✓✓ |
153 |
if (avctx->time_base.num != fmt->time_base.num) |
1055 |
|
93 |
continue; |
1056 |
✓✓ |
60 |
if (avctx->time_base.den != fmt->time_base.den) |
1057 |
|
42 |
continue; |
1058 |
✓✗ |
18 |
if (avctx->width != fmt->width) |
1059 |
|
18 |
continue; |
1060 |
|
|
if (avctx->height != fmt->height) |
1061 |
|
|
continue; |
1062 |
|
|
if (s->interlaced != fmt->interlaced) |
1063 |
|
|
continue; |
1064 |
|
|
s->base_vf = i; |
1065 |
|
|
s->level = base_video_fmts[i].level; |
1066 |
|
|
break; |
1067 |
|
|
} |
1068 |
|
|
|
1069 |
✗✓ |
33 |
if (s->interlaced) |
1070 |
|
|
av_log(avctx, AV_LOG_WARNING, "Interlacing enabled!\n"); |
1071 |
|
|
|
1072 |
✓✗ |
33 |
if ((s->slice_width & (s->slice_width - 1)) || |
1073 |
✗✓ |
33 |
(s->slice_height & (s->slice_height - 1))) { |
1074 |
|
|
av_log(avctx, AV_LOG_ERROR, "Slice size is not a power of two!\n"); |
1075 |
|
|
return AVERROR_UNKNOWN; |
1076 |
|
|
} |
1077 |
|
|
|
1078 |
✓✗ |
33 |
if ((s->slice_width > avctx->width) || |
1079 |
✗✓ |
33 |
(s->slice_height > avctx->height)) { |
1080 |
|
|
av_log(avctx, AV_LOG_ERROR, "Slice size is bigger than the image!\n"); |
1081 |
|
|
return AVERROR_UNKNOWN; |
1082 |
|
|
} |
1083 |
|
|
|
1084 |
✓✗ |
33 |
if (s->base_vf <= 0) { |
1085 |
✓✗ |
33 |
if (avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) { |
1086 |
|
33 |
s->strict_compliance = s->base_vf = 0; |
1087 |
|
33 |
av_log(avctx, AV_LOG_WARNING, "Format does not strictly comply with VC2 specs\n"); |
1088 |
|
|
} else { |
1089 |
|
|
av_log(avctx, AV_LOG_WARNING, "Given format does not strictly comply with " |
1090 |
|
|
"the specifications, decrease strictness to use it.\n"); |
1091 |
|
|
return AVERROR_UNKNOWN; |
1092 |
|
|
} |
1093 |
|
|
} else { |
1094 |
|
|
av_log(avctx, AV_LOG_INFO, "Selected base video format = %i (%s)\n", |
1095 |
|
|
s->base_vf, base_video_fmts[s->base_vf].name); |
1096 |
|
|
} |
1097 |
|
|
|
1098 |
|
|
/* Chroma subsampling */ |
1099 |
|
33 |
ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift); |
1100 |
✗✓ |
33 |
if (ret) |
1101 |
|
|
return ret; |
1102 |
|
|
|
1103 |
|
|
/* Bit depth and color range index */ |
1104 |
✓✓✗✓
|
33 |
if (depth == 8 && avctx->color_range == AVCOL_RANGE_JPEG) { |
1105 |
|
|
s->bpp = 1; |
1106 |
|
|
s->bpp_idx = 1; |
1107 |
|
|
s->diff_offset = 128; |
1108 |
✓✓✓✓
|
33 |
} else if (depth == 8 && (avctx->color_range == AVCOL_RANGE_MPEG || |
1109 |
✓✗ |
3 |
avctx->color_range == AVCOL_RANGE_UNSPECIFIED)) { |
1110 |
|
9 |
s->bpp = 1; |
1111 |
|
9 |
s->bpp_idx = 2; |
1112 |
|
9 |
s->diff_offset = 128; |
1113 |
✓✓ |
24 |
} else if (depth == 10) { |
1114 |
|
15 |
s->bpp = 2; |
1115 |
|
15 |
s->bpp_idx = 3; |
1116 |
|
15 |
s->diff_offset = 512; |
1117 |
|
|
} else { |
1118 |
|
9 |
s->bpp = 2; |
1119 |
|
9 |
s->bpp_idx = 4; |
1120 |
|
9 |
s->diff_offset = 2048; |
1121 |
|
|
} |
1122 |
|
|
|
1123 |
|
|
/* Planes initialization */ |
1124 |
✓✓ |
132 |
for (i = 0; i < 3; i++) { |
1125 |
|
|
int w, h; |
1126 |
|
99 |
p = &s->plane[i]; |
1127 |
✓✓ |
99 |
p->width = avctx->width >> (i ? s->chroma_x_shift : 0); |
1128 |
✓✓ |
99 |
p->height = avctx->height >> (i ? s->chroma_y_shift : 0); |
1129 |
✗✓ |
99 |
if (s->interlaced) |
1130 |
|
|
p->height >>= 1; |
1131 |
|
99 |
p->dwt_width = w = FFALIGN(p->width, (1 << s->wavelet_depth)); |
1132 |
|
99 |
p->dwt_height = h = FFALIGN(p->height, (1 << s->wavelet_depth)); |
1133 |
|
99 |
p->coef_stride = FFALIGN(p->dwt_width, 32); |
1134 |
|
99 |
p->coef_buf = av_mallocz(p->coef_stride*p->dwt_height*sizeof(dwtcoef)); |
1135 |
✗✓ |
99 |
if (!p->coef_buf) |
1136 |
|
|
goto alloc_fail; |
1137 |
✓✓ |
495 |
for (level = s->wavelet_depth-1; level >= 0; level--) { |
1138 |
|
396 |
w = w >> 1; |
1139 |
|
396 |
h = h >> 1; |
1140 |
✓✓ |
1980 |
for (o = 0; o < 4; o++) { |
1141 |
|
1584 |
b = &p->band[level][o]; |
1142 |
|
1584 |
b->width = w; |
1143 |
|
1584 |
b->height = h; |
1144 |
|
1584 |
b->stride = p->coef_stride; |
1145 |
|
1584 |
shift = (o > 1)*b->height*b->stride + (o & 1)*b->width; |
1146 |
|
1584 |
b->buf = p->coef_buf + shift; |
1147 |
|
|
} |
1148 |
|
|
} |
1149 |
|
|
|
1150 |
|
|
/* DWT init */ |
1151 |
✗✓ |
99 |
if (ff_vc2enc_init_transforms(&s->transform_args[i].t, |
1152 |
|
99 |
s->plane[i].coef_stride, |
1153 |
|
|
s->plane[i].dwt_height, |
1154 |
|
|
s->slice_width, s->slice_height)) |
1155 |
|
|
goto alloc_fail; |
1156 |
|
|
} |
1157 |
|
|
|
1158 |
|
|
/* Slices */ |
1159 |
|
33 |
s->num_x = s->plane[0].dwt_width/s->slice_width; |
1160 |
|
33 |
s->num_y = s->plane[0].dwt_height/s->slice_height; |
1161 |
|
|
|
1162 |
|
33 |
s->slice_args = av_calloc(s->num_x*s->num_y, sizeof(SliceArgs)); |
1163 |
✗✓ |
33 |
if (!s->slice_args) |
1164 |
|
|
goto alloc_fail; |
1165 |
|
|
|
1166 |
✓✓ |
3861 |
for (i = 0; i < 116; i++) { |
1167 |
|
3828 |
const uint64_t qf = ff_dirac_qscale_tab[i]; |
1168 |
|
3828 |
const uint32_t m = av_log2(qf); |
1169 |
|
3828 |
const uint32_t t = (1ULL << (m + 32)) / qf; |
1170 |
|
3828 |
const uint32_t r = (t*qf + qf) & UINT32_MAX; |
1171 |
✓✓ |
3828 |
if (!(qf & (qf - 1))) { |
1172 |
|
957 |
s->qmagic_lut[i][0] = 0xFFFFFFFF; |
1173 |
|
957 |
s->qmagic_lut[i][1] = 0xFFFFFFFF; |
1174 |
✓✓ |
2871 |
} else if (r <= 1 << m) { |
1175 |
|
2145 |
s->qmagic_lut[i][0] = t + 1; |
1176 |
|
2145 |
s->qmagic_lut[i][1] = 0; |
1177 |
|
|
} else { |
1178 |
|
726 |
s->qmagic_lut[i][0] = t; |
1179 |
|
726 |
s->qmagic_lut[i][1] = t; |
1180 |
|
|
} |
1181 |
|
|
} |
1182 |
|
|
|
1183 |
|
33 |
return 0; |
1184 |
|
|
|
1185 |
|
|
alloc_fail: |
1186 |
|
|
vc2_encode_end(avctx); |
1187 |
|
|
av_log(avctx, AV_LOG_ERROR, "Unable to allocate memory!\n"); |
1188 |
|
|
return AVERROR(ENOMEM); |
1189 |
|
|
} |
1190 |
|
|
|
1191 |
|
|
#define VC2ENC_FLAGS (AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM) |
1192 |
|
|
static const AVOption vc2enc_options[] = { |
1193 |
|
|
{"tolerance", "Max undershoot in percent", offsetof(VC2EncContext, tolerance), AV_OPT_TYPE_DOUBLE, {.dbl = 5.0f}, 0.0f, 45.0f, VC2ENC_FLAGS, "tolerance"}, |
1194 |
|
|
{"slice_width", "Slice width", offsetof(VC2EncContext, slice_width), AV_OPT_TYPE_INT, {.i64 = 32}, 32, 1024, VC2ENC_FLAGS, "slice_width"}, |
1195 |
|
|
{"slice_height", "Slice height", offsetof(VC2EncContext, slice_height), AV_OPT_TYPE_INT, {.i64 = 16}, 8, 1024, VC2ENC_FLAGS, "slice_height"}, |
1196 |
|
|
{"wavelet_depth", "Transform depth", offsetof(VC2EncContext, wavelet_depth), AV_OPT_TYPE_INT, {.i64 = 4}, 1, 5, VC2ENC_FLAGS, "wavelet_depth"}, |
1197 |
|
|
{"wavelet_type", "Transform type", offsetof(VC2EncContext, wavelet_idx), AV_OPT_TYPE_INT, {.i64 = VC2_TRANSFORM_9_7}, 0, VC2_TRANSFORMS_NB, VC2ENC_FLAGS, "wavelet_idx"}, |
1198 |
|
|
{"9_7", "Deslauriers-Dubuc (9,7)", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_TRANSFORM_9_7}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "wavelet_idx"}, |
1199 |
|
|
{"5_3", "LeGall (5,3)", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_TRANSFORM_5_3}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "wavelet_idx"}, |
1200 |
|
|
{"haar", "Haar (with shift)", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_TRANSFORM_HAAR_S}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "wavelet_idx"}, |
1201 |
|
|
{"haar_noshift", "Haar (without shift)", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_TRANSFORM_HAAR}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "wavelet_idx"}, |
1202 |
|
|
{"qm", "Custom quantization matrix", offsetof(VC2EncContext, quant_matrix), AV_OPT_TYPE_INT, {.i64 = VC2_QM_DEF}, 0, VC2_QM_NB, VC2ENC_FLAGS, "quant_matrix"}, |
1203 |
|
|
{"default", "Default from the specifications", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_QM_DEF}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "quant_matrix"}, |
1204 |
|
|
{"color", "Prevents low bitrate discoloration", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_QM_COL}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "quant_matrix"}, |
1205 |
|
|
{"flat", "Optimize for PSNR", 0, AV_OPT_TYPE_CONST, {.i64 = VC2_QM_FLAT}, INT_MIN, INT_MAX, VC2ENC_FLAGS, "quant_matrix"}, |
1206 |
|
|
{NULL} |
1207 |
|
|
}; |
1208 |
|
|
|
1209 |
|
|
static const AVClass vc2enc_class = { |
1210 |
|
|
.class_name = "SMPTE VC-2 encoder", |
1211 |
|
|
.category = AV_CLASS_CATEGORY_ENCODER, |
1212 |
|
|
.option = vc2enc_options, |
1213 |
|
|
.item_name = av_default_item_name, |
1214 |
|
|
.version = LIBAVUTIL_VERSION_INT |
1215 |
|
|
}; |
1216 |
|
|
|
1217 |
|
|
static const AVCodecDefault vc2enc_defaults[] = { |
1218 |
|
|
{ "b", "600000000" }, |
1219 |
|
|
{ NULL }, |
1220 |
|
|
}; |
1221 |
|
|
|
1222 |
|
|
static const enum AVPixelFormat allowed_pix_fmts[] = { |
1223 |
|
|
AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, |
1224 |
|
|
AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, |
1225 |
|
|
AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, |
1226 |
|
|
AV_PIX_FMT_NONE |
1227 |
|
|
}; |
1228 |
|
|
|
1229 |
|
|
AVCodec ff_vc2_encoder = { |
1230 |
|
|
.name = "vc2", |
1231 |
|
|
.long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-2"), |
1232 |
|
|
.type = AVMEDIA_TYPE_VIDEO, |
1233 |
|
|
.id = AV_CODEC_ID_DIRAC, |
1234 |
|
|
.priv_data_size = sizeof(VC2EncContext), |
1235 |
|
|
.init = vc2_encode_init, |
1236 |
|
|
.close = vc2_encode_end, |
1237 |
|
|
.capabilities = AV_CODEC_CAP_SLICE_THREADS, |
1238 |
|
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, |
1239 |
|
|
.encode2 = vc2_encode_frame, |
1240 |
|
|
.priv_class = &vc2enc_class, |
1241 |
|
|
.defaults = vc2enc_defaults, |
1242 |
|
|
.pix_fmts = allowed_pix_fmts |
1243 |
|
|
}; |