FFmpeg
fic.c
Go to the documentation of this file.
1 /*
2  * Mirillis FIC decoder
3  *
4  * Copyright (c) 2014 Konstantin Shishkov
5  * Copyright (c) 2014 Derek Buitenhuis
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "libavutil/common.h"
25 #include "libavutil/mem_internal.h"
26 #include "libavutil/opt.h"
27 #include "avcodec.h"
28 #include "codec_internal.h"
29 #include "internal.h"
30 #include "get_bits.h"
31 #include "golomb.h"
32 
33 typedef struct FICThreadContext {
34  DECLARE_ALIGNED(16, int16_t, block)[64];
35  uint8_t *src;
36  int slice_h;
37  int src_size;
38  int y_off;
39  int p_frame;
41 
42 typedef struct FICContext {
43  AVClass *class;
47 
50 
51  const uint8_t *qmat;
52 
54 
57 
58  uint8_t cursor_buf[4096];
60 } FICContext;
61 
62 static const uint8_t fic_qmat_hq[64] = {
63  1, 2, 2, 2, 3, 3, 3, 4,
64  2, 2, 2, 3, 3, 3, 4, 4,
65  2, 2, 3, 3, 3, 4, 4, 4,
66  2, 2, 3, 3, 3, 4, 4, 5,
67  2, 3, 3, 3, 4, 4, 5, 6,
68  3, 3, 3, 4, 4, 5, 6, 7,
69  3, 3, 3, 4, 4, 5, 7, 7,
70  3, 3, 4, 4, 5, 7, 7, 7,
71 };
72 
73 static const uint8_t fic_qmat_lq[64] = {
74  1, 5, 6, 7, 8, 9, 9, 11,
75  5, 5, 7, 8, 9, 9, 11, 12,
76  6, 7, 8, 9, 9, 11, 11, 12,
77  7, 7, 8, 9, 9, 11, 12, 13,
78  7, 8, 9, 9, 10, 11, 13, 16,
79  8, 9, 9, 10, 11, 13, 16, 19,
80  8, 9, 9, 11, 12, 15, 18, 23,
81  9, 9, 11, 12, 15, 18, 23, 27
82 };
83 
84 static const uint8_t fic_header[7] = { 0, 0, 1, 'F', 'I', 'C', 'V' };
85 
86 #define FIC_HEADER_SIZE 27
87 #define CURSOR_OFFSET 59
88 
89 static av_always_inline void fic_idct(int16_t *blk, int step, int shift, int rnd)
90 {
91  const unsigned t0 = 27246 * blk[3 * step] + 18405 * blk[5 * step];
92  const unsigned t1 = 27246 * blk[5 * step] - 18405 * blk[3 * step];
93  const unsigned t2 = 6393 * blk[7 * step] + 32139 * blk[1 * step];
94  const unsigned t3 = 6393 * blk[1 * step] - 32139 * blk[7 * step];
95  const unsigned t4 = 5793U * ((int)(t2 + t0 + 0x800) >> 12);
96  const unsigned t5 = 5793U * ((int)(t3 + t1 + 0x800) >> 12);
97  const unsigned t6 = t2 - t0;
98  const unsigned t7 = t3 - t1;
99  const unsigned t8 = 17734 * blk[2 * step] - 42813 * blk[6 * step];
100  const unsigned t9 = 17734 * blk[6 * step] + 42814 * blk[2 * step];
101  const unsigned tA = (blk[0 * step] - blk[4 * step]) * 32768 + rnd;
102  const unsigned tB = (blk[0 * step] + blk[4 * step]) * 32768 + rnd;
103  blk[0 * step] = (int)( t4 + t9 + tB) >> shift;
104  blk[1 * step] = (int)( t6 + t7 + t8 + tA) >> shift;
105  blk[2 * step] = (int)( t6 - t7 - t8 + tA) >> shift;
106  blk[3 * step] = (int)( t5 - t9 + tB) >> shift;
107  blk[4 * step] = (int)( -t5 - t9 + tB) >> shift;
108  blk[5 * step] = (int)(-(t6 - t7) - t8 + tA) >> shift;
109  blk[6 * step] = (int)(-(t6 + t7) + t8 + tA) >> shift;
110  blk[7 * step] = (int)( -t4 + t9 + tB) >> shift;
111 }
112 
113 static void fic_idct_put(uint8_t *dst, int stride, int16_t *block)
114 {
115  int i, j;
116  int16_t *ptr;
117 
118  ptr = block;
119  fic_idct(ptr++, 8, 13, (1 << 12) + (1 << 17));
120  for (i = 1; i < 8; i++) {
121  fic_idct(ptr, 8, 13, 1 << 12);
122  ptr++;
123  }
124 
125  ptr = block;
126  for (i = 0; i < 8; i++) {
127  fic_idct(ptr, 1, 20, 0);
128  ptr += 8;
129  }
130 
131  ptr = block;
132  for (j = 0; j < 8; j++) {
133  for (i = 0; i < 8; i++)
134  dst[i] = av_clip_uint8(ptr[i]);
135  dst += stride;
136  ptr += 8;
137  }
138 }
140  uint8_t *dst, int stride, int16_t *block, int *is_p)
141 {
142  int i, num_coeff;
143 
144  if (get_bits_left(gb) < 8)
145  return AVERROR_INVALIDDATA;
146 
147  /* Is it a skip block? */
148  if (get_bits1(gb)) {
149  *is_p = 1;
150  return 0;
151  }
152 
153  memset(block, 0, sizeof(*block) * 64);
154 
155  num_coeff = get_bits(gb, 7);
156  if (num_coeff > 64)
157  return AVERROR_INVALIDDATA;
158 
159  for (i = 0; i < num_coeff; i++) {
160  int v = get_se_golomb(gb);
161  if (v < -2048 || v > 2048)
162  return AVERROR_INVALIDDATA;
163  block[ff_zigzag_direct[i]] = v *
164  ctx->qmat[ff_zigzag_direct[i]];
165  }
166 
167  fic_idct_put(dst, stride, block);
168 
169  return 0;
170 }
171 
172 static int fic_decode_slice(AVCodecContext *avctx, void *tdata)
173 {
174  FICContext *ctx = avctx->priv_data;
175  FICThreadContext *tctx = tdata;
176  GetBitContext gb;
177  uint8_t *src = tctx->src;
178  int slice_h = tctx->slice_h;
179  int src_size = tctx->src_size;
180  int y_off = tctx->y_off;
181  int x, y, p, ret;
182 
183  ret = init_get_bits8(&gb, src, src_size);
184  if (ret < 0)
185  return ret;
186 
187  for (p = 0; p < 3; p++) {
188  int stride = ctx->frame->linesize[p];
189  uint8_t* dst = ctx->frame->data[p] + (y_off >> !!p) * stride;
190 
191  for (y = 0; y < (slice_h >> !!p); y += 8) {
192  for (x = 0; x < (ctx->aligned_width >> !!p); x += 8) {
193  int ret;
194 
195  if ((ret = fic_decode_block(ctx, &gb, dst + x, stride,
196  tctx->block, &tctx->p_frame)) != 0)
197  return ret;
198  }
199 
200  dst += 8 * stride;
201  }
202  }
203 
204  return 0;
205 }
206 
207 static av_always_inline void fic_alpha_blend(uint8_t *dst, uint8_t *src,
208  int size, uint8_t *alpha)
209 {
210  int i;
211 
212  for (i = 0; i < size; i++)
213  dst[i] += ((src[i] - dst[i]) * alpha[i]) >> 8;
214 }
215 
216 static void fic_draw_cursor(AVCodecContext *avctx, int cur_x, int cur_y)
217 {
218  FICContext *ctx = avctx->priv_data;
219  uint8_t *ptr = ctx->cursor_buf;
220  uint8_t *dstptr[3];
221  uint8_t planes[4][1024];
222  uint8_t chroma[3][256];
223  int i, j, p;
224 
225  /* Convert to YUVA444. */
226  for (i = 0; i < 1024; i++) {
227  planes[0][i] = (( 25 * ptr[0] + 129 * ptr[1] + 66 * ptr[2]) / 255) + 16;
228  planes[1][i] = ((-38 * ptr[0] + 112 * ptr[1] + -74 * ptr[2]) / 255) + 128;
229  planes[2][i] = ((-18 * ptr[0] + 112 * ptr[1] + -94 * ptr[2]) / 255) + 128;
230  planes[3][i] = ptr[3];
231 
232  ptr += 4;
233  }
234 
235  /* Subsample chroma. */
236  for (i = 0; i < 32; i += 2)
237  for (j = 0; j < 32; j += 2)
238  for (p = 0; p < 3; p++)
239  chroma[p][16 * (i / 2) + j / 2] = (planes[p + 1][32 * i + j ] +
240  planes[p + 1][32 * i + j + 1] +
241  planes[p + 1][32 * (i + 1) + j ] +
242  planes[p + 1][32 * (i + 1) + j + 1]) / 4;
243 
244  /* Seek to x/y pos of cursor. */
245  for (i = 0; i < 3; i++)
246  dstptr[i] = ctx->final_frame->data[i] +
247  (ctx->final_frame->linesize[i] * (cur_y >> !!i)) +
248  (cur_x >> !!i) + !!i;
249 
250  /* Copy. */
251  for (i = 0; i < FFMIN(32, avctx->height - cur_y) - 1; i += 2) {
252  int lsize = FFMIN(32, avctx->width - cur_x);
253  int csize = lsize / 2;
254 
255  fic_alpha_blend(dstptr[0],
256  planes[0] + i * 32, lsize, planes[3] + i * 32);
257  fic_alpha_blend(dstptr[0] + ctx->final_frame->linesize[0],
258  planes[0] + (i + 1) * 32, lsize, planes[3] + (i + 1) * 32);
259  fic_alpha_blend(dstptr[1],
260  chroma[0] + (i / 2) * 16, csize, chroma[2] + (i / 2) * 16);
261  fic_alpha_blend(dstptr[2],
262  chroma[1] + (i / 2) * 16, csize, chroma[2] + (i / 2) * 16);
263 
264  dstptr[0] += ctx->final_frame->linesize[0] * 2;
265  dstptr[1] += ctx->final_frame->linesize[1];
266  dstptr[2] += ctx->final_frame->linesize[2];
267  }
268 }
269 
270 static int fic_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
271  int *got_frame, AVPacket *avpkt)
272 {
273  FICContext *ctx = avctx->priv_data;
274  uint8_t *src = avpkt->data;
275  int ret;
276  int slice, nslices;
277  int msize;
278  int tsize;
279  int cur_x, cur_y;
280  int skip_cursor = ctx->skip_cursor;
281  uint8_t *sdata;
282 
283  if ((ret = ff_reget_buffer(avctx, ctx->frame, 0)) < 0)
284  return ret;
285 
286  /* Header + at least one slice (4) */
287  if (avpkt->size < FIC_HEADER_SIZE + 4) {
288  av_log(avctx, AV_LOG_ERROR, "Frame data is too small.\n");
289  return AVERROR_INVALIDDATA;
290  }
291 
292  /* Check for header. */
293  if (memcmp(src, fic_header, 7))
294  av_log(avctx, AV_LOG_WARNING, "Invalid FIC Header.\n");
295 
296  /* Is it a skip frame? */
297  if (src[17]) {
298  if (!ctx->final_frame) {
299  av_log(avctx, AV_LOG_WARNING, "Initial frame is skipped\n");
300  return AVERROR_INVALIDDATA;
301  }
302  goto skip;
303  }
304 
305  nslices = src[13];
306  if (!nslices) {
307  av_log(avctx, AV_LOG_ERROR, "Zero slices found.\n");
308  return AVERROR_INVALIDDATA;
309  }
310 
311  /* High or Low Quality Matrix? */
312  ctx->qmat = src[23] ? fic_qmat_hq : fic_qmat_lq;
313 
314  /* Skip cursor data. */
315  tsize = AV_RB24(src + 24);
316  if (tsize > avpkt->size - FIC_HEADER_SIZE) {
317  av_log(avctx, AV_LOG_ERROR,
318  "Packet is too small to contain cursor (%d vs %d bytes).\n",
319  tsize, avpkt->size - FIC_HEADER_SIZE);
320  return AVERROR_INVALIDDATA;
321  }
322 
323  if (!tsize || !AV_RL16(src + 37) || !AV_RL16(src + 39))
324  skip_cursor = 1;
325 
326  if (!skip_cursor && tsize < 32) {
327  av_log(avctx, AV_LOG_WARNING,
328  "Cursor data too small. Skipping cursor.\n");
329  skip_cursor = 1;
330  }
331 
332  /* Cursor position. */
333  cur_x = AV_RL16(src + 33);
334  cur_y = AV_RL16(src + 35);
335  if (!skip_cursor && (cur_x > avctx->width || cur_y > avctx->height)) {
336  av_log(avctx, AV_LOG_DEBUG,
337  "Invalid cursor position: (%d,%d). Skipping cursor.\n",
338  cur_x, cur_y);
339  skip_cursor = 1;
340  }
341 
342  if (!skip_cursor && (AV_RL16(src + 37) != 32 || AV_RL16(src + 39) != 32)) {
343  av_log(avctx, AV_LOG_WARNING,
344  "Invalid cursor size. Skipping cursor.\n");
345  skip_cursor = 1;
346  }
347 
348  if (!skip_cursor && avpkt->size < CURSOR_OFFSET + sizeof(ctx->cursor_buf)) {
349  skip_cursor = 1;
350  }
351 
352  /* Slice height for all but the last slice. */
353  ctx->slice_h = 16 * (ctx->aligned_height >> 4) / nslices;
354  if (ctx->slice_h % 16)
355  ctx->slice_h = FFALIGN(ctx->slice_h - 16, 16);
356 
357  /* First slice offset and remaining data. */
358  sdata = src + tsize + FIC_HEADER_SIZE + 4 * nslices;
359  msize = avpkt->size - nslices * 4 - tsize - FIC_HEADER_SIZE;
360 
361  if (msize <= ctx->aligned_width/8 * (ctx->aligned_height/8) / 8) {
362  av_log(avctx, AV_LOG_ERROR, "Not enough frame data to decode.\n");
363  return AVERROR_INVALIDDATA;
364  }
365 
366  /* Allocate slice data. */
367  av_fast_malloc(&ctx->slice_data, &ctx->slice_data_size,
368  nslices * sizeof(ctx->slice_data[0]));
369  if (!ctx->slice_data_size) {
370  av_log(avctx, AV_LOG_ERROR, "Could not allocate slice data.\n");
371  return AVERROR(ENOMEM);
372  }
373  memset(ctx->slice_data, 0, nslices * sizeof(ctx->slice_data[0]));
374 
375  for (slice = 0; slice < nslices; slice++) {
376  unsigned slice_off = AV_RB32(src + tsize + FIC_HEADER_SIZE + slice * 4);
377  unsigned slice_size;
378  int y_off = ctx->slice_h * slice;
379  int slice_h = ctx->slice_h;
380 
381  /*
382  * Either read the slice size, or consume all data left.
383  * Also, special case the last slight height.
384  */
385  if (slice == nslices - 1) {
386  slice_size = msize;
387  slice_h = FFALIGN(avctx->height - ctx->slice_h * (nslices - 1), 16);
388  } else {
389  slice_size = AV_RB32(src + tsize + FIC_HEADER_SIZE + slice * 4 + 4);
390  if (slice_size < slice_off)
391  return AVERROR_INVALIDDATA;
392  }
393 
394  if (slice_size < slice_off || slice_size > msize)
395  continue;
396 
397  slice_size -= slice_off;
398 
399  ctx->slice_data[slice].src = sdata + slice_off;
400  ctx->slice_data[slice].src_size = slice_size;
401  ctx->slice_data[slice].slice_h = slice_h;
402  ctx->slice_data[slice].y_off = y_off;
403  }
404 
405  if ((ret = avctx->execute(avctx, fic_decode_slice, ctx->slice_data,
406  NULL, nslices, sizeof(ctx->slice_data[0]))) < 0)
407  return ret;
408 
409  ctx->frame->key_frame = 1;
410  ctx->frame->pict_type = AV_PICTURE_TYPE_I;
411  for (slice = 0; slice < nslices; slice++) {
412  if (ctx->slice_data[slice].p_frame) {
413  ctx->frame->key_frame = 0;
414  ctx->frame->pict_type = AV_PICTURE_TYPE_P;
415  break;
416  }
417  }
418  av_frame_free(&ctx->final_frame);
419  ctx->final_frame = av_frame_clone(ctx->frame);
420  if (!ctx->final_frame) {
421  av_log(avctx, AV_LOG_ERROR, "Could not clone frame buffer.\n");
422  return AVERROR(ENOMEM);
423  }
424 
425  /* Make sure we use a user-supplied buffer. */
426  if ((ret = ff_reget_buffer(avctx, ctx->final_frame, 0)) < 0) {
427  av_log(avctx, AV_LOG_ERROR, "Could not make frame writable.\n");
428  return ret;
429  }
430 
431  /* Draw cursor. */
432  if (!skip_cursor) {
433  memcpy(ctx->cursor_buf, src + CURSOR_OFFSET, sizeof(ctx->cursor_buf));
434  fic_draw_cursor(avctx, cur_x, cur_y);
435  }
436 
437 skip:
438  *got_frame = 1;
439  if ((ret = av_frame_ref(rframe, ctx->final_frame)) < 0)
440  return ret;
441 
442  return avpkt->size;
443 }
444 
446 {
447  FICContext *ctx = avctx->priv_data;
448 
449  av_freep(&ctx->slice_data);
450  av_frame_free(&ctx->final_frame);
451  av_frame_free(&ctx->frame);
452 
453  return 0;
454 }
455 
457 {
458  FICContext *ctx = avctx->priv_data;
459 
460  /* Initialize various context values */
461  ctx->avctx = avctx;
462  ctx->aligned_width = FFALIGN(avctx->width, 16);
463  ctx->aligned_height = FFALIGN(avctx->height, 16);
464 
465  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
466  avctx->bits_per_raw_sample = 8;
467 
468  ctx->frame = av_frame_alloc();
469  if (!ctx->frame)
470  return AVERROR(ENOMEM);
471 
472  return 0;
473 }
474 
475 static const AVOption options[] = {
476 { "skip_cursor", "skip the cursor", offsetof(FICContext, skip_cursor), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM },
477 { NULL },
478 };
479 
480 static const AVClass fic_decoder_class = {
481  .class_name = "FIC decoder",
482  .item_name = av_default_item_name,
483  .option = options,
484  .version = LIBAVUTIL_VERSION_INT,
485 };
486 
488  .p.name = "fic",
489  .p.long_name = NULL_IF_CONFIG_SMALL("Mirillis FIC"),
490  .p.type = AVMEDIA_TYPE_VIDEO,
491  .p.id = AV_CODEC_ID_FIC,
492  .priv_data_size = sizeof(FICContext),
495  .close = fic_decode_close,
496  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
497  .p.priv_class = &fic_decoder_class,
498  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
499 };
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
FICContext::frame
AVFrame * frame
Definition: fic.c:45
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:850
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
fic_decode_frame
static int fic_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt)
Definition: fic.c:270
AV_OPT_FLAG_VIDEO_PARAM
#define AV_OPT_FLAG_VIDEO_PARAM
Definition: opt.h:284
mem_internal.h
FICContext::aligned_width
int aligned_width
Definition: fic.c:55
AVPictureType
AVPictureType
Definition: avutil.h:272
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:111
fic_decoder_class
static const AVClass fic_decoder_class
Definition: fic.c:480
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:374
planes
static const struct @327 planes[]
AVOption
AVOption.
Definition: opt.h:251
t0
#define t0
Definition: regdef.h:28
FICContext::skip_cursor
int skip_cursor
Definition: fic.c:59
chroma
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1635
FFCodec
Definition: codec_internal.h:112
t1
#define t1
Definition: regdef.h:29
FICContext::slice_h
int slice_h
Definition: fic.c:56
FICContext::num_slices
int num_slices
Definition: fic.c:56
fic_decode_slice
static int fic_decode_slice(AVCodecContext *avctx, void *tdata)
Definition: fic.c:172
init
static int init
Definition: av_tx.c:47
golomb.h
exp golomb vlc stuff
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:380
fic_decode_init
static av_cold int fic_decode_init(AVCodecContext *avctx)
Definition: fic.c:456
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:116
FICContext::final_frame
AVFrame * final_frame
Definition: fic.c:46
U
#define U(x)
Definition: vp56_arith.h:37
FICContext::cur_frame_type
enum AVPictureType cur_frame_type
Definition: fic.c:53
GetBitContext
Definition: get_bits.h:62
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:99
rnd
#define rnd()
Definition: checkasm.h:114
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
FICThreadContext
Definition: fic.c:33
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:678
FICThreadContext::src_size
int src_size
Definition: fic.c:37
fic_decode_close
static av_cold int fic_decode_close(AVCodecContext *avctx)
Definition: fic.c:445
options
static const AVOption options[]
Definition: fic.c:475
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:254
fic_idct_put
static void fic_idct_put(uint8_t *dst, int stride, int16_t *block)
Definition: fic.c:113
t7
#define t7
Definition: regdef.h:35
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1448
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
get_bits.h
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
fic_header
static const uint8_t fic_header[7]
Definition: fic.c:84
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:464
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
blk
#define blk(i)
Definition: sha.c:186
FICContext::cursor_buf
uint8_t cursor_buf[4096]
Definition: fic.c:58
get_se_golomb
static int get_se_golomb(GetBitContext *gb)
read signed exp golomb code.
Definition: golomb.h:239
fic_qmat_hq
static const uint8_t fic_qmat_hq[64]
Definition: fic.c:62
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
CURSOR_OFFSET
#define CURSOR_OFFSET
Definition: fic.c:87
t5
#define t5
Definition: regdef.h:33
t6
#define t6
Definition: regdef.h:34
FICThreadContext::src
uint8_t * src
Definition: fic.c:35
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
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:499
FICContext::slice_data_size
int slice_data_size
Definition: fic.c:49
FICContext::aligned_height
int aligned_height
Definition: fic.c:55
FICContext
Definition: fic.c:42
FICContext::slice_data
FICThreadContext * slice_data
Definition: fic.c:48
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:375
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:116
av_frame_ref
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:343
codec_internal.h
size
int size
Definition: twinvq_data.h:10344
AV_RB32
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_RB32
Definition: bytestream.h:96
t8
#define t8
Definition: regdef.h:53
FICThreadContext::p_frame
int p_frame
Definition: fic.c:39
AV_CODEC_CAP_SLICE_THREADS
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition: codec.h:117
DECLARE_ALIGNED
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:116
fic_draw_cursor
static void fic_draw_cursor(AVCodecContext *avctx, int cur_x, int cur_y)
Definition: fic.c:216
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
t4
#define t4
Definition: regdef.h:32
t3
#define t3
Definition: regdef.h:31
common.h
AV_CODEC_ID_FIC
@ AV_CODEC_ID_FIC
Definition: codec_id.h:226
av_always_inline
#define av_always_inline
Definition: attributes.h:49
AV_OPT_FLAG_DECODING_PARAM
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding
Definition: opt.h:282
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
fic_idct
static av_always_inline void fic_idct(int16_t *blk, int step, int shift, int rnd)
Definition: fic.c:89
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: codec_internal.h:31
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:203
AVCodecContext::height
int height
Definition: avcodec.h:562
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:599
avcodec.h
stride
#define stride
Definition: h264pred_template.c:537
fic_qmat_lq
static const uint8_t fic_qmat_lq[64]
Definition: fic.c:73
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
FICThreadContext::y_off
int y_off
Definition: fic.c:38
ff_reget_buffer
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
Definition: decode.c:1521
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
fic_alpha_blend
static av_always_inline void fic_alpha_blend(uint8_t *dst, uint8_t *src, int size, uint8_t *alpha)
Definition: fic.c:207
FICContext::avctx
AVCodecContext * avctx
Definition: fic.c:44
AVCodecContext
main external API structure.
Definition: avcodec.h:389
FICThreadContext::slice_h
int slice_h
Definition: fic.c:36
AVCodecContext::execute
int(* execute)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size)
The codec may call this to execute several independent things.
Definition: avcodec.h:1514
t2
#define t2
Definition: regdef.h:30
FICThreadContext::block
int16_t block[64]
Definition: fic.c:34
av_clip_uint8
#define av_clip_uint8
Definition: common.h:101
shift
static int shift(int a, int b)
Definition: sonic.c:88
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
t9
#define t9
Definition: regdef.h:54
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
fic_decode_block
static int fic_decode_block(FICContext *ctx, GetBitContext *gb, uint8_t *dst, int stride, int16_t *block, int *is_p)
Definition: fic.c:139
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_fast_malloc
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
Definition: mem.c:561
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
FICContext::qmat
const uint8_t * qmat
Definition: fic.c:51
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:562
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:27
ff_fic_decoder
const FFCodec ff_fic_decoder
Definition: fic.c:487
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
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:97
int
int
Definition: ffmpeg_filter.c:153
FIC_HEADER_SIZE
#define FIC_HEADER_SIZE
Definition: fic.c:86