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