08bf2cb6dae0a1d7f175110200392d4848ef5575
[libav.git] / libavcodec / clearvideo.c
1 /*
2 * ClearVideo decoder
3 * Copyright (c) 2012 Konstantin Shishkov
4 *
5 * This file is part of Libav.
6 *
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * ClearVideo decoder
25 */
26
27 #include "avcodec.h"
28 #include "bitstream.h"
29 #include "bytestream.h"
30 #include "idctdsp.h"
31 #include "internal.h"
32
33 #define NUM_DC_CODES 127
34 #define NUM_AC_CODES 103
35
36 static const uint8_t clv_dc_codes[NUM_DC_CODES] = {
37 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
38 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
39 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x07, 0x0B,
40 0x0C, 0x08, 0x08, 0x09, 0x04, 0x06, 0x07, 0x05,
41 0x04, 0x05, 0x04, 0x06, 0x05, 0x06, 0x07, 0x05,
42 0x06, 0x07, 0x06, 0x07, 0x08, 0x06, 0x07, 0x08,
43 0x09, 0x0A, 0x0B, 0x07, 0x08, 0x09, 0x07, 0x08,
44 0x06, 0x07, 0x08, 0x06, 0x04, 0x05, 0x02, 0x01,
45 0x03, 0x06, 0x07, 0x07, 0x09, 0x0A, 0x0B, 0x09,
46 0x0A, 0x0B, 0x0A, 0x0B, 0x0C, 0x0D, 0x0C, 0x09,
47 0x0D, 0x0A, 0x0B, 0x08, 0x09, 0x0A, 0x0B, 0x07,
48 0x08, 0x09, 0x0A, 0x0B, 0x06, 0x07, 0x06, 0x08,
49 0x07, 0x09, 0x0A, 0x0B, 0x09, 0x0A, 0x0B, 0x0C,
50 0x14, 0x0D, 0x0D, 0x0E, 0x0F, 0x15, 0x15, 0x16,
51 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
52 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
53 };
54
55 static const uint8_t clv_dc_bits[NUM_DC_CODES] = {
56 22, 22, 22, 22, 22, 22, 22, 22,
57 22, 22, 22, 22, 22, 22, 22, 22,
58 22, 22, 22, 21, 22, 22, 19, 20,
59 20, 19, 18, 18, 15, 17, 17, 16,
60 14, 15, 12, 13, 14, 14, 14, 12,
61 12, 12, 11, 11, 11, 10, 10, 10,
62 10, 10, 10, 9, 9, 9, 8, 8,
63 7, 7, 7, 6, 5, 5, 3, 1,
64 3, 5, 5, 6, 7, 7, 7, 8,
65 8, 8, 9, 9, 9, 9, 10, 11,
66 10, 11, 11, 12, 12, 12, 12, 13,
67 14, 14, 14, 14, 15, 15, 16, 17,
68 16, 17, 18, 18, 19, 19, 19, 19,
69 21, 19, 20, 19, 19, 21, 22, 22,
70 22, 22, 22, 22, 22, 22, 22, 22,
71 22, 22, 22, 22, 22, 22, 22,
72 };
73
74 static const uint16_t clv_ac_syms[NUM_AC_CODES] = {
75 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
76 0x0009, 0x000A, 0x000B, 0x000C, 0x0011, 0x0012, 0x0013, 0x0014,
77 0x0015, 0x0016, 0x0021, 0x0022, 0x0023, 0x0024, 0x0031, 0x0032,
78 0x0033, 0x0041, 0x0042, 0x0043, 0x0051, 0x0052, 0x0053, 0x0061,
79 0x0062, 0x0063, 0x0071, 0x0072, 0x0081, 0x0082, 0x0091, 0x0092,
80 0x00A1, 0x00A2, 0x00B1, 0x00C1, 0x00D1, 0x00E1, 0x00F1, 0x0101,
81 0x0111, 0x0121, 0x0131, 0x0141, 0x0151, 0x0161, 0x0171, 0x0181,
82 0x0191, 0x01A1, 0x1001, 0x1002, 0x1003, 0x1011, 0x1012, 0x1021,
83 0x1031, 0x1041, 0x1051, 0x1061, 0x1071, 0x1081, 0x1091, 0x10A1,
84 0x10B1, 0x10C1, 0x10D1, 0x10E1, 0x10F1, 0x1101, 0x1111, 0x1121,
85 0x1131, 0x1141, 0x1151, 0x1161, 0x1171, 0x1181, 0x1191, 0x11A1,
86 0x11B1, 0x11C1, 0x11D1, 0x11E1, 0x11F1, 0x1201, 0x1211, 0x1221,
87 0x1231, 0x1241, 0x1251, 0x1261, 0x1271, 0x1281, 0x1BFF,
88 };
89
90 static const uint8_t clv_ac_codes[NUM_AC_CODES] = {
91 0x02, 0x0F, 0x15, 0x17, 0x1F, 0x25, 0x24, 0x21,
92 0x20, 0x07, 0x06, 0x20, 0x06, 0x14, 0x1E, 0x0F,
93 0x21, 0x50, 0x0E, 0x1D, 0x0E, 0x51, 0x0D, 0x23,
94 0x0D, 0x0C, 0x22, 0x52, 0x0B, 0x0C, 0x53, 0x13,
95 0x0B, 0x54, 0x12, 0x0A, 0x11, 0x09, 0x10, 0x08,
96 0x16, 0x55, 0x15, 0x14, 0x1C, 0x1B, 0x21, 0x20,
97 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x22, 0x23,
98 0x56, 0x57, 0x07, 0x19, 0x05, 0x0F, 0x04, 0x0E,
99 0x0D, 0x0C, 0x13, 0x12, 0x11, 0x10, 0x1A, 0x19,
100 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x18, 0x17,
101 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x07, 0x06,
102 0x05, 0x04, 0x24, 0x25, 0x26, 0x27, 0x58, 0x59,
103 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x03,
104 };
105
106 static const uint8_t clv_ac_bits[NUM_AC_CODES] = {
107 2, 4, 6, 7, 8, 9, 9, 10,
108 10, 11, 11, 11, 3, 6, 8, 10,
109 11, 12, 4, 8, 10, 12, 5, 9,
110 10, 5, 9, 12, 5, 10, 12, 6,
111 10, 12, 6, 10, 6, 10, 6, 10,
112 7, 12, 7, 7, 8, 8, 9, 9,
113 9, 9, 9, 9, 9, 9, 11, 11,
114 12, 12, 4, 9, 11, 6, 11, 6,
115 6, 6, 7, 7, 7, 7, 8, 8,
116 8, 8, 8, 8, 8, 8, 9, 9,
117 9, 9, 9, 9, 9, 9, 10, 10,
118 10, 10, 11, 11, 11, 11, 12, 12,
119 12, 12, 12, 12, 12, 12, 7,
120 };
121
122 typedef struct CLVContext {
123 AVCodecContext *avctx;
124 IDCTDSPContext idsp;
125 AVFrame *pic;
126 BitstreamContext bc;
127 int mb_width, mb_height;
128 VLC dc_vlc, ac_vlc;
129 int luma_dc_quant, chroma_dc_quant, ac_quant;
130 DECLARE_ALIGNED(16, int16_t, block)[64];
131 int top_dc[3], left_dc[4];
132 int iframes_warning;
133 } CLVContext;
134
135 static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac,
136 int ac_quant)
137 {
138 BitstreamContext *bc = &ctx->bc;
139 int idx = 1, last = 0, val, skip;
140
141 memset(blk, 0, sizeof(*blk) * 64);
142 blk[0] = bitstream_read_vlc(bc, ctx->dc_vlc.table, 9, 3);
143 if (blk[0] < 0)
144 return AVERROR_INVALIDDATA;
145 blk[0] -= 63;
146
147 if (!has_ac)
148 return 0;
149
150 while (idx < 64 && !last) {
151 val = bitstream_read_vlc(bc, ctx->ac_vlc.table, 9, 2);
152 if (val < 0)
153 return AVERROR_INVALIDDATA;
154 if (val != 0x1BFF) {
155 last = val >> 12;
156 skip = (val >> 4) & 0xFF;
157 val &= 0xF;
158 if (bitstream_read_bit(bc))
159 val = -val;
160 } else {
161 last = bitstream_read_bit(bc);
162 skip = bitstream_read(bc, 6);
163 val = bitstream_read_signed(bc, 8);
164 }
165 if (val) {
166 int aval = FFABS(val), sign = val < 0;
167 val = ac_quant * (2 * aval + 1);
168 if (!(ac_quant & 1))
169 val--;
170 if (sign)
171 val = -val;
172 }
173 idx += skip;
174 if (idx >= 64)
175 return AVERROR_INVALIDDATA;
176 blk[ff_zigzag_direct[idx++]] = val;
177 }
178
179 return (idx <= 64 && last) ? 0 : -1;
180 }
181
182 #define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP) \
183 const int t0 = OP(2841 * blk[1 * step] + 565 * blk[7 * step]); \
184 const int t1 = OP( 565 * blk[1 * step] - 2841 * blk[7 * step]); \
185 const int t2 = OP(1609 * blk[5 * step] + 2408 * blk[3 * step]); \
186 const int t3 = OP(2408 * blk[5 * step] - 1609 * blk[3 * step]); \
187 const int t4 = OP(1108 * blk[2 * step] - 2676 * blk[6 * step]); \
188 const int t5 = OP(2676 * blk[2 * step] + 1108 * blk[6 * step]); \
189 const int t6 = ((blk[0 * step] + blk[4 * step]) << dshift) + bias; \
190 const int t7 = ((blk[0 * step] - blk[4 * step]) << dshift) + bias; \
191 const int t8 = t0 + t2; \
192 const int t9 = t0 - t2; \
193 const int tA = 181 * (t9 + (t1 - t3)) + 0x80 >> 8; \
194 const int tB = 181 * (t9 - (t1 - t3)) + 0x80 >> 8; \
195 const int tC = t1 + t3; \
196 \
197 blk[0 * step] = (t6 + t5 + t8) >> shift; \
198 blk[1 * step] = (t7 + t4 + tA) >> shift; \
199 blk[2 * step] = (t7 - t4 + tB) >> shift; \
200 blk[3 * step] = (t6 - t5 + tC) >> shift; \
201 blk[4 * step] = (t6 - t5 - tC) >> shift; \
202 blk[5 * step] = (t7 - t4 - tB) >> shift; \
203 blk[6 * step] = (t7 + t4 - tA) >> shift; \
204 blk[7 * step] = (t6 + t5 - t8) >> shift; \
205
206 #define ROP(x) x
207 #define COP(x) (((x) + 4) >> 3)
208
209 static void clv_dct(int16_t *block)
210 {
211 int i;
212 int16_t *ptr;
213
214 ptr = block;
215 for (i = 0; i < 8; i++) {
216 DCT_TEMPLATE(ptr, 1, 0x80, 8, 11, ROP);
217 ptr += 8;
218 }
219
220 ptr = block;
221 for (i = 0; i < 8; i++) {
222 DCT_TEMPLATE(ptr, 8, 0x2000, 14, 8, COP);
223 ptr++;
224 }
225 }
226
227 static int decode_mb(CLVContext *c, int x, int y)
228 {
229 int i, has_ac[6], off;
230
231 for (i = 0; i < 6; i++)
232 has_ac[i] = bitstream_read_bit(&c->bc);
233
234 off = x * 16 + y * 16 * c->pic->linesize[0];
235 for (i = 0; i < 4; i++) {
236 if (decode_block(c, c->block, has_ac[i], c->ac_quant) < 0)
237 return AVERROR_INVALIDDATA;
238 if (!x && !(i & 1)) {
239 c->block[0] += c->top_dc[0];
240 c->top_dc[0] = c->block[0];
241 } else {
242 c->block[0] += c->left_dc[(i & 2) >> 1];
243 }
244 c->left_dc[(i & 2) >> 1] = c->block[0];
245 c->block[0] *= c->luma_dc_quant;
246 clv_dct(c->block);
247 if (i == 2)
248 off += c->pic->linesize[0] * 8;
249 c->idsp.put_pixels_clamped(c->block,
250 c->pic->data[0] + off + (i & 1) * 8,
251 c->pic->linesize[0]);
252 }
253
254 off = x * 8 + y * 8 * c->pic->linesize[1];
255 for (i = 1; i < 3; i++) {
256 if (decode_block(c, c->block, has_ac[i + 3], c->ac_quant) < 0)
257 return AVERROR_INVALIDDATA;
258 if (!x) {
259 c->block[0] += c->top_dc[i];
260 c->top_dc[i] = c->block[0];
261 } else {
262 c->block[0] += c->left_dc[i + 1];
263 }
264 c->left_dc[i + 1] = c->block[0];
265 c->block[0] *= c->chroma_dc_quant;
266 clv_dct(c->block);
267 c->idsp.put_pixels_clamped(c->block, c->pic->data[i] + off,
268 c->pic->linesize[i]);
269 }
270
271 return 0;
272 }
273
274 static int clv_decode_frame(AVCodecContext *avctx, void *data,
275 int *got_frame, AVPacket *avpkt)
276 {
277 const uint8_t *buf = avpkt->data;
278 int buf_size = avpkt->size;
279 CLVContext *c = avctx->priv_data;
280 GetByteContext gb;
281 uint32_t frame_type;
282 int i, j, ret;
283
284 bytestream2_init(&gb, buf, buf_size);
285 if (avctx->codec_tag == MKTAG('C', 'L', 'V', '1')) {
286 int skip = bytestream2_get_byte(&gb);
287 bytestream2_skip(&gb, (skip + 1) * 8);
288 }
289
290 frame_type = bytestream2_get_byte(&gb);
291 if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
292 return ret;
293
294 c->pic->key_frame = frame_type & 0x20 ? 1 : 0;
295 c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I
296 : AV_PICTURE_TYPE_P;
297
298 if (frame_type & 0x2) {
299 bytestream2_get_be32(&gb); // frame size;
300 c->ac_quant = bytestream2_get_byte(&gb);
301 c->luma_dc_quant = 32;
302 c->chroma_dc_quant = 32;
303
304 if ((ret = bitstream_init8(&c->bc, buf + bytestream2_tell(&gb),
305 buf_size - bytestream2_tell(&gb))) < 0)
306 return ret;
307
308 for (i = 0; i < 3; i++)
309 c->top_dc[i] = 32;
310 for (i = 0; i < 4; i++)
311 c->left_dc[i] = 32;
312
313 for (j = 0; j < c->mb_height; j++) {
314 for (i = 0; i < c->mb_width; i++) {
315 ret |= decode_mb(c, i, j);
316 }
317 }
318 } else {
319 if (!c->iframes_warning)
320 avpriv_report_missing_feature(avctx, "Non-I-frames in Clearvideo");
321 c->iframes_warning = 1;
322 return AVERROR_PATCHWELCOME;
323 }
324
325 if ((ret = av_frame_ref(data, c->pic)) < 0)
326 return ret;
327
328 *got_frame = 1;
329
330 return ret < 0 ? ret : buf_size;
331 }
332
333 static av_cold int clv_decode_init(AVCodecContext *avctx)
334 {
335 CLVContext *const c = avctx->priv_data;
336 int ret;
337
338 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
339
340 c->avctx = avctx;
341 c->mb_width = FFALIGN(avctx->width, 16) >> 4;
342 c->mb_height = FFALIGN(avctx->height, 16) >> 4;
343 c->iframes_warning = 0;
344 c->pic = av_frame_alloc();
345 if (!c->pic)
346 return AVERROR(ENOMEM);
347
348 ff_idctdsp_init(&c->idsp, avctx);
349 ret = init_vlc(&c->dc_vlc, 9, NUM_DC_CODES,
350 clv_dc_bits, 1, 1,
351 clv_dc_codes, 1, 1, 0);
352 if (ret) {
353 av_log(avctx, AV_LOG_ERROR, "Error initialising DC VLC\n");
354 return ret;
355 }
356 ret = ff_init_vlc_sparse(&c->ac_vlc, 9, NUM_AC_CODES,
357 clv_ac_bits, 1, 1,
358 clv_ac_codes, 1, 1,
359 clv_ac_syms, 2, 2, 0);
360 if (ret) {
361 av_log(avctx, AV_LOG_ERROR, "Error initialising AC VLC\n");
362 return ret;
363 }
364
365 return 0;
366 }
367
368 static av_cold int clv_decode_end(AVCodecContext *avctx)
369 {
370 CLVContext *const c = avctx->priv_data;
371
372 av_frame_free(&c->pic);
373
374 ff_free_vlc(&c->dc_vlc);
375 ff_free_vlc(&c->ac_vlc);
376
377 return 0;
378 }
379
380 AVCodec ff_clearvideo_decoder = {
381 .name = "clearvideo",
382 .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"),
383 .type = AVMEDIA_TYPE_VIDEO,
384 .id = AV_CODEC_ID_CLEARVIDEO,
385 .priv_data_size = sizeof(CLVContext),
386 .init = clv_decode_init,
387 .close = clv_decode_end,
388 .decode = clv_decode_frame,
389 .capabilities = AV_CODEC_CAP_DR1,
390 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
391 };