FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/hq_hqa.c
Date: 2024-04-24 02:45:42
Exec Total Coverage
Lines: 161 192 83.9%
Functions: 10 10 100.0%
Branches: 64 90 71.1%

Line Branch Exec Source
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_hqadata.h"
34 #include "hq_hqadsp.h"
35 #include "vlc.h"
36
37 /* HQ/HQA slices are a set of macroblocks belonging to a frame, and
38 * they usually form a pseudorandom pattern (probably because it is
39 * nicer to display on partial decode).
40 *
41 * For HQA it just happens that each slice is on every 8th macroblock,
42 * but they can be on any frame width like
43 * X.......X.
44 * ......X...
45 * ....X.....
46 * ..X.......
47 * etc.
48 *
49 * The original decoder has special handling for edge macroblocks,
50 * while lavc simply aligns coded_width and coded_height.
51 */
52
53 typedef struct HQContext {
54 AVCodecContext *avctx;
55 HQDSPContext hqhqadsp;
56
57 DECLARE_ALIGNED(16, int16_t, block)[12][64];
58 } HQContext;
59
60 static VLCElem hq_ac_vlc[1184];
61 static VLCElem hqa_cbp_vlc[32];
62
63 221520 static inline void put_blocks(HQContext *c, AVFrame *pic,
64 int plane, int x, int y, int ilace,
65 int16_t *block0, int16_t *block1)
66 {
67 221520 uint8_t *p = pic->data[plane] + x;
68
69 221520 c->hqhqadsp.idct_put(p + y * pic->linesize[plane],
70 221520 pic->linesize[plane] << ilace, block0);
71 221520 c->hqhqadsp.idct_put(p + (y + (ilace ? 1 : 8)) * pic->linesize[plane],
72
2/2
✓ Branch 0 taken 1916 times.
✓ Branch 1 taken 219604 times.
221520 pic->linesize[plane] << ilace, block1);
73 221520 }
74
75 365300 static int hq_decode_block(HQContext *c, GetBitContext *gb, int16_t block[64],
76 int qsel, int is_chroma, int is_hqa)
77 {
78 const int32_t *q;
79 365300 int val, pos = 1;
80
81 365300 memset(block, 0, 64 * sizeof(*block));
82
83
2/2
✓ Branch 0 taken 247200 times.
✓ Branch 1 taken 118100 times.
365300 if (!is_hqa) {
84 247200 block[0] = get_sbits(gb, 9) * 64;
85 247200 q = hq_quants[qsel][is_chroma][get_bits(gb, 2)];
86 } else {
87 118100 q = hq_quants[qsel][is_chroma][get_bits(gb, 2)];
88 118100 block[0] = get_sbits(gb, 9) * 64;
89 }
90
91 for (;;) {
92 5841374 val = get_vlc2(gb, hq_ac_vlc, 9, 2);
93
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5841374 times.
5841374 if (val < 0)
94 return AVERROR_INVALIDDATA;
95
96 5841374 pos += hq_ac_skips[val];
97
2/2
✓ Branch 0 taken 365300 times.
✓ Branch 1 taken 5476074 times.
5841374 if (pos >= 64)
98 365300 break;
99 5476074 block[ff_zigzag_direct[pos]] = (int)(hq_ac_syms[val] * (unsigned)q[pos]) >> 12;
100 5476074 pos++;
101 }
102
103 365300 return 0;
104 }
105
106 30900 static int hq_decode_mb(HQContext *c, AVFrame *pic,
107 GetBitContext *gb, int x, int y)
108 {
109 int qgroup, flag;
110 int i, ret;
111
112 30900 qgroup = get_bits(gb, 4);
113 30900 flag = get_bits1(gb);
114
115
2/2
✓ Branch 0 taken 247200 times.
✓ Branch 1 taken 30900 times.
278100 for (i = 0; i < 8; i++) {
116 247200 ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 4, 0);
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 247200 times.
247200 if (ret < 0)
118 return ret;
119 }
120
121 30900 put_blocks(c, pic, 0, x, y, flag, c->block[0], c->block[2]);
122 30900 put_blocks(c, pic, 0, x + 8, y, flag, c->block[1], c->block[3]);
123 30900 put_blocks(c, pic, 2, x >> 1, y, flag, c->block[4], c->block[5]);
124 30900 put_blocks(c, pic, 1, x >> 1, y, flag, c->block[6], c->block[7]);
125
126 30900 return 0;
127 }
128
129 11 static int hq_decode_frame(HQContext *ctx, AVFrame *pic, GetByteContext *gbc,
130 int prof_num, size_t data_size)
131 {
132 const HQProfile *profile;
133 GetBitContext gb;
134 11 const uint8_t *perm, *src = gbc->buffer;
135 uint32_t slice_off[21];
136 int slice, start_off, next_off, i, ret;
137
138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if ((unsigned)prof_num >= NUM_HQ_PROFILES) {
139 profile = &hq_profile[0];
140 avpriv_request_sample(ctx->avctx, "HQ Profile %d", prof_num);
141 } else {
142 11 profile = &hq_profile[prof_num];
143 11 av_log(ctx->avctx, AV_LOG_VERBOSE, "HQ Profile %d\n", prof_num);
144 }
145
146 11 ctx->avctx->coded_width = FFALIGN(profile->width, 16);
147 11 ctx->avctx->coded_height = FFALIGN(profile->height, 16);
148 11 ctx->avctx->width = profile->width;
149 11 ctx->avctx->height = profile->height;
150 11 ctx->avctx->bits_per_raw_sample = 8;
151 11 ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P;
152
153 11 ret = ff_get_buffer(ctx->avctx, pic, 0);
154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (ret < 0)
155 return ret;
156
157 /* Offsets are stored from CUV position, so adjust them accordingly. */
158
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 11 times.
134 for (i = 0; i < profile->num_slices + 1; i++)
159 123 slice_off[i] = bytestream2_get_be24(gbc) - 4;
160
161 11 next_off = 0;
162
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 11 times.
123 for (slice = 0; slice < profile->num_slices; slice++) {
163 112 start_off = next_off;
164 112 next_off = profile->tab_h * (slice + 1) / profile->num_slices;
165 112 perm = profile->perm_tab + start_off * profile->tab_w * 2;
166
167
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (slice_off[slice] < (profile->num_slices + 1) * 3 ||
168
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 slice_off[slice] >= slice_off[slice + 1] ||
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 slice_off[slice + 1] > data_size) {
170 av_log(ctx->avctx, AV_LOG_ERROR,
171 "Invalid slice size %"SIZE_SPECIFIER".\n", data_size);
172 break;
173 }
174 112 init_get_bits(&gb, src + slice_off[slice],
175 112 (slice_off[slice + 1] - slice_off[slice]) * 8);
176
177
2/2
✓ Branch 0 taken 30900 times.
✓ Branch 1 taken 112 times.
31012 for (i = 0; i < (next_off - start_off) * profile->tab_w; i++) {
178 30900 ret = hq_decode_mb(ctx, pic, &gb, perm[0] * 16, perm[1] * 16);
179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30900 times.
30900 if (ret < 0) {
180 av_log(ctx->avctx, AV_LOG_ERROR,
181 "Error decoding macroblock %d at slice %d.\n", i, slice);
182 return ret;
183 }
184 30900 perm += 2;
185 }
186 }
187
188 11 return 0;
189 }
190
191 16320 static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup,
192 GetBitContext *gb, int x, int y)
193 {
194 16320 int flag = 0;
195 int i, ret, cbp;
196
197
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 16320 times.
16320 if (get_bits_left(gb) < 1)
198 return AVERROR_INVALIDDATA;
199
200 16320 cbp = get_vlc2(gb, hqa_cbp_vlc, 5, 1);
201
202
2/2
✓ Branch 0 taken 195840 times.
✓ Branch 1 taken 16320 times.
212160 for (i = 0; i < 12; i++)
203 195840 memset(c->block[i], 0, sizeof(*c->block));
204
2/2
✓ Branch 0 taken 195840 times.
✓ Branch 1 taken 16320 times.
212160 for (i = 0; i < 12; i++)
205 195840 c->block[i][0] = -128 * (1 << 6);
206
207
2/2
✓ Branch 0 taken 9978 times.
✓ Branch 1 taken 6342 times.
16320 if (cbp) {
208 9978 flag = get_bits1(gb);
209
210 9978 cbp |= cbp << 4;
211
2/2
✓ Branch 0 taken 9890 times.
✓ Branch 1 taken 88 times.
9978 if (cbp & 0x3)
212 9890 cbp |= 0x500;
213
2/2
✓ Branch 0 taken 9874 times.
✓ Branch 1 taken 104 times.
9978 if (cbp & 0xC)
214 9874 cbp |= 0xA00;
215
2/2
✓ Branch 0 taken 119736 times.
✓ Branch 1 taken 9978 times.
129714 for (i = 0; i < 12; i++) {
216
2/2
✓ Branch 0 taken 1636 times.
✓ Branch 1 taken 118100 times.
119736 if (!(cbp & (1 << i)))
217 1636 continue;
218 118100 ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 8, 1);
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 118100 times.
118100 if (ret < 0)
220 return ret;
221 }
222 }
223
224 16320 put_blocks(c, pic, 3, x, y, flag, c->block[ 0], c->block[ 2]);
225 16320 put_blocks(c, pic, 3, x + 8, y, flag, c->block[ 1], c->block[ 3]);
226 16320 put_blocks(c, pic, 0, x, y, flag, c->block[ 4], c->block[ 6]);
227 16320 put_blocks(c, pic, 0, x + 8, y, flag, c->block[ 5], c->block[ 7]);
228 16320 put_blocks(c, pic, 2, x >> 1, y, flag, c->block[ 8], c->block[ 9]);
229 16320 put_blocks(c, pic, 1, x >> 1, y, flag, c->block[10], c->block[11]);
230
231 16320 return 0;
232 }
233
234 16 static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb,
235 int quant, int slice_no, int w, int h)
236 {
237 int i, j, off;
238 int ret;
239
240
2/2
✓ Branch 0 taken 1088 times.
✓ Branch 1 taken 16 times.
1104 for (i = 0; i < h; i += 16) {
241 1088 off = (slice_no * 16 + i * 3) & 0x70;
242
2/2
✓ Branch 0 taken 16320 times.
✓ Branch 1 taken 1088 times.
17408 for (j = off; j < w; j += 128) {
243 16320 ret = hqa_decode_mb(ctx, pic, quant, gb, j, i);
244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16320 times.
16320 if (ret < 0) {
245 av_log(ctx->avctx, AV_LOG_ERROR,
246 "Error decoding macroblock at %dx%d.\n", i, j);
247 return ret;
248 }
249 }
250 }
251
252 16 return 0;
253 }
254
255 2 static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, GetByteContext *gbc, size_t data_size)
256 {
257 GetBitContext gb;
258 2 const int num_slices = 8;
259 uint32_t slice_off[9];
260 int i, slice, ret;
261 int width, height, quant;
262 2 const uint8_t *src = gbc->buffer;
263
264
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (bytestream2_get_bytes_left(gbc) < 8 + 4*(num_slices + 1))
265 return AVERROR_INVALIDDATA;
266
267 2 width = bytestream2_get_be16(gbc);
268 2 height = bytestream2_get_be16(gbc);
269
270 2 ret = ff_set_dimensions(ctx->avctx, width, height);
271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0)
272 return ret;
273
274 2 ctx->avctx->coded_width = FFALIGN(width, 16);
275 2 ctx->avctx->coded_height = FFALIGN(height, 16);
276 2 ctx->avctx->bits_per_raw_sample = 8;
277 2 ctx->avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
278
279 2 av_log(ctx->avctx, AV_LOG_VERBOSE, "HQA Profile\n");
280
281 2 quant = bytestream2_get_byte(gbc);
282 2 bytestream2_skip(gbc, 3);
283
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (quant >= NUM_HQ_QUANTS) {
284 av_log(ctx->avctx, AV_LOG_ERROR,
285 "Invalid quantization matrix %d.\n", quant);
286 return AVERROR_INVALIDDATA;
287 }
288
289 2 ret = ff_get_buffer(ctx->avctx, pic, 0);
290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0)
291 return ret;
292
293 /* Offsets are stored from HQA1 position, so adjust them accordingly. */
294
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
20 for (i = 0; i < num_slices + 1; i++)
295 18 slice_off[i] = bytestream2_get_be32(gbc) - 4;
296
297
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
18 for (slice = 0; slice < num_slices; slice++) {
298
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (slice_off[slice] < (num_slices + 1) * 3 ||
299
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 slice_off[slice] >= slice_off[slice + 1] ||
300
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 slice_off[slice + 1] > data_size) {
301 av_log(ctx->avctx, AV_LOG_ERROR,
302 "Invalid slice size %"SIZE_SPECIFIER".\n", data_size);
303 break;
304 }
305 16 init_get_bits(&gb, src + slice_off[slice],
306 16 (slice_off[slice + 1] - slice_off[slice]) * 8);
307
308 16 ret = hqa_decode_slice(ctx, pic, &gb, quant, slice, width, height);
309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ret < 0)
310 return ret;
311 }
312
313 2 return 0;
314 }
315
316 13 static int hq_hqa_decode_frame(AVCodecContext *avctx, AVFrame *pic,
317 int *got_frame, AVPacket *avpkt)
318 {
319 13 HQContext *ctx = avctx->priv_data;
320 13 GetByteContext gbc0, *const gbc = &gbc0;
321 uint32_t info_tag;
322 unsigned int data_size;
323 int ret;
324 unsigned tag;
325
326 13 bytestream2_init(gbc, avpkt->data, avpkt->size);
327
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if (bytestream2_get_bytes_left(gbc) < 4 + 4) {
328 av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", avpkt->size);
329 return AVERROR_INVALIDDATA;
330 }
331
332 13 info_tag = bytestream2_peek_le32(gbc);
333
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
334 int info_size;
335 13 bytestream2_skip(gbc, 4);
336 13 info_size = bytestream2_get_le32(gbc);
337
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
13 if (info_size < 0 || bytestream2_get_bytes_left(gbc) < info_size) {
338 av_log(avctx, AV_LOG_ERROR, "Invalid INFO size (%d).\n", info_size);
339 return AVERROR_INVALIDDATA;
340 }
341 13 ff_canopus_parse_info_tag(avctx, gbc->buffer, info_size);
342
343 13 bytestream2_skip(gbc, info_size);
344 }
345
346 13 data_size = bytestream2_get_bytes_left(gbc);
347
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (data_size < 4) {
348 av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", data_size);
349 return AVERROR_INVALIDDATA;
350 }
351
352 /* HQ defines dimensions and number of slices, and thus slice traversal
353 * order. HQA has no size constraint and a fixed number of slices, so it
354 * needs a separate scheme for it. */
355 13 tag = bytestream2_get_le32(gbc);
356
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2 times.
13 if ((tag & 0x00FFFFFF) == (MKTAG('U', 'V', 'C', ' ') & 0x00FFFFFF)) {
357 11 ret = hq_decode_frame(ctx, pic, gbc, tag >> 24, data_size);
358
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 } else if (tag == MKTAG('H', 'Q', 'A', '1')) {
359 2 ret = hqa_decode_frame(ctx, pic, gbc, data_size);
360 } else {
361 av_log(avctx, AV_LOG_ERROR, "Not a HQ/HQA frame.\n");
362 return AVERROR_INVALIDDATA;
363 }
364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (ret < 0) {
365 av_log(avctx, AV_LOG_ERROR, "Error decoding frame.\n");
366 return ret;
367 }
368
369 13 pic->flags |= AV_FRAME_FLAG_KEY;
370 13 pic->pict_type = AV_PICTURE_TYPE_I;
371
372 13 *got_frame = 1;
373
374 13 return avpkt->size;
375 }
376
377 3 static av_cold void hq_init_vlcs(void)
378 {
379 3 VLC_INIT_STATIC_TABLE(hqa_cbp_vlc, 5, FF_ARRAY_ELEMS(cbp_vlc_lens),
380 cbp_vlc_lens, 1, 1, cbp_vlc_bits, 1, 1, 0);
381
382 3 VLC_INIT_STATIC_TABLE(hq_ac_vlc, 9, NUM_HQ_AC_ENTRIES,
383 hq_ac_bits, 1, 1, hq_ac_codes, 2, 2, 0);
384 3 }
385
386 6 static av_cold int hq_hqa_decode_init(AVCodecContext *avctx)
387 {
388 static AVOnce init_static_once = AV_ONCE_INIT;
389 6 HQContext *ctx = avctx->priv_data;
390 6 ctx->avctx = avctx;
391
392 6 ff_hqdsp_init(&ctx->hqhqadsp);
393
394 6 ff_thread_once(&init_static_once, hq_init_vlcs);
395
396 6 return 0;
397 }
398
399 const FFCodec ff_hq_hqa_decoder = {
400 .p.name = "hq_hqa",
401 CODEC_LONG_NAME("Canopus HQ/HQA"),
402 .p.type = AVMEDIA_TYPE_VIDEO,
403 .p.id = AV_CODEC_ID_HQ_HQA,
404 .priv_data_size = sizeof(HQContext),
405 .init = hq_hqa_decode_init,
406 FF_CODEC_DECODE_CB(hq_hqa_decode_frame),
407 .p.capabilities = AV_CODEC_CAP_DR1,
408 };
409