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
25
29
32
33 /* HQ/HQA slices are a set of macroblocks belonging to a frame, and
34 * they usually form a pseudorandom pattern (probably because it is
35 * nicer to display on partial decode).
36 *
37 * For HQA it just happens that each slice is on every 8th macroblock,
38 * but they can be on any frame width like
39 * X.......X.
40 * ......X...
41 * ....X.....
42 * ..X.......
43 * etc.
44 *
45 * The original decoder has special handling for edge macroblocks,
46 * while lavc simply aligns coded_width and coded_height.
47 */
48
50 int plane,
int x,
int y,
int ilace,
51 int16_t *block0, int16_t *
block1)
52 {
54
56 pic->
linesize[plane] << ilace, block0);
58 pic->
linesize[plane] << ilace, block1);
59 }
60
62 int qsel, int is_chroma, int is_hqa)
63 {
66
67 memset(block, 0, 64 * sizeof(*block));
68
69 if (!is_hqa) {
72 } else {
75 }
76
77 for (;;) {
79 if (val < 0)
81
83 if (pos >= 64)
84 break;
86 pos++;
87 }
88
89 return 0;
90 }
91
94 {
96 int i, ret;
97
100
101 for (i = 0; i < 8; i++) {
103 if (ret < 0)
104 return ret;
105 }
106
111
112 return 0;
113 }
114
116 int prof_num, size_t data_size)
117 {
121 uint32_t slice_off[21];
122 int slice, start_off, next_off, i, ret;
123
127 } else {
130 }
131
138
140 if (ret < 0)
141 return ret;
142
143 /* Offsets are stored from CUV position, so adjust them accordingly. */
145 slice_off[i] = bytestream2_get_be24(&ctx->
gbc) - 4;
146
147 next_off = 0;
148 for (slice = 0; slice < profile->
num_slices; slice++) {
149 start_off = next_off;
152
154 slice_off[slice] >= slice_off[slice + 1] ||
155 slice_off[slice + 1] > data_size) {
157 "Invalid slice size %zu.\n", data_size);
158 break;
159 }
161 (slice_off[slice + 1] - slice_off[slice]) * 8);
162
163 for (i = 0; i < (next_off - start_off) * profile->
tab_w; i++) {
164 ret =
hq_decode_mb(ctx, pic, &gb, perm[0] * 16, perm[1] * 16);
165 if (ret < 0) {
167 "Error decoding macroblock %d at slice %d.\n", i, slice);
168 return ret;
169 }
170 perm += 2;
171 }
172 }
173
174 return 0;
175 }
176
179 {
181 int i, ret, cbp;
182
184
185 for (i = 0; i < 12; i++)
187 for (i = 0; i < 12; i++)
188 c->
block[i][0] = -128 * (1 << 6);
189
190 if (cbp) {
192
193 cbp |= cbp << 4;
194 if (cbp & 0x3)
195 cbp |= 0x500;
196 if (cbp & 0xC)
197 cbp |= 0xA00;
198 for (i = 0; i < 12; i++) {
199 if (!(cbp & (1 << i)))
200 continue;
202 if (ret < 0)
203 return ret;
204 }
205 }
206
213
214 return 0;
215 }
216
218 int quant,
int slice_no,
int w,
int h)
219 {
220 int i, j, off;
221 int ret;
222
223 for (i = 0; i <
h; i += 16) {
224 off = (slice_no * 16 + i * 3) & 0x70;
225 for (j = off; j < w; j += 128) {
227 if (ret < 0) {
229 "Error decoding macroblock at %dx%d.\n", i, j);
230 return ret;
231 }
232 }
233 }
234
235 return 0;
236 }
237
239 {
241 const int num_slices = 8;
242 uint32_t slice_off[9];
243 int i, slice, ret;
246
247 width = bytestream2_get_be16(&ctx->
gbc);
248 height = bytestream2_get_be16(&ctx->
gbc);
249
256
258
259 quant = bytestream2_get_byte(&ctx->
gbc);
263 "Invalid quantization matrix %d.\n", quant);
265 }
266
268 if (ret < 0)
269 return ret;
270
271 /* Offsets are stored from HQA1 position, so adjust them accordingly. */
272 for (i = 0; i < num_slices + 1; i++)
273 slice_off[i] = bytestream2_get_be32(&ctx->
gbc) - 4;
274
275 for (slice = 0; slice < num_slices; slice++) {
276 if (slice_off[slice] < (num_slices + 1) * 3 ||
277 slice_off[slice] >= slice_off[slice + 1] ||
278 slice_off[slice + 1] > data_size) {
280 "Invalid slice size %zu.\n", data_size);
281 break;
282 }
284 (slice_off[slice + 1] - slice_off[slice]) * 8);
285
287 if (ret < 0)
288 return ret;
289 }
290
291 return 0;
292 }
293
296 {
299 uint32_t info_tag;
300 unsigned int data_size;
301 int ret;
303
308 }
309
310 info_tag = bytestream2_peek_le32(&ctx->
gbc);
311 if (info_tag ==
MKTAG(
'I',
'N',
'F',
'O')) {
312 int info_size;
314 info_size = bytestream2_get_le32(&ctx->
gbc);
318 }
320
322 }
323
325 if (data_size < 4) {
328 }
329
330 /* HQ defines dimensions and number of slices, and thus slice traversal
331 * order. HQA has no size constraint and a fixed number of slices, so it
332 * needs a separate scheme for it. */
333 tag = bytestream2_get_le32(&ctx->
gbc);
334 if ((tag & 0x00FFFFFF) == (
MKTAG(
'U',
'V',
'C',
' ') & 0x00FFFFFF)) {
336 }
else if (tag ==
MKTAG(
'H',
'Q',
'A',
'1')) {
338 } else {
341 }
342 if (ret < 0) {
344 return ret;
345 }
346
349
350 *got_frame = 1;
351
353 }
354
356 {
359
361
363 }
364
366 {
368
371
372 return 0;
373 }
374
387 };
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
const char const char void * val
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
int coded_width
Bitstream width / height, may be different from width/height e.g.
static int hq_decode_frame(HQContext *ctx, AVFrame *pic, int prof_num, size_t data_size)
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
static av_cold int init(AVCodecContext *avctx)
int ff_canopus_parse_info_tag(AVCodecContext *avctx, const uint8_t *src, size_t size)
void(* idct_put)(uint8_t *dst, int stride, int16_t *block)
static int hq_hqa_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static av_cold int hq_hqa_decode_init(AVCodecContext *avctx)
static int hq_decode_mb(HQContext *c, AVFrame *pic, GetBitContext *gb, int x, int y)
const int32_t *const ff_hq_quants[16][2][4]
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
AVCodec ff_hq_hqa_decoder
static int get_sbits(GetBitContext *s, int n)
const HQProfile ff_hq_profile[NUM_HQ_PROFILES]
Macro definitions for various function/variable attributes.
HQ/HQA variant of AAN IDCT It differs from the standard AAN IDCT in precision and in the second stage...
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb, int quant, int slice_no, int w, int h)
#define AV_LOG_VERBOSE
Detailed information.
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
const char * name
Name of the codec implementation.
int ff_hq_init_vlcs(HQContext *c)
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup, GetBitContext *gb, int x, int y)
enum AVPictureType pict_type
Picture type of the frame.
int width
picture width / height.
static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size)
static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE(*table)[2], int bits, int max_depth)
Parse a vlc code.
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
main external API structure.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
static unsigned int get_bits1(GetBitContext *s)
BYTE int const BYTE int int int height
const int16_t ff_hq_ac_syms[NUM_HQ_AC_ENTRIES]
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
const uint8_t ff_zigzag_direct[64]
static void put_blocks(HQContext *c, AVFrame *pic, int plane, int x, int y, int ilace, int16_t *block0, int16_t *block1)
static int16_t block1[64]
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt)
common internal api header.
static int hq_decode_block(HQContext *c, GetBitContext *gb, int16_t block[64], int qsel, int is_chroma, int is_hqa)
static av_cold int hq_hqa_decode_close(AVCodecContext *avctx)
VLC_TYPE(* table)[2]
code, bits
int key_frame
1 -> keyframe, 0-> not
av_cold void ff_hqdsp_init(HQDSPContext *c)
#define MKTAG(a, b, c, d)
This structure stores compressed data.
void ff_free_vlc(VLC *vlc)
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
const uint8_t ff_hq_ac_skips[NUM_HQ_AC_ENTRIES]