summaryrefslogtreecommitdiff
path: root/libavcodec/aic.c (plain)
blob: 67d78c5ddd2600b76604beb8f62b929d3ba72cf7
1/*
2 * Apple Intermediate Codec decoder
3 *
4 * Copyright (c) 2013 Konstantin Shishkov
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <inttypes.h>
24
25#include "avcodec.h"
26#include "bytestream.h"
27#include "internal.h"
28#include "get_bits.h"
29#include "golomb.h"
30#include "idctdsp.h"
31#include "thread.h"
32#include "unary.h"
33
34#define AIC_HDR_SIZE 24
35#define AIC_BAND_COEFFS (64 + 32 + 192 + 96)
36
37enum AICBands {
38 COEFF_LUMA = 0,
39 COEFF_CHROMA,
40 COEFF_LUMA_EXT,
41 COEFF_CHROMA_EXT,
42 NUM_BANDS
43};
44
45static const int aic_num_band_coeffs[NUM_BANDS] = { 64, 32, 192, 96 };
46
47static const int aic_band_off[NUM_BANDS] = { 0, 64, 96, 288 };
48
49static const uint8_t aic_quant_matrix[64] = {
50 8, 16, 19, 22, 22, 26, 26, 27,
51 16, 16, 22, 22, 26, 27, 27, 29,
52 19, 22, 26, 26, 27, 29, 29, 35,
53 22, 24, 27, 27, 29, 32, 34, 38,
54 26, 27, 29, 29, 32, 35, 38, 46,
55 27, 29, 34, 34, 35, 40, 46, 56,
56 29, 34, 34, 37, 40, 48, 56, 69,
57 34, 37, 38, 40, 48, 58, 69, 83,
58};
59
60static const uint8_t aic_y_scan[64] = {
61 0, 4, 1, 2, 5, 8, 12, 9,
62 6, 3, 7, 10, 13, 14, 11, 15,
63 47, 43, 46, 45, 42, 39, 35, 38,
64 41, 44, 40, 37, 34, 33, 36, 32,
65 16, 20, 17, 18, 21, 24, 28, 25,
66 22, 19, 23, 26, 29, 30, 27, 31,
67 63, 59, 62, 61, 58, 55, 51, 54,
68 57, 60, 56, 53, 50, 49, 52, 48,
69};
70
71static const uint8_t aic_y_ext_scan[192] = {
72 64, 72, 65, 66, 73, 80, 88, 81,
73 74, 67, 75, 82, 89, 90, 83, 91,
74 0, 4, 1, 2, 5, 8, 12, 9,
75 6, 3, 7, 10, 13, 14, 11, 15,
76 16, 20, 17, 18, 21, 24, 28, 25,
77 22, 19, 23, 26, 29, 30, 27, 31,
78 155, 147, 154, 153, 146, 139, 131, 138,
79 145, 152, 144, 137, 130, 129, 136, 128,
80 47, 43, 46, 45, 42, 39, 35, 38,
81 41, 44, 40, 37, 34, 33, 36, 32,
82 63, 59, 62, 61, 58, 55, 51, 54,
83 57, 60, 56, 53, 50, 49, 52, 48,
84 96, 104, 97, 98, 105, 112, 120, 113,
85 106, 99, 107, 114, 121, 122, 115, 123,
86 68, 76, 69, 70, 77, 84, 92, 85,
87 78, 71, 79, 86, 93, 94, 87, 95,
88 100, 108, 101, 102, 109, 116, 124, 117,
89 110, 103, 111, 118, 125, 126, 119, 127,
90 187, 179, 186, 185, 178, 171, 163, 170,
91 177, 184, 176, 169, 162, 161, 168, 160,
92 159, 151, 158, 157, 150, 143, 135, 142,
93 149, 156, 148, 141, 134, 133, 140, 132,
94 191, 183, 190, 189, 182, 175, 167, 174,
95 181, 188, 180, 173, 166, 165, 172, 164,
96};
97
98static const uint8_t aic_c_scan[64] = {
99 0, 4, 1, 2, 5, 8, 12, 9,
100 6, 3, 7, 10, 13, 14, 11, 15,
101 31, 27, 30, 29, 26, 23, 19, 22,
102 25, 28, 24, 21, 18, 17, 20, 16,
103 32, 36, 33, 34, 37, 40, 44, 41,
104 38, 35, 39, 42, 45, 46, 43, 47,
105 63, 59, 62, 61, 58, 55, 51, 54,
106 57, 60, 56, 53, 50, 49, 52, 48,
107};
108
109static const uint8_t aic_c_ext_scan[192] = {
110 16, 24, 17, 18, 25, 32, 40, 33,
111 26, 19, 27, 34, 41, 42, 35, 43,
112 0, 4, 1, 2, 5, 8, 12, 9,
113 6, 3, 7, 10, 13, 14, 11, 15,
114 20, 28, 21, 22, 29, 36, 44, 37,
115 30, 23, 31, 38, 45, 46, 39, 47,
116 95, 87, 94, 93, 86, 79, 71, 78,
117 85, 92, 84, 77, 70, 69, 76, 68,
118 63, 59, 62, 61, 58, 55, 51, 54,
119 57, 60, 56, 53, 50, 49, 52, 48,
120 91, 83, 90, 89, 82, 75, 67, 74,
121 81, 88, 80, 73, 66, 65, 72, 64,
122 112, 120, 113, 114, 121, 128, 136, 129,
123 122, 115, 123, 130, 137, 138, 131, 139,
124 96, 100, 97, 98, 101, 104, 108, 105,
125 102, 99, 103, 106, 109, 110, 107, 111,
126 116, 124, 117, 118, 125, 132, 140, 133,
127 126, 119, 127, 134, 141, 142, 135, 143,
128 191, 183, 190, 189, 182, 175, 167, 174,
129 181, 188, 180, 173, 166, 165, 172, 164,
130 159, 155, 158, 157, 154, 151, 147, 150,
131 153, 156, 152, 149, 146, 145, 148, 144,
132 187, 179, 186, 185, 178, 171, 163, 170,
133 177, 184, 176, 169, 162, 161, 168, 160,
134};
135
136static const uint8_t * const aic_scan[NUM_BANDS] = {
137 aic_y_scan, aic_c_scan, aic_y_ext_scan, aic_c_ext_scan
138};
139
140typedef struct AICContext {
141 AVCodecContext *avctx;
142 AVFrame *frame;
143 IDCTDSPContext idsp;
144 ScanTable scantable;
145
146 int num_x_slices;
147 int slice_width;
148 int mb_width, mb_height;
149 int quant;
150 int interlaced;
151
152 int16_t *slice_data;
153 int16_t *data_ptr[NUM_BANDS];
154
155 DECLARE_ALIGNED(16, int16_t, block)[64];
156 DECLARE_ALIGNED(16, uint8_t, quant_matrix)[64];
157} AICContext;
158
159static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size)
160{
161 uint32_t frame_size;
162 int width, height;
163
164 if (src[0] != 1) {
165 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid version %d\n", src[0]);
166 return AVERROR_INVALIDDATA;
167 }
168 if (src[1] != AIC_HDR_SIZE - 2) {
169 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid header size %d\n", src[1]);
170 return AVERROR_INVALIDDATA;
171 }
172 frame_size = AV_RB32(src + 2);
173 width = AV_RB16(src + 6);
174 height = AV_RB16(src + 8);
175 if (frame_size > size) {
176 av_log(ctx->avctx, AV_LOG_ERROR, "Frame size should be %"PRIu32" got %d\n",
177 frame_size, size);
178 return AVERROR_INVALIDDATA;
179 }
180 if (width != ctx->avctx->width || height != ctx->avctx->height) {
181 av_log(ctx->avctx, AV_LOG_ERROR,
182 "Picture dimension changed: old: %d x %d, new: %d x %d\n",
183 ctx->avctx->width, ctx->avctx->height, width, height);
184 return AVERROR_INVALIDDATA;
185 }
186 ctx->quant = src[15];
187 ctx->interlaced = ((src[16] >> 4) == 3);
188
189 return 0;
190}
191
192#define GET_CODE(val, type, add_bits) \
193 do { \
194 if (type) \
195 val = get_ue_golomb(gb); \
196 else \
197 val = get_unary(gb, 1, 31); \
198 if (add_bits) \
199 val = (val << add_bits) + get_bits(gb, add_bits); \
200 } while (0)
201
202static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,
203 int band, int slice_width, int force_chroma)
204{
205 int has_skips, coeff_type, coeff_bits, skip_type, skip_bits;
206 const int num_coeffs = aic_num_band_coeffs[band];
207 const uint8_t *scan = aic_scan[band | force_chroma];
208 int mb, idx;
209 unsigned val;
210
211 has_skips = get_bits1(gb);
212 coeff_type = get_bits1(gb);
213 coeff_bits = get_bits(gb, 3);
214
215 if (has_skips) {
216 skip_type = get_bits1(gb);
217 skip_bits = get_bits(gb, 3);
218
219 for (mb = 0; mb < slice_width; mb++) {
220 idx = -1;
221 do {
222 GET_CODE(val, skip_type, skip_bits);
223 if (val >= 0x10000)
224 return AVERROR_INVALIDDATA;
225 idx += val + 1;
226 if (idx >= num_coeffs)
227 break;
228 GET_CODE(val, coeff_type, coeff_bits);
229 val++;
230 if (val >= 0x10000)
231 return AVERROR_INVALIDDATA;
232 dst[scan[idx]] = val;
233 } while (idx < num_coeffs - 1);
234 dst += num_coeffs;
235 }
236 } else {
237 for (mb = 0; mb < slice_width; mb++) {
238 for (idx = 0; idx < num_coeffs; idx++) {
239 GET_CODE(val, coeff_type, coeff_bits);
240 if (val >= 0x10000)
241 return AVERROR_INVALIDDATA;
242 dst[scan[idx]] = val;
243 }
244 dst += num_coeffs;
245 }
246 }
247 return 0;
248}
249
250static void recombine_block(int16_t *dst, const uint8_t *scan,
251 int16_t **base, int16_t **ext)
252{
253 int i, j;
254
255 for (i = 0; i < 4; i++) {
256 for (j = 0; j < 4; j++)
257 dst[scan[i * 8 + j]] = (*base)[j];
258 for (j = 0; j < 4; j++)
259 dst[scan[i * 8 + j + 4]] = (*ext)[j];
260 *base += 4;
261 *ext += 4;
262 }
263 for (; i < 8; i++) {
264 for (j = 0; j < 8; j++)
265 dst[scan[i * 8 + j]] = (*ext)[j];
266 *ext += 8;
267 }
268}
269
270static void recombine_block_il(int16_t *dst, const uint8_t *scan,
271 int16_t **base, int16_t **ext,
272 int block_no)
273{
274 int i, j;
275
276 if (block_no < 2) {
277 for (i = 0; i < 8; i++) {
278 for (j = 0; j < 4; j++)
279 dst[scan[i * 8 + j]] = (*base)[j];
280 for (j = 0; j < 4; j++)
281 dst[scan[i * 8 + j + 4]] = (*ext)[j];
282 *base += 4;
283 *ext += 4;
284 }
285 } else {
286 for (i = 0; i < 64; i++)
287 dst[scan[i]] = (*ext)[i];
288 *ext += 64;
289 }
290}
291
292static void unquant_block(int16_t *block, int q, uint8_t *quant_matrix)
293{
294 int i;
295
296 for (i = 0; i < 64; i++) {
297 int val = (uint16_t)block[i];
298 int sign = val & 1;
299
300 block[i] = (((val >> 1) ^ -sign) * q * quant_matrix[i] >> 4)
301 + sign;
302 }
303}
304
305static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
306 const uint8_t *src, int src_size)
307{
308 GetBitContext gb;
309 int ret, i, mb, blk;
310 int slice_width = FFMIN(ctx->slice_width, ctx->mb_width - mb_x);
311 uint8_t *Y, *C[2];
312 uint8_t *dst;
313 int16_t *base_y = ctx->data_ptr[COEFF_LUMA];
314 int16_t *base_c = ctx->data_ptr[COEFF_CHROMA];
315 int16_t *ext_y = ctx->data_ptr[COEFF_LUMA_EXT];
316 int16_t *ext_c = ctx->data_ptr[COEFF_CHROMA_EXT];
317 const int ystride = ctx->frame->linesize[0];
318
319 Y = ctx->frame->data[0] + mb_x * 16 + mb_y * 16 * ystride;
320 for (i = 0; i < 2; i++)
321 C[i] = ctx->frame->data[i + 1] + mb_x * 8
322 + mb_y * 8 * ctx->frame->linesize[i + 1];
323 init_get_bits(&gb, src, src_size * 8);
324
325 memset(ctx->slice_data, 0,
326 sizeof(*ctx->slice_data) * slice_width * AIC_BAND_COEFFS);
327 for (i = 0; i < NUM_BANDS; i++)
328 if ((ret = aic_decode_coeffs(&gb, ctx->data_ptr[i],
329 i, slice_width,
330 !ctx->interlaced)) < 0)
331 return ret;
332
333 for (mb = 0; mb < slice_width; mb++) {
334 for (blk = 0; blk < 4; blk++) {
335 if (!ctx->interlaced)
336 recombine_block(ctx->block, ctx->scantable.permutated,
337 &base_y, &ext_y);
338 else
339 recombine_block_il(ctx->block, ctx->scantable.permutated,
340 &base_y, &ext_y, blk);
341 unquant_block(ctx->block, ctx->quant, ctx->quant_matrix);
342 ctx->idsp.idct(ctx->block);
343
344 if (!ctx->interlaced) {
345 dst = Y + (blk >> 1) * 8 * ystride + (blk & 1) * 8;
346 ctx->idsp.put_signed_pixels_clamped(ctx->block, dst, ystride);
347 } else {
348 dst = Y + (blk & 1) * 8 + (blk >> 1) * ystride;
349 ctx->idsp.put_signed_pixels_clamped(ctx->block, dst,
350 ystride * 2);
351 }
352 }
353 Y += 16;
354
355 for (blk = 0; blk < 2; blk++) {
356 recombine_block(ctx->block, ctx->scantable.permutated,
357 &base_c, &ext_c);
358 unquant_block(ctx->block, ctx->quant, ctx->quant_matrix);
359 ctx->idsp.idct(ctx->block);
360 ctx->idsp.put_signed_pixels_clamped(ctx->block, C[blk],
361 ctx->frame->linesize[blk + 1]);
362 C[blk] += 8;
363 }
364 }
365
366 return 0;
367}
368
369static int aic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
370 AVPacket *avpkt)
371{
372 AICContext *ctx = avctx->priv_data;
373 const uint8_t *buf = avpkt->data;
374 int buf_size = avpkt->size;
375 GetByteContext gb;
376 uint32_t off;
377 int x, y, ret;
378 int slice_size;
379 ThreadFrame frame = { .f = data };
380
381 ctx->frame = data;
382 ctx->frame->pict_type = AV_PICTURE_TYPE_I;
383 ctx->frame->key_frame = 1;
384
385 off = FFALIGN(AIC_HDR_SIZE + ctx->num_x_slices * ctx->mb_height * 2, 4);
386
387 if (buf_size < off) {
388 av_log(avctx, AV_LOG_ERROR, "Too small frame\n");
389 return AVERROR_INVALIDDATA;
390 }
391
392 ret = aic_decode_header(ctx, buf, buf_size);
393 if (ret < 0) {
394 av_log(avctx, AV_LOG_ERROR, "Invalid header\n");
395 return ret;
396 }
397
398 if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
399 return ret;
400
401 bytestream2_init(&gb, buf + AIC_HDR_SIZE,
402 ctx->num_x_slices * ctx->mb_height * 2);
403
404 for (y = 0; y < ctx->mb_height; y++) {
405 for (x = 0; x < ctx->mb_width; x += ctx->slice_width) {
406 slice_size = bytestream2_get_le16(&gb) * 4;
407 if (slice_size + off > buf_size || !slice_size) {
408 av_log(avctx, AV_LOG_ERROR,
409 "Incorrect slice size %d at %d.%d\n", slice_size, x, y);
410 return AVERROR_INVALIDDATA;
411 }
412
413 ret = aic_decode_slice(ctx, x, y, buf + off, slice_size);
414 if (ret < 0) {
415 av_log(avctx, AV_LOG_ERROR,
416 "Error decoding slice at %d.%d\n", x, y);
417 return ret;
418 }
419
420 off += slice_size;
421 }
422 }
423
424 *got_frame = 1;
425
426 return avpkt->size;
427}
428
429static av_cold int aic_decode_init(AVCodecContext *avctx)
430{
431 AICContext *ctx = avctx->priv_data;
432 int i;
433 uint8_t scan[64];
434
435 ctx->avctx = avctx;
436
437 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
438
439 ff_idctdsp_init(&ctx->idsp, avctx);
440
441 for (i = 0; i < 64; i++)
442 scan[i] = i;
443 ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, scan);
444 for (i = 0; i < 64; i++)
445 ctx->quant_matrix[ctx->idsp.idct_permutation[i]] = aic_quant_matrix[i];
446
447 ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
448 ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
449
450 ctx->num_x_slices = (ctx->mb_width + 15) >> 4;
451 ctx->slice_width = 16;
452 for (i = 1; i < ctx->mb_width; i++) {
453 if (!(ctx->mb_width % i) && (ctx->mb_width / i <= 32)) {
454 ctx->slice_width = ctx->mb_width / i;
455 ctx->num_x_slices = i;
456 break;
457 }
458 }
459
460 ctx->slice_data = av_malloc_array(ctx->slice_width, AIC_BAND_COEFFS
461 * sizeof(*ctx->slice_data));
462 if (!ctx->slice_data) {
463 av_log(avctx, AV_LOG_ERROR, "Error allocating slice buffer\n");
464
465 return AVERROR(ENOMEM);
466 }
467
468 for (i = 0; i < NUM_BANDS; i++)
469 ctx->data_ptr[i] = ctx->slice_data + ctx->slice_width
470 * aic_band_off[i];
471
472 return 0;
473}
474
475static av_cold int aic_decode_close(AVCodecContext *avctx)
476{
477 AICContext *ctx = avctx->priv_data;
478
479 av_freep(&ctx->slice_data);
480
481 return 0;
482}
483
484AVCodec ff_aic_decoder = {
485 .name = "aic",
486 .long_name = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec"),
487 .type = AVMEDIA_TYPE_VIDEO,
488 .id = AV_CODEC_ID_AIC,
489 .priv_data_size = sizeof(AICContext),
490 .init = aic_decode_init,
491 .close = aic_decode_close,
492 .decode = aic_decode_frame,
493 .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
494 .init_thread_copy = ONLY_IF_THREADS_ENABLED(aic_decode_init),
495 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
496};
497