3 * Copyright (c) 2012 Konstantin Shishkov
5 * This file is part of FFmpeg.
7 * FFmpeg 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.
12 * FFmpeg 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #include "bytestream.h"
33 #define NUM_DC_CODES 127
34 #define NUM_AC_CODES 103
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,
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,
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,
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,
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,
122 typedef struct CLVContext {
123 AVCodecContext *avctx;
127 int mb_width, mb_height;
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];
135 static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac,
138 GetBitContext *gb = &ctx->gb;
139 int idx = 1, last = 0, val, skip;
141 memset(blk, 0, sizeof(*blk) * 64);
142 blk[0] = get_vlc2(gb, ctx->dc_vlc.table, 9, 3);
144 return AVERROR_INVALIDDATA;
150 while (idx < 64 && !last) {
151 val = get_vlc2(gb, ctx->ac_vlc.table, 9, 2);
153 return AVERROR_INVALIDDATA;
156 skip = (val >> 4) & 0xFF;
161 last = get_bits1(gb);
162 skip = get_bits(gb, 6);
163 val = get_sbits(gb, 8);
166 int aval = FFABS(val), sign = val < 0;
167 val = ac_quant * (2 * aval + 1);
175 return AVERROR_INVALIDDATA;
176 blk[ff_zigzag_direct[idx++]] = val;
179 return (idx <= 64 && last) ? 0 : -1;
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]) * (1 << dshift)) + bias; \
190 const int t7 = ((blk[0 * step] - blk[4 * step]) * (1 << dshift)) + bias; \
191 const int t8 = t0 + t2; \
192 const int t9 = t0 - t2; \
193 const int tA = (int)(181U * (t9 + (t1 - t3)) + 0x80) >> 8; \
194 const int tB = (int)(181U * (t9 - (t1 - t3)) + 0x80) >> 8; \
195 const int tC = t1 + t3; \
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; \
207 #define COP(x) (((x) + 4) >> 3)
209 static void clv_dct(int16_t *block)
215 for (i = 0; i < 8; i++) {
216 DCT_TEMPLATE(ptr, 1, 0x80, 8, 11, ROP);
221 for (i = 0; i < 8; i++) {
222 DCT_TEMPLATE(ptr, 8, 0x2000, 14, 8, COP);
227 static int decode_mb(CLVContext *c, int x, int y)
229 int i, has_ac[6], off;
231 for (i = 0; i < 6; i++)
232 has_ac[i] = get_bits1(&c->gb);
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];
242 c->block[0] += c->left_dc[(i & 2) >> 1];
244 c->left_dc[(i & 2) >> 1] = c->block[0];
245 c->block[0] *= c->luma_dc_quant;
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]);
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;
259 c->block[0] += c->top_dc[i];
260 c->top_dc[i] = c->block[0];
262 c->block[0] += c->left_dc[i + 1];
264 c->left_dc[i + 1] = c->block[0];
265 c->block[0] *= c->chroma_dc_quant;
267 c->idsp.put_pixels_clamped(c->block, c->pic->data[i] + off,
268 c->pic->linesize[i]);
274 static int clv_decode_frame(AVCodecContext *avctx, void *data,
275 int *got_frame, AVPacket *avpkt)
277 const uint8_t *buf = avpkt->data;
278 int buf_size = avpkt->size;
279 CLVContext *c = avctx->priv_data;
285 bytestream2_init(&gb, buf, buf_size);
286 if (avctx->codec_tag == MKTAG('C', 'L', 'V', '1')) {
287 int skip = bytestream2_get_byte(&gb);
288 bytestream2_skip(&gb, (skip + 1) * 8);
291 frame_type = bytestream2_get_byte(&gb);
293 if (frame_type & 0x2) {
294 if (buf_size < c->mb_width * c->mb_height) {
295 av_log(avctx, AV_LOG_ERROR, "Packet too small\n");
296 return AVERROR_INVALIDDATA;
299 if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
302 c->pic->key_frame = frame_type & 0x20 ? 1 : 0;
303 c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I
306 bytestream2_get_be32(&gb); // frame size;
307 c->ac_quant = bytestream2_get_byte(&gb);
308 c->luma_dc_quant = 32;
309 c->chroma_dc_quant = 32;
311 if ((ret = init_get_bits8(&c->gb, buf + bytestream2_tell(&gb),
312 buf_size - bytestream2_tell(&gb))) < 0)
315 for (i = 0; i < 3; i++)
317 for (i = 0; i < 4; i++)
320 for (j = 0; j < c->mb_height; j++) {
321 for (i = 0; i < c->mb_width; i++) {
322 ret = decode_mb(c, i, j);
328 if ((ret = av_frame_ref(data, c->pic)) < 0)
333 if (!c->iframes_warning)
334 avpriv_report_missing_feature(avctx, "Non-I-frames in Clearvideo");
335 c->iframes_warning = 1;
336 return AVERROR_PATCHWELCOME;
339 return mb_ret < 0 ? mb_ret : buf_size;
342 static av_cold int clv_decode_init(AVCodecContext *avctx)
344 CLVContext *const c = avctx->priv_data;
347 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
350 c->mb_width = FFALIGN(avctx->width, 16) >> 4;
351 c->mb_height = FFALIGN(avctx->height, 16) >> 4;
352 c->iframes_warning = 0;
353 c->pic = av_frame_alloc();
355 return AVERROR(ENOMEM);
357 ff_idctdsp_init(&c->idsp, avctx);
358 ret = init_vlc(&c->dc_vlc, 9, NUM_DC_CODES,
360 clv_dc_codes, 1, 1, 0);
362 av_log(avctx, AV_LOG_ERROR, "Error initialising DC VLC\n");
365 ret = ff_init_vlc_sparse(&c->ac_vlc, 9, NUM_AC_CODES,
368 clv_ac_syms, 2, 2, 0);
370 av_log(avctx, AV_LOG_ERROR, "Error initialising AC VLC\n");
377 static av_cold int clv_decode_end(AVCodecContext *avctx)
379 CLVContext *const c = avctx->priv_data;
381 av_frame_free(&c->pic);
383 ff_free_vlc(&c->dc_vlc);
384 ff_free_vlc(&c->ac_vlc);
389 AVCodec ff_clearvideo_decoder = {
390 .name = "clearvideo",
391 .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"),
392 .type = AVMEDIA_TYPE_VIDEO,
393 .id = AV_CODEC_ID_CLEARVIDEO,
394 .priv_data_size = sizeof(CLVContext),
395 .init = clv_decode_init,
396 .close = clv_decode_end,
397 .decode = clv_decode_frame,
398 .capabilities = AV_CODEC_CAP_DR1,
399 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,