FFmpeg
clearvideo.c
Go to the documentation of this file.
1 /*
2  * ClearVideo decoder
3  * Copyright (c) 2012-2018 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  * ClearVideo decoder
25  */
26 
27 #include "libavutil/mem_internal.h"
28 #include "libavutil/thread.h"
29 
30 #include "avcodec.h"
31 #include "bytestream.h"
32 #include "codec_internal.h"
33 #include "get_bits.h"
34 #include "idctdsp.h"
35 #include "internal.h"
36 #include "mathops.h"
37 #include "clearvideodata.h"
38 
39 #define CLV_VLC_BITS 9
40 
41 typedef struct LevelCodes {
45 } LevelCodes;
46 
47 typedef struct MV {
48  int16_t x, y;
49 } MV;
50 
51 static const MV zero_mv = { 0 };
52 
53 typedef struct MVInfo {
54  int mb_w;
55  int mb_h;
56  int mb_size;
57  int mb_stride;
58  int top;
59  MV *mv;
60 } MVInfo;
61 
62 typedef struct TileInfo {
63  uint16_t flags;
64  int16_t bias;
65  MV mv;
66  struct TileInfo *child[4];
67 } TileInfo;
68 
69 typedef struct CLVContext {
78  int tile_size;
81  DECLARE_ALIGNED(16, int16_t, block)[64];
82  int top_dc[3], left_dc[4];
83 } CLVContext;
84 
85 static VLC dc_vlc, ac_vlc;
86 static LevelCodes lev[4 + 3 + 3]; // 0..3: Y, 4..6: U, 7..9: V
87 static VLCElem vlc_buf[16716];
88 
89 static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac,
90  int ac_quant)
91 {
92  GetBitContext *gb = &ctx->gb;
93  int idx = 1, last = 0, val, skip;
94 
95  memset(blk, 0, sizeof(*blk) * 64);
96  blk[0] = get_vlc2(gb, dc_vlc.table, CLV_VLC_BITS, 3);
97 
98  if (!has_ac)
99  return 0;
100 
101  while (idx < 64 && !last) {
102  val = get_vlc2(gb, ac_vlc.table, CLV_VLC_BITS, 2);
103  if (val < 0)
104  return AVERROR_INVALIDDATA;
105  if (val != 0x1BFF) {
106  last = val >> 12;
107  skip = (val >> 4) & 0xFF;
108  val &= 0xF;
109  if (get_bits1(gb))
110  val = -val;
111  } else {
112  last = get_bits1(gb);
113  skip = get_bits(gb, 6);
114  val = get_sbits(gb, 8);
115  }
116  if (val) {
117  int aval = FFABS(val), sign = val < 0;
118  val = ac_quant * (2 * aval + 1);
119  if (!(ac_quant & 1))
120  val--;
121  if (sign)
122  val = -val;
123  }
124  idx += skip;
125  if (idx >= 64)
126  return AVERROR_INVALIDDATA;
127  blk[ff_zigzag_direct[idx++]] = val;
128  }
129 
130  return (idx <= 64 && last) ? 0 : -1;
131 }
132 
133 #define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP) \
134  const int t0 = OP(2841 * blk[1 * step] + 565 * blk[7 * step]); \
135  const int t1 = OP( 565 * blk[1 * step] - 2841 * blk[7 * step]); \
136  const int t2 = OP(1609 * blk[5 * step] + 2408 * blk[3 * step]); \
137  const int t3 = OP(2408 * blk[5 * step] - 1609 * blk[3 * step]); \
138  const int t4 = OP(1108 * blk[2 * step] - 2676 * blk[6 * step]); \
139  const int t5 = OP(2676 * blk[2 * step] + 1108 * blk[6 * step]); \
140  const int t6 = ((blk[0 * step] + blk[4 * step]) * (1 << dshift)) + bias; \
141  const int t7 = ((blk[0 * step] - blk[4 * step]) * (1 << dshift)) + bias; \
142  const int t8 = t0 + t2; \
143  const int t9 = t0 - t2; \
144  const int tA = (int)(181U * (t9 + (t1 - t3)) + 0x80) >> 8; \
145  const int tB = (int)(181U * (t9 - (t1 - t3)) + 0x80) >> 8; \
146  const int tC = t1 + t3; \
147  \
148  blk[0 * step] = (t6 + t5 + t8) >> shift; \
149  blk[1 * step] = (t7 + t4 + tA) >> shift; \
150  blk[2 * step] = (t7 - t4 + tB) >> shift; \
151  blk[3 * step] = (t6 - t5 + tC) >> shift; \
152  blk[4 * step] = (t6 - t5 - tC) >> shift; \
153  blk[5 * step] = (t7 - t4 - tB) >> shift; \
154  blk[6 * step] = (t7 + t4 - tA) >> shift; \
155  blk[7 * step] = (t6 + t5 - t8) >> shift; \
156 
157 #define ROP(x) x
158 #define COP(x) (((x) + 4) >> 3)
159 
160 static void clv_dct(int16_t *block)
161 {
162  int i;
163  int16_t *ptr;
164 
165  ptr = block;
166  for (i = 0; i < 8; i++) {
167  DCT_TEMPLATE(ptr, 1, 0x80, 8, 11, ROP);
168  ptr += 8;
169  }
170 
171  ptr = block;
172  for (i = 0; i < 8; i++) {
173  DCT_TEMPLATE(ptr, 8, 0x2000, 14, 8, COP);
174  ptr++;
175  }
176 }
177 
178 static int decode_mb(CLVContext *c, int x, int y)
179 {
180  int i, has_ac[6], off;
181 
182  for (i = 0; i < 6; i++)
183  has_ac[i] = get_bits1(&c->gb);
184 
185  off = x * 16 + y * 16 * c->pic->linesize[0];
186  for (i = 0; i < 4; i++) {
187  if (decode_block(c, c->block, has_ac[i], c->ac_quant) < 0)
188  return AVERROR_INVALIDDATA;
189  if (!x && !(i & 1)) {
190  c->block[0] += c->top_dc[0];
191  c->top_dc[0] = c->block[0];
192  } else {
193  c->block[0] += c->left_dc[(i & 2) >> 1];
194  }
195  c->left_dc[(i & 2) >> 1] = c->block[0];
196  c->block[0] *= c->luma_dc_quant;
197  clv_dct(c->block);
198  if (i == 2)
199  off += c->pic->linesize[0] * 8;
200  c->idsp.put_pixels_clamped(c->block,
201  c->pic->data[0] + off + (i & 1) * 8,
202  c->pic->linesize[0]);
203  }
204 
205  off = x * 8 + y * 8 * c->pic->linesize[1];
206  for (i = 1; i < 3; i++) {
207  if (decode_block(c, c->block, has_ac[i + 3], c->ac_quant) < 0)
208  return AVERROR_INVALIDDATA;
209  if (!x) {
210  c->block[0] += c->top_dc[i];
211  c->top_dc[i] = c->block[0];
212  } else {
213  c->block[0] += c->left_dc[i + 1];
214  }
215  c->left_dc[i + 1] = c->block[0];
216  c->block[0] *= c->chroma_dc_quant;
217  clv_dct(c->block);
218  c->idsp.put_pixels_clamped(c->block, c->pic->data[i] + off,
219  c->pic->linesize[i]);
220  }
221 
222  return 0;
223 }
224 
225 static int copy_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
226  int plane, int x, int y, int dx, int dy, int size)
227 {
228  int shift = plane > 0;
229  int sx = x + dx;
230  int sy = y + dy;
231  int sstride, dstride, soff, doff;
232  uint8_t *sbuf, *dbuf;
233  int i;
234 
235  if (x < 0 || sx < 0 || y < 0 || sy < 0 ||
236  x + size > avctx->coded_width >> shift ||
237  y + size > avctx->coded_height >> shift ||
238  sx + size > avctx->coded_width >> shift ||
239  sy + size > avctx->coded_height >> shift)
240  return AVERROR_INVALIDDATA;
241 
242  sstride = src->linesize[plane];
243  dstride = dst->linesize[plane];
244  soff = sx + sy * sstride;
245  sbuf = src->data[plane];
246  doff = x + y * dstride;
247  dbuf = dst->data[plane];
248 
249  for (i = 0; i < size; i++) {
250  uint8_t *dptr = &dbuf[doff];
251  uint8_t *sptr = &sbuf[soff];
252 
253  memcpy(dptr, sptr, size);
254  doff += dstride;
255  soff += sstride;
256  }
257 
258  return 0;
259 }
260 
261 static int copyadd_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
262  int plane, int x, int y, int dx, int dy, int size, int bias)
263 {
264  int shift = plane > 0;
265  int sx = x + dx;
266  int sy = y + dy;
267  int sstride = src->linesize[plane];
268  int dstride = dst->linesize[plane];
269  int soff = sx + sy * sstride;
270  uint8_t *sbuf = src->data[plane];
271  int doff = x + y * dstride;
272  uint8_t *dbuf = dst->data[plane];
273  int i, j;
274 
275  if (x < 0 || sx < 0 || y < 0 || sy < 0 ||
276  x + size > avctx->coded_width >> shift ||
277  y + size > avctx->coded_height >> shift ||
278  sx + size > avctx->coded_width >> shift ||
279  sy + size > avctx->coded_height >> shift)
280  return AVERROR_INVALIDDATA;
281 
282  for (j = 0; j < size; j++) {
283  uint8_t *dptr = &dbuf[doff];
284  uint8_t *sptr = &sbuf[soff];
285 
286  for (i = 0; i < size; i++) {
287  int val = sptr[i] + bias;
288 
289  dptr[i] = av_clip_uint8(val);
290  }
291 
292  doff += dstride;
293  soff += sstride;
294  }
295 
296  return 0;
297 }
298 
299 static MV mvi_predict(MVInfo *mvi, int mb_x, int mb_y, MV diff)
300 {
301  MV res, pred_mv;
302  int left_mv, right_mv, top_mv, bot_mv;
303 
304  if (mvi->top) {
305  if (mb_x > 0) {
306  pred_mv = mvi->mv[mvi->mb_stride + mb_x - 1];
307  } else {
308  pred_mv = zero_mv;
309  }
310  } else if ((mb_x == 0) || (mb_x == mvi->mb_w - 1)) {
311  pred_mv = mvi->mv[mb_x];
312  } else {
313  MV A = mvi->mv[mvi->mb_stride + mb_x - 1];
314  MV B = mvi->mv[ mb_x ];
315  MV C = mvi->mv[ mb_x + 1];
316  pred_mv.x = mid_pred(A.x, B.x, C.x);
317  pred_mv.y = mid_pred(A.y, B.y, C.y);
318  }
319 
320  res = pred_mv;
321 
322  left_mv = -((mb_x * mvi->mb_size));
323  right_mv = ((mvi->mb_w - mb_x - 1) * mvi->mb_size);
324  if (res.x < left_mv) {
325  res.x = left_mv;
326  }
327  if (res.x > right_mv) {
328  res.x = right_mv;
329  }
330  top_mv = -((mb_y * mvi->mb_size));
331  bot_mv = ((mvi->mb_h - mb_y - 1) * mvi->mb_size);
332  if (res.y < top_mv) {
333  res.y = top_mv;
334  }
335  if (res.y > bot_mv) {
336  res.y = bot_mv;
337  }
338 
339  mvi->mv[mvi->mb_stride + mb_x].x = res.x + diff.x;
340  mvi->mv[mvi->mb_stride + mb_x].y = res.y + diff.y;
341 
342  return res;
343 }
344 
345 static void mvi_reset(MVInfo *mvi, int mb_w, int mb_h, int mb_size)
346 {
347  mvi->top = 1;
348  mvi->mb_w = mb_w;
349  mvi->mb_h = mb_h;
350  mvi->mb_size = mb_size;
351  mvi->mb_stride = mb_w;
352  memset(mvi->mv, 0, sizeof(MV) * mvi->mb_stride * 2);
353 }
354 
355 static void mvi_update_row(MVInfo *mvi)
356 {
357  int i;
358 
359  mvi->top = 0;
360  for (i = 0 ; i < mvi->mb_stride; i++) {
361  mvi->mv[i] = mvi->mv[mvi->mb_stride + i];
362  }
363 }
364 
366 {
367  TileInfo *ti;
368  int i, flags = 0;
369  int16_t bias = 0;
370  MV mv = { 0 };
371 
372  if (lc[level].flags_cb.table) {
373  flags = get_vlc2(gb, lc[level].flags_cb.table, CLV_VLC_BITS, 2);
374  }
375 
376  if (lc[level].mv_cb.table) {
377  uint16_t mv_code = get_vlc2(gb, lc[level].mv_cb.table, CLV_VLC_BITS, 2);
378 
379  if (mv_code != MV_ESC) {
380  mv.x = (int8_t)(mv_code & 0xff);
381  mv.y = (int8_t)(mv_code >> 8);
382  } else {
383  mv.x = get_sbits(gb, 8);
384  mv.y = get_sbits(gb, 8);
385  }
386  }
387 
388  if (lc[level].bias_cb.table) {
389  uint16_t bias_val = get_vlc2(gb, lc[level].bias_cb.table, CLV_VLC_BITS, 2);
390 
391  if (bias_val != BIAS_ESC) {
392  bias = (int16_t)(bias_val);
393  } else {
394  bias = get_sbits(gb, 16);
395  }
396  }
397 
398  ti = av_calloc(1, sizeof(*ti));
399  if (!ti)
400  return NULL;
401 
402  ti->flags = flags;
403  ti->mv = mv;
404  ti->bias = bias;
405 
406  if (ti->flags) {
407  for (i = 0; i < 4; i++) {
408  if (ti->flags & (1 << i)) {
409  TileInfo *subti = decode_tile_info(gb, lc, level + 1);
410  ti->child[i] = subti;
411  }
412  }
413  }
414 
415  return ti;
416 }
417 
418 static int tile_do_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
419  int plane, int x, int y, int dx, int dy, int size, int bias)
420 {
421  int ret;
422 
423  if (!bias) {
424  ret = copy_block(avctx, dst, src, plane, x, y, dx, dy, size);
425  } else {
426  ret = copyadd_block(avctx, dst, src, plane, x, y, dx, dy, size, bias);
427  }
428 
429  return ret;
430 }
431 
432 static int restore_tree(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
433  int plane, int x, int y, int size,
434  TileInfo *tile, MV root_mv)
435 {
436  int ret;
437  MV mv;
438 
439  mv.x = root_mv.x + tile->mv.x;
440  mv.y = root_mv.y + tile->mv.y;
441 
442  if (!tile->flags) {
443  ret = tile_do_block(avctx, dst, src, plane, x, y, mv.x, mv.y, size, tile->bias);
444  } else {
445  int i, hsize = size >> 1;
446 
447  for (i = 0; i < 4; i++) {
448  int xoff = (i & 2) == 0 ? 0 : hsize;
449  int yoff = (i & 1) == 0 ? 0 : hsize;
450 
451  if (tile->child[i]) {
452  ret = restore_tree(avctx, dst, src, plane, x + xoff, y + yoff, hsize, tile->child[i], root_mv);
453  av_freep(&tile->child[i]);
454  } else {
455  ret = tile_do_block(avctx, dst, src, plane, x + xoff, y + yoff, mv.x, mv.y, hsize, tile->bias);
456  }
457  }
458  }
459 
460  return ret;
461 }
462 
463 static void extend_edges(AVFrame *buf, int tile_size)
464 {
465  int comp, i, j;
466 
467  for (comp = 0; comp < 3; comp++) {
468  int shift = comp > 0;
469  int w = buf->width >> shift;
470  int h = buf->height >> shift;
471  int size = comp == 0 ? tile_size : tile_size >> 1;
472  int stride = buf->linesize[comp];
473  uint8_t *framebuf = buf->data[comp];
474 
475  int right = size - (w & (size - 1));
476  int bottom = size - (h & (size - 1));
477 
478  if ((right == size) && (bottom == size)) {
479  return;
480  }
481  if (right != size) {
482  int off = w;
483  for (j = 0; j < h; j++) {
484  for (i = 0; i < right; i++) {
485  framebuf[off + i] = 0x80;
486  }
487  off += stride;
488  }
489  }
490  if (bottom != size) {
491  int off = h * stride;
492  for (j = 0; j < bottom; j++) {
493  for (i = 0; i < stride; i++) {
494  framebuf[off + i] = 0x80;
495  }
496  off += stride;
497  }
498  }
499  }
500 }
501 
502 static int clv_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
503  int *got_frame, AVPacket *avpkt)
504 {
505  const uint8_t *buf = avpkt->data;
506  int buf_size = avpkt->size;
507  CLVContext *c = avctx->priv_data;
508  GetByteContext gb;
509  uint32_t frame_type;
510  int i, j, ret;
511  int mb_ret = 0;
512 
513  bytestream2_init(&gb, buf, buf_size);
514  if (avctx->codec_tag == MKTAG('C', 'L', 'V', '1')) {
515  int skip = bytestream2_get_byte(&gb);
516  bytestream2_skip(&gb, (skip + 1) * 8);
517  }
518 
519  frame_type = bytestream2_get_byte(&gb);
520 
521  if ((frame_type & 0x7f) == 0x30) {
522  *got_frame = 0;
523  return buf_size;
524  } else if (frame_type & 0x2) {
525  if (buf_size < c->mb_width * c->mb_height) {
526  av_log(avctx, AV_LOG_ERROR, "Packet too small\n");
527  return AVERROR_INVALIDDATA;
528  }
529 
530  if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0)
531  return ret;
532 
533  c->pic->key_frame = 1;
534  c->pic->pict_type = AV_PICTURE_TYPE_I;
535 
536  bytestream2_get_be32(&gb); // frame size;
537  c->ac_quant = bytestream2_get_byte(&gb);
538  c->luma_dc_quant = 32;
539  c->chroma_dc_quant = 32;
540 
541  if ((ret = init_get_bits8(&c->gb, buf + bytestream2_tell(&gb),
542  buf_size - bytestream2_tell(&gb))) < 0)
543  return ret;
544 
545  for (i = 0; i < 3; i++)
546  c->top_dc[i] = 32;
547  for (i = 0; i < 4; i++)
548  c->left_dc[i] = 32;
549 
550  for (j = 0; j < c->mb_height; j++) {
551  for (i = 0; i < c->mb_width; i++) {
552  ret = decode_mb(c, i, j);
553  if (ret < 0)
554  mb_ret = ret;
555  }
556  }
557  extend_edges(c->pic, c->tile_size);
558  } else {
559  int plane;
560 
561  if (c->pmb_width * c->pmb_height > 8LL*(buf_size - bytestream2_tell(&gb)))
562  return AVERROR_INVALIDDATA;
563 
564  if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0)
565  return ret;
566 
567  ret = av_frame_copy(c->pic, c->prev);
568  if (ret < 0)
569  return ret;
570 
571  if ((ret = init_get_bits8(&c->gb, buf + bytestream2_tell(&gb),
572  buf_size - bytestream2_tell(&gb))) < 0)
573  return ret;
574 
575  mvi_reset(&c->mvi, c->pmb_width, c->pmb_height, 1 << c->tile_shift);
576 
577  for (j = 0; j < c->pmb_height; j++) {
578  for (i = 0; i < c->pmb_width; i++) {
579  if (get_bits_left(&c->gb) <= 0)
580  return AVERROR_INVALIDDATA;
581  if (get_bits1(&c->gb)) {
582  MV mv = mvi_predict(&c->mvi, i, j, zero_mv);
583 
584  for (plane = 0; plane < 3; plane++) {
585  int16_t x = plane == 0 ? i << c->tile_shift : i << (c->tile_shift - 1);
586  int16_t y = plane == 0 ? j << c->tile_shift : j << (c->tile_shift - 1);
587  int16_t size = plane == 0 ? 1 << c->tile_shift : 1 << (c->tile_shift - 1);
588  int16_t mx = plane == 0 ? mv.x : mv.x / 2;
589  int16_t my = plane == 0 ? mv.y : mv.y / 2;
590 
591  ret = copy_block(avctx, c->pic, c->prev, plane, x, y, mx, my, size);
592  if (ret < 0)
593  mb_ret = ret;
594  }
595  } else {
596  int x = i << c->tile_shift;
597  int y = j << c->tile_shift;
598  int size = 1 << c->tile_shift;
599  TileInfo *tile;
600  MV mv, cmv;
601 
602  tile = decode_tile_info(&c->gb, &lev[0], 0); // Y
603  if (!tile)
604  return AVERROR(ENOMEM);
605  mv = mvi_predict(&c->mvi, i, j, tile->mv);
606  ret = restore_tree(avctx, c->pic, c->prev, 0, x, y, size, tile, mv);
607  if (ret < 0)
608  mb_ret = ret;
609  x = i << (c->tile_shift - 1);
610  y = j << (c->tile_shift - 1);
611  size = 1 << (c->tile_shift - 1);
612  cmv.x = mv.x + tile->mv.x;
613  cmv.y = mv.y + tile->mv.y;
614  cmv.x /= 2;
615  cmv.y /= 2;
616  av_freep(&tile);
617  tile = decode_tile_info(&c->gb, &lev[4], 0); // U
618  if (!tile)
619  return AVERROR(ENOMEM);
620  ret = restore_tree(avctx, c->pic, c->prev, 1, x, y, size, tile, cmv);
621  if (ret < 0)
622  mb_ret = ret;
623  av_freep(&tile);
624  tile = decode_tile_info(&c->gb, &lev[7], 0); // V
625  if (!tile)
626  return AVERROR(ENOMEM);
627  ret = restore_tree(avctx, c->pic, c->prev, 2, x, y, size, tile, cmv);
628  if (ret < 0)
629  mb_ret = ret;
630  av_freep(&tile);
631  }
632  }
633  mvi_update_row(&c->mvi);
634  }
635  extend_edges(c->pic, c->tile_size);
636 
637  c->pic->key_frame = 0;
638  c->pic->pict_type = AV_PICTURE_TYPE_P;
639  }
640 
641  if ((ret = av_frame_ref(rframe, c->pic)) < 0)
642  return ret;
643 
644  FFSWAP(AVFrame *, c->pic, c->prev);
645 
646  *got_frame = 1;
647 
648  if (get_bits_left(&c->gb) < 0)
649  av_log(c->avctx, AV_LOG_WARNING, "overread %d\n", -get_bits_left(&c->gb));
650 
651  return mb_ret < 0 ? mb_ret : buf_size;
652 }
653 
654 static av_cold void build_vlc(VLC *vlc, const uint8_t counts[16],
655  const uint16_t **syms, unsigned *offset)
656 {
657  uint8_t lens[MAX_VLC_ENTRIES];
658  unsigned num = 0;
659 
660  for (int i = 0; i < 16; i++) {
661  unsigned count = counts[i];
662  if (count == 255) /* Special case for Y_3 table */
663  count = 303;
664  for (count += num; num < count; num++)
665  lens[num] = i + 1;
666  }
667  vlc->table = &vlc_buf[*offset];
669  ff_init_vlc_from_lengths(vlc, CLV_VLC_BITS, num, lens, 1,
670  *syms, 2, 2, 0, INIT_VLC_STATIC_OVERLONG, NULL);
671  *syms += num;
672  *offset += vlc->table_size;
673 }
674 
675 static av_cold void clv_init_static(void)
676 {
677  const uint16_t *mv_syms = clv_mv_syms, *bias_syms = clv_bias_syms;
678 
680  clv_dc_lens, 1,
681  clv_dc_syms, 1, 1, -63, 0, 1104);
683  clv_ac_bits, 1,
684  clv_ac_syms, 2, 2, 0, 0, 554);
685  for (unsigned i = 0, j = 0, k = 0, offset = 0;; i++) {
686  if (0x36F & (1 << i)) {
687  build_vlc(&lev[i].mv_cb, clv_mv_len_counts[k], &mv_syms, &offset);
688  k++;
689  }
690  if (i == FF_ARRAY_ELEMS(lev) - 1)
691  break;
692  if (0x1B7 & (1 << i)) {
695  ff_init_vlc_from_lengths(&lev[i].flags_cb, CLV_VLC_BITS, 16,
696  clv_flags_bits[j], 1,
697  clv_flags_syms[j], 1, 1,
700 
701  build_vlc(&lev[i + 1].bias_cb, clv_bias_len_counts[j],
702  &bias_syms, &offset);
703  j++;
704  }
705  }
706 }
707 
709 {
710  static AVOnce init_static_once = AV_ONCE_INIT;
711  CLVContext *const c = avctx->priv_data;
712  int ret, w, h;
713 
714  if (avctx->extradata_size == 110) {
715  c->tile_size = AV_RL32(&avctx->extradata[94]);
716  } else if (avctx->extradata_size == 150) {
717  c->tile_size = AV_RB32(&avctx->extradata[134]);
718  } else if (!avctx->extradata_size) {
719  c->tile_size = 16;
720  } else {
721  av_log(avctx, AV_LOG_ERROR, "Unsupported extradata size: %d\n", avctx->extradata_size);
722  return AVERROR_INVALIDDATA;
723  }
724 
725  c->tile_shift = av_log2(c->tile_size);
726  if (1U << c->tile_shift != c->tile_size || c->tile_shift < 1 || c->tile_shift > 30) {
727  av_log(avctx, AV_LOG_ERROR, "Tile size: %d, is not power of 2 > 1 and < 2^31\n", c->tile_size);
728  return AVERROR_INVALIDDATA;
729  }
730 
731  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
732  w = avctx->width;
733  h = avctx->height;
734  ret = ff_set_dimensions(avctx, FFALIGN(w, 1 << c->tile_shift), FFALIGN(h, 1 << c->tile_shift));
735  if (ret < 0)
736  return ret;
737  avctx->width = w;
738  avctx->height = h;
739 
740  c->avctx = avctx;
741  c->mb_width = FFALIGN(avctx->width, 16) >> 4;
742  c->mb_height = FFALIGN(avctx->height, 16) >> 4;
743  c->pmb_width = (w + c->tile_size - 1) >> c->tile_shift;
744  c->pmb_height = (h + c->tile_size - 1) >> c->tile_shift;
745  c->pic = av_frame_alloc();
746  c->prev = av_frame_alloc();
747  c->mvi.mv = av_calloc(c->pmb_width * 2, sizeof(*c->mvi.mv));
748  if (!c->pic || !c->prev || !c->mvi.mv)
749  return AVERROR(ENOMEM);
750 
751  ff_idctdsp_init(&c->idsp, avctx);
752 
753  ff_thread_once(&init_static_once, clv_init_static);
754 
755  return 0;
756 }
757 
759 {
760  CLVContext *const c = avctx->priv_data;
761 
762  av_frame_free(&c->prev);
763  av_frame_free(&c->pic);
764 
765  av_freep(&c->mvi.mv);
766 
767  return 0;
768 }
769 
771  .p.name = "clearvideo",
772  .p.long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"),
773  .p.type = AVMEDIA_TYPE_VIDEO,
774  .p.id = AV_CODEC_ID_CLEARVIDEO,
775  .priv_data_size = sizeof(CLVContext),
777  .close = clv_decode_end,
779  .p.capabilities = AV_CODEC_CAP_DR1,
780  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
781 };
A
#define A(x)
Definition: vpx_arith.h:28
MAX_VLC_ENTRIES
#define MAX_VLC_ENTRIES
Definition: clearvideodata.h:27
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
level
uint8_t level
Definition: svq3.c:206
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:41
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:839
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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. Frame references ownership and permissions
mem_internal.h
comp
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:86
GetByteContext
Definition: bytestream.h:33
clv_dc_syms
static const uint8_t clv_dc_syms[NUM_DC_CODES]
Definition: clearvideodata.h:41
thread.h
CLVContext::pmb_width
int pmb_width
Definition: clearvideo.c:76
LevelCodes::mv_cb
VLC mv_cb
Definition: clearvideo.c:43
mv
static const int8_t mv[256][2]
Definition: 4xm.c:80
TileInfo
Definition: clearvideo.c:62
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:116
MVInfo::mv
MV * mv
Definition: clearvideo.c:59
copyadd_block
static int copyadd_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src, int plane, int x, int y, int dx, int dy, int size, int bias)
Definition: clearvideo.c:261
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
clv_mv_syms
static const uint16_t clv_mv_syms[]
Definition: clearvideodata.h:112
MV::y
int16_t y
Definition: clearvideo.c:48
AVFrame::width
int width
Definition: frame.h:397
w
uint8_t w
Definition: llviddspenc.c:38
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:374
MVInfo::mb_w
int mb_w
Definition: clearvideo.c:54
TileInfo::bias
int16_t bias
Definition: clearvideo.c:64
clv_decode_frame
static int clv_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt)
Definition: clearvideo.c:502
FFCodec
Definition: codec_internal.h:118
clearvideodata.h
CLVContext::top_dc
int top_dc[3]
Definition: clearvideo.c:82
CLVContext::mvi
MVInfo mvi
Definition: clearvideo.c:77
clv_flags_syms
static const uint8_t clv_flags_syms[][16]
Definition: clearvideodata.h:90
CLVContext::pic
AVFrame * pic
Definition: clearvideo.c:72
ff_idctdsp_init
av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
Definition: idctdsp.c:240
clv_decode_init
static av_cold int clv_decode_init(AVCodecContext *avctx)
Definition: clearvideo.c:708
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:346
MVInfo::top
int top
Definition: clearvideo.c:58
LevelCodes::flags_cb
VLC flags_cb
Definition: clearvideo.c:42
init
static int init
Definition: av_tx.c:47
ROP
#define ROP(x)
Definition: clearvideo.c:157
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
extend_edges
static void extend_edges(AVFrame *buf, int tile_size)
Definition: clearvideo.c:463
BIAS_ESC
#define BIAS_ESC
Definition: clearvideodata.h:619
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:122
decode_mb
static int decode_mb(CLVContext *c, int x, int y)
Definition: clearvideo.c:178
GetBitContext
Definition: get_bits.h:61
clv_dc_lens
static const uint8_t clv_dc_lens[NUM_DC_CODES]
Definition: clearvideodata.h:31
mvi_predict
static MV mvi_predict(MVInfo *mvi, int mb_x, int mb_y, MV diff)
Definition: clearvideo.c:299
CLVContext::mb_width
int mb_width
Definition: clearvideo.c:75
val
static double val(void *priv, double ch)
Definition: aeval.c:77
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:586
dc_vlc
static VLC dc_vlc
Definition: clearvideo.c:85
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:104
clv_init_static
static av_cold void clv_init_static(void)
Definition: clearvideo.c:675
C
s EdgeDetect Foobar g libavfilter vf_edgedetect c libavfilter vf_foobar c edit libavfilter and add an entry for foobar following the pattern of the other filters edit libavfilter allfilters and add an entry for foobar following the pattern of the other filters configure make j< whatever > ffmpeg ffmpeg i you should get a foobar png with Lena edge detected That s your new playground is ready Some little details about what s going which in turn will define variables for the build system and the C
Definition: writing_filters.txt:58
ff_thread_once
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:179
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
clv_bias_syms
static const uint16_t clv_bias_syms[]
Definition: clearvideodata.h:620
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:667
TileInfo::child
struct TileInfo * child[4]
Definition: clearvideo.c:66
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:500
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:260
CLVContext::avctx
AVCodecContext * avctx
Definition: clearvideo.c:70
clv_dct
static void clv_dct(int16_t *block)
Definition: clearvideo.c:160
CLVContext::gb
GetBitContext gb
Definition: clearvideo.c:74
vlc_buf
static VLCElem vlc_buf[16716]
Definition: clearvideo.c:87
get_sbits
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:359
ctx
AVFormatContext * ctx
Definition: movenc.c:48
get_bits.h
MV::x
int16_t x
Definition: clearvideo.c:48
CLVContext::left_dc
int left_dc[4]
Definition: clearvideo.c:82
LevelCodes
Definition: clearvideo.c:41
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
blk
#define blk(i)
Definition: sha.c:186
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:64
CLVContext::tile_shift
int tile_shift
Definition: clearvideo.c:79
AV_ONCE_INIT
#define AV_ONCE_INIT
Definition: thread.h:177
NULL
#define NULL
Definition: coverity.c:32
INIT_VLC_STATIC_FROM_LENGTHS
#define INIT_VLC_STATIC_FROM_LENGTHS(vlc, bits, nb_codes, lens, len_wrap, symbols, symbols_wrap, symbols_size, offset, flags, static_size)
Definition: vlc.h:131
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
ff_init_vlc_from_lengths
int ff_init_vlc_from_lengths(VLC *vlc, int nb_bits, int nb_codes, const int8_t *lens, int lens_wrap, const void *symbols, int symbols_wrap, int symbols_size, int offset, int flags, void *logctx)
Build VLC decoding tables suitable for use with get_vlc2()
Definition: vlc.c:328
mathops.h
clv_decode_end
static av_cold int clv_decode_end(AVCodecContext *avctx)
Definition: clearvideo.c:758
MVInfo
Definition: clearvideo.c:53
MVInfo::mb_stride
int mb_stride
Definition: clearvideo.c:57
get_vlc2
static av_always_inline int get_vlc2(GetBitContext *s, const VLCElem *table, int bits, int max_depth)
Parse a vlc code.
Definition: get_bits.h:787
mvi_update_row
static void mvi_update_row(MVInfo *mvi)
Definition: clearvideo.c:355
AVOnce
#define AVOnce
Definition: thread.h:176
TileInfo::mv
MV mv
Definition: clearvideo.c:65
ac_vlc
static VLC ac_vlc
Definition: clearvideo.c:85
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
bytestream2_tell
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:192
VLC::table_allocated
int table_allocated
Definition: vlc.h:34
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:375
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
av_frame_ref
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:353
MVInfo::mb_h
int mb_h
Definition: clearvideo.c:55
codec_internal.h
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:771
MV
Definition: clearvideo.c:47
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
restore_tree
static int restore_tree(AVCodecContext *avctx, AVFrame *dst, AVFrame *src, int plane, int x, int y, int size, TileInfo *tile, MV root_mv)
Definition: clearvideo.c:432
size
int size
Definition: twinvq_data.h:10344
VLCElem
Definition: vlc.h:27
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
ff_clearvideo_decoder
const FFCodec ff_clearvideo_decoder
Definition: clearvideo.c:770
CLVContext::pmb_height
int pmb_height
Definition: clearvideo.c:76
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
copy_block
static int copy_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src, int plane, int x, int y, int dx, int dy, int size)
Definition: clearvideo.c:225
DECLARE_ALIGNED
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:116
NUM_AC_CODES
#define NUM_AC_CODES
Definition: clearvideodata.h:29
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
frame_type
frame_type
Definition: jpeg2000_parser.c:31
pred_mv
static void pred_mv(DiracBlock *block, int stride, int x, int y, int ref)
Definition: diracdec.c:1392
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:499
clv_ac_bits
static const uint8_t clv_ac_bits[NUM_AC_CODES]
Definition: clearvideodata.h:71
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:211
TileInfo::flags
uint16_t flags
Definition: clearvideo.c:63
lev
static LevelCodes lev[4+3+3]
Definition: clearvideo.c:86
AVCodecContext::height
int height
Definition: avcodec.h:571
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:608
CLVContext::tile_size
int tile_size
Definition: clearvideo.c:78
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
clv_flags_bits
static const uint8_t clv_flags_bits[][16]
Definition: clearvideodata.h:80
idctdsp.h
avcodec.h
CLV_VLC_BITS
#define CLV_VLC_BITS
Definition: clearvideo.c:39
stride
#define stride
Definition: h264pred_template.c:537
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
mid_pred
#define mid_pred
Definition: mathops.h:97
ff_reget_buffer
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
Definition: decode.c:1580
ret
ret
Definition: filter_design.txt:187
INIT_VLC_STATIC_OVERLONG
#define INIT_VLC_STATIC_OVERLONG
Definition: vlc.h:101
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
decode_tile_info
static TileInfo * decode_tile_info(GetBitContext *gb, const LevelCodes *lc, int level)
Definition: clearvideo.c:365
IDCTDSPContext
Definition: idctdsp.h:53
COP
#define COP(x)
Definition: clearvideo.c:158
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
U
#define U(x)
Definition: vpx_arith.h:37
CLVContext::luma_dc_quant
int luma_dc_quant
Definition: clearvideo.c:80
LevelCodes::bias_cb
VLC bias_cb
Definition: clearvideo.c:44
B
#define B
Definition: huffyuvdsp.h:32
AVCodecContext
main external API structure.
Definition: avcodec.h:398
AVFrame::height
int height
Definition: frame.h:397
decode_block
static int decode_block(CLVContext *ctx, int16_t *blk, int has_ac, int ac_quant)
Definition: clearvideo.c:89
CLVContext::mb_height
int mb_height
Definition: clearvideo.c:75
VLC
Definition: vlc.h:31
MV_ESC
#define MV_ESC
Definition: clearvideodata.h:111
DCT_TEMPLATE
#define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP)
Definition: clearvideo.c:133
VLC::table
VLCElem * table
Definition: vlc.h:33
av_clip_uint8
#define av_clip_uint8
Definition: common.h:101
VLC::table_size
int table_size
Definition: vlc.h:34
shift
static int shift(int a, int b)
Definition: sonic.c:88
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:586
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
CLVContext::prev
AVFrame * prev
Definition: clearvideo.c:73
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:90
mvi_reset
static void mvi_reset(MVInfo *mvi, int mb_w, int mb_h, int mb_size)
Definition: clearvideo.c:345
diff
static av_always_inline int diff(const uint32_t a, const uint32_t b)
Definition: vf_palettegen.c:139
AVCodecContext::codec_tag
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:423
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
CLVContext::idsp
IDCTDSPContext idsp
Definition: clearvideo.c:71
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:425
AVPacket
This structure stores compressed data.
Definition: packet.h:351
clv_mv_len_counts
static const uint8_t clv_mv_len_counts[][16]
Definition: clearvideodata.h:100
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
CLVContext::chroma_dc_quant
int chroma_dc_quant
Definition: clearvideo.c:80
NUM_DC_CODES
#define NUM_DC_CODES
Definition: clearvideodata.h:28
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:571
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:370
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
CLVContext
Definition: clearvideo.c:69
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
CLVContext::block
int16_t block[64]
Definition: clearvideo.c:81
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
h
h
Definition: vp9dsp_template.c:2038
AV_CODEC_ID_CLEARVIDEO
@ AV_CODEC_ID_CLEARVIDEO
Definition: codec_id.h:277
zero_mv
static const MV zero_mv
Definition: clearvideo.c:51
tile_do_block
static int tile_do_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src, int plane, int x, int y, int dx, int dy, int size, int bias)
Definition: clearvideo.c:418
CLVContext::ac_quant
int ac_quant
Definition: clearvideo.c:80
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
MVInfo::mb_size
int mb_size
Definition: clearvideo.c:56
clv_ac_syms
static const uint16_t clv_ac_syms[NUM_AC_CODES]
Definition: clearvideodata.h:55
build_vlc
static av_cold void build_vlc(VLC *vlc, const uint8_t counts[16], const uint16_t **syms, unsigned *offset)
Definition: clearvideo.c:654
clv_bias_len_counts
static const uint8_t clv_bias_len_counts[][16]
Definition: clearvideodata.h:609
mv_syms
static const uint8_t mv_syms[2][16][10]
Definition: mobiclip.c:203