/src/ffmpeg/libavcodec/hq_hqa.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Canopus HQ/HQA decoder |
3 | | * |
4 | | * This file is part of FFmpeg. |
5 | | * |
6 | | * FFmpeg is free software; you can redistribute it and/or |
7 | | * modify it under the terms of the GNU Lesser General Public |
8 | | * License as published by the Free Software Foundation; either |
9 | | * version 2.1 of the License, or (at your option) any later version. |
10 | | * |
11 | | * FFmpeg is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | | * Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with FFmpeg; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | */ |
20 | | |
21 | | #include <stdint.h> |
22 | | |
23 | | #include "libavutil/attributes.h" |
24 | | #include "libavutil/mem_internal.h" |
25 | | #include "libavutil/thread.h" |
26 | | |
27 | | #include "avcodec.h" |
28 | | #include "bytestream.h" |
29 | | #include "canopus.h" |
30 | | #include "codec_internal.h" |
31 | | #include "decode.h" |
32 | | #include "get_bits.h" |
33 | | #include "hq_common.h" |
34 | | #include "hq_hqadata.h" |
35 | | #include "hq_hqadsp.h" |
36 | | #include "vlc.h" |
37 | | |
38 | | /* HQ/HQA slices are a set of macroblocks belonging to a frame, and |
39 | | * they usually form a pseudorandom pattern (probably because it is |
40 | | * nicer to display on partial decode). |
41 | | * |
42 | | * For HQA it just happens that each slice is on every 8th macroblock, |
43 | | * but they can be on any frame width like |
44 | | * X.......X. |
45 | | * ......X... |
46 | | * ....X..... |
47 | | * ..X....... |
48 | | * etc. |
49 | | * |
50 | | * The original decoder has special handling for edge macroblocks, |
51 | | * while lavc simply aligns coded_width and coded_height. |
52 | | */ |
53 | | |
54 | | typedef struct HQContext { |
55 | | AVCodecContext *avctx; |
56 | | HQDSPContext hqhqadsp; |
57 | | |
58 | | DECLARE_ALIGNED(16, int16_t, block)[12][64]; |
59 | | } HQContext; |
60 | | |
61 | | static const int32_t *hq_quants[NUM_HQ_QUANTS][2][4]; |
62 | | |
63 | | static RL_VLC_ELEM hq_ac_rvlc[1184]; |
64 | | |
65 | | static inline void put_blocks(HQContext *c, AVFrame *pic, |
66 | | int plane, int x, int y, int ilace, |
67 | | int16_t *block0, int16_t *block1) |
68 | 2.44M | { |
69 | 2.44M | uint8_t *p = pic->data[plane] + x; |
70 | | |
71 | 2.44M | c->hqhqadsp.idct_put(p + y * pic->linesize[plane], |
72 | 2.44M | pic->linesize[plane] << ilace, block0); |
73 | 2.44M | c->hqhqadsp.idct_put(p + (y + (ilace ? 1 : 8)) * pic->linesize[plane], |
74 | 2.44M | pic->linesize[plane] << ilace, block1); |
75 | 2.44M | } |
76 | | |
77 | | static int hq_decode_block(HQContext *c, GetBitContext *gb, int16_t block[64], |
78 | | int qsel, int is_chroma, int is_hqa) |
79 | 4.84M | { |
80 | 4.84M | const int32_t *q; |
81 | | |
82 | 4.84M | if (!is_hqa) { |
83 | 4.61M | block[0] = get_sbits(gb, 9) * 64; |
84 | 4.61M | q = hq_quants[qsel][is_chroma][get_bits(gb, 2)]; |
85 | 4.61M | } else { |
86 | 230k | q = hq_quants[qsel][is_chroma][get_bits(gb, 2)]; |
87 | 230k | block[0] = get_sbits(gb, 9) * 64; |
88 | 230k | } |
89 | | |
90 | 4.84M | OPEN_READER(re, gb); |
91 | 307M | for (int pos = 0;;) { |
92 | 307M | int level, run; |
93 | 307M | UPDATE_CACHE(re, gb); |
94 | 307M | GET_RL_VLC(level, run, re, gb, hq_ac_rvlc, 9, 2, 0); |
95 | 307M | if (run == HQ_AC_INVALID_RUN) { |
96 | 428 | CLOSE_READER(re, gb); |
97 | 428 | return AVERROR_INVALIDDATA; |
98 | 428 | } |
99 | | |
100 | 307M | pos += run; |
101 | 307M | if (pos >= 64) |
102 | 4.84M | break; |
103 | 302M | block[ff_zigzag_direct[pos]] = (int)(level * (unsigned)q[pos]) >> 12; |
104 | 302M | } |
105 | 4.84M | CLOSE_READER(re, gb); |
106 | | |
107 | 4.84M | return 0; |
108 | 4.84M | } |
109 | | |
110 | | static int hq_decode_mb(HQContext *c, AVFrame *pic, |
111 | | GetBitContext *gb, int x, int y) |
112 | 577k | { |
113 | 577k | int qgroup, flag; |
114 | 577k | int i, ret; |
115 | | |
116 | 577k | memset(c->block, 0, 8 * sizeof(c->block[0])); |
117 | | |
118 | 577k | qgroup = get_bits(gb, 4); |
119 | 577k | flag = get_bits1(gb); |
120 | | |
121 | 5.19M | for (i = 0; i < 8; i++) { |
122 | 4.61M | ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 4, 0); |
123 | 4.61M | if (ret < 0) |
124 | 220 | return ret; |
125 | 4.61M | } |
126 | | |
127 | 577k | put_blocks(c, pic, 0, x, y, flag, c->block[0], c->block[2]); |
128 | 577k | put_blocks(c, pic, 0, x + 8, y, flag, c->block[1], c->block[3]); |
129 | 577k | put_blocks(c, pic, 2, x >> 1, y, flag, c->block[4], c->block[5]); |
130 | 577k | put_blocks(c, pic, 1, x >> 1, y, flag, c->block[6], c->block[7]); |
131 | | |
132 | 577k | return 0; |
133 | 577k | } |
134 | | |
135 | | static int hq_decode_frame(HQContext *ctx, AVFrame *pic, GetByteContext *gbc, |
136 | | int prof_num, size_t data_size) |
137 | 52.3k | { |
138 | 52.3k | const HQProfile *profile; |
139 | 52.3k | GetBitContext gb; |
140 | 52.3k | const uint8_t *perm, *src = gbc->buffer; |
141 | 52.3k | uint32_t slice_off[21]; |
142 | 52.3k | int slice, start_off, next_off, i, ret; |
143 | | |
144 | 52.3k | if ((unsigned)prof_num >= NUM_HQ_PROFILES) { |
145 | 2.01k | profile = &hq_profile[0]; |
146 | 2.01k | avpriv_request_sample(ctx->avctx, "HQ Profile %d", prof_num); |
147 | 50.3k | } else { |
148 | 50.3k | profile = &hq_profile[prof_num]; |
149 | 50.3k | av_log(ctx->avctx, AV_LOG_VERBOSE, "HQ Profile %d\n", prof_num); |
150 | 50.3k | } |
151 | | |
152 | 52.3k | if (bytestream2_get_bytes_left(gbc) < 3 * (profile->num_slices + 1)) |
153 | 3.01k | return AVERROR_INVALIDDATA; |
154 | | |
155 | 49.3k | ctx->avctx->coded_width = FFALIGN(profile->width, 16); |
156 | 49.3k | ctx->avctx->coded_height = FFALIGN(profile->height, 16); |
157 | 49.3k | ctx->avctx->width = profile->width; |
158 | 49.3k | ctx->avctx->height = profile->height; |
159 | 49.3k | ctx->avctx->bits_per_raw_sample = 8; |
160 | 49.3k | ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P; |
161 | | |
162 | 49.3k | ret = ff_get_buffer(ctx->avctx, pic, 0); |
163 | 49.3k | if (ret < 0) |
164 | 0 | return ret; |
165 | | |
166 | | /* Offsets are stored from CUV position, so adjust them accordingly. */ |
167 | 493k | for (i = 0; i < profile->num_slices + 1; i++) |
168 | 444k | slice_off[i] = bytestream2_get_be24u(gbc) - 4; |
169 | | |
170 | 49.3k | next_off = 0; |
171 | 52.8k | for (slice = 0; slice < profile->num_slices; slice++) { |
172 | 52.8k | start_off = next_off; |
173 | 52.8k | next_off = profile->tab_h * (slice + 1) / profile->num_slices; |
174 | 52.8k | perm = profile->perm_tab + start_off * profile->tab_w * 2; |
175 | | |
176 | 52.8k | if (slice_off[slice] < (profile->num_slices + 1) * 3 || |
177 | 52.8k | slice_off[slice] >= slice_off[slice + 1] || |
178 | 52.8k | slice_off[slice + 1] > data_size) { |
179 | 49.0k | av_log(ctx->avctx, AV_LOG_ERROR, |
180 | 49.0k | "Invalid slice size %"SIZE_SPECIFIER".\n", data_size); |
181 | 49.0k | break; |
182 | 49.0k | } |
183 | 3.78k | init_get_bits(&gb, src + slice_off[slice], |
184 | 3.78k | (slice_off[slice + 1] - slice_off[slice]) * 8); |
185 | | |
186 | 580k | for (i = 0; i < (next_off - start_off) * profile->tab_w; i++) { |
187 | 577k | ret = hq_decode_mb(ctx, pic, &gb, perm[0] * 16, perm[1] * 16); |
188 | 577k | if (ret < 0) { |
189 | 220 | av_log(ctx->avctx, AV_LOG_ERROR, |
190 | 220 | "Error decoding macroblock %d at slice %d.\n", i, slice); |
191 | 220 | return ret; |
192 | 220 | } |
193 | 577k | perm += 2; |
194 | 577k | } |
195 | 3.78k | } |
196 | | |
197 | 49.1k | return 0; |
198 | 49.3k | } |
199 | | |
200 | | static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup, |
201 | | GetBitContext *gb, int x, int y) |
202 | 23.8k | { |
203 | 23.8k | int flag = 0; |
204 | 23.8k | int i, ret; |
205 | | |
206 | 23.8k | if (get_bits_left(gb) < 1) |
207 | 978 | return AVERROR_INVALIDDATA; |
208 | | |
209 | 22.9k | memset(c->block, 0, 12 * sizeof(c->block[0])); |
210 | 297k | for (i = 0; i < 12; i++) |
211 | 274k | c->block[i][0] = -128 * (1 << 6); |
212 | | |
213 | 22.9k | int cbp = get_vlc2(gb, ff_hq_cbp_vlc, HQ_CBP_VLC_BITS, 1); |
214 | 22.9k | if (cbp) { |
215 | 20.6k | flag = get_bits1(gb); |
216 | | |
217 | 20.6k | if (cbp & 0x3) |
218 | 19.2k | cbp |= 0x500; |
219 | 20.6k | if (cbp & 0xC) |
220 | 19.9k | cbp |= 0xA00; |
221 | 267k | for (i = 0; i < 12; i++) { |
222 | 246k | if (!(cbp & (1 << i))) |
223 | 16.2k | continue; |
224 | 230k | ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 8, 1); |
225 | 230k | if (ret < 0) |
226 | 208 | return ret; |
227 | 230k | } |
228 | 20.6k | } |
229 | | |
230 | 22.6k | put_blocks(c, pic, 3, x, y, flag, c->block[ 0], c->block[ 2]); |
231 | 22.6k | put_blocks(c, pic, 3, x + 8, y, flag, c->block[ 1], c->block[ 3]); |
232 | 22.6k | put_blocks(c, pic, 0, x, y, flag, c->block[ 4], c->block[ 6]); |
233 | 22.6k | put_blocks(c, pic, 0, x + 8, y, flag, c->block[ 5], c->block[ 7]); |
234 | 22.6k | put_blocks(c, pic, 2, x >> 1, y, flag, c->block[ 8], c->block[ 9]); |
235 | 22.6k | put_blocks(c, pic, 1, x >> 1, y, flag, c->block[10], c->block[11]); |
236 | | |
237 | 22.6k | return 0; |
238 | 22.9k | } |
239 | | |
240 | | static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb, |
241 | | int quant, int slice_no, int w, int h) |
242 | 2.76k | { |
243 | 2.76k | int i, j, off; |
244 | 2.76k | int ret; |
245 | | |
246 | 21.1k | for (i = 0; i < h; i += 16) { |
247 | 19.6k | off = (slice_no * 16 + i * 3) & 0x70; |
248 | 42.3k | for (j = off; j < w; j += 128) { |
249 | 23.8k | ret = hqa_decode_mb(ctx, pic, quant, gb, j, i); |
250 | 23.8k | if (ret < 0) { |
251 | 1.18k | av_log(ctx->avctx, AV_LOG_ERROR, |
252 | 1.18k | "Error decoding macroblock at %dx%d.\n", i, j); |
253 | 1.18k | return ret; |
254 | 1.18k | } |
255 | 23.8k | } |
256 | 19.6k | } |
257 | | |
258 | 1.58k | return 0; |
259 | 2.76k | } |
260 | | |
261 | | static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, GetByteContext *gbc, size_t data_size) |
262 | 4.51k | { |
263 | 4.51k | GetBitContext gb; |
264 | 4.51k | const int num_slices = 8; |
265 | 4.51k | uint32_t slice_off[9]; |
266 | 4.51k | int i, slice, ret; |
267 | 4.51k | const uint8_t *src = gbc->buffer; |
268 | | |
269 | 4.51k | if (bytestream2_get_bytes_left(gbc) < 8 + 4*(num_slices + 1)) |
270 | 270 | return AVERROR_INVALIDDATA; |
271 | | |
272 | 4.24k | int width = bytestream2_get_be16u(gbc); |
273 | 4.24k | int height = bytestream2_get_be16u(gbc); |
274 | | |
275 | 4.24k | ret = ff_set_dimensions(ctx->avctx, width, height); |
276 | 4.24k | if (ret < 0) |
277 | 785 | return ret; |
278 | | |
279 | 3.46k | ctx->avctx->coded_width = FFALIGN(width, 16); |
280 | 3.46k | ctx->avctx->coded_height = FFALIGN(height, 16); |
281 | 3.46k | ctx->avctx->bits_per_raw_sample = 8; |
282 | 3.46k | ctx->avctx->pix_fmt = AV_PIX_FMT_YUVA422P; |
283 | | |
284 | 3.46k | av_log(ctx->avctx, AV_LOG_VERBOSE, "HQA Profile\n"); |
285 | | |
286 | 3.46k | int quant = bytestream2_get_byteu(gbc); |
287 | 3.46k | bytestream2_skipu(gbc, 3); |
288 | 3.46k | if (quant >= NUM_HQ_QUANTS) { |
289 | 262 | av_log(ctx->avctx, AV_LOG_ERROR, |
290 | 262 | "Invalid quantization matrix %d.\n", quant); |
291 | 262 | return AVERROR_INVALIDDATA; |
292 | 262 | } |
293 | | |
294 | 3.20k | ret = ff_get_buffer(ctx->avctx, pic, 0); |
295 | 3.20k | if (ret < 0) |
296 | 84 | return ret; |
297 | | |
298 | | /* Offsets are stored from HQA1 position, so adjust them accordingly. */ |
299 | 31.1k | for (i = 0; i < num_slices + 1; i++) |
300 | 28.0k | slice_off[i] = bytestream2_get_be32u(gbc) - 4; |
301 | | |
302 | 4.69k | for (slice = 0; slice < num_slices; slice++) { |
303 | 4.63k | if (slice_off[slice] < (num_slices + 1) * 3 || |
304 | 4.63k | slice_off[slice] >= slice_off[slice + 1] || |
305 | 4.63k | slice_off[slice + 1] > data_size) { |
306 | 1.86k | av_log(ctx->avctx, AV_LOG_ERROR, |
307 | 1.86k | "Invalid slice size %"SIZE_SPECIFIER".\n", data_size); |
308 | 1.86k | break; |
309 | 1.86k | } |
310 | 2.76k | init_get_bits(&gb, src + slice_off[slice], |
311 | 2.76k | (slice_off[slice + 1] - slice_off[slice]) * 8); |
312 | | |
313 | 2.76k | ret = hqa_decode_slice(ctx, pic, &gb, quant, slice, width, height); |
314 | 2.76k | if (ret < 0) |
315 | 1.18k | return ret; |
316 | 2.76k | } |
317 | | |
318 | 1.93k | return 0; |
319 | 3.11k | } |
320 | | |
321 | | static int hq_hqa_decode_frame(AVCodecContext *avctx, AVFrame *pic, |
322 | | int *got_frame, AVPacket *avpkt) |
323 | 81.2k | { |
324 | 81.2k | HQContext *ctx = avctx->priv_data; |
325 | 81.2k | GetByteContext gbc0, *const gbc = &gbc0; |
326 | 81.2k | unsigned int data_size; |
327 | 81.2k | int ret; |
328 | | |
329 | 81.2k | if (avpkt->size < 4 + 4) { |
330 | 12.6k | av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", avpkt->size); |
331 | 12.6k | return AVERROR_INVALIDDATA; |
332 | 12.6k | } |
333 | 68.5k | bytestream2_init(gbc, avpkt->data, avpkt->size); |
334 | | |
335 | 68.5k | uint32_t info_tag = bytestream2_peek_le32u(gbc); |
336 | 68.5k | if (info_tag == MKTAG('I', 'N', 'F', 'O')) { |
337 | 8.58k | bytestream2_skipu(gbc, 4); |
338 | 8.58k | int info_size = bytestream2_get_le32u(gbc); |
339 | 8.58k | if (info_size < 0 || bytestream2_get_bytes_left(gbc) < info_size) { |
340 | 624 | av_log(avctx, AV_LOG_ERROR, "Invalid INFO size (%d).\n", info_size); |
341 | 624 | return AVERROR_INVALIDDATA; |
342 | 624 | } |
343 | 7.95k | ff_canopus_parse_info_tag(avctx, gbc->buffer, info_size); |
344 | | |
345 | 7.95k | bytestream2_skipu(gbc, info_size); |
346 | 7.95k | } |
347 | | |
348 | 67.9k | data_size = bytestream2_get_bytes_left(gbc); |
349 | 67.9k | if (data_size < 4) { |
350 | 7.33k | av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", data_size); |
351 | 7.33k | return AVERROR_INVALIDDATA; |
352 | 7.33k | } |
353 | | |
354 | | /* HQ defines dimensions and number of slices, and thus slice traversal |
355 | | * order. HQA has no size constraint and a fixed number of slices, so it |
356 | | * needs a separate scheme for it. */ |
357 | 60.5k | unsigned tag = bytestream2_get_le32u(gbc); |
358 | 60.5k | if ((tag & 0x00FFFFFF) == (MKTAG('U', 'V', 'C', ' ') & 0x00FFFFFF)) { |
359 | 52.3k | ret = hq_decode_frame(ctx, pic, gbc, tag >> 24, data_size); |
360 | 52.3k | } else if (tag == MKTAG('H', 'Q', 'A', '1')) { |
361 | 4.51k | ret = hqa_decode_frame(ctx, pic, gbc, data_size); |
362 | 4.51k | } else { |
363 | 3.72k | av_log(avctx, AV_LOG_ERROR, "Not a HQ/HQA frame.\n"); |
364 | 3.72k | return AVERROR_INVALIDDATA; |
365 | 3.72k | } |
366 | 56.8k | if (ret < 0) { |
367 | 5.81k | av_log(avctx, AV_LOG_ERROR, "Error decoding frame.\n"); |
368 | 5.81k | return ret; |
369 | 5.81k | } |
370 | | |
371 | 51.0k | *got_frame = 1; |
372 | | |
373 | 51.0k | return avpkt->size; |
374 | 56.8k | } |
375 | | |
376 | | static av_cold void hq_init_static(void) |
377 | 1 | { |
378 | 1 | VLC_INIT_STATIC_TABLE_FROM_LENGTHS(hq_ac_rvlc, 9, NUM_HQ_AC_ENTRIES, |
379 | 1 | hq_ac_lens, 1, hq_ac_sym, 2, 2, 0, 0); |
380 | | |
381 | 1.18k | for (size_t i = 0; i < FF_ARRAY_ELEMS(hq_ac_rvlc); ++i) { |
382 | 1.18k | int len = hq_ac_rvlc[i].len; |
383 | 1.18k | int sym = (int16_t)hq_ac_rvlc[i].sym, level = sym; |
384 | | |
385 | | // The invalid code has been remapped to HQ_AC_INVALID_RUN, |
386 | | // so the VLC is complete. |
387 | 1.18k | av_assert1(len != 0); |
388 | | |
389 | 1.18k | if (len > 0) { |
390 | 1.15k | level = sym >> 7; |
391 | 1.15k | hq_ac_rvlc[i].run = sym & 0x7F; |
392 | 1.15k | } |
393 | 1.18k | hq_ac_rvlc[i].len8 = len; |
394 | 1.18k | hq_ac_rvlc[i].level = level; |
395 | 1.18k | } |
396 | | |
397 | 17 | for (size_t i = 0; i < FF_ARRAY_ELEMS(hq_quants); ++i) { |
398 | 48 | for (size_t j = 0; j < FF_ARRAY_ELEMS(hq_quants[0]); ++j) { |
399 | 160 | for (size_t k = 0; k < FF_ARRAY_ELEMS(hq_quants[0][0]); ++k) |
400 | 128 | hq_quants[i][j][k] = qmats[hq_quant_map[i][j][k]]; |
401 | 32 | } |
402 | 16 | } |
403 | 1 | } |
404 | | |
405 | | static av_cold int hq_hqa_decode_init(AVCodecContext *avctx) |
406 | 1.91k | { |
407 | 1.91k | static AVOnce init_static_once = AV_ONCE_INIT; |
408 | 1.91k | HQContext *ctx = avctx->priv_data; |
409 | 1.91k | ctx->avctx = avctx; |
410 | | |
411 | 1.91k | ff_hqdsp_init(&ctx->hqhqadsp); |
412 | | |
413 | 1.91k | ff_thread_once(&init_static_once, hq_init_static); |
414 | | |
415 | 1.91k | return 0; |
416 | 1.91k | } |
417 | | |
418 | | const FFCodec ff_hq_hqa_decoder = { |
419 | | .p.name = "hq_hqa", |
420 | | CODEC_LONG_NAME("Canopus HQ/HQA"), |
421 | | .p.type = AVMEDIA_TYPE_VIDEO, |
422 | | .p.id = AV_CODEC_ID_HQ_HQA, |
423 | | .priv_data_size = sizeof(HQContext), |
424 | | .init = hq_hqa_decode_init, |
425 | | FF_CODEC_DECODE_CB(hq_hqa_decode_frame), |
426 | | .p.capabilities = AV_CODEC_CAP_DR1, |
427 | | }; |