2 * Canopus HQ/HQA decoder
4 * This file is part of FFmpeg.
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.
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.
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
23 #include "libavutil/attributes.h"
24 #include "libavutil/mem_internal.h"
25 #include "libavutil/thread.h"
28 #include "bytestream.h"
30 #include "codec_internal.h"
33 #include "hq_hqadata.h"
34 #include "hq_hqadsp.h"
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).
41 * For HQA it just happens that each slice is on every 8th macroblock,
42 * but they can be on any frame width like
49 * The original decoder has special handling for edge macroblocks,
50 * while lavc simply aligns coded_width and coded_height.
53 typedef struct HQContext
{
54 AVCodecContext
*avctx
;
55 HQDSPContext hqhqadsp
;
57 DECLARE_ALIGNED(16, int16_t, block
)[12][64];
60 static VLCElem hq_ac_vlc
[1184];
61 static VLCElem hqa_cbp_vlc
[32];
63 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
)
67 uint8_t *p
= pic
->data
[plane
] + x
;
69 c
->hqhqadsp
.idct_put(p
+ y
* pic
->linesize
[plane
],
70 pic
->linesize
[plane
] << ilace
, block0
);
71 c
->hqhqadsp
.idct_put(p
+ (y
+ (ilace
? 1 : 8)) * pic
->linesize
[plane
],
72 pic
->linesize
[plane
] << ilace
, block1
);
75 static int hq_decode_block(HQContext
*c
, GetBitContext
*gb
, int16_t block
[64],
76 int qsel
, int is_chroma
, int is_hqa
)
81 memset(block
, 0, 64 * sizeof(*block
));
84 block
[0] = get_sbits(gb
, 9) * 64;
85 q
= hq_quants
[qsel
][is_chroma
][get_bits(gb
, 2)];
87 q
= hq_quants
[qsel
][is_chroma
][get_bits(gb
, 2)];
88 block
[0] = get_sbits(gb
, 9) * 64;
92 val
= get_vlc2(gb
, hq_ac_vlc
, 9, 2);
94 return AVERROR_INVALIDDATA
;
96 pos
+= hq_ac_skips
[val
];
99 block
[ff_zigzag_direct
[pos
]] = (int)(hq_ac_syms
[val
] * (unsigned)q
[pos
]) >> 12;
106 static int hq_decode_mb(HQContext
*c
, AVFrame
*pic
,
107 GetBitContext
*gb
, int x
, int y
)
112 qgroup
= get_bits(gb
, 4);
113 flag
= get_bits1(gb
);
115 for (i
= 0; i
< 8; i
++) {
116 ret
= hq_decode_block(c
, gb
, c
->block
[i
], qgroup
, i
>= 4, 0);
121 put_blocks(c
, pic
, 0, x
, y
, flag
, c
->block
[0], c
->block
[2]);
122 put_blocks(c
, pic
, 0, x
+ 8, y
, flag
, c
->block
[1], c
->block
[3]);
123 put_blocks(c
, pic
, 2, x
>> 1, y
, flag
, c
->block
[4], c
->block
[5]);
124 put_blocks(c
, pic
, 1, x
>> 1, y
, flag
, c
->block
[6], c
->block
[7]);
129 static int hq_decode_frame(HQContext
*ctx
, AVFrame
*pic
, GetByteContext
*gbc
,
130 int prof_num
, size_t data_size
)
132 const HQProfile
*profile
;
134 const uint8_t *perm
, *src
= gbc
->buffer
;
135 uint32_t slice_off
[21];
136 int slice
, start_off
, next_off
, i
, ret
;
138 if ((unsigned)prof_num
>= NUM_HQ_PROFILES
) {
139 profile
= &hq_profile
[0];
140 avpriv_request_sample(ctx
->avctx
, "HQ Profile %d", prof_num
);
142 profile
= &hq_profile
[prof_num
];
143 av_log(ctx
->avctx
, AV_LOG_VERBOSE
, "HQ Profile %d\n", prof_num
);
146 ctx
->avctx
->coded_width
= FFALIGN(profile
->width
, 16);
147 ctx
->avctx
->coded_height
= FFALIGN(profile
->height
, 16);
148 ctx
->avctx
->width
= profile
->width
;
149 ctx
->avctx
->height
= profile
->height
;
150 ctx
->avctx
->bits_per_raw_sample
= 8;
151 ctx
->avctx
->pix_fmt
= AV_PIX_FMT_YUV422P
;
153 ret
= ff_get_buffer(ctx
->avctx
, pic
, 0);
157 /* Offsets are stored from CUV position, so adjust them accordingly. */
158 for (i
= 0; i
< profile
->num_slices
+ 1; i
++)
159 slice_off
[i
] = bytestream2_get_be24(gbc
) - 4;
162 for (slice
= 0; slice
< profile
->num_slices
; slice
++) {
163 start_off
= next_off
;
164 next_off
= profile
->tab_h
* (slice
+ 1) / profile
->num_slices
;
165 perm
= profile
->perm_tab
+ start_off
* profile
->tab_w
* 2;
167 if (slice_off
[slice
] < (profile
->num_slices
+ 1) * 3 ||
168 slice_off
[slice
] >= slice_off
[slice
+ 1] ||
169 slice_off
[slice
+ 1] > data_size
) {
170 av_log(ctx
->avctx
, AV_LOG_ERROR
,
171 "Invalid slice size %"SIZE_SPECIFIER
".\n", data_size
);
174 init_get_bits(&gb
, src
+ slice_off
[slice
],
175 (slice_off
[slice
+ 1] - slice_off
[slice
]) * 8);
177 for (i
= 0; i
< (next_off
- start_off
) * profile
->tab_w
; i
++) {
178 ret
= hq_decode_mb(ctx
, pic
, &gb
, perm
[0] * 16, perm
[1] * 16);
180 av_log(ctx
->avctx
, AV_LOG_ERROR
,
181 "Error decoding macroblock %d at slice %d.\n", i
, slice
);
191 static int hqa_decode_mb(HQContext
*c
, AVFrame
*pic
, int qgroup
,
192 GetBitContext
*gb
, int x
, int y
)
197 if (get_bits_left(gb
) < 1)
198 return AVERROR_INVALIDDATA
;
200 cbp
= get_vlc2(gb
, hqa_cbp_vlc
, 5, 1);
202 for (i
= 0; i
< 12; i
++)
203 memset(c
->block
[i
], 0, sizeof(*c
->block
));
204 for (i
= 0; i
< 12; i
++)
205 c
->block
[i
][0] = -128 * (1 << 6);
208 flag
= get_bits1(gb
);
215 for (i
= 0; i
< 12; i
++) {
216 if (!(cbp
& (1 << i
)))
218 ret
= hq_decode_block(c
, gb
, c
->block
[i
], qgroup
, i
>= 8, 1);
224 put_blocks(c
, pic
, 3, x
, y
, flag
, c
->block
[ 0], c
->block
[ 2]);
225 put_blocks(c
, pic
, 3, x
+ 8, y
, flag
, c
->block
[ 1], c
->block
[ 3]);
226 put_blocks(c
, pic
, 0, x
, y
, flag
, c
->block
[ 4], c
->block
[ 6]);
227 put_blocks(c
, pic
, 0, x
+ 8, y
, flag
, c
->block
[ 5], c
->block
[ 7]);
228 put_blocks(c
, pic
, 2, x
>> 1, y
, flag
, c
->block
[ 8], c
->block
[ 9]);
229 put_blocks(c
, pic
, 1, x
>> 1, y
, flag
, c
->block
[10], c
->block
[11]);
234 static int hqa_decode_slice(HQContext
*ctx
, AVFrame
*pic
, GetBitContext
*gb
,
235 int quant
, int slice_no
, int w
, int h
)
240 for (i
= 0; i
< h
; i
+= 16) {
241 off
= (slice_no
* 16 + i
* 3) & 0x70;
242 for (j
= off
; j
< w
; j
+= 128) {
243 ret
= hqa_decode_mb(ctx
, pic
, quant
, gb
, j
, i
);
245 av_log(ctx
->avctx
, AV_LOG_ERROR
,
246 "Error decoding macroblock at %dx%d.\n", i
, j
);
255 static int hqa_decode_frame(HQContext
*ctx
, AVFrame
*pic
, GetByteContext
*gbc
, size_t data_size
)
258 const int num_slices
= 8;
259 uint32_t slice_off
[9];
261 int width
, height
, quant
;
262 const uint8_t *src
= gbc
->buffer
;
264 if (bytestream2_get_bytes_left(gbc
) < 8 + 4*(num_slices
+ 1))
265 return AVERROR_INVALIDDATA
;
267 width
= bytestream2_get_be16(gbc
);
268 height
= bytestream2_get_be16(gbc
);
270 ret
= ff_set_dimensions(ctx
->avctx
, width
, height
);
274 ctx
->avctx
->coded_width
= FFALIGN(width
, 16);
275 ctx
->avctx
->coded_height
= FFALIGN(height
, 16);
276 ctx
->avctx
->bits_per_raw_sample
= 8;
277 ctx
->avctx
->pix_fmt
= AV_PIX_FMT_YUVA422P
;
279 av_log(ctx
->avctx
, AV_LOG_VERBOSE
, "HQA Profile\n");
281 quant
= bytestream2_get_byte(gbc
);
282 bytestream2_skip(gbc
, 3);
283 if (quant
>= NUM_HQ_QUANTS
) {
284 av_log(ctx
->avctx
, AV_LOG_ERROR
,
285 "Invalid quantization matrix %d.\n", quant
);
286 return AVERROR_INVALIDDATA
;
289 ret
= ff_get_buffer(ctx
->avctx
, pic
, 0);
293 /* Offsets are stored from HQA1 position, so adjust them accordingly. */
294 for (i
= 0; i
< num_slices
+ 1; i
++)
295 slice_off
[i
] = bytestream2_get_be32(gbc
) - 4;
297 for (slice
= 0; slice
< num_slices
; slice
++) {
298 if (slice_off
[slice
] < (num_slices
+ 1) * 3 ||
299 slice_off
[slice
] >= slice_off
[slice
+ 1] ||
300 slice_off
[slice
+ 1] > data_size
) {
301 av_log(ctx
->avctx
, AV_LOG_ERROR
,
302 "Invalid slice size %"SIZE_SPECIFIER
".\n", data_size
);
305 init_get_bits(&gb
, src
+ slice_off
[slice
],
306 (slice_off
[slice
+ 1] - slice_off
[slice
]) * 8);
308 ret
= hqa_decode_slice(ctx
, pic
, &gb
, quant
, slice
, width
, height
);
316 static int hq_hqa_decode_frame(AVCodecContext
*avctx
, AVFrame
*pic
,
317 int *got_frame
, AVPacket
*avpkt
)
319 HQContext
*ctx
= avctx
->priv_data
;
320 GetByteContext gbc0
, *const gbc
= &gbc0
;
322 unsigned int data_size
;
326 bytestream2_init(gbc
, avpkt
->data
, avpkt
->size
);
327 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
;
332 info_tag
= bytestream2_peek_le32(gbc
);
333 if (info_tag
== MKTAG('I', 'N', 'F', 'O')) {
335 bytestream2_skip(gbc
, 4);
336 info_size
= bytestream2_get_le32(gbc
);
337 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
;
341 ff_canopus_parse_info_tag(avctx
, gbc
->buffer
, info_size
);
343 bytestream2_skip(gbc
, info_size
);
346 data_size
= bytestream2_get_bytes_left(gbc
);
348 av_log(avctx
, AV_LOG_ERROR
, "Frame is too small (%d).\n", data_size
);
349 return AVERROR_INVALIDDATA
;
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 tag
= bytestream2_get_le32(gbc
);
356 if ((tag
& 0x00FFFFFF) == (MKTAG('U', 'V', 'C', ' ') & 0x00FFFFFF)) {
357 ret
= hq_decode_frame(ctx
, pic
, gbc
, tag
>> 24, data_size
);
358 } else if (tag
== MKTAG('H', 'Q', 'A', '1')) {
359 ret
= hqa_decode_frame(ctx
, pic
, gbc
, data_size
);
361 av_log(avctx
, AV_LOG_ERROR
, "Not a HQ/HQA frame.\n");
362 return AVERROR_INVALIDDATA
;
365 av_log(avctx
, AV_LOG_ERROR
, "Error decoding frame.\n");
374 static av_cold
void hq_init_vlcs(void)
376 VLC_INIT_STATIC_TABLE(hqa_cbp_vlc
, 5, FF_ARRAY_ELEMS(cbp_vlc_lens
),
377 cbp_vlc_lens
, 1, 1, cbp_vlc_bits
, 1, 1, 0);
379 VLC_INIT_STATIC_TABLE(hq_ac_vlc
, 9, NUM_HQ_AC_ENTRIES
,
380 hq_ac_bits
, 1, 1, hq_ac_codes
, 2, 2, 0);
383 static av_cold
int hq_hqa_decode_init(AVCodecContext
*avctx
)
385 static AVOnce init_static_once
= AV_ONCE_INIT
;
386 HQContext
*ctx
= avctx
->priv_data
;
389 ff_hqdsp_init(&ctx
->hqhqadsp
);
391 ff_thread_once(&init_static_once
, hq_init_vlcs
);
396 const FFCodec ff_hq_hqa_decoder
= {
398 CODEC_LONG_NAME("Canopus HQ/HQA"),
399 .p
.type
= AVMEDIA_TYPE_VIDEO
,
400 .p
.id
= AV_CODEC_ID_HQ_HQA
,
401 .priv_data_size
= sizeof(HQContext
),
402 .init
= hq_hqa_decode_init
,
403 FF_CODEC_DECODE_CB(hq_hqa_decode_frame
),
404 .p
.capabilities
= AV_CODEC_CAP_DR1
,