2 * TechSmith Screen Codec 2 (aka Dora) decoder
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
24 * TechSmith Screen Codec 2 decoder
29 #define BITSTREAM_READER_LE
32 #include "bytestream.h"
34 #include "tscc2data.h"
36 typedef struct TSCC2Context
{
37 AVCodecContext
*avctx
;
39 int mb_width
, mb_height
;
40 uint8_t *slice_quants
;
45 VLC dc_vlc
, nc_vlc
[NUM_VLC_SETS
], ac_vlc
[NUM_VLC_SETS
];
49 static av_cold
void free_vlcs(TSCC2Context
*c
)
53 ff_free_vlc(&c
->dc_vlc
);
54 for (i
= 0; i
< NUM_VLC_SETS
; i
++) {
55 ff_free_vlc(c
->nc_vlc
+ i
);
56 ff_free_vlc(c
->ac_vlc
+ i
);
60 static av_cold
int init_vlcs(TSCC2Context
*c
)
64 ret
= ff_init_vlc_sparse(&c
->dc_vlc
, 9, DC_VLC_COUNT
,
65 tscc2_dc_vlc_bits
, 1, 1,
66 tscc2_dc_vlc_codes
, 2, 2,
67 tscc2_dc_vlc_syms
, 2, 2, INIT_VLC_LE
);
71 for (i
= 0; i
< NUM_VLC_SETS
; i
++) {
72 ret
= ff_init_vlc_sparse(c
->nc_vlc
+ i
, 9, 16,
73 tscc2_nc_vlc_bits
[i
], 1, 1,
74 tscc2_nc_vlc_codes
[i
], 2, 2,
75 tscc2_nc_vlc_syms
, 1, 1, INIT_VLC_LE
);
80 ret
= ff_init_vlc_sparse(c
->ac_vlc
+ i
, 9, tscc2_ac_vlc_sizes
[i
],
81 tscc2_ac_vlc_bits
[i
], 1, 1,
82 tscc2_ac_vlc_codes
[i
], 2, 2,
83 tscc2_ac_vlc_syms
[i
], 2, 2, INIT_VLC_LE
);
93 #define DEQUANT(val, q) (((q) * (val) + 0x80) >> 8)
94 #define DCT1D(d0, d1, d2, d3, s0, s1, s2, s3, OP) \
95 OP(d0, 5 * ((s0) + (s1) + (s2)) + 2 * (s3)); \
96 OP(d1, 5 * ((s0) - (s2) - (s3)) + 2 * (s1)); \
97 OP(d2, 5 * ((s0) - (s2) + (s3)) - 2 * (s1)); \
98 OP(d3, 5 * ((s0) - (s1) + (s2)) - 2 * (s3)); \
100 #define COL_OP(a, b) a = (b)
101 #define ROW_OP(a, b) a = ((b) + 0x20) >> 6
103 static void tscc2_idct4_put(int *in
, int q
[3], uint8_t *dst
, int stride
)
109 for (i
= 0; i
< 4; i
++) {
110 t0
= DEQUANT(q
[0 + (i
& 1)], in
[0 * 4 + i
]);
111 t1
= DEQUANT(q
[1 + (i
& 1)], in
[1 * 4 + i
]);
112 t2
= DEQUANT(q
[0 + (i
& 1)], in
[2 * 4 + i
]);
113 t3
= DEQUANT(q
[1 + (i
& 1)], in
[3 * 4 + i
]);
114 DCT1D(tblk
[0 * 4 + i
], tblk
[1 * 4 + i
],
115 tblk
[2 * 4 + i
], tblk
[3 * 4 + i
],
116 t0
, t1
, t2
, t3
, COL_OP
);
118 for (i
= 0; i
< 4; i
++) {
119 DCT1D(dst
[0], dst
[1], dst
[2], dst
[3],
120 tblk
[i
* 4 + 0], tblk
[i
* 4 + 1],
121 tblk
[i
* 4 + 2], tblk
[i
* 4 + 3], ROW_OP
);
126 static int tscc2_decode_mb(TSCC2Context
*c
, int *q
, int vlc_set
,
127 uint8_t *dst
, int stride
, int plane
)
129 GetBitContext
*gb
= &c
->gb
;
130 int prev_dc
, dc
, nc
, ac
, bpos
, val
;
135 val
= get_bits(gb
, 8);
136 for (i
= 0; i
< 8; i
++, dst
+= stride
)
137 memset(dst
, val
, 16);
139 if (get_bits_left(gb
) < 16 * 8 * 8)
140 return AVERROR_INVALIDDATA
;
141 for (i
= 0; i
< 8; i
++) {
142 for (j
= 0; j
< 16; j
++)
143 dst
[j
] = get_bits(gb
, 8);
151 for (j
= 0; j
< 2; j
++) {
152 for (k
= 0; k
< 4; k
++) {
154 dc
= get_bits(gb
, 8);
156 dc
= get_vlc2(gb
, c
->dc_vlc
.table
, 9, 2);
158 return AVERROR_INVALIDDATA
;
160 dc
= get_bits(gb
, 8);
162 dc
= (dc
+ prev_dc
) & 0xFF;
166 nc
= get_vlc2(gb
, c
->nc_vlc
[vlc_set
].table
, 9, 1);
168 return AVERROR_INVALIDDATA
;
171 memset(c
->block
+ 1, 0, 15 * sizeof(*c
->block
));
172 for (l
= 0; l
< nc
; l
++) {
173 ac
= get_vlc2(gb
, c
->ac_vlc
[vlc_set
].table
, 9, 2);
175 return AVERROR_INVALIDDATA
;
177 ac
= get_bits(gb
, 12);
180 return AVERROR_INVALIDDATA
;
181 val
= sign_extend(ac
>> 4, 8);
182 c
->block
[tscc2_zigzag
[bpos
++]] = val
;
184 tscc2_idct4_put(c
->block
, q
, dst
+ k
* 4, stride
);
191 static int tscc2_decode_slice(TSCC2Context
*c
, int mb_y
,
192 const uint8_t *buf
, int buf_size
)
197 if ((ret
= init_get_bits8(&c
->gb
, buf
, buf_size
)) < 0)
200 for (mb_x
= 0; mb_x
< c
->mb_width
; mb_x
++) {
201 q
= c
->slice_quants
[mb_x
+ c
->mb_width
* mb_y
];
203 if (q
== 0 || q
== 3) // skip block
205 for (i
= 0; i
< 3; i
++) {
206 off
= mb_x
* 16 + mb_y
* 8 * c
->pic
->linesize
[i
];
207 ret
= tscc2_decode_mb(c
, c
->q
[q
- 1], c
->quant
[q
- 1] - 2,
208 c
->pic
->data
[i
] + off
, c
->pic
->linesize
[i
], i
);
217 static int tscc2_decode_frame(AVCodecContext
*avctx
, void *data
,
218 int *got_frame
, AVPacket
*avpkt
)
220 const uint8_t *buf
= avpkt
->data
;
221 int buf_size
= avpkt
->size
;
222 TSCC2Context
*c
= avctx
->priv_data
;
224 uint32_t frame_type
, size
;
225 int i
, val
, len
, pos
= 0;
226 int num_mb
= c
->mb_width
* c
->mb_height
;
229 bytestream2_init(&gb
, buf
, buf_size
);
230 frame_type
= bytestream2_get_byte(&gb
);
231 if (frame_type
> 1) {
232 av_log(avctx
, AV_LOG_ERROR
, "Incorrect frame type %"PRIu32
"\n",
234 return AVERROR_INVALIDDATA
;
237 if ((ret
= ff_reget_buffer(avctx
, c
->pic
)) < 0) {
241 if (frame_type
== 0) {
243 if ((ret
= av_frame_ref(data
, c
->pic
)) < 0)
249 if (bytestream2_get_bytes_left(&gb
) < 4) {
250 av_log(avctx
, AV_LOG_ERROR
, "Frame is too short\n");
251 return AVERROR_INVALIDDATA
;
254 c
->quant
[0] = bytestream2_get_byte(&gb
);
255 c
->quant
[1] = bytestream2_get_byte(&gb
);
256 if (c
->quant
[0] < 2 || c
->quant
[0] > NUM_VLC_SETS
+ 1 ||
257 c
->quant
[1] < 2 || c
->quant
[1] > NUM_VLC_SETS
+ 1) {
258 av_log(avctx
, AV_LOG_ERROR
, "Invalid quantisers %d / %d\n",
259 c
->quant
[0], c
->quant
[1]);
260 return AVERROR_INVALIDDATA
;
263 for (i
= 0; i
< 3; i
++) {
264 c
->q
[0][i
] = tscc2_quants
[c
->quant
[0] - 2][i
];
265 c
->q
[1][i
] = tscc2_quants
[c
->quant
[1] - 2][i
];
268 bytestream2_skip(&gb
, 1);
270 size
= bytestream2_get_le32(&gb
);
271 if (size
> bytestream2_get_bytes_left(&gb
)) {
272 av_log(avctx
, AV_LOG_ERROR
, "Slice properties chunk is too large\n");
273 return AVERROR_INVALIDDATA
;
276 for (i
= 0; i
< size
; i
++) {
277 val
= bytestream2_get_byte(&gb
);
280 if (pos
+ len
> num_mb
) {
281 av_log(avctx
, AV_LOG_ERROR
, "Too many slice properties\n");
282 return AVERROR_INVALIDDATA
;
284 memset(c
->slice_quants
+ pos
, val
, len
);
288 av_log(avctx
, AV_LOG_ERROR
, "Too few slice properties (%d / %d)\n",
290 return AVERROR_INVALIDDATA
;
293 for (i
= 0; i
< c
->mb_height
; i
++) {
294 size
= bytestream2_peek_byte(&gb
);
296 size
= bytestream2_get_byte(&gb
) - 1;
298 size
= bytestream2_get_le32(&gb
) >> 1;
301 int skip_row
= 1, j
, off
= i
* c
->mb_width
;
302 for (j
= 0; j
< c
->mb_width
; j
++) {
303 if (c
->slice_quants
[off
+ j
] == 1 ||
304 c
->slice_quants
[off
+ j
] == 2) {
310 av_log(avctx
, AV_LOG_ERROR
, "Non-skip row with zero size\n");
311 return AVERROR_INVALIDDATA
;
314 if (bytestream2_get_bytes_left(&gb
) < size
) {
315 av_log(avctx
, AV_LOG_ERROR
, "Invalid slice size (%"PRIu32
"/%u)\n",
316 size
, bytestream2_get_bytes_left(&gb
));
317 return AVERROR_INVALIDDATA
;
319 ret
= tscc2_decode_slice(c
, i
, buf
+ bytestream2_tell(&gb
), size
);
321 av_log(avctx
, AV_LOG_ERROR
, "Error decoding slice %d\n", i
);
324 bytestream2_skip(&gb
, size
);
328 if ((ret
= av_frame_ref(data
, c
->pic
)) < 0)
331 /* always report that the buffer was completely consumed */
335 static av_cold
int tscc2_decode_end(AVCodecContext
*avctx
)
337 TSCC2Context
* const c
= avctx
->priv_data
;
339 av_frame_free(&c
->pic
);
340 av_freep(&c
->slice_quants
);
346 static av_cold
int tscc2_decode_init(AVCodecContext
*avctx
)
348 TSCC2Context
* const c
= avctx
->priv_data
;
353 avctx
->pix_fmt
= AV_PIX_FMT_YUV444P
;
355 if ((ret
= init_vlcs(c
)) < 0) {
356 av_log(avctx
, AV_LOG_ERROR
, "Cannot initialise VLCs\n");
360 c
->mb_width
= FFALIGN(avctx
->width
, 16) >> 4;
361 c
->mb_height
= FFALIGN(avctx
->height
, 8) >> 3;
362 c
->slice_quants
= av_malloc(c
->mb_width
* c
->mb_height
);
363 if (!c
->slice_quants
) {
364 av_log(avctx
, AV_LOG_ERROR
, "Cannot allocate slice information\n");
366 return AVERROR(ENOMEM
);
369 c
->pic
= av_frame_alloc();
371 tscc2_decode_end(avctx
);
372 return AVERROR(ENOMEM
);
378 AVCodec ff_tscc2_decoder
= {
380 .long_name
= NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"),
381 .type
= AVMEDIA_TYPE_VIDEO
,
382 .id
= AV_CODEC_ID_TSCC2
,
383 .priv_data_size
= sizeof(TSCC2Context
),
384 .init
= tscc2_decode_init
,
385 .close
= tscc2_decode_end
,
386 .decode
= tscc2_decode_frame
,
387 .capabilities
= CODEC_CAP_DR1
,