tscc2.c
Go to the documentation of this file.
1 /*
2  * TechSmith Screen Codec 2 (aka Dora) decoder
3  * Copyright (c) 2012 Konstantin Shishkov
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
20  */
21 
22 /**
23  * @file
24  * TechSmith Screen Codec 2 decoder
25  */
26 
27 #define BITSTREAM_READER_LE
28 #include "avcodec.h"
29 #include "get_bits.h"
30 #include "bytestream.h"
31 #include "internal.h"
32 #include "tscc2data.h"
33 
34 typedef struct TSCC2Context {
38  uint8_t *slice_quants;
39  int quant[2];
40  int q[2][3];
42 
44  int block[16];
45 } TSCC2Context;
46 
48 {
49  int i;
50 
51  ff_free_vlc(&c->dc_vlc);
52  for (i = 0; i < NUM_VLC_SETS; i++) {
53  ff_free_vlc(c->nc_vlc + i);
54  ff_free_vlc(c->ac_vlc + i);
55  }
56 }
57 
59 {
60  int i, ret;
61 
63  tscc2_dc_vlc_bits, 1, 1,
64  tscc2_dc_vlc_codes, 2, 2,
66  if (ret)
67  return ret;
68 
69  for (i = 0; i < NUM_VLC_SETS; i++) {
70  ret = ff_init_vlc_sparse(c->nc_vlc + i, 9, 16,
71  tscc2_nc_vlc_bits[i], 1, 1,
72  tscc2_nc_vlc_codes[i], 2, 2,
74  if (ret) {
75  free_vlcs(c);
76  return ret;
77  }
78  ret = ff_init_vlc_sparse(c->ac_vlc + i, 9, tscc2_ac_vlc_sizes[i],
79  tscc2_ac_vlc_bits[i], 1, 1,
80  tscc2_ac_vlc_codes[i], 2, 2,
81  tscc2_ac_vlc_syms[i], 2, 2, INIT_VLC_LE);
82  if (ret) {
83  free_vlcs(c);
84  return ret;
85  }
86  }
87 
88  return 0;
89 }
90 
91 #define DEQUANT(val, q) ((q * val + 0x80) >> 8)
92 #define DCT1D(d0, d1, d2, d3, s0, s1, s2, s3, OP) \
93  OP(d0, 5 * ((s0) + (s1) + (s2)) + 2 * (s3)); \
94  OP(d1, 5 * ((s0) - (s2) - (s3)) + 2 * (s1)); \
95  OP(d2, 5 * ((s0) - (s2) + (s3)) - 2 * (s1)); \
96  OP(d3, 5 * ((s0) - (s1) + (s2)) - 2 * (s3)); \
97 
98 #define COL_OP(a, b) a = b
99 #define ROW_OP(a, b) a = ((b) + 0x20) >> 6
100 
101 static void tscc2_idct4_put(int *in, int q[3], uint8_t *dst, int stride)
102 {
103  int i;
104  int tblk[4 * 4];
105  int t0, t1, t2, t3;
106 
107  for (i = 0; i < 4; i++) {
108  t0 = DEQUANT(q[0 + (i & 1)], in[0 * 4 + i]);
109  t1 = DEQUANT(q[1 + (i & 1)], in[1 * 4 + i]);
110  t2 = DEQUANT(q[0 + (i & 1)], in[2 * 4 + i]);
111  t3 = DEQUANT(q[1 + (i & 1)], in[3 * 4 + i]);
112  DCT1D(tblk[0 * 4 + i], tblk[1 * 4 + i],
113  tblk[2 * 4 + i], tblk[3 * 4 + i],
114  t0, t1, t2, t3, COL_OP);
115  }
116  for (i = 0; i < 4; i++) {
117  DCT1D(dst[0], dst[1], dst[2], dst[3],
118  tblk[i * 4 + 0], tblk[i * 4 + 1],
119  tblk[i * 4 + 2], tblk[i * 4 + 3], ROW_OP);
120  dst += stride;
121  }
122 }
123 
124 static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set,
125  uint8_t *dst, int stride, int plane)
126 {
127  GetBitContext *gb = &c->gb;
128  int prev_dc, dc, nc, ac, bpos, val;
129  int i, j, k, l;
130 
131  if (get_bits1(gb)) {
132  if (get_bits1(gb)) {
133  val = get_bits(gb, 8);
134  for (i = 0; i < 8; i++, dst += stride)
135  memset(dst, val, 16);
136  } else {
137  if (get_bits_left(gb) < 16 * 8 * 8)
138  return AVERROR_INVALIDDATA;
139  for (i = 0; i < 8; i++) {
140  for (j = 0; j < 16; j++)
141  dst[j] = get_bits(gb, 8);
142  dst += stride;
143  }
144  }
145  return 0;
146  }
147 
148  prev_dc = 0;
149  for (j = 0; j < 2; j++) {
150  for (k = 0; k < 4; k++) {
151  if (!(j | k)) {
152  dc = get_bits(gb, 8);
153  } else {
154  dc = get_vlc2(gb, c->dc_vlc.table, 9, 2);
155  if (dc == -1)
156  return AVERROR_INVALIDDATA;
157  if (dc == 0x100)
158  dc = get_bits(gb, 8);
159  }
160  dc = (dc + prev_dc) & 0xFF;
161  prev_dc = dc;
162  c->block[0] = dc;
163 
164  nc = get_vlc2(gb, c->nc_vlc[vlc_set].table, 9, 1);
165  if (nc == -1)
166  return AVERROR_INVALIDDATA;
167 
168  bpos = 1;
169  memset(c->block + 1, 0, 15 * sizeof(*c->block));
170  for (l = 0; l < nc; l++) {
171  ac = get_vlc2(gb, c->ac_vlc[vlc_set].table, 9, 2);
172  if (ac == -1)
173  return AVERROR_INVALIDDATA;
174  if (ac == 0x1000)
175  ac = get_bits(gb, 12);
176  bpos += ac & 0xF;
177  if (bpos >= 16)
178  return AVERROR_INVALIDDATA;
179  val = sign_extend(ac >> 4, 8);
180  c->block[tscc2_zigzag[bpos++]] = val;
181  }
182  tscc2_idct4_put(c->block, q, dst + k * 4, stride);
183  }
184  dst += 4 * stride;
185  }
186  return 0;
187 }
188 
189 static int tscc2_decode_slice(TSCC2Context *c, int mb_y,
190  const uint8_t *buf, int buf_size)
191 {
192  int i, mb_x, q, ret;
193  int off;
194 
195  init_get_bits(&c->gb, buf, buf_size * 8);
196 
197  for (mb_x = 0; mb_x < c->mb_width; mb_x++) {
198  q = c->slice_quants[mb_x + c->mb_width * mb_y];
199 
200  if (q == 0 || q == 3) // skip block
201  continue;
202  for (i = 0; i < 3; i++) {
203  off = mb_x * 16 + mb_y * 8 * c->pic->linesize[i];
204  ret = tscc2_decode_mb(c, c->q[q - 1], c->quant[q - 1] - 2,
205  c->pic->data[i] + off, c->pic->linesize[i], i);
206  if (ret)
207  return ret;
208  }
209  }
210 
211  return 0;
212 }
213 
215  int *got_frame, AVPacket *avpkt)
216 {
217  const uint8_t *buf = avpkt->data;
218  int buf_size = avpkt->size;
219  TSCC2Context *c = avctx->priv_data;
221  uint32_t frame_type, size;
222  int i, val, len, pos = 0;
223  int num_mb = c->mb_width * c->mb_height;
224  int ret;
225 
226  bytestream2_init(&gb, buf, buf_size);
227  frame_type = bytestream2_get_byte(&gb);
228  if (frame_type > 1) {
229  av_log(avctx, AV_LOG_ERROR, "Incorrect frame type %d\n", frame_type);
230  return AVERROR_INVALIDDATA;
231  }
232 
233  if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) {
234  return ret;
235  }
236 
237  if (frame_type == 0) {
238  *got_frame = 1;
239  if ((ret = av_frame_ref(data, c->pic)) < 0)
240  return ret;
241 
242  return buf_size;
243  }
244 
245  if (bytestream2_get_bytes_left(&gb) < 4) {
246  av_log(avctx, AV_LOG_ERROR, "Frame is too short\n");
247  return AVERROR_INVALIDDATA;
248  }
249 
250  c->quant[0] = bytestream2_get_byte(&gb);
251  c->quant[1] = bytestream2_get_byte(&gb);
252  if (c->quant[0] < 2 || c->quant[0] > NUM_VLC_SETS + 1 ||
253  c->quant[1] < 2 || c->quant[1] > NUM_VLC_SETS + 1) {
254  av_log(avctx, AV_LOG_ERROR, "Invalid quantisers %d / %d\n",
255  c->quant[0], c->quant[1]);
256  return AVERROR_INVALIDDATA;
257  }
258 
259  for (i = 0; i < 3; i++) {
260  c->q[0][i] = tscc2_quants[c->quant[0] - 2][i];
261  c->q[1][i] = tscc2_quants[c->quant[1] - 2][i];
262  }
263 
264  bytestream2_skip(&gb, 1);
265 
266  size = bytestream2_get_le32(&gb);
267  if (size > bytestream2_get_bytes_left(&gb)) {
268  av_log(avctx, AV_LOG_ERROR, "Slice properties chunk is too large\n");
269  return AVERROR_INVALIDDATA;
270  }
271 
272  for (i = 0; i < size; i++) {
273  val = bytestream2_get_byte(&gb);
274  len = val & 0x3F;
275  val >>= 6;
276  if (pos + len > num_mb) {
277  av_log(avctx, AV_LOG_ERROR, "Too many slice properties\n");
278  return AVERROR_INVALIDDATA;
279  }
280  memset(c->slice_quants + pos, val, len);
281  pos += len;
282  }
283  if (pos < num_mb) {
284  av_log(avctx, AV_LOG_ERROR, "Too few slice properties (%d / %d)\n",
285  pos, num_mb);
286  return AVERROR_INVALIDDATA;
287  }
288 
289  for (i = 0; i < c->mb_height; i++) {
290  size = bytestream2_peek_byte(&gb);
291  if (size & 1) {
292  size = bytestream2_get_byte(&gb) - 1;
293  } else {
294  size = bytestream2_get_le32(&gb) >> 1;
295  }
296  if (!size) {
297  int skip_row = 1, j, off = i * c->mb_width;
298  for (j = 0; j < c->mb_width; j++) {
299  if (c->slice_quants[off + j] == 1 ||
300  c->slice_quants[off + j] == 2) {
301  skip_row = 0;
302  break;
303  }
304  }
305  if (!skip_row) {
306  av_log(avctx, AV_LOG_ERROR, "Non-skip row with zero size\n");
307  return AVERROR_INVALIDDATA;
308  }
309  }
310  if (bytestream2_get_bytes_left(&gb) < size) {
311  av_log(avctx, AV_LOG_ERROR, "Invalid slice size (%d/%d)\n",
312  size, bytestream2_get_bytes_left(&gb));
313  return AVERROR_INVALIDDATA;
314  }
315  ret = tscc2_decode_slice(c, i, buf + bytestream2_tell(&gb), size);
316  if (ret) {
317  av_log(avctx, AV_LOG_ERROR, "Error decoding slice %d\n", i);
318  return ret;
319  }
320  bytestream2_skip(&gb, size);
321  }
322 
323  *got_frame = 1;
324  if ((ret = av_frame_ref(data, c->pic)) < 0)
325  return ret;
326 
327  /* always report that the buffer was completely consumed */
328  return buf_size;
329 }
330 
332 {
333  TSCC2Context * const c = avctx->priv_data;
334 
335  av_frame_free(&c->pic);
336  av_freep(&c->slice_quants);
337  free_vlcs(c);
338 
339  return 0;
340 }
341 
343 {
344  TSCC2Context * const c = avctx->priv_data;
345  int ret;
346 
347  c->avctx = avctx;
348 
349  avctx->pix_fmt = AV_PIX_FMT_YUV444P;
350 
351  if ((ret = init_vlcs(c)) < 0) {
352  av_log(avctx, AV_LOG_ERROR, "Cannot initialise VLCs\n");
353  return ret;
354  }
355 
356  c->mb_width = FFALIGN(avctx->width, 16) >> 4;
357  c->mb_height = FFALIGN(avctx->height, 8) >> 3;
359  if (!c->slice_quants) {
360  av_log(avctx, AV_LOG_ERROR, "Cannot allocate slice information\n");
361  free_vlcs(c);
362  return AVERROR(ENOMEM);
363  }
364 
365  c->pic = av_frame_alloc();
366  if (!c->pic) {
367  tscc2_decode_end(avctx);
368  return AVERROR(ENOMEM);
369  }
370 
371  return 0;
372 }
373 
375  .name = "tscc2",
376  .type = AVMEDIA_TYPE_VIDEO,
377  .id = AV_CODEC_ID_TSCC2,
378  .priv_data_size = sizeof(TSCC2Context),
382  .capabilities = CODEC_CAP_DR1,
383  .long_name = NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"),
384 };
struct TSCC2Context TSCC2Context
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
static const uint16_t tscc2_dc_vlc_syms[47]
Definition: tscc2data.h:46
static const int tscc2_ac_vlc_sizes[13]
Definition: tscc2data.h:909
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int size
static void tscc2_idct4_put(int *in, int q[3], uint8_t *dst, int stride)
Definition: tscc2.c:101
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
int16_t(* table)[2]
code, bits
Definition: get_bits.h:65
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:73
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:240
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
AVFrame * pic
Definition: tscc2.c:36
#define NUM_VLC_SETS
Definition: tscc2data.h:34
About Git write you should know how to use GIT properly Luckily Git comes with excellent documentation git help man git shows you the available git< command > help man git< command > shows information about the subcommand< command > The most comprehensive manual is the website Git Reference visit they are quite exhaustive You do not need a special username or password All you need is to provide a ssh public key to the Git server admin What follows now is a basic introduction to Git and some FFmpeg specific guidelines Read it at least if you are granted commit privileges to the FFmpeg project you are expected to be familiar with these rules I if not You can get git from etc no matter how small Every one of them has been saved from looking like a fool by this many times It s very easy for stray debug output or cosmetic modifications to slip in
Definition: git-howto.txt:5
int block[16]
Definition: tscc2.c:44
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:130
static av_always_inline int get_vlc2(GetBitContext *s, int16_t(*table)[2], int bits, int max_depth)
Parse a vlc code.
Definition: get_bits.h:524
static const uint16_t tscc2_nc_vlc_codes[13][16]
Definition: tscc2data.h:78
static const uint8_t tscc2_dc_vlc_bits[47]
Definition: tscc2data.h:64
int stride
Definition: mace.c:144
AVCodecContext * avctx
Definition: tscc2.c:35
#define FFALIGN(x, a)
Definition: common.h:63
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
#define COL_OP(a, b)
Definition: tscc2.c:98
static av_cold void free_vlcs(TSCC2Context *c)
Definition: tscc2.c:47
int q[2][3]
Definition: tscc2.c:40
static const uint16_t * tscc2_ac_vlc_syms[13]
Definition: tscc2data.h:913
int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, const void *symbols, int symbols_wrap, int symbols_size, int flags)
Definition: bitstream.c:262
#define av_cold
Definition: attributes.h:78
static int tscc2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: tscc2.c:214
#define t0
Definition: regdef.h:28
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
uint8_t * data
bitstream reader API header.
end end ac
uint8_t * data[8]
pointer to the picture/channel planes.
Definition: frame.h:87
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:557
VLC dc_vlc
Definition: tscc2.c:43
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:159
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
#define t1
Definition: regdef.h:29
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:149
void av_log(void *avcl, int level, const char *fmt,...)
Send the specified message to the log if the level is less than or equal to the current av_log_level...
Definition: log.c:246
const char * name
Name of the codec implementation.
#define t3
Definition: regdef.h:31
static const uint8_t tscc2_nc_vlc_bits[13][16]
Definition: tscc2data.h:107
external API header
Definition: get_bits.h:63
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
Identical in function to av_frame_make_writable(), except it uses ff_get_buffer() to allocate the buf...
static av_cold int tscc2_decode_end(AVCodecContext *avctx)
Definition: tscc2.c:331
static int tscc2_decode_mb(TSCC2Context *c, int *q, int vlc_set, uint8_t *dst, int stride, int plane)
Definition: tscc2.c:124
ret
Definition: avfilter.c:821
int width
picture width / height.
static av_always_inline unsigned int bytestream2_peek_byte(GetByteContext *g)
Definition: bytestream.h:92
static const uint8_t * tscc2_ac_vlc_bits[13]
Definition: tscc2data.h:928
#define DC_VLC_COUNT
Definition: tscc2data.h:44
#define ROW_OP(a, b)
Definition: tscc2.c:99
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:183
for k
static av_always_inline unsigned int bytestream2_get_le32(GetByteContext *g)
Definition: bytestream.h:85
uint8_t * slice_quants
Definition: tscc2.c:38
static const uint16_t tscc2_quants[13][3]
Definition: tscc2data.h:36
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
FIXME Range Coding of cr are mx and my are Motion Vector top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff)*mv_scale Intra DC Predicton block[y][x] dc[1]
Definition: snow.txt:392
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
static const uint8_t tscc2_zigzag[16]
Definition: tscc2data.h:27
#define INIT_VLC_LE
Definition: get_bits.h:442
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:273
synthesis window for stochastic i
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:379
static av_cold int tscc2_decode_init(AVCodecContext *avctx)
Definition: tscc2.c:342
VLC nc_vlc[13]
Definition: tscc2.c:43
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:95
static const uint16_t * tscc2_ac_vlc_codes[13]
Definition: tscc2data.h:920
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:123
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by an given frame.
Definition: frame.c:228
#define DCT1D(d0, d1, d2, d3, s0, s1, s2, s3, OP)
Definition: tscc2.c:92
int mb_height
Definition: tscc2.c:37
static av_cold int init_vlcs(TSCC2Context *c)
Definition: tscc2.c:58
static const uint16_t tscc2_dc_vlc_codes[47]
Definition: tscc2data.h:55
int quant[2]
Definition: tscc2.c:39
common internal api header.
static int tscc2_decode_slice(TSCC2Context *c, int mb_y, const uint8_t *buf, int buf_size)
Definition: tscc2.c:189
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:108
static double c[64]
int linesize[8]
For video, size in bytes of each picture line.
Definition: frame.h:101
VLC ac_vlc[13]
Definition: tscc2.c:43
#define DEQUANT(val, q)
Definition: tscc2.c:91
static const uint8_t tscc2_nc_vlc_syms[16]
Definition: tscc2data.h:73
int len
int mb_width
Definition: tscc2.c:37
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
GetBitContext gb
Definition: tscc2.c:41
This structure stores compressed data.
void ff_free_vlc(VLC *vlc)
Definition: bitstream.c:344
#define t2
Definition: regdef.h:30
static av_always_inline unsigned int bytestream2_get_byte(GetByteContext *g)
Definition: bytestream.h:92
AVCodec ff_tscc2_decoder
Definition: tscc2.c:374