2 * TechSmith Screen Codec 2 (aka Dora) decoder
3 * Copyright (c) 2012 Konstantin Shishkov
5 * This file is part of Libav.
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.
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.
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
24 * TechSmith Screen Codec 2 decoder
29 #define BITSTREAM_READER_LE
31 #include "bitstream.h"
32 #include "bytestream.h"
35 #include "tscc2data.h"
38 typedef struct TSCC2Context
{
39 AVCodecContext
*avctx
;
41 int mb_width
, mb_height
;
42 uint8_t *slice_quants
;
47 VLC dc_vlc
, nc_vlc
[NUM_VLC_SETS
], ac_vlc
[NUM_VLC_SETS
];
51 static av_cold
void free_vlcs(TSCC2Context
*c
)
55 ff_free_vlc(&c
->dc_vlc
);
56 for (i
= 0; i
< NUM_VLC_SETS
; i
++) {
57 ff_free_vlc(c
->nc_vlc
+ i
);
58 ff_free_vlc(c
->ac_vlc
+ i
);
62 static av_cold
int init_vlcs(TSCC2Context
*c
)
66 ret
= ff_init_vlc_sparse(&c
->dc_vlc
, 9, DC_VLC_COUNT
,
67 tscc2_dc_vlc_bits
, 1, 1,
68 tscc2_dc_vlc_codes
, 2, 2,
69 tscc2_dc_vlc_syms
, 2, 2, INIT_VLC_LE
);
73 for (i
= 0; i
< NUM_VLC_SETS
; i
++) {
74 ret
= ff_init_vlc_sparse(c
->nc_vlc
+ i
, 9, 16,
75 tscc2_nc_vlc_bits
[i
], 1, 1,
76 tscc2_nc_vlc_codes
[i
], 2, 2,
77 tscc2_nc_vlc_syms
, 1, 1, INIT_VLC_LE
);
82 ret
= ff_init_vlc_sparse(c
->ac_vlc
+ i
, 9, tscc2_ac_vlc_sizes
[i
],
83 tscc2_ac_vlc_bits
[i
], 1, 1,
84 tscc2_ac_vlc_codes
[i
], 2, 2,
85 tscc2_ac_vlc_syms
[i
], 2, 2, INIT_VLC_LE
);
95 #define DEQUANT(val, q) ((q * val + 0x80) >> 8)
96 #define DCT1D(d0, d1, d2, d3, s0, s1, s2, s3, OP) \
97 OP(d0, 5 * ((s0) + (s1) + (s2)) + 2 * (s3)); \
98 OP(d1, 5 * ((s0) - (s2) - (s3)) + 2 * (s1)); \
99 OP(d2, 5 * ((s0) - (s2) + (s3)) - 2 * (s1)); \
100 OP(d3, 5 * ((s0) - (s1) + (s2)) - 2 * (s3)); \
102 #define COL_OP(a, b) a = b
103 #define ROW_OP(a, b) a = ((b) + 0x20) >> 6
105 static void tscc2_idct4_put(int *in
, int q
[3], uint8_t *dst
, int stride
)
111 for (i
= 0; i
< 4; i
++) {
112 t0
= DEQUANT(q
[0 + (i
& 1)], in
[0 * 4 + i
]);
113 t1
= DEQUANT(q
[1 + (i
& 1)], in
[1 * 4 + i
]);
114 t2
= DEQUANT(q
[0 + (i
& 1)], in
[2 * 4 + i
]);
115 t3
= DEQUANT(q
[1 + (i
& 1)], in
[3 * 4 + i
]);
116 DCT1D(tblk
[0 * 4 + i
], tblk
[1 * 4 + i
],
117 tblk
[2 * 4 + i
], tblk
[3 * 4 + i
],
118 t0
, t1
, t2
, t3
, COL_OP
);
120 for (i
= 0; i
< 4; i
++) {
121 DCT1D(dst
[0], dst
[1], dst
[2], dst
[3],
122 tblk
[i
* 4 + 0], tblk
[i
* 4 + 1],
123 tblk
[i
* 4 + 2], tblk
[i
* 4 + 3], ROW_OP
);
128 static int tscc2_decode_mb(TSCC2Context
*c
, int *q
, int vlc_set
,
129 uint8_t *dst
, int stride
, int plane
)
131 BitstreamContext
*bc
= &c
->bc
;
132 int prev_dc
, dc
, nc
, ac
, bpos
, val
;
135 if (bitstream_read_bit(bc
)) {
136 if (bitstream_read_bit(bc
)) {
137 val
= bitstream_read(bc
, 8);
138 for (i
= 0; i
< 8; i
++, dst
+= stride
)
139 memset(dst
, val
, 16);
141 if (bitstream_bits_left(bc
) < 16 * 8 * 8)
142 return AVERROR_INVALIDDATA
;
143 for (i
= 0; i
< 8; i
++) {
144 for (j
= 0; j
< 16; j
++)
145 dst
[j
] = bitstream_read(bc
, 8);
153 for (j
= 0; j
< 2; j
++) {
154 for (k
= 0; k
< 4; k
++) {
156 dc
= bitstream_read(bc
, 8);
158 dc
= bitstream_read_vlc(bc
, c
->dc_vlc
.table
, 9, 2);
160 return AVERROR_INVALIDDATA
;
162 dc
= bitstream_read(bc
, 8);
164 dc
= (dc
+ prev_dc
) & 0xFF;
168 nc
= bitstream_read_vlc(bc
, c
->nc_vlc
[vlc_set
].table
, 9, 1);
170 return AVERROR_INVALIDDATA
;
173 memset(c
->block
+ 1, 0, 15 * sizeof(*c
->block
));
174 for (l
= 0; l
< nc
; l
++) {
175 ac
= bitstream_read_vlc(bc
, c
->ac_vlc
[vlc_set
].table
, 9, 2);
177 return AVERROR_INVALIDDATA
;
179 ac
= bitstream_read(bc
, 12);
182 return AVERROR_INVALIDDATA
;
183 val
= sign_extend(ac
>> 4, 8);
184 c
->block
[ff_zigzag_scan
[bpos
++]] = val
;
186 tscc2_idct4_put(c
->block
, q
, dst
+ k
* 4, stride
);
193 static int tscc2_decode_slice(TSCC2Context
*c
, int mb_y
,
194 const uint8_t *buf
, int buf_size
)
199 bitstream_init8(&c
->bc
, buf
, buf_size
);
201 for (mb_x
= 0; mb_x
< c
->mb_width
; mb_x
++) {
202 q
= c
->slice_quants
[mb_x
+ c
->mb_width
* mb_y
];
204 if (q
== 0 || q
== 3) // skip block
206 for (i
= 0; i
< 3; i
++) {
207 off
= mb_x
* 16 + mb_y
* 8 * c
->pic
->linesize
[i
];
208 ret
= tscc2_decode_mb(c
, c
->q
[q
- 1], c
->quant
[q
- 1] - 2,
209 c
->pic
->data
[i
] + off
, c
->pic
->linesize
[i
], i
);
218 static int tscc2_decode_frame(AVCodecContext
*avctx
, void *data
,
219 int *got_frame
, AVPacket
*avpkt
)
221 const uint8_t *buf
= avpkt
->data
;
222 int buf_size
= avpkt
->size
;
223 TSCC2Context
*c
= avctx
->priv_data
;
225 uint32_t frame_type
, size
;
226 int i
, val
, len
, pos
= 0;
227 int num_mb
= c
->mb_width
* c
->mb_height
;
230 bytestream2_init(&gb
, buf
, buf_size
);
231 frame_type
= bytestream2_get_byte(&gb
);
232 if (frame_type
> 1) {
233 av_log(avctx
, AV_LOG_ERROR
, "Incorrect frame type %"PRIu32
"\n",
235 return AVERROR_INVALIDDATA
;
238 if ((ret
= ff_reget_buffer(avctx
, c
->pic
)) < 0) {
239 av_log(avctx
, AV_LOG_ERROR
, "reget_buffer() failed\n");
243 if (frame_type
== 0) {
245 if ((ret
= av_frame_ref(data
, c
->pic
)) < 0)
251 if (bytestream2_get_bytes_left(&gb
) < 4) {
252 av_log(avctx
, AV_LOG_ERROR
, "Frame is too short\n");
253 return AVERROR_INVALIDDATA
;
256 c
->quant
[0] = bytestream2_get_byte(&gb
);
257 c
->quant
[1] = bytestream2_get_byte(&gb
);
258 if (c
->quant
[0] < 2 || c
->quant
[0] > NUM_VLC_SETS
+ 1 ||
259 c
->quant
[1] < 2 || c
->quant
[1] > NUM_VLC_SETS
+ 1) {
260 av_log(avctx
, AV_LOG_ERROR
, "Invalid quantisers %d / %d\n",
261 c
->quant
[0], c
->quant
[1]);
262 return AVERROR_INVALIDDATA
;
265 for (i
= 0; i
< 3; i
++) {
266 c
->q
[0][i
] = tscc2_quants
[c
->quant
[0] - 2][i
];
267 c
->q
[1][i
] = tscc2_quants
[c
->quant
[1] - 2][i
];
270 bytestream2_skip(&gb
, 1);
272 size
= bytestream2_get_le32(&gb
);
273 if (size
> bytestream2_get_bytes_left(&gb
)) {
274 av_log(avctx
, AV_LOG_ERROR
, "Slice properties chunk is too large\n");
275 return AVERROR_INVALIDDATA
;
278 for (i
= 0; i
< size
; i
++) {
279 val
= bytestream2_get_byte(&gb
);
282 if (pos
+ len
> num_mb
) {
283 av_log(avctx
, AV_LOG_ERROR
, "Too many slice properties\n");
284 return AVERROR_INVALIDDATA
;
286 memset(c
->slice_quants
+ pos
, val
, len
);
290 av_log(avctx
, AV_LOG_ERROR
, "Too few slice properties (%d / %d)\n",
292 return AVERROR_INVALIDDATA
;
295 for (i
= 0; i
< c
->mb_height
; i
++) {
296 size
= bytestream2_peek_byte(&gb
);
298 size
= bytestream2_get_byte(&gb
) - 1;
300 size
= bytestream2_get_le32(&gb
) >> 1;
303 int skip_row
= 1, j
, off
= i
* c
->mb_width
;
304 for (j
= 0; j
< c
->mb_width
; j
++) {
305 if (c
->slice_quants
[off
+ j
] == 1 ||
306 c
->slice_quants
[off
+ j
] == 2) {
312 av_log(avctx
, AV_LOG_ERROR
, "Non-skip row with zero size\n");
313 return AVERROR_INVALIDDATA
;
316 if (bytestream2_get_bytes_left(&gb
) < size
) {
317 av_log(avctx
, AV_LOG_ERROR
, "Invalid slice size (%"PRIu32
"/%u)\n",
318 size
, bytestream2_get_bytes_left(&gb
));
319 return AVERROR_INVALIDDATA
;
321 ret
= tscc2_decode_slice(c
, i
, buf
+ bytestream2_tell(&gb
), size
);
323 av_log(avctx
, AV_LOG_ERROR
, "Error decoding slice %d\n", i
);
326 bytestream2_skip(&gb
, size
);
330 if ((ret
= av_frame_ref(data
, c
->pic
)) < 0)
333 /* always report that the buffer was completely consumed */
337 static av_cold
int tscc2_decode_end(AVCodecContext
*avctx
)
339 TSCC2Context
* const c
= avctx
->priv_data
;
341 av_frame_free(&c
->pic
);
342 av_freep(&c
->slice_quants
);
348 static av_cold
int tscc2_decode_init(AVCodecContext
*avctx
)
350 TSCC2Context
* const c
= avctx
->priv_data
;
355 avctx
->pix_fmt
= AV_PIX_FMT_YUV444P
;
357 if ((ret
= init_vlcs(c
)) < 0) {
358 av_log(avctx
, AV_LOG_ERROR
, "Cannot initialise VLCs\n");
362 c
->mb_width
= FFALIGN(avctx
->width
, 16) >> 4;
363 c
->mb_height
= FFALIGN(avctx
->height
, 8) >> 3;
364 c
->slice_quants
= av_malloc(c
->mb_width
* c
->mb_height
);
365 if (!c
->slice_quants
) {
366 av_log(avctx
, AV_LOG_ERROR
, "Cannot allocate slice information\n");
368 return AVERROR(ENOMEM
);
371 c
->pic
= av_frame_alloc();
373 tscc2_decode_end(avctx
);
374 return AVERROR(ENOMEM
);
380 AVCodec ff_tscc2_decoder
= {
382 .long_name
= NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"),
383 .type
= AVMEDIA_TYPE_VIDEO
,
384 .id
= AV_CODEC_ID_TSCC2
,
385 .priv_data_size
= sizeof(TSCC2Context
),
386 .init
= tscc2_decode_init
,
387 .close
= tscc2_decode_end
,
388 .decode
= tscc2_decode_frame
,
389 .capabilities
= AV_CODEC_CAP_DR1
,