4 * Copyright (c) 2014 Konstantin Shishkov
5 * Copyright (c) 2014 Derek Buitenhuis
7 * This file is part of FFmpeg.
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.
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.
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
24 #include "libavutil/common.h"
30 typedef struct FICThreadContext
{
31 DECLARE_ALIGNED(16, int16_t, block
)[64];
38 typedef struct FICContext
{
39 AVCodecContext
*avctx
;
43 FICThreadContext
*slice_data
;
48 enum AVPictureType cur_frame_type
;
50 int aligned_width
, aligned_height
;
51 int num_slices
, slice_h
;
53 uint8_t cursor_buf
[4096];
56 static const uint8_t fic_qmat_hq
[64] = {
57 1, 2, 2, 2, 3, 3, 3, 4,
58 2, 2, 2, 3, 3, 3, 4, 4,
59 2, 2, 3, 3, 3, 4, 4, 4,
60 2, 2, 3, 3, 3, 4, 4, 5,
61 2, 3, 3, 3, 4, 4, 5, 6,
62 3, 3, 3, 4, 4, 5, 6, 7,
63 3, 3, 3, 4, 4, 5, 7, 7,
64 3, 3, 4, 4, 5, 7, 7, 7,
67 static const uint8_t fic_qmat_lq
[64] = {
68 1, 5, 6, 7, 8, 9, 9, 11,
69 5, 5, 7, 8, 9, 9, 11, 12,
70 6, 7, 8, 9, 9, 11, 11, 12,
71 7, 7, 8, 9, 9, 11, 12, 13,
72 7, 8, 9, 9, 10, 11, 13, 16,
73 8, 9, 9, 10, 11, 13, 16, 19,
74 8, 9, 9, 11, 12, 15, 18, 23,
75 9, 9, 11, 12, 15, 18, 23, 27
78 static const uint8_t fic_header
[7] = { 0, 0, 1, 'F', 'I', 'C', 'V' };
80 #define FIC_HEADER_SIZE 27
82 static av_always_inline
void fic_idct(int16_t *blk
, int step
, int shift
, int rnd
)
84 const int t0
= 27246 * blk
[3 * step
] + 18405 * blk
[5 * step
];
85 const int t1
= 27246 * blk
[5 * step
] - 18405 * blk
[3 * step
];
86 const int t2
= 6393 * blk
[7 * step
] + 32139 * blk
[1 * step
];
87 const int t3
= 6393 * blk
[1 * step
] - 32139 * blk
[7 * step
];
88 const int t4
= 5793 * (t2
+ t0
+ 0x800 >> 12);
89 const int t5
= 5793 * (t3
+ t1
+ 0x800 >> 12);
90 const int t6
= t2
- t0
;
91 const int t7
= t3
- t1
;
92 const int t8
= 17734 * blk
[2 * step
] - 42813 * blk
[6 * step
];
93 const int t9
= 17734 * blk
[6 * step
] + 42814 * blk
[2 * step
];
94 const int tA
= (blk
[0 * step
] - blk
[4 * step
] << 15) + rnd
;
95 const int tB
= (blk
[0 * step
] + blk
[4 * step
] << 15) + rnd
;
96 blk
[0 * step
] = ( t4
+ t9
+ tB
) >> shift
;
97 blk
[1 * step
] = ( t6
+ t7
+ t8
+ tA
) >> shift
;
98 blk
[2 * step
] = ( t6
- t7
- t8
+ tA
) >> shift
;
99 blk
[3 * step
] = ( t5
- t9
+ tB
) >> shift
;
100 blk
[4 * step
] = ( -t5
- t9
+ tB
) >> shift
;
101 blk
[5 * step
] = (-(t6
- t7
) - t8
+ tA
) >> shift
;
102 blk
[6 * step
] = (-(t6
+ t7
) + t8
+ tA
) >> shift
;
103 blk
[7 * step
] = ( -t4
+ t9
+ tB
) >> shift
;
106 static void fic_idct_put(uint8_t *dst
, int stride
, int16_t *block
)
112 fic_idct(ptr
++, 8, 13, (1 << 12) + (1 << 17));
113 for (i
= 1; i
< 8; i
++) {
114 fic_idct(ptr
, 8, 13, 1 << 12);
119 for (i
= 0; i
< 8; i
++) {
120 fic_idct(ptr
, 1, 20, 0);
125 for (j
= 0; j
< 8; j
++) {
126 for (i
= 0; i
< 8; i
++)
127 dst
[i
] = av_clip_uint8(ptr
[i
]);
132 static int fic_decode_block(FICContext
*ctx
, GetBitContext
*gb
,
133 uint8_t *dst
, int stride
, int16_t *block
)
137 /* Is it a skip block? */
139 /* This is a P-frame. */
140 ctx
->frame
->key_frame
= 0;
141 ctx
->frame
->pict_type
= AV_PICTURE_TYPE_P
;
146 memset(block
, 0, sizeof(*block
) * 64);
148 num_coeff
= get_bits(gb
, 7);
150 return AVERROR_INVALIDDATA
;
152 for (i
= 0; i
< num_coeff
; i
++)
153 block
[ff_zigzag_direct
[i
]] = get_se_golomb(gb
) *
154 ctx
->qmat
[ff_zigzag_direct
[i
]];
156 fic_idct_put(dst
, stride
, block
);
161 static int fic_decode_slice(AVCodecContext
*avctx
, void *tdata
)
163 FICContext
*ctx
= avctx
->priv_data
;
164 FICThreadContext
*tctx
= tdata
;
166 uint8_t *src
= tctx
->src
;
167 int slice_h
= tctx
->slice_h
;
168 int src_size
= tctx
->src_size
;
169 int y_off
= tctx
->y_off
;
172 init_get_bits(&gb
, src
, src_size
* 8);
174 for (p
= 0; p
< 3; p
++) {
175 int stride
= ctx
->frame
->linesize
[p
];
176 uint8_t* dst
= ctx
->frame
->data
[p
] + (y_off
>> !!p
) * stride
;
178 for (y
= 0; y
< (slice_h
>> !!p
); y
+= 8) {
179 for (x
= 0; x
< (ctx
->aligned_width
>> !!p
); x
+= 8) {
182 if ((ret
= fic_decode_block(ctx
, &gb
, dst
+ x
, stride
, tctx
->block
)) != 0)
193 static av_always_inline
void fic_alpha_blend(uint8_t *dst
, uint8_t *src
,
194 int size
, uint8_t *alpha
)
198 for (i
= 0; i
< size
; i
++)
199 dst
[i
] += ((src
[i
] - dst
[i
]) * alpha
[i
]) >> 8;
202 static void fic_draw_cursor(AVCodecContext
*avctx
, int cur_x
, int cur_y
)
204 FICContext
*ctx
= avctx
->priv_data
;
205 uint8_t *ptr
= ctx
->cursor_buf
;
207 uint8_t planes
[4][1024];
208 uint8_t chroma
[3][256];
211 /* Convert to YUVA444. */
212 for (i
= 0; i
< 1024; i
++) {
213 planes
[0][i
] = (( 25 * ptr
[0] + 129 * ptr
[1] + 66 * ptr
[2]) / 255) + 16;
214 planes
[1][i
] = ((-38 * ptr
[0] + 112 * ptr
[1] + -74 * ptr
[2]) / 255) + 128;
215 planes
[2][i
] = ((-18 * ptr
[0] + 112 * ptr
[1] + -94 * ptr
[2]) / 255) + 128;
216 planes
[3][i
] = ptr
[3];
221 /* Subsample chroma. */
222 for (i
= 0; i
< 32; i
+= 2)
223 for (j
= 0; j
< 32; j
+= 2)
224 for (p
= 0; p
< 3; p
++)
225 chroma
[p
][16 * (i
/ 2) + j
/ 2] = (planes
[p
+ 1][32 * i
+ j
] +
226 planes
[p
+ 1][32 * i
+ j
+ 1] +
227 planes
[p
+ 1][32 * (i
+ 1) + j
] +
228 planes
[p
+ 1][32 * (i
+ 1) + j
+ 1]) / 4;
230 /* Seek to x/y pos of cursor. */
231 for (i
= 0; i
< 3; i
++)
232 dstptr
[i
] = ctx
->final_frame
->data
[i
] +
233 (ctx
->final_frame
->linesize
[i
] * (cur_y
>> !!i
)) +
234 (cur_x
>> !!i
) + !!i
;
237 for (i
= 0; i
< FFMIN(32, avctx
->height
- cur_y
) - 1; i
+= 2) {
238 int lsize
= FFMIN(32, avctx
->width
- cur_x
);
239 int csize
= lsize
/ 2;
241 fic_alpha_blend(dstptr
[0],
242 planes
[0] + i
* 32, lsize
, planes
[3] + i
* 32);
243 fic_alpha_blend(dstptr
[0] + ctx
->final_frame
->linesize
[0],
244 planes
[0] + (i
+ 1) * 32, lsize
, planes
[3] + (i
+ 1) * 32);
245 fic_alpha_blend(dstptr
[1],
246 chroma
[0] + (i
/ 2) * 16, csize
, chroma
[2] + (i
/ 2) * 16);
247 fic_alpha_blend(dstptr
[2],
248 chroma
[1] + (i
/ 2) * 16, csize
, chroma
[2] + (i
/ 2) * 16);
250 dstptr
[0] += ctx
->final_frame
->linesize
[0] * 2;
251 dstptr
[1] += ctx
->final_frame
->linesize
[1];
252 dstptr
[2] += ctx
->final_frame
->linesize
[2];
256 static int fic_decode_frame(AVCodecContext
*avctx
, void *data
,
257 int *got_frame
, AVPacket
*avpkt
)
259 FICContext
*ctx
= avctx
->priv_data
;
260 uint8_t *src
= avpkt
->data
;
269 if ((ret
= ff_reget_buffer(avctx
, ctx
->frame
)) < 0) {
270 av_log(avctx
, AV_LOG_ERROR
, "reget_buffer() failed\n");
274 /* Header + at least one slice (4) */
275 if (avpkt
->size
< FIC_HEADER_SIZE
+ 4) {
276 av_log(avctx
, AV_LOG_ERROR
, "Frame data is too small.\n");
277 return AVERROR_INVALIDDATA
;
280 /* Check for header. */
281 if (memcmp(src
, fic_header
, 7))
282 av_log(avctx
, AV_LOG_WARNING
, "Invalid FIC Header.\n");
284 /* Is it a skip frame? */
286 if (!ctx
->final_frame
) {
287 av_log(avctx
, AV_LOG_WARNING
, "Initial frame is skipped\n");
288 return AVERROR_INVALIDDATA
;
295 av_log(avctx
, AV_LOG_ERROR
, "Zero slices found.\n");
296 return AVERROR_INVALIDDATA
;
299 /* High or Low Quality Matrix? */
300 ctx
->qmat
= src
[23] ? fic_qmat_hq
: fic_qmat_lq
;
302 /* Skip cursor data. */
303 tsize
= AV_RB24(src
+ 24);
304 if (tsize
> avpkt
->size
- FIC_HEADER_SIZE
) {
305 av_log(avctx
, AV_LOG_ERROR
,
306 "Packet is too small to contain cursor (%d vs %d bytes).\n",
307 tsize
, avpkt
->size
- FIC_HEADER_SIZE
);
308 return AVERROR_INVALIDDATA
;
314 if (!skip_cursor
&& tsize
< 32) {
315 av_log(avctx
, AV_LOG_WARNING
,
316 "Cursor data too small. Skipping cursor.\n");
320 /* Cursor position. */
321 cur_x
= AV_RL16(src
+ 33);
322 cur_y
= AV_RL16(src
+ 35);
323 if (!skip_cursor
&& (cur_x
> avctx
->width
|| cur_y
> avctx
->height
)) {
324 av_log(avctx
, AV_LOG_WARNING
,
325 "Invalid cursor position: (%d,%d). Skipping cusor.\n",
330 if (!skip_cursor
&& (AV_RL16(src
+ 37) != 32 || AV_RL16(src
+ 39) != 32)) {
331 av_log(avctx
, AV_LOG_WARNING
,
332 "Invalid cursor size. Skipping cursor.\n");
336 /* Slice height for all but the last slice. */
337 ctx
->slice_h
= 16 * (ctx
->aligned_height
>> 4) / nslices
;
338 if (ctx
->slice_h
% 16)
339 ctx
->slice_h
= FFALIGN(ctx
->slice_h
- 16, 16);
341 /* First slice offset and remaining data. */
342 sdata
= src
+ tsize
+ FIC_HEADER_SIZE
+ 4 * nslices
;
343 msize
= avpkt
->size
- nslices
* 4 - tsize
- FIC_HEADER_SIZE
;
346 av_log(avctx
, AV_LOG_ERROR
, "Not enough frame data to decode.\n");
347 return AVERROR_INVALIDDATA
;
351 * Set the frametype to I initially. It will be set to P if the frame
352 * has any dependencies (skip blocks). There will be a race condition
353 * inside the slice decode function to set these, but we do not care.
354 * since they will only ever be set to 0/P.
356 ctx
->frame
->key_frame
= 1;
357 ctx
->frame
->pict_type
= AV_PICTURE_TYPE_I
;
359 /* Allocate slice data. */
360 av_fast_malloc(&ctx
->slice_data
, &ctx
->slice_data_size
,
361 nslices
* sizeof(ctx
->slice_data
[0]));
362 if (!ctx
->slice_data_size
) {
363 av_log(avctx
, AV_LOG_ERROR
, "Could not allocate slice data.\n");
364 return AVERROR(ENOMEM
);
366 memset(ctx
->slice_data
, 0, nslices
* sizeof(ctx
->slice_data
[0]));
368 for (slice
= 0; slice
< nslices
; slice
++) {
369 unsigned slice_off
= AV_RB32(src
+ tsize
+ FIC_HEADER_SIZE
+ slice
* 4);
371 int y_off
= ctx
->slice_h
* slice
;
372 int slice_h
= ctx
->slice_h
;
375 * Either read the slice size, or consume all data left.
376 * Also, special case the last slight height.
378 if (slice
== nslices
- 1) {
380 slice_h
= FFALIGN(avctx
->height
- ctx
->slice_h
* (nslices
- 1), 16);
382 slice_size
= AV_RB32(src
+ tsize
+ FIC_HEADER_SIZE
+ slice
* 4 + 4);
385 if (slice_size
< slice_off
|| slice_size
> msize
)
388 slice_size
-= slice_off
;
390 ctx
->slice_data
[slice
].src
= sdata
+ slice_off
;
391 ctx
->slice_data
[slice
].src_size
= slice_size
;
392 ctx
->slice_data
[slice
].slice_h
= slice_h
;
393 ctx
->slice_data
[slice
].y_off
= y_off
;
396 if ((ret
= avctx
->execute(avctx
, fic_decode_slice
, ctx
->slice_data
,
397 NULL
, nslices
, sizeof(ctx
->slice_data
[0]))) < 0)
400 av_frame_free(&ctx
->final_frame
);
401 ctx
->final_frame
= av_frame_clone(ctx
->frame
);
402 if (!ctx
->final_frame
) {
403 av_log(avctx
, AV_LOG_ERROR
, "Could not clone frame buffer.\n");
404 return AVERROR(ENOMEM
);
407 /* Make sure we use a user-supplied buffer. */
408 if ((ret
= ff_reget_buffer(avctx
, ctx
->final_frame
)) < 0) {
409 av_log(avctx
, AV_LOG_ERROR
, "Could not make frame writable.\n");
415 memcpy(ctx
->cursor_buf
, src
+ 59, 32 * 32 * 4);
416 fic_draw_cursor(avctx
, cur_x
, cur_y
);
421 if ((ret
= av_frame_ref(data
, ctx
->final_frame
)) < 0)
427 static av_cold
int fic_decode_close(AVCodecContext
*avctx
)
429 FICContext
*ctx
= avctx
->priv_data
;
431 av_freep(&ctx
->slice_data
);
432 av_frame_free(&ctx
->final_frame
);
433 av_frame_free(&ctx
->frame
);
438 static av_cold
int fic_decode_init(AVCodecContext
*avctx
)
440 FICContext
*ctx
= avctx
->priv_data
;
442 /* Initialize various context values */
444 ctx
->aligned_width
= FFALIGN(avctx
->width
, 16);
445 ctx
->aligned_height
= FFALIGN(avctx
->height
, 16);
447 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
448 avctx
->bits_per_raw_sample
= 8;
450 ctx
->frame
= av_frame_alloc();
452 return AVERROR(ENOMEM
);
457 AVCodec ff_fic_decoder
= {
459 .long_name
= NULL_IF_CONFIG_SMALL("Mirillis FIC"),
460 .type
= AVMEDIA_TYPE_VIDEO
,
461 .id
= AV_CODEC_ID_FIC
,
462 .priv_data_size
= sizeof(FICContext
),
463 .init
= fic_decode_init
,
464 .decode
= fic_decode_frame
,
465 .close
= fic_decode_close
,
466 .capabilities
= CODEC_CAP_DR1
| CODEC_CAP_SLICE_THREADS
,