FFmpeg
hqx.c
Go to the documentation of this file.
1 /*
2  * Canopus HQX 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 <inttypes.h>
22 
23 #include "libavutil/imgutils.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 #include "thread.h"
31 
32 #include "hqx.h"
33 #include "hqxdsp.h"
34 
35 /* HQX has four modes - 422, 444, 422alpha and 444alpha - all 12-bit */
36 enum HQXFormat {
37  HQX_422 = 0,
41 };
42 
43 #define HQX_HEADER_SIZE 59
44 
45 /* macroblock selects a group of 4 possible quants and
46  * a block can use any of those four quantisers
47  * one column is powers of 2, the other one is powers of 2 * 3,
48  * then there is the special one, powers of 2 * 5 */
49 static const int hqx_quants[16][4] = {
50  { 0x1, 0x2, 0x4, 0x8 }, { 0x1, 0x3, 0x6, 0xC },
51  { 0x2, 0x4, 0x8, 0x10 }, { 0x3, 0x6, 0xC, 0x18 },
52  { 0x4, 0x8, 0x10, 0x20 }, { 0x6, 0xC, 0x18, 0x30 },
53  { 0x8, 0x10, 0x20, 0x40 },
54  { 0xA, 0x14, 0x28, 0x50 },
55  { 0xC, 0x18, 0x30, 0x60 },
56  { 0x10, 0x20, 0x40, 0x80 }, { 0x18, 0x30, 0x60, 0xC0 },
57  { 0x20, 0x40, 0x80, 0x100 }, { 0x30, 0x60, 0xC0, 0x180 },
58  { 0x40, 0x80, 0x100, 0x200 }, { 0x60, 0xC0, 0x180, 0x300 },
59  { 0x80, 0x100, 0x200, 0x400 }
60 };
61 
62 static const uint8_t hqx_quant_luma[64] = {
63  16, 16, 16, 19, 19, 19, 42, 44,
64  16, 16, 19, 19, 19, 38, 43, 45,
65  16, 19, 19, 19, 40, 41, 45, 48,
66  19, 19, 19, 40, 41, 42, 46, 49,
67  19, 19, 40, 41, 42, 43, 48, 101,
68  19, 38, 41, 42, 43, 44, 98, 104,
69  42, 43, 45, 46, 48, 98, 109, 116,
70  44, 45, 48, 49, 101, 104, 116, 123,
71 };
72 
73 static const uint8_t hqx_quant_chroma[64] = {
74  16, 16, 19, 25, 26, 26, 42, 44,
75  16, 19, 25, 25, 26, 38, 43, 91,
76  19, 25, 26, 27, 40, 41, 91, 96,
77  25, 25, 27, 40, 41, 84, 93, 197,
78  26, 26, 40, 41, 84, 86, 191, 203,
79  26, 38, 41, 84, 86, 177, 197, 209,
80  42, 43, 91, 93, 191, 197, 219, 232,
81  44, 91, 96, 197, 203, 209, 232, 246,
82 };
83 
84 static inline void put_blocks(HQXContext *ctx, int plane,
85  int x, int y, int ilace,
86  int16_t *block0, int16_t *block1,
87  const uint8_t *quant)
88 {
89  int fields = ilace ? 2 : 1;
90  int lsize = ctx->pic->linesize[plane];
91  uint8_t *p = ctx->pic->data[plane] + x * 2;
92 
93  ctx->hqxdsp.idct_put((uint16_t *)(p + y * lsize),
94  lsize * fields, block0, quant);
95  ctx->hqxdsp.idct_put((uint16_t *)(p + (y + (ilace ? 1 : 8)) * lsize),
96  lsize * fields, block1, quant);
97 }
98 
99 static inline void hqx_get_ac(GetBitContext *gb, const HQXAC *ac,
100  int *run, int *lev)
101 {
102  int val;
103 
104  val = show_bits(gb, ac->lut_bits);
105  if (ac->lut[val].bits == -1) {
106  GetBitContext gb2 = *gb;
107  skip_bits(&gb2, ac->lut_bits);
108  val = ac->lut[val].lev + show_bits(&gb2, ac->extra_bits);
109  }
110  *run = ac->lut[val].run;
111  *lev = ac->lut[val].lev;
112  skip_bits(gb, ac->lut[val].bits);
113 }
114 
115 static int decode_block(GetBitContext *gb, VLC *vlc,
116  const int *quants, int dcb,
117  int16_t block[64], int *last_dc)
118 {
119  int q, dc;
120  int ac_idx;
121  int run, lev, pos = 1;
122 
123  memset(block, 0, 64 * sizeof(*block));
124  dc = get_vlc2(gb, vlc->table, HQX_DC_VLC_BITS, 2);
125  if (dc < 0)
126  return AVERROR_INVALIDDATA;
127  *last_dc += dc;
128 
129  block[0] = sign_extend(*last_dc << (12 - dcb), 12);
130 
131  q = quants[get_bits(gb, 2)];
132  if (q >= 128)
133  ac_idx = HQX_AC_Q128;
134  else if (q >= 64)
135  ac_idx = HQX_AC_Q64;
136  else if (q >= 32)
137  ac_idx = HQX_AC_Q32;
138  else if (q >= 16)
139  ac_idx = HQX_AC_Q16;
140  else if (q >= 8)
141  ac_idx = HQX_AC_Q8;
142  else
143  ac_idx = HQX_AC_Q0;
144 
145  do {
146  hqx_get_ac(gb, &ff_hqx_ac[ac_idx], &run, &lev);
147  pos += run;
148  if (pos >= 64)
149  break;
150  block[ff_zigzag_direct[pos++]] = lev * q;
151  } while (pos < 64);
152 
153  return 0;
154 }
155 
156 static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y)
157 {
158  HQXSlice *slice = &ctx->slice[slice_no];
159  GetBitContext *gb = &slice->gb;
160  const int *quants;
161  int flag;
162  int last_dc;
163  int i, ret;
164 
165  if (ctx->interlaced)
166  flag = get_bits1(gb);
167  else
168  flag = 0;
169 
170  quants = hqx_quants[get_bits(gb, 4)];
171 
172  for (i = 0; i < 8; i++) {
173  int vlc_index = ctx->dcb - 9;
174  if (i == 0 || i == 4 || i == 6)
175  last_dc = 0;
176  ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
177  ctx->dcb, slice->block[i], &last_dc);
178  if (ret < 0)
179  return ret;
180  }
181 
182  put_blocks(ctx, 0, x, y, flag, slice->block[0], slice->block[2], hqx_quant_luma);
183  put_blocks(ctx, 0, x + 8, y, flag, slice->block[1], slice->block[3], hqx_quant_luma);
184  put_blocks(ctx, 2, x >> 1, y, flag, slice->block[4], slice->block[5], hqx_quant_chroma);
185  put_blocks(ctx, 1, x >> 1, y, flag, slice->block[6], slice->block[7], hqx_quant_chroma);
186 
187  return 0;
188 }
189 
190 static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y)
191 {
192  HQXSlice *slice = &ctx->slice[slice_no];
193  GetBitContext *gb = &slice->gb;
194  const int *quants;
195  int flag = 0;
196  int last_dc;
197  int i, ret;
198  int cbp;
199 
200  cbp = get_vlc2(gb, ctx->cbp_vlc.table, ctx->cbp_vlc.bits, 1);
201 
202  for (i = 0; i < 12; i++)
203  memset(slice->block[i], 0, sizeof(**slice->block) * 64);
204  for (i = 0; i < 12; i++)
205  slice->block[i][0] = -0x800;
206  if (cbp) {
207  if (ctx->interlaced)
208  flag = get_bits1(gb);
209 
210  quants = hqx_quants[get_bits(gb, 4)];
211 
212  cbp |= cbp << 4; // alpha CBP
213  if (cbp & 0x3) // chroma CBP - top
214  cbp |= 0x500;
215  if (cbp & 0xC) // chroma CBP - bottom
216  cbp |= 0xA00;
217  for (i = 0; i < 12; i++) {
218  if (i == 0 || i == 4 || i == 8 || i == 10)
219  last_dc = 0;
220  if (cbp & (1 << i)) {
221  int vlc_index = ctx->dcb - 9;
222  ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
223  ctx->dcb, slice->block[i], &last_dc);
224  if (ret < 0)
225  return ret;
226  }
227  }
228  }
229 
230  put_blocks(ctx, 3, x, y, flag, slice->block[ 0], slice->block[ 2], hqx_quant_luma);
231  put_blocks(ctx, 3, x + 8, y, flag, slice->block[ 1], slice->block[ 3], hqx_quant_luma);
232  put_blocks(ctx, 0, x, y, flag, slice->block[ 4], slice->block[ 6], hqx_quant_luma);
233  put_blocks(ctx, 0, x + 8, y, flag, slice->block[ 5], slice->block[ 7], hqx_quant_luma);
234  put_blocks(ctx, 2, x >> 1, y, flag, slice->block[ 8], slice->block[ 9], hqx_quant_chroma);
235  put_blocks(ctx, 1, x >> 1, y, flag, slice->block[10], slice->block[11], hqx_quant_chroma);
236 
237  return 0;
238 }
239 
240 static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y)
241 {
242  HQXSlice *slice = &ctx->slice[slice_no];
243  GetBitContext *gb = &slice->gb;
244  const int *quants;
245  int flag;
246  int last_dc;
247  int i, ret;
248 
249  if (ctx->interlaced)
250  flag = get_bits1(gb);
251  else
252  flag = 0;
253 
254  quants = hqx_quants[get_bits(gb, 4)];
255 
256  for (i = 0; i < 12; i++) {
257  int vlc_index = ctx->dcb - 9;
258  if (i == 0 || i == 4 || i == 8)
259  last_dc = 0;
260  ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
261  ctx->dcb, slice->block[i], &last_dc);
262  if (ret < 0)
263  return ret;
264  }
265 
266  put_blocks(ctx, 0, x, y, flag, slice->block[0], slice->block[ 2], hqx_quant_luma);
267  put_blocks(ctx, 0, x + 8, y, flag, slice->block[1], slice->block[ 3], hqx_quant_luma);
268  put_blocks(ctx, 2, x, y, flag, slice->block[4], slice->block[ 6], hqx_quant_chroma);
269  put_blocks(ctx, 2, x + 8, y, flag, slice->block[5], slice->block[ 7], hqx_quant_chroma);
270  put_blocks(ctx, 1, x, y, flag, slice->block[8], slice->block[10], hqx_quant_chroma);
271  put_blocks(ctx, 1, x + 8, y, flag, slice->block[9], slice->block[11], hqx_quant_chroma);
272 
273  return 0;
274 }
275 
276 static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
277 {
278  HQXSlice *slice = &ctx->slice[slice_no];
279  GetBitContext *gb = &slice->gb;
280  const int *quants;
281  int flag = 0;
282  int last_dc;
283  int i, ret;
284  int cbp;
285 
286  cbp = get_vlc2(gb, ctx->cbp_vlc.table, ctx->cbp_vlc.bits, 1);
287 
288  for (i = 0; i < 16; i++)
289  memset(slice->block[i], 0, sizeof(**slice->block) * 64);
290  for (i = 0; i < 16; i++)
291  slice->block[i][0] = -0x800;
292  if (cbp) {
293  if (ctx->interlaced)
294  flag = get_bits1(gb);
295 
296  quants = hqx_quants[get_bits(gb, 4)];
297 
298  cbp |= cbp << 4; // alpha CBP
299  cbp |= cbp << 8; // chroma CBP
300  for (i = 0; i < 16; i++) {
301  if (i == 0 || i == 4 || i == 8 || i == 12)
302  last_dc = 0;
303  if (cbp & (1 << i)) {
304  int vlc_index = ctx->dcb - 9;
305  ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants,
306  ctx->dcb, slice->block[i], &last_dc);
307  if (ret < 0)
308  return ret;
309  }
310  }
311  }
312 
313  put_blocks(ctx, 3, x, y, flag, slice->block[ 0], slice->block[ 2], hqx_quant_luma);
314  put_blocks(ctx, 3, x + 8, y, flag, slice->block[ 1], slice->block[ 3], hqx_quant_luma);
315  put_blocks(ctx, 0, x, y, flag, slice->block[ 4], slice->block[ 6], hqx_quant_luma);
316  put_blocks(ctx, 0, x + 8, y, flag, slice->block[ 5], slice->block[ 7], hqx_quant_luma);
317  put_blocks(ctx, 2, x, y, flag, slice->block[ 8], slice->block[10], hqx_quant_chroma);
318  put_blocks(ctx, 2, x + 8, y, flag, slice->block[ 9], slice->block[11], hqx_quant_chroma);
319  put_blocks(ctx, 1, x, y, flag, slice->block[12], slice->block[14], hqx_quant_chroma);
320  put_blocks(ctx, 1, x + 8, y, flag, slice->block[13], slice->block[15], hqx_quant_chroma);
321 
322  return 0;
323 }
324 
325 static const int shuffle_16[16] = {
326  0, 5, 11, 14, 2, 7, 9, 13, 1, 4, 10, 15, 3, 6, 8, 12
327 };
328 
329 static int decode_slice(HQXContext *ctx, int slice_no)
330 {
331  int mb_w = (ctx->width + 15) >> 4;
332  int mb_h = (ctx->height + 15) >> 4;
333  int grp_w = (mb_w + 4) / 5;
334  int grp_h = (mb_h + 4) / 5;
335  int grp_h_edge = grp_w * (mb_w / grp_w);
336  int grp_v_edge = grp_h * (mb_h / grp_h);
337  int grp_v_rest = mb_w - grp_h_edge;
338  int grp_h_rest = mb_h - grp_v_edge;
339  int num_mbs = mb_w * mb_h;
340  int num_tiles = (num_mbs + 479) / 480;
341  int std_tile_blocks = num_mbs / (16 * num_tiles);
342  int g_tile = slice_no * num_tiles;
343  int blk_addr, loc_addr, mb_x, mb_y, pos, loc_row, i;
344  int tile_blocks, tile_limit, tile_no;
345 
346  for (tile_no = 0; tile_no < num_tiles; tile_no++, g_tile++) {
347  tile_blocks = std_tile_blocks;
348  tile_limit = -1;
349  if (g_tile < num_mbs - std_tile_blocks * 16 * num_tiles) {
350  tile_limit = num_mbs / (16 * num_tiles);
351  tile_blocks++;
352  }
353  for (i = 0; i < tile_blocks; i++) {
354  if (i == tile_limit)
355  blk_addr = g_tile + 16 * num_tiles * i;
356  else
357  blk_addr = tile_no + 16 * num_tiles * i +
358  num_tiles * shuffle_16[(i + slice_no) & 0xF];
359  loc_row = grp_h * (blk_addr / (grp_h * mb_w));
360  loc_addr = blk_addr % (grp_h * mb_w);
361  if (loc_row >= grp_v_edge) {
362  mb_x = grp_w * (loc_addr / (grp_h_rest * grp_w));
363  pos = loc_addr % (grp_h_rest * grp_w);
364  } else {
365  mb_x = grp_w * (loc_addr / (grp_h * grp_w));
366  pos = loc_addr % (grp_h * grp_w);
367  }
368  if (mb_x >= grp_h_edge) {
369  mb_x += pos % grp_v_rest;
370  mb_y = loc_row + (pos / grp_v_rest);
371  } else {
372  mb_x += pos % grp_w;
373  mb_y = loc_row + (pos / grp_w);
374  }
375  ctx->decode_func(ctx, slice_no, mb_x * 16, mb_y * 16);
376  }
377  }
378 
379  return 0;
380 }
381 
382 static int decode_slice_thread(AVCodecContext *avctx, void *arg,
383  int slice_no, int threadnr)
384 {
385  HQXContext *ctx = avctx->priv_data;
386  uint32_t *slice_off = ctx->slice_off;
387  int ret;
388 
389  if (slice_off[slice_no] < HQX_HEADER_SIZE ||
390  slice_off[slice_no] >= slice_off[slice_no + 1] ||
391  slice_off[slice_no + 1] > ctx->data_size) {
392  av_log(avctx, AV_LOG_ERROR, "Invalid slice size %d.\n", ctx->data_size);
393  return AVERROR_INVALIDDATA;
394  }
395 
396  ret = init_get_bits8(&ctx->slice[slice_no].gb,
397  ctx->src + slice_off[slice_no],
398  slice_off[slice_no + 1] - slice_off[slice_no]);
399  if (ret < 0)
400  return ret;
401 
402  return decode_slice(ctx, slice_no);
403 }
404 
405 static int hqx_decode_frame(AVCodecContext *avctx, void *data,
406  int *got_picture_ptr, AVPacket *avpkt)
407 {
408  HQXContext *ctx = avctx->priv_data;
409  ThreadFrame frame = { .f = data };
410  uint8_t *src = avpkt->data;
411  uint32_t info_tag;
412  int data_start;
413  int i, ret;
414 
415  if (avpkt->size < 4 + 4) {
416  av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size);
417  return AVERROR_INVALIDDATA;
418  }
419 
420  info_tag = AV_RL32(src);
421  if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
422  uint32_t info_offset = AV_RL32(src + 4);
423  if (info_offset > INT_MAX || info_offset + 8 > avpkt->size) {
424  av_log(avctx, AV_LOG_ERROR,
425  "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n",
426  info_offset);
427  return AVERROR_INVALIDDATA;
428  }
429  ff_canopus_parse_info_tag(avctx, src + 8, info_offset);
430 
431  info_offset += 8;
432  src += info_offset;
433  }
434 
435  data_start = src - avpkt->data;
436  ctx->data_size = avpkt->size - data_start;
437  ctx->src = src;
438  ctx->pic = data;
439 
440  if (ctx->data_size < HQX_HEADER_SIZE) {
441  av_log(avctx, AV_LOG_ERROR, "Frame too small.\n");
442  return AVERROR_INVALIDDATA;
443  }
444 
445  if (src[0] != 'H' || src[1] != 'Q') {
446  av_log(avctx, AV_LOG_ERROR, "Not an HQX frame.\n");
447  return AVERROR_INVALIDDATA;
448  }
449  ctx->interlaced = !(src[2] & 0x80);
450  ctx->format = src[2] & 7;
451  ctx->dcb = (src[3] & 3) + 8;
452  ctx->width = AV_RB16(src + 4);
453  ctx->height = AV_RB16(src + 6);
454  for (i = 0; i < 17; i++)
455  ctx->slice_off[i] = AV_RB24(src + 8 + i * 3);
456 
457  if (ctx->dcb == 8) {
458  av_log(avctx, AV_LOG_ERROR, "Invalid DC precision %d.\n", ctx->dcb);
459  return AVERROR_INVALIDDATA;
460  }
461  ret = av_image_check_size(ctx->width, ctx->height, 0, avctx);
462  if (ret < 0) {
463  av_log(avctx, AV_LOG_ERROR, "Invalid stored dimensions %dx%d.\n",
464  ctx->width, ctx->height);
465  return AVERROR_INVALIDDATA;
466  }
467 
468  avctx->coded_width = FFALIGN(ctx->width, 16);
469  avctx->coded_height = FFALIGN(ctx->height, 16);
470  avctx->width = ctx->width;
471  avctx->height = ctx->height;
472  avctx->bits_per_raw_sample = 10;
473 
474  switch (ctx->format) {
475  case HQX_422:
476  avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
477  ctx->decode_func = hqx_decode_422;
478  break;
479  case HQX_444:
480  avctx->pix_fmt = AV_PIX_FMT_YUV444P16;
481  ctx->decode_func = hqx_decode_444;
482  break;
483  case HQX_422A:
485  ctx->decode_func = hqx_decode_422a;
486  break;
487  case HQX_444A:
489  ctx->decode_func = hqx_decode_444a;
490  break;
491  default:
492  av_log(avctx, AV_LOG_ERROR, "Invalid format: %d.\n", ctx->format);
493  return AVERROR_INVALIDDATA;
494  }
495 
496  ret = ff_thread_get_buffer(avctx, &frame, 0);
497  if (ret < 0)
498  return ret;
499 
500  avctx->execute2(avctx, decode_slice_thread, NULL, NULL, 16);
501 
502  ctx->pic->key_frame = 1;
503  ctx->pic->pict_type = AV_PICTURE_TYPE_I;
504 
505  *got_picture_ptr = 1;
506 
507  return avpkt->size;
508 }
509 
511 {
512  int i;
513  HQXContext *ctx = avctx->priv_data;
514 
515  if (avctx->internal->is_copy)
516  return 0;
517 
518  ff_free_vlc(&ctx->cbp_vlc);
519  for (i = 0; i < 3; i++) {
520  ff_free_vlc(&ctx->dc_vlc[i]);
521  }
522 
523  return 0;
524 }
525 
527 {
528  HQXContext *ctx = avctx->priv_data;
529 
530  ff_hqxdsp_init(&ctx->hqxdsp);
531 
532  return ff_hqx_init_vlcs(ctx);
533 }
534 
536  .name = "hqx",
537  .long_name = NULL_IF_CONFIG_SMALL("Canopus HQX"),
538  .type = AVMEDIA_TYPE_VIDEO,
539  .id = AV_CODEC_ID_HQX,
540  .priv_data_size = sizeof(HQXContext),
543  .close = hqx_decode_close,
544  .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS |
546  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
548 };
AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:430
AVCodec
AVCodec.
Definition: avcodec.h:3481
ff_hqx_init_vlcs
int ff_hqx_init_vlcs(HQXContext *ctx)
Definition: hqxvlc.c:2151
FF_CODEC_CAP_INIT_THREADSAFE
#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:40
hqx_decode_init
static av_cold int hqx_decode_init(AVCodecContext *avctx)
Definition: hqx.c:526
HQXLUT::bits
int8_t bits
Definition: hqx.h:44
HQX_AC_Q8
@ HQX_AC_Q8
Definition: hqx.h:33
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
hqx_decode_422a
static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y)
Definition: hqx.c:190
HQX_422
@ HQX_422
Definition: hqx.c:37
HQXSlice::gb
GetBitContext gb
Definition: hqx.h:58
MKTAG
#define MKTAG(a, b, c, d)
Definition: common.h:366
ff_hqx_decoder
AVCodec ff_hqx_decoder
Definition: hqx.c:535
HQXAC::lut
const HQXLUT * lut
Definition: hqx.h:49
internal.h
AVPacket::data
uint8_t * data
Definition: avcodec.h:1477
hqx_decode_422
static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y)
Definition: hqx.c:156
hqx_decode_close
static av_cold int hqx_decode_close(AVCodecContext *avctx)
Definition: hqx.c:510
data
const char data[16]
Definition: mxf.c:91
get_vlc2
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
thread.h
ff_hqxdsp_init
av_cold void ff_hqxdsp_init(HQXDSPContext *c)
Definition: hqxdsp.c:128
decode_slice_thread
static int decode_slice_thread(AVCodecContext *avctx, void *arg, int slice_no, int threadnr)
Definition: hqx.c:382
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:467
AVCodecInternal::is_copy
int is_copy
Whether the parent AVCodecContext is a copy of the context which had init() called on it.
Definition: internal.h:136
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
HQXLUT::lev
int16_t lev
Definition: hqx.h:42
HQX_DC_VLC_BITS
#define HQX_DC_VLC_BITS
Definition: hqx.h:80
hqx_quant_luma
static const uint8_t hqx_quant_luma[64]
Definition: hqx.c:62
AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:431
ff_canopus_parse_info_tag
int ff_canopus_parse_info_tag(AVCodecContext *avctx, const uint8_t *src, size_t size)
Definition: canopus.c:30
plane
int plane
Definition: avisynth_c.h:384
GetBitContext
Definition: get_bits.h:61
hqx_quant_chroma
static const uint8_t hqx_quant_chroma[64]
Definition: hqx.c:73
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:1753
src
#define src
Definition: vp8dsp.c:254
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_cold
#define av_cold
Definition: attributes.h:84
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:399
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
HQXAC::lut_bits
int lut_bits
Definition: hqx.h:48
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
intreadwrite.h
HQX_444
@ HQX_444
Definition: hqx.c:38
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:400
hqx_decode_444
static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y)
Definition: hqx.c:240
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:2796
ctx
AVFormatContext * ctx
Definition: movenc.c:48
get_bits.h
ff_free_vlc
void ff_free_vlc(VLC *vlc)
Definition: bitstream.c:359
arg
const char * arg
Definition: jacosubdec.c:66
fields
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the then the processing requires a frame on this link and the filter is expected to make efforts in that direction The status of input links is stored by the fifo and status_out fields
Definition: filter_design.txt:155
HQX_AC_Q32
@ HQX_AC_Q32
Definition: hqx.h:35
if
if(ret)
Definition: filter_design.txt:179
HQXAC::extra_bits
int extra_bits
Definition: hqx.h:48
AV_CODEC_CAP_FRAME_THREADS
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: avcodec.h:1037
HQX_HEADER_SIZE
#define HQX_HEADER_SIZE
Definition: hqx.c:43
NULL
#define NULL
Definition: coverity.c:32
run
uint8_t run
Definition: svq3.c:206
ff_hqx_ac
const HQXAC ff_hqx_ac[NUM_HQX_AC]
Definition: hqxvlc.c:2132
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:1600
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
hqx.h
ff_thread_get_buffer
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:964
HQXLUT::run
uint8_t run
Definition: hqx.h:43
canopus.h
HQXSlice
Definition: hqx.h:57
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:981
AVPacket::size
int size
Definition: avcodec.h:1478
dc
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff) *mv_scale Intra DC Prediction block[y][x] dc[1]
Definition: snow.txt:400
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
put_blocks
static void put_blocks(HQXContext *ctx, int plane, int x, int y, int ilace, int16_t *block0, int16_t *block1, const uint8_t *quant)
Definition: hqx.c:84
decode_block
static int decode_block(GetBitContext *gb, VLC *vlc, const int *quants, int dcb, int16_t block[64], int *last_dc)
Definition: hqx.c:115
val
const char const char void * val
Definition: avisynth_c.h:863
hqxdsp.h
HQX_AC_Q64
@ HQX_AC_Q64
Definition: hqx.h:36
AV_CODEC_CAP_SLICE_THREADS
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: avcodec.h:1041
HQXContext
Definition: hqx.h:62
shuffle_16
static const int shuffle_16[16]
Definition: hqx.c:325
HQXSlice::block
int16_t block[16][64]
Definition: hqx.h:59
flag
#define flag(name)
Definition: cbs_av1.c:557
hqx_decode_444a
static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y)
Definition: hqx.c:276
hqx_quants
static const int hqx_quants[16][4]
Definition: hqx.c:49
AV_CODEC_ID_HQX
@ AV_CODEC_ID_HQX
Definition: avcodec.h:404
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
show_bits
static unsigned int show_bits(GetBitContext *s, int n)
Show 1-25 bits.
Definition: get_bits.h:446
FF_CODEC_CAP_INIT_CLEANUP
#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:48
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodec::name
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
AVCodecContext::height
int height
Definition: avcodec.h:1738
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
HQX_AC_Q128
@ HQX_AC_Q128
Definition: hqx.h:37
avcodec.h
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
decode_slice
static int decode_slice(HQXContext *ctx, int slice_no)
Definition: hqx.c:329
hqx_decode_frame
static int hqx_decode_frame(AVCodecContext *avctx, void *data, int *got_picture_ptr, AVPacket *avpkt)
Definition: hqx.c:405
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:88
HQX_444A
@ HQX_444A
Definition: hqx.c:40
AVCodecContext
main external API structure.
Definition: avcodec.h:1565
ThreadFrame
Definition: thread.h:34
HQX_AC_Q0
@ HQX_AC_Q0
Definition: hqx.h:32
VLC
Definition: vlc.h:26
HQXAC
Definition: hqx.h:47
sign_extend
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:130
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1753
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
quant
const uint8_t * quant
Definition: vorbis_enc_data.h:458
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:1592
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:1738
imgutils.h
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
HQXFormat
HQXFormat
Definition: hqx.c:36
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
av_image_check_size
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:282
AV_RB24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:93
VLC::table
VLC_TYPE(* table)[2]
code, bits
Definition: vlc.h:28
AVCodecContext::execute2
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
Definition: avcodec.h:2884
block1
static int16_t block1[64]
Definition: dct.c:116
hqx_get_ac
static void hqx_get_ac(GetBitContext *gb, const HQXAC *ac, int *run, int *lev)
Definition: hqx.c:99
HQX_AC_Q16
@ HQX_AC_Q16
Definition: hqx.h:34
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:94
HQX_422A
@ HQX_422A
Definition: hqx.c:39