FFmpeg  4.4.5
hq_hqa.c
Go to the documentation of this file.
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) * 64;
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) * 64;
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 
84  if (pos >= 64)
85  break;
86  block[ff_zigzag_direct[pos]] = (int)(ff_hq_ac_syms[val] * (unsigned)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 
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  if (get_bits_left(gb) < 1)
185  return AVERROR_INVALIDDATA;
186 
187  cbp = get_vlc2(gb, c->hqa_cbp_vlc.table, 5, 1);
188 
189  for (i = 0; i < 12; i++)
190  memset(c->block[i], 0, sizeof(*c->block));
191  for (i = 0; i < 12; i++)
192  c->block[i][0] = -128 * (1 << 6);
193 
194  if (cbp) {
195  flag = get_bits1(gb);
196 
197  cbp |= cbp << 4;
198  if (cbp & 0x3)
199  cbp |= 0x500;
200  if (cbp & 0xC)
201  cbp |= 0xA00;
202  for (i = 0; i < 12; i++) {
203  if (!(cbp & (1 << i)))
204  continue;
205  ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 8, 1);
206  if (ret < 0)
207  return ret;
208  }
209  }
210 
211  put_blocks(c, pic, 3, x, y, flag, c->block[ 0], c->block[ 2]);
212  put_blocks(c, pic, 3, x + 8, y, flag, c->block[ 1], c->block[ 3]);
213  put_blocks(c, pic, 0, x, y, flag, c->block[ 4], c->block[ 6]);
214  put_blocks(c, pic, 0, x + 8, y, flag, c->block[ 5], c->block[ 7]);
215  put_blocks(c, pic, 2, x >> 1, y, flag, c->block[ 8], c->block[ 9]);
216  put_blocks(c, pic, 1, x >> 1, y, flag, c->block[10], c->block[11]);
217 
218  return 0;
219 }
220 
222  int quant, int slice_no, int w, int h)
223 {
224  int i, j, off;
225  int ret;
226 
227  for (i = 0; i < h; i += 16) {
228  off = (slice_no * 16 + i * 3) & 0x70;
229  for (j = off; j < w; j += 128) {
230  ret = hqa_decode_mb(ctx, pic, quant, gb, j, i);
231  if (ret < 0) {
232  av_log(ctx->avctx, AV_LOG_ERROR,
233  "Error decoding macroblock at %dx%d.\n", i, j);
234  return ret;
235  }
236  }
237  }
238 
239  return 0;
240 }
241 
242 static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size)
243 {
244  GetBitContext gb;
245  const int num_slices = 8;
246  uint32_t slice_off[9];
247  int i, slice, ret;
248  int width, height, quant;
249  const uint8_t *src = ctx->gbc.buffer;
250 
251  if (bytestream2_get_bytes_left(&ctx->gbc) < 8 + 4*(num_slices + 1))
252  return AVERROR_INVALIDDATA;
253 
254  width = bytestream2_get_be16(&ctx->gbc);
255  height = bytestream2_get_be16(&ctx->gbc);
256 
257  ret = ff_set_dimensions(ctx->avctx, width, height);
258  if (ret < 0)
259  return ret;
260 
261  ctx->avctx->coded_width = FFALIGN(width, 16);
262  ctx->avctx->coded_height = FFALIGN(height, 16);
263  ctx->avctx->bits_per_raw_sample = 8;
264  ctx->avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
265 
266  av_log(ctx->avctx, AV_LOG_VERBOSE, "HQA Profile\n");
267 
268  quant = bytestream2_get_byte(&ctx->gbc);
269  bytestream2_skip(&ctx->gbc, 3);
270  if (quant >= NUM_HQ_QUANTS) {
271  av_log(ctx->avctx, AV_LOG_ERROR,
272  "Invalid quantization matrix %d.\n", quant);
273  return AVERROR_INVALIDDATA;
274  }
275 
276  ret = ff_get_buffer(ctx->avctx, pic, 0);
277  if (ret < 0)
278  return ret;
279 
280  /* Offsets are stored from HQA1 position, so adjust them accordingly. */
281  for (i = 0; i < num_slices + 1; i++)
282  slice_off[i] = bytestream2_get_be32(&ctx->gbc) - 4;
283 
284  for (slice = 0; slice < num_slices; slice++) {
285  if (slice_off[slice] < (num_slices + 1) * 3 ||
286  slice_off[slice] >= slice_off[slice + 1] ||
287  slice_off[slice + 1] > data_size) {
288  av_log(ctx->avctx, AV_LOG_ERROR,
289  "Invalid slice size %"SIZE_SPECIFIER".\n", data_size);
290  break;
291  }
292  init_get_bits(&gb, src + slice_off[slice],
293  (slice_off[slice + 1] - slice_off[slice]) * 8);
294 
295  ret = hqa_decode_slice(ctx, pic, &gb, quant, slice, width, height);
296  if (ret < 0)
297  return ret;
298  }
299 
300  return 0;
301 }
302 
303 static int hq_hqa_decode_frame(AVCodecContext *avctx, void *data,
304  int *got_frame, AVPacket *avpkt)
305 {
306  HQContext *ctx = avctx->priv_data;
307  AVFrame *pic = data;
308  uint32_t info_tag;
309  unsigned int data_size;
310  int ret;
311  unsigned tag;
312 
313  bytestream2_init(&ctx->gbc, avpkt->data, avpkt->size);
314  if (bytestream2_get_bytes_left(&ctx->gbc) < 4 + 4) {
315  av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", avpkt->size);
316  return AVERROR_INVALIDDATA;
317  }
318 
319  info_tag = bytestream2_peek_le32(&ctx->gbc);
320  if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
321  int info_size;
322  bytestream2_skip(&ctx->gbc, 4);
323  info_size = bytestream2_get_le32(&ctx->gbc);
324  if (info_size < 0 || bytestream2_get_bytes_left(&ctx->gbc) < info_size) {
325  av_log(avctx, AV_LOG_ERROR, "Invalid INFO size (%d).\n", info_size);
326  return AVERROR_INVALIDDATA;
327  }
328  ff_canopus_parse_info_tag(avctx, ctx->gbc.buffer, info_size);
329 
330  bytestream2_skip(&ctx->gbc, info_size);
331  }
332 
333  data_size = bytestream2_get_bytes_left(&ctx->gbc);
334  if (data_size < 4) {
335  av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", data_size);
336  return AVERROR_INVALIDDATA;
337  }
338 
339  /* HQ defines dimensions and number of slices, and thus slice traversal
340  * order. HQA has no size constraint and a fixed number of slices, so it
341  * needs a separate scheme for it. */
342  tag = bytestream2_get_le32(&ctx->gbc);
343  if ((tag & 0x00FFFFFF) == (MKTAG('U', 'V', 'C', ' ') & 0x00FFFFFF)) {
344  ret = hq_decode_frame(ctx, pic, tag >> 24, data_size);
345  } else if (tag == MKTAG('H', 'Q', 'A', '1')) {
346  ret = hqa_decode_frame(ctx, pic, data_size);
347  } else {
348  av_log(avctx, AV_LOG_ERROR, "Not a HQ/HQA frame.\n");
349  return AVERROR_INVALIDDATA;
350  }
351  if (ret < 0) {
352  av_log(avctx, AV_LOG_ERROR, "Error decoding frame.\n");
353  return ret;
354  }
355 
356  pic->key_frame = 1;
358 
359  *got_frame = 1;
360 
361  return avpkt->size;
362 }
363 
365 {
366  HQContext *ctx = avctx->priv_data;
367  ctx->avctx = avctx;
368 
369  ff_hqdsp_init(&ctx->hqhqadsp);
370 
371  return ff_hq_init_vlcs(ctx);
372 }
373 
375 {
376  HQContext *ctx = avctx->priv_data;
377 
378  ff_free_vlc(&ctx->hq_ac_vlc);
379  ff_free_vlc(&ctx->hqa_cbp_vlc);
380 
381  return 0;
382 }
383 
385  .name = "hq_hqa",
386  .long_name = NULL_IF_CONFIG_SMALL("Canopus HQ/HQA"),
387  .type = AVMEDIA_TYPE_VIDEO,
388  .id = AV_CODEC_ID_HQ_HQA,
389  .priv_data_size = sizeof(HQContext),
392  .close = hq_hqa_decode_close,
393  .capabilities = AV_CODEC_CAP_DR1,
394  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
396 };
static double val(void *priv, double ch)
Definition: aeval.c:76
Macro definitions for various function/variable attributes.
#define av_cold
Definition: attributes.h:88
uint8_t
int32_t
Libavcodec external API header.
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
void ff_free_vlc(VLC *vlc)
Definition: bitstream.c:431
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
int ff_canopus_parse_info_tag(AVCodecContext *avctx, const uint8_t *src, size_t size)
Definition: canopus.c:30
#define flag(name)
Definition: cbs_av1.c:564
#define MKTAG(a, b, c, d)
Definition: common.h:478
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1900
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
perm
Definition: f_perms.c:74
int
bitstream reader API header.
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:359
static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE(*table)[2], int bits, int max_depth)
Parse a vlc code.
Definition: get_bits.h:797
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:659
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
@ AV_CODEC_ID_HQ_HQA
Definition: codec_id.h:237
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
static int hq_decode_mb(HQContext *c, AVFrame *pic, GetBitContext *gb, int x, int y)
Definition: hq_hqa.c:93
static int hq_decode_block(HQContext *c, GetBitContext *gb, int16_t block[64], int qsel, int is_chroma, int is_hqa)
Definition: hq_hqa.c:62
AVCodec ff_hq_hqa_decoder
Definition: hq_hqa.c:384
static int hq_decode_frame(HQContext *ctx, AVFrame *pic, int prof_num, size_t data_size)
Definition: hq_hqa.c:116
static av_cold int hq_hqa_decode_close(AVCodecContext *avctx)
Definition: hq_hqa.c:374
static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size)
Definition: hq_hqa.c:242
static void put_blocks(HQContext *c, AVFrame *pic, int plane, int x, int y, int ilace, int16_t *block0, int16_t *block1)
Definition: hq_hqa.c:50
static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup, GetBitContext *gb, int x, int y)
Definition: hq_hqa.c:178
static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb, int quant, int slice_no, int w, int h)
Definition: hq_hqa.c:221
static int hq_hqa_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: hq_hqa.c:303
static av_cold int hq_hqa_decode_init(AVCodecContext *avctx)
Definition: hq_hqa.c:364
const HQProfile ff_hq_profile[NUM_HQ_PROFILES]
Definition: hq_hqadata.c:8343
const int32_t *const ff_hq_quants[16][2][4]
Definition: hq_hqadata.c:1126
#define NUM_HQ_QUANTS
Definition: hq_hqa.h:35
#define NUM_HQ_PROFILES
Definition: hq_hqa.h:34
const uint8_t ff_hq_ac_skips[NUM_HQ_AC_ENTRIES]
Definition: hq_hqadata.c:1292
int ff_hq_init_vlcs(HQContext *c)
Definition: hq_hqadata.c:8368
const int16_t ff_hq_ac_syms[NUM_HQ_AC_ENTRIES]
Definition: hq_hqadata.c:1342
av_cold void ff_hqdsp_init(HQDSPContext *c)
Definition: hq_hqadsp.c:127
HQ/HQA variant of AAN IDCT It differs from the standard AAN IDCT in precision and in the second stage...
int i
Definition: input.c:407
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:41
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:49
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:84
common internal API header
#define SIZE_SPECIFIER
Definition: internal.h:193
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
uint8_t w
Definition: llviddspenc.c:39
#define FFALIGN(x, a)
Definition: macros.h:48
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
uint32_t tag
Definition: movenc.c:1611
const char data[16]
Definition: mxf.c:142
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
mfxU16 profile
Definition: qsvenc.c:45
unsigned int pos
Definition: spdifenc.c:412
main external API structure.
Definition: avcodec.h:536
void * priv_data
Definition: avcodec.h:563
AVCodec.
Definition: codec.h:197
const char * name
Name of the codec implementation.
Definition: codec.h:204
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:396
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:401
This structure stores compressed data.
Definition: packet.h:346
int size
Definition: packet.h:370
uint8_t * data
Definition: packet.h:369
#define avpriv_request_sample(...)
#define av_log(a,...)
#define src
Definition: vp8dsp.c:255
static int16_t block[64]
Definition: dct.c:116
static int16_t block1[64]
Definition: dct.c:117
AVFormatContext * ctx
Definition: movenc.c:48
#define height
#define width
if(ret< 0)
Definition: vf_mcdeint.c:282
const uint8_t * quant
static double c[64]