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 "get_bits.h"
33 #include "idctdsp.h"
34 #include "internal.h"
35 #include "mathops.h"
36 #include "clearvideodata.h"
37 
38 #define CLV_VLC_BITS 9
39 
40 typedef struct LevelCodes {
44 } LevelCodes;
45 
46 typedef struct MV {
47  int16_t x, y;
48 } MV;
49 
50 static const MV zero_mv = { 0 };
51 
52 typedef struct MVInfo {
53  int mb_w;
54  int mb_h;
55  int mb_size;
56  int mb_stride;
57  int top;
58  MV *mv;
59 } MVInfo;
60 
61 typedef struct TileInfo {
62  uint16_t flags;
63  int16_t bias;
64  MV mv;
65  struct TileInfo *child[4];
66 } TileInfo;
67 
68 typedef struct CLVContext {
77  int tile_size;
80  DECLARE_ALIGNED(16, int16_t, block)[64];
81  int top_dc[3], left_dc[4];
82 } CLVContext;
83 
84 static VLC dc_vlc, ac_vlc;
85 static LevelCodes lev[4 + 3 + 3]; // 0..3: Y, 4..6: U, 7..9: V
86 static VLC_TYPE vlc_buf[16716][2];
87 
88 static inline int decode_block(CLVContext *ctx, int16_t *blk, int has_ac,
89  int ac_quant)
90 {
91  GetBitContext *gb = &ctx->gb;
92  int idx = 1, last = 0, val, skip;
93 
94  memset(blk, 0, sizeof(*blk) * 64);
95  blk[0] = get_vlc2(gb, dc_vlc.table, CLV_VLC_BITS, 3);
96 
97  if (!has_ac)
98  return 0;
99 
100  while (idx < 64 && !last) {
101  val = get_vlc2(gb, ac_vlc.table, CLV_VLC_BITS, 2);
102  if (val < 0)
103  return AVERROR_INVALIDDATA;
104  if (val != 0x1BFF) {
105  last = val >> 12;
106  skip = (val >> 4) & 0xFF;
107  val &= 0xF;
108  if (get_bits1(gb))
109  val = -val;
110  } else {
111  last = get_bits1(gb);
112  skip = get_bits(gb, 6);
113  val = get_sbits(gb, 8);
114  }
115  if (val) {
116  int aval = FFABS(val), sign = val < 0;
117  val = ac_quant * (2 * aval + 1);
118  if (!(ac_quant & 1))
119  val--;
120  if (sign)
121  val = -val;
122  }
123  idx += skip;
124  if (idx >= 64)
125  return AVERROR_INVALIDDATA;
126  blk[ff_zigzag_direct[idx++]] = val;
127  }
128 
129  return (idx <= 64 && last) ? 0 : -1;
130 }
131 
132 #define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP) \
133  const int t0 = OP(2841 * blk[1 * step] + 565 * blk[7 * step]); \
134  const int t1 = OP( 565 * blk[1 * step] - 2841 * blk[7 * step]); \
135  const int t2 = OP(1609 * blk[5 * step] + 2408 * blk[3 * step]); \
136  const int t3 = OP(2408 * blk[5 * step] - 1609 * blk[3 * step]); \
137  const int t4 = OP(1108 * blk[2 * step] - 2676 * blk[6 * step]); \
138  const int t5 = OP(2676 * blk[2 * step] + 1108 * blk[6 * step]); \
139  const int t6 = ((blk[0 * step] + blk[4 * step]) * (1 << dshift)) + bias; \
140  const int t7 = ((blk[0 * step] - blk[4 * step]) * (1 << dshift)) + bias; \
141  const int t8 = t0 + t2; \
142  const int t9 = t0 - t2; \
143  const int tA = (int)(181U * (t9 + (t1 - t3)) + 0x80) >> 8; \
144  const int tB = (int)(181U * (t9 - (t1 - t3)) + 0x80) >> 8; \
145  const int tC = t1 + t3; \
146  \
147  blk[0 * step] = (t6 + t5 + t8) >> shift; \
148  blk[1 * step] = (t7 + t4 + tA) >> shift; \
149  blk[2 * step] = (t7 - t4 + tB) >> shift; \
150  blk[3 * step] = (t6 - t5 + tC) >> shift; \
151  blk[4 * step] = (t6 - t5 - tC) >> shift; \
152  blk[5 * step] = (t7 - t4 - tB) >> shift; \
153  blk[6 * step] = (t7 + t4 - tA) >> shift; \
154  blk[7 * step] = (t6 + t5 - t8) >> shift; \
155 
156 #define ROP(x) x
157 #define COP(x) (((x) + 4) >> 3)
158 
159 static void clv_dct(int16_t *block)
160 {
161  int i;
162  int16_t *ptr;
163 
164  ptr = block;
165  for (i = 0; i < 8; i++) {
166  DCT_TEMPLATE(ptr, 1, 0x80, 8, 11, ROP);
167  ptr += 8;
168  }
169 
170  ptr = block;
171  for (i = 0; i < 8; i++) {
172  DCT_TEMPLATE(ptr, 8, 0x2000, 14, 8, COP);
173  ptr++;
174  }
175 }
176 
177 static int decode_mb(CLVContext *c, int x, int y)
178 {
179  int i, has_ac[6], off;
180 
181  for (i = 0; i < 6; i++)
182  has_ac[i] = get_bits1(&c->gb);
183 
184  off = x * 16 + y * 16 * c->pic->linesize[0];
185  for (i = 0; i < 4; i++) {
186  if (decode_block(c, c->block, has_ac[i], c->ac_quant) < 0)
187  return AVERROR_INVALIDDATA;
188  if (!x && !(i & 1)) {
189  c->block[0] += c->top_dc[0];
190  c->top_dc[0] = c->block[0];
191  } else {
192  c->block[0] += c->left_dc[(i & 2) >> 1];
193  }
194  c->left_dc[(i & 2) >> 1] = c->block[0];
195  c->block[0] *= c->luma_dc_quant;
196  clv_dct(c->block);
197  if (i == 2)
198  off += c->pic->linesize[0] * 8;
199  c->idsp.put_pixels_clamped(c->block,
200  c->pic->data[0] + off + (i & 1) * 8,
201  c->pic->linesize[0]);
202  }
203 
204  off = x * 8 + y * 8 * c->pic->linesize[1];
205  for (i = 1; i < 3; i++) {
206  if (decode_block(c, c->block, has_ac[i + 3], c->ac_quant) < 0)
207  return AVERROR_INVALIDDATA;
208  if (!x) {
209  c->block[0] += c->top_dc[i];
210  c->top_dc[i] = c->block[0];
211  } else {
212  c->block[0] += c->left_dc[i + 1];
213  }
214  c->left_dc[i + 1] = c->block[0];
215  c->block[0] *= c->chroma_dc_quant;
216  clv_dct(c->block);
217  c->idsp.put_pixels_clamped(c->block, c->pic->data[i] + off,
218  c->pic->linesize[i]);
219  }
220 
221  return 0;
222 }
223 
224 static int copy_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
225  int plane, int x, int y, int dx, int dy, int size)
226 {
227  int shift = plane > 0;
228  int sx = x + dx;
229  int sy = y + dy;
230  int sstride, dstride, soff, doff;
231  uint8_t *sbuf, *dbuf;
232  int i;
233 
234  if (x < 0 || sx < 0 || y < 0 || sy < 0 ||
235  x + size > avctx->coded_width >> shift ||
236  y + size > avctx->coded_height >> shift ||
237  sx + size > avctx->coded_width >> shift ||
238  sy + size > avctx->coded_height >> shift)
239  return AVERROR_INVALIDDATA;
240 
241  sstride = src->linesize[plane];
242  dstride = dst->linesize[plane];
243  soff = sx + sy * sstride;
244  sbuf = src->data[plane];
245  doff = x + y * dstride;
246  dbuf = dst->data[plane];
247 
248  for (i = 0; i < size; i++) {
249  uint8_t *dptr = &dbuf[doff];
250  uint8_t *sptr = &sbuf[soff];
251 
252  memcpy(dptr, sptr, size);
253  doff += dstride;
254  soff += sstride;
255  }
256 
257  return 0;
258 }
259 
260 static int copyadd_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
261  int plane, int x, int y, int dx, int dy, int size, int bias)
262 {
263  int shift = plane > 0;
264  int sx = x + dx;
265  int sy = y + dy;
266  int sstride = src->linesize[plane];
267  int dstride = dst->linesize[plane];
268  int soff = sx + sy * sstride;
269  uint8_t *sbuf = src->data[plane];
270  int doff = x + y * dstride;
271  uint8_t *dbuf = dst->data[plane];
272  int i, j;
273 
274  if (x < 0 || sx < 0 || y < 0 || sy < 0 ||
275  x + size > avctx->coded_width >> shift ||
276  y + size > avctx->coded_height >> shift ||
277  sx + size > avctx->coded_width >> shift ||
278  sy + size > avctx->coded_height >> shift)
279  return AVERROR_INVALIDDATA;
280 
281  for (j = 0; j < size; j++) {
282  uint8_t *dptr = &dbuf[doff];
283  uint8_t *sptr = &sbuf[soff];
284 
285  for (i = 0; i < size; i++) {
286  int val = sptr[i] + bias;
287 
288  dptr[i] = av_clip_uint8(val);
289  }
290 
291  doff += dstride;
292  soff += sstride;
293  }
294 
295  return 0;
296 }
297 
298 static MV mvi_predict(MVInfo *mvi, int mb_x, int mb_y, MV diff)
299 {
300  MV res, pred_mv;
301  int left_mv, right_mv, top_mv, bot_mv;
302 
303  if (mvi->top) {
304  if (mb_x > 0) {
305  pred_mv = mvi->mv[mvi->mb_stride + mb_x - 1];
306  } else {
307  pred_mv = zero_mv;
308  }
309  } else if ((mb_x == 0) || (mb_x == mvi->mb_w - 1)) {
310  pred_mv = mvi->mv[mb_x];
311  } else {
312  MV A = mvi->mv[mvi->mb_stride + mb_x - 1];
313  MV B = mvi->mv[ mb_x ];
314  MV C = mvi->mv[ mb_x + 1];
315  pred_mv.x = mid_pred(A.x, B.x, C.x);
316  pred_mv.y = mid_pred(A.y, B.y, C.y);
317  }
318 
319  res = pred_mv;
320 
321  left_mv = -((mb_x * mvi->mb_size));
322  right_mv = ((mvi->mb_w - mb_x - 1) * mvi->mb_size);
323  if (res.x < left_mv) {
324  res.x = left_mv;
325  }
326  if (res.x > right_mv) {
327  res.x = right_mv;
328  }
329  top_mv = -((mb_y * mvi->mb_size));
330  bot_mv = ((mvi->mb_h - mb_y - 1) * mvi->mb_size);
331  if (res.y < top_mv) {
332  res.y = top_mv;
333  }
334  if (res.y > bot_mv) {
335  res.y = bot_mv;
336  }
337 
338  mvi->mv[mvi->mb_stride + mb_x].x = res.x + diff.x;
339  mvi->mv[mvi->mb_stride + mb_x].y = res.y + diff.y;
340 
341  return res;
342 }
343 
344 static void mvi_reset(MVInfo *mvi, int mb_w, int mb_h, int mb_size)
345 {
346  mvi->top = 1;
347  mvi->mb_w = mb_w;
348  mvi->mb_h = mb_h;
349  mvi->mb_size = mb_size;
350  mvi->mb_stride = mb_w;
351  memset(mvi->mv, 0, sizeof(MV) * mvi->mb_stride * 2);
352 }
353 
354 static void mvi_update_row(MVInfo *mvi)
355 {
356  int i;
357 
358  mvi->top = 0;
359  for (i = 0 ; i < mvi->mb_stride; i++) {
360  mvi->mv[i] = mvi->mv[mvi->mb_stride + i];
361  }
362 }
363 
365 {
366  TileInfo *ti;
367  int i, flags = 0;
368  int16_t bias = 0;
369  MV mv = { 0 };
370 
371  if (lc[level].flags_cb.table) {
372  flags = get_vlc2(gb, lc[level].flags_cb.table, CLV_VLC_BITS, 2);
373  }
374 
375  if (lc[level].mv_cb.table) {
376  uint16_t mv_code = get_vlc2(gb, lc[level].mv_cb.table, CLV_VLC_BITS, 2);
377 
378  if (mv_code != MV_ESC) {
379  mv.x = (int8_t)(mv_code & 0xff);
380  mv.y = (int8_t)(mv_code >> 8);
381  } else {
382  mv.x = get_sbits(gb, 8);
383  mv.y = get_sbits(gb, 8);
384  }
385  }
386 
387  if (lc[level].bias_cb.table) {
388  uint16_t bias_val = get_vlc2(gb, lc[level].bias_cb.table, CLV_VLC_BITS, 2);
389 
390  if (bias_val != BIAS_ESC) {
391  bias = (int16_t)(bias_val);
392  } else {
393  bias = get_sbits(gb, 16);
394  }
395  }
396 
397  ti = av_calloc(1, sizeof(*ti));
398  if (!ti)
399  return NULL;
400 
401  ti->flags = flags;
402  ti->mv = mv;
403  ti->bias = bias;
404 
405  if (ti->flags) {
406  for (i = 0; i < 4; i++) {
407  if (ti->flags & (1 << i)) {
408  TileInfo *subti = decode_tile_info(gb, lc, level + 1);
409  ti->child[i] = subti;
410  }
411  }
412  }
413 
414  return ti;
415 }
416 
417 static int tile_do_block(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
418  int plane, int x, int y, int dx, int dy, int size, int bias)
419 {
420  int ret;
421 
422  if (!bias) {
423  ret = copy_block(avctx, dst, src, plane, x, y, dx, dy, size);
424  } else {
425  ret = copyadd_block(avctx, dst, src, plane, x, y, dx, dy, size, bias);
426  }
427 
428  return ret;
429 }
430 
431 static int restore_tree(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
432  int plane, int x, int y, int size,
433  TileInfo *tile, MV root_mv)
434 {
435  int ret;
436  MV mv;
437 
438  mv.x = root_mv.x + tile->mv.x;
439  mv.y = root_mv.y + tile->mv.y;
440 
441  if (!tile->flags) {
442  ret = tile_do_block(avctx, dst, src, plane, x, y, mv.x, mv.y, size, tile->bias);
443  } else {
444  int i, hsize = size >> 1;
445 
446  for (i = 0; i < 4; i++) {
447  int xoff = (i & 2) == 0 ? 0 : hsize;
448  int yoff = (i & 1) == 0 ? 0 : hsize;
449 
450  if (tile->child[i]) {
451  ret = restore_tree(avctx, dst, src, plane, x + xoff, y + yoff, hsize, tile->child[i], root_mv);
452  av_freep(&tile->child[i]);
453  } else {
454  ret = tile_do_block(avctx, dst, src, plane, x + xoff, y + yoff, mv.x, mv.y, hsize, tile->bias);
455  }
456  }
457  }
458 
459  return ret;
460 }
461 
462 static void extend_edges(AVFrame *buf, int tile_size)
463 {
464  int comp, i, j;
465 
466  for (comp = 0; comp < 3; comp++) {
467  int shift = comp > 0;
468  int w = buf->width >> shift;
469  int h = buf->height >> shift;
470  int size = comp == 0 ? tile_size : tile_size >> 1;
471  int stride = buf->linesize[comp];
472  uint8_t *framebuf = buf->data[comp];
473 
474  int right = size - (w & (size - 1));
475  int bottom = size - (h & (size - 1));
476 
477  if ((right == size) && (bottom == size)) {
478  return;
479  }
480  if (right != size) {
481  int off = w;
482  for (j = 0; j < h; j++) {
483  for (i = 0; i < right; i++) {
484  framebuf[off + i] = 0x80;
485  }
486  off += stride;
487  }
488  }
489  if (bottom != size) {
490  int off = h * stride;
491  for (j = 0; j < bottom; j++) {
492  for (i = 0; i < stride; i++) {
493  framebuf[off + i] = 0x80;
494  }
495  off += stride;
496  }
497  }
498  }
499 }
500 
501 static int clv_decode_frame(AVCodecContext *avctx, void *data,
502  int *got_frame, AVPacket *avpkt)
503 {
504  const uint8_t *buf = avpkt->data;
505  int buf_size = avpkt->size;
506  CLVContext *c = avctx->priv_data;
507  GetByteContext gb;
508  uint32_t frame_type;
509  int i, j, ret;
510  int mb_ret = 0;
511 
512  bytestream2_init(&gb, buf, buf_size);
513  if (avctx->codec_tag == MKTAG('C', 'L', 'V', '1')) {
514  int skip = bytestream2_get_byte(&gb);
515  bytestream2_skip(&gb, (skip + 1) * 8);
516  }
517 
518  frame_type = bytestream2_get_byte(&gb);
519 
520  if ((frame_type & 0x7f) == 0x30) {
521  *got_frame = 0;
522  return buf_size;
523  } else if (frame_type & 0x2) {
524  if (buf_size < c->mb_width * c->mb_height) {
525  av_log(avctx, AV_LOG_ERROR, "Packet too small\n");
526  return AVERROR_INVALIDDATA;
527  }
528 
529  if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0)
530  return ret;
531 
532  c->pic->key_frame = 1;
533  c->pic->pict_type = AV_PICTURE_TYPE_I;
534 
535  bytestream2_get_be32(&gb); // frame size;
536  c->ac_quant = bytestream2_get_byte(&gb);
537  c->luma_dc_quant = 32;
538  c->chroma_dc_quant = 32;
539 
540  if ((ret = init_get_bits8(&c->gb, buf + bytestream2_tell(&gb),
541  buf_size - bytestream2_tell(&gb))) < 0)
542  return ret;
543 
544  for (i = 0; i < 3; i++)
545  c->top_dc[i] = 32;
546  for (i = 0; i < 4; i++)
547  c->left_dc[i] = 32;
548 
549  for (j = 0; j < c->mb_height; j++) {
550  for (i = 0; i < c->mb_width; i++) {
551  ret = decode_mb(c, i, j);
552  if (ret < 0)
553  mb_ret = ret;
554  }
555  }
556  extend_edges(c->pic, c->tile_size);
557  } else {
558  int plane;
559 
560  if (c->pmb_width * c->pmb_height > 8LL*(buf_size - bytestream2_tell(&gb)))
561  return AVERROR_INVALIDDATA;
562 
563  if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0)
564  return ret;
565 
566  ret = av_frame_copy(c->pic, c->prev);
567  if (ret < 0)
568  return ret;
569 
570  if ((ret = init_get_bits8(&c->gb, buf + bytestream2_tell(&gb),
571  buf_size - bytestream2_tell(&gb))) < 0)
572  return ret;
573 
574  mvi_reset(&c->mvi, c->pmb_width, c->pmb_height, 1 << c->tile_shift);
575 
576  for (j = 0; j < c->pmb_height; j++) {
577  for (i = 0; i < c->pmb_width; i++) {
578  if (get_bits_left(&c->gb) <= 0)
579  return AVERROR_INVALIDDATA;
580  if (get_bits1(&c->gb)) {
581  MV mv = mvi_predict(&c->mvi, i, j, zero_mv);
582 
583  for (plane = 0; plane < 3; plane++) {
584  int16_t x = plane == 0 ? i << c->tile_shift : i << (c->tile_shift - 1);
585  int16_t y = plane == 0 ? j << c->tile_shift : j << (c->tile_shift - 1);
586  int16_t size = plane == 0 ? 1 << c->tile_shift : 1 << (c->tile_shift - 1);
587  int16_t mx = plane == 0 ? mv.x : mv.x / 2;
588  int16_t my = plane == 0 ? mv.y : mv.y / 2;
589 
590  ret = copy_block(avctx, c->pic, c->prev, plane, x, y, mx, my, size);
591  if (ret < 0)
592  mb_ret = ret;
593  }
594  } else {
595  int x = i << c->tile_shift;
596  int y = j << c->tile_shift;
597  int size = 1 << c->tile_shift;
598  TileInfo *tile;
599  MV mv, cmv;
600 
601  tile = decode_tile_info(&c->gb, &lev[0], 0); // Y
602  if (!tile)
603  return AVERROR(ENOMEM);
604  mv = mvi_predict(&c->mvi, i, j, tile->mv);
605  ret = restore_tree(avctx, c->pic, c->prev, 0, x, y, size, tile, mv);
606  if (ret < 0)
607  mb_ret = ret;
608  x = i << (c->tile_shift - 1);
609  y = j << (c->tile_shift - 1);
610  size = 1 << (c->tile_shift - 1);
611  cmv.x = mv.x + tile->mv.x;
612  cmv.y = mv.y + tile->mv.y;
613  cmv.x /= 2;
614  cmv.y /= 2;
615  av_freep(&tile);
616  tile = decode_tile_info(&c->gb, &lev[4], 0); // U
617  if (!tile)
618  return AVERROR(ENOMEM);
619  ret = restore_tree(avctx, c->pic, c->prev, 1, x, y, size, tile, cmv);
620  if (ret < 0)
621  mb_ret = ret;
622  av_freep(&tile);
623  tile = decode_tile_info(&c->gb, &lev[7], 0); // V
624  if (!tile)
625  return AVERROR(ENOMEM);
626  ret = restore_tree(avctx, c->pic, c->prev, 2, x, y, size, tile, cmv);
627  if (ret < 0)
628  mb_ret = ret;
629  av_freep(&tile);
630  }
631  }
632  mvi_update_row(&c->mvi);
633  }
634  extend_edges(c->pic, c->tile_size);
635 
636  c->pic->key_frame = 0;
637  c->pic->pict_type = AV_PICTURE_TYPE_P;
638  }
639 
640  if ((ret = av_frame_ref(data, c->pic)) < 0)
641  return ret;
642 
643  FFSWAP(AVFrame *, c->pic, c->prev);
644 
645  *got_frame = 1;
646 
647  if (get_bits_left(&c->gb) < 0)
648  av_log(c->avctx, AV_LOG_WARNING, "overread %d\n", -get_bits_left(&c->gb));
649 
650  return mb_ret < 0 ? mb_ret : buf_size;
651 }
652 
653 static av_cold void build_vlc(VLC *vlc, const uint8_t counts[16],
654  const uint16_t **syms, unsigned *offset)
655 {
656  uint8_t lens[MAX_VLC_ENTRIES];
657  unsigned num = 0;
658 
659  for (int i = 0; i < 16; i++) {
660  unsigned count = counts[i];
661  if (count == 255) /* Special case for Y_3 table */
662  count = 303;
663  for (count += num; num < count; num++)
664  lens[num] = i + 1;
665  }
666  vlc->table = &vlc_buf[*offset];
668  ff_init_vlc_from_lengths(vlc, CLV_VLC_BITS, num, lens, 1,
669  *syms, 2, 2, 0, INIT_VLC_STATIC_OVERLONG, NULL);
670  *syms += num;
671  *offset += vlc->table_size;
672 }
673 
674 static av_cold void clv_init_static(void)
675 {
676  const uint16_t *mv_syms = clv_mv_syms, *bias_syms = clv_bias_syms;
677 
679  clv_dc_lens, 1,
680  clv_dc_syms, 1, 1, -63, 0, 1104);
682  clv_ac_bits, 1,
683  clv_ac_syms, 2, 2, 0, 0, 554);
684  for (unsigned i = 0, j = 0, k = 0, offset = 0;; i++) {
685  if (0x36F & (1 << i)) {
686  build_vlc(&lev[i].mv_cb, clv_mv_len_counts[k], &mv_syms, &offset);
687  k++;
688  }
689  if (i == FF_ARRAY_ELEMS(lev) - 1)
690  break;
691  if (0x1B7 & (1 << i)) {
694  ff_init_vlc_from_lengths(&lev[i].flags_cb, CLV_VLC_BITS, 16,
695  clv_flags_bits[j], 1,
696  clv_flags_syms[j], 1, 1,
699 
700  build_vlc(&lev[i + 1].bias_cb, clv_bias_len_counts[j],
701  &bias_syms, &offset);
702  j++;
703  }
704  }
705 }
706 
708 {
709  static AVOnce init_static_once = AV_ONCE_INIT;
710  CLVContext *const c = avctx->priv_data;
711  int ret, w, h;
712 
713  if (avctx->extradata_size == 110) {
714  c->tile_size = AV_RL32(&avctx->extradata[94]);
715  } else if (avctx->extradata_size == 150) {
716  c->tile_size = AV_RB32(&avctx->extradata[134]);
717  } else if (!avctx->extradata_size) {
718  c->tile_size = 16;
719  } else {
720  av_log(avctx, AV_LOG_ERROR, "Unsupported extradata size: %d\n", avctx->extradata_size);
721  return AVERROR_INVALIDDATA;
722  }
723 
724  c->tile_shift = av_log2(c->tile_size);
725  if (1U << c->tile_shift != c->tile_size || c->tile_shift < 1 || c->tile_shift > 30) {
726  av_log(avctx, AV_LOG_ERROR, "Tile size: %d, is not power of 2 > 1 and < 2^31\n", c->tile_size);
727  return AVERROR_INVALIDDATA;
728  }
729 
730  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
731  w = avctx->width;
732  h = avctx->height;
733  ret = ff_set_dimensions(avctx, FFALIGN(w, 1 << c->tile_shift), FFALIGN(h, 1 << c->tile_shift));
734  if (ret < 0)
735  return ret;
736  avctx->width = w;
737  avctx->height = h;
738 
739  c->avctx = avctx;
740  c->mb_width = FFALIGN(avctx->width, 16) >> 4;
741  c->mb_height = FFALIGN(avctx->height, 16) >> 4;
742  c->pmb_width = (w + c->tile_size - 1) >> c->tile_shift;
743  c->pmb_height = (h + c->tile_size - 1) >> c->tile_shift;
744  c->pic = av_frame_alloc();
745  c->prev = av_frame_alloc();
746  c->mvi.mv = av_calloc(c->pmb_width * 2, sizeof(*c->mvi.mv));
747  if (!c->pic || !c->prev || !c->mvi.mv)
748  return AVERROR(ENOMEM);
749 
750  ff_idctdsp_init(&c->idsp, avctx);
751 
752  ff_thread_once(&init_static_once, clv_init_static);
753 
754  return 0;
755 }
756 
758 {
759  CLVContext *const c = avctx->priv_data;
760 
761  av_frame_free(&c->prev);
762  av_frame_free(&c->pic);
763 
764  av_freep(&c->mvi.mv);
765 
766  return 0;
767 }
768 
770  .name = "clearvideo",
771  .long_name = NULL_IF_CONFIG_SMALL("Iterated Systems ClearVideo"),
772  .type = AVMEDIA_TYPE_VIDEO,
774  .priv_data_size = sizeof(CLVContext),
776  .close = clv_decode_end,
778  .capabilities = AV_CODEC_CAP_DR1,
780 };
MAX_VLC_ENTRIES
#define MAX_VLC_ENTRIES
Definition: clearvideodata.h:27
AVCodec
AVCodec.
Definition: codec.h:202
stride
int stride
Definition: mace.c:144
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:42
level
uint8_t level
Definition: svq3.c:204
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:850
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:85
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:75
LevelCodes::mv_cb
VLC mv_cb
Definition: clearvideo.c:42
mv
static const int8_t mv[256][2]
Definition: 4xm.c:79
TileInfo
Definition: clearvideo.c:61
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:109
MVInfo::mv
MV * mv
Definition: clearvideo.c:58
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:260
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
clv_mv_syms
static const uint16_t clv_mv_syms[]
Definition: clearvideodata.h:112
MV::y
int16_t y
Definition: clearvideo.c:47
AVFrame::width
int width
Definition: frame.h:389
w
uint8_t w
Definition: llviddspenc.c:38
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
MVInfo::mb_w
int mb_w
Definition: clearvideo.c:53
TileInfo::bias
int16_t bias
Definition: clearvideo.c:63
data
const char data[16]
Definition: mxf.c:143
clearvideodata.h
get_vlc2
static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE(*table)[2], int bits, int max_depth)
Parse a vlc code.
Definition: get_bits.h:798
CLVContext::top_dc
int top_dc[3]
Definition: clearvideo.c:81
CLVContext::mvi
MVInfo mvi
Definition: clearvideo.c:76
clv_flags_syms
static const uint8_t clv_flags_syms[][16]
Definition: clearvideodata.h:90
CLVContext::pic
AVFrame * pic
Definition: clearvideo.c:71
clv_decode_init
static av_cold int clv_decode_init(AVCodecContext *avctx)
Definition: clearvideo.c:707
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:338
MVInfo::top
int top
Definition: clearvideo.c:57
LevelCodes::flags_cb
VLC flags_cb
Definition: clearvideo.c:41
init
static int init
Definition: av_tx.c:47
A
#define A(x)
Definition: vp56_arith.h:28
ROP
#define ROP(x)
Definition: clearvideo.c:156
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:380
extend_edges
static void extend_edges(AVFrame *buf, int tile_size)
Definition: clearvideo.c:462
BIAS_ESC
#define BIAS_ESC
Definition: clearvideodata.h:619
decode_mb
static int decode_mb(CLVContext *c, int x, int y)
Definition: clearvideo.c:177
VLC_TYPE
#define VLC_TYPE
Definition: vlc.h:24
U
#define U(x)
Definition: vp56_arith.h:37
GetBitContext
Definition: get_bits.h:62
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:298
CLVContext::mb_width
int mb_width
Definition: clearvideo.c:74
val
static double val(void *priv, double ch)
Definition: aeval.c:76
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:571
dc_vlc
static VLC dc_vlc
Definition: clearvideo.c:84
ff_init_vlc_from_lengths
int ff_init_vlc_from_lengths(VLC *vlc_arg, 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: bitstream.c:381
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:97
clv_init_static
static av_cold void clv_init_static(void)
Definition: clearvideo.c:674
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:175
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:678
TileInfo::child
struct TileInfo * child[4]
Definition: clearvideo.c:65
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:485
CLVContext::avctx
AVCodecContext * avctx
Definition: clearvideo.c:69
clv_dct
static void clv_dct(int16_t *block)
Definition: clearvideo.c:159
CLVContext::gb
GetBitContext gb
Definition: clearvideo.c:73
get_sbits
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:360
ctx
AVFormatContext * ctx
Definition: movenc.c:48
get_bits.h
MV::x
int16_t x
Definition: clearvideo.c:47
CLVContext::left_dc
int left_dc[4]
Definition: clearvideo.c:81
LevelCodes
Definition: clearvideo.c:40
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:185
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:65
CLVContext::tile_shift
int tile_shift
Definition: clearvideo.c:78
AV_ONCE_INIT
#define AV_ONCE_INIT
Definition: thread.h:173
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:126
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:499
src
#define src
Definition: vp8dsp.c:255
mathops.h
clv_decode_end
static av_cold int clv_decode_end(AVCodecContext *avctx)
Definition: clearvideo.c:757
MVInfo
Definition: clearvideo.c:52
MVInfo::mb_stride
int mb_stride
Definition: clearvideo.c:56
mvi_update_row
static void mvi_update_row(MVInfo *mvi)
Definition: clearvideo.c:354
AVOnce
#define AVOnce
Definition: thread.h:172
TileInfo::mv
MV mv
Definition: clearvideo.c:64
ac_vlc
static VLC ac_vlc
Definition: clearvideo.c:84
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
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
bytestream2_tell
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:192
clv_decode_frame
static int clv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: clearvideo.c:501
VLC::table_allocated
int table_allocated
Definition: vlc.h:29
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:374
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:325
MVInfo::mb_h
int mb_h
Definition: clearvideo.c:54
av_frame_copy
int av_frame_copy(AVFrame *dst, const AVFrame *src)
Copy the frame data from src to dst.
Definition: frame.c:678
MV
Definition: clearvideo.c:46
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:431
size
int size
Definition: twinvq_data.h:10344
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
CLVContext::pmb_height
int pmb_height
Definition: clearvideo.c:75
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:224
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:271
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:1390
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:484
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: internal.h:50
clv_ac_bits
static const uint8_t clv_ac_bits[NUM_AC_CODES]
Definition: clearvideodata.h:71
ff_idctdsp_init
av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
Definition: idctdsp.c:238
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
TileInfo::flags
uint16_t flags
Definition: clearvideo.c:62
lev
static LevelCodes lev[4+3+3]
Definition: clearvideo.c:85
AVCodecContext::height
int height
Definition: avcodec.h:556
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:593
ff_clearvideo_decoder
const AVCodec ff_clearvideo_decoder
Definition: clearvideo.c:769
CLVContext::tile_size
int tile_size
Definition: clearvideo.c:77
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:271
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:38
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:1759
ret
ret
Definition: filter_design.txt:187
INIT_VLC_STATIC_OVERLONG
#define INIT_VLC_STATIC_OVERLONG
Definition: vlc.h:96
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:364
IDCTDSPContext
Definition: idctdsp.h:53
COP
#define COP(x)
Definition: clearvideo.c:157
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
CLVContext::luma_dc_quant
int luma_dc_quant
Definition: clearvideo.c:79
vlc_buf
static VLC_TYPE vlc_buf[16716][2]
Definition: clearvideo.c:86
LevelCodes::bias_cb
VLC bias_cb
Definition: clearvideo.c:43
B
#define B
Definition: huffyuvdsp.h:32
AVCodecContext
main external API structure.
Definition: avcodec.h:383
AVFrame::height
int height
Definition: frame.h:389
decode_block
static int decode_block(CLVContext *ctx, int16_t *blk, int has_ac, int ac_quant)
Definition: clearvideo.c:88
CLVContext::mb_height
int mb_height
Definition: clearvideo.c:74
VLC
Definition: vlc.h:26
MV_ESC
#define MV_ESC
Definition: clearvideodata.h:111
DCT_TEMPLATE
#define DCT_TEMPLATE(blk, step, bias, shift, dshift, OP)
Definition: clearvideo.c:132
av_clip_uint8
#define av_clip_uint8
Definition: common.h:102
VLC::table_size
int table_size
Definition: vlc.h:29
shift
static int shift(int a, int b)
Definition: sonic.c:83
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:571
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:72
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:86
mvi_reset
static void mvi_reset(MVInfo *mvi, int mb_w, int mb_h, int mb_size)
Definition: clearvideo.c:344
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:408
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
CLVContext::idsp
IDCTDSPContext idsp
Definition: clearvideo.c:70
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
AVPacket
This structure stores compressed data.
Definition: packet.h:350
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:35
CLVContext::chroma_dc_quant
int chroma_dc_quant
Definition: clearvideo.c:79
NUM_DC_CODES
#define NUM_DC_CODES
Definition: clearvideodata.h:28
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:556
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:362
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:68
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
CLVContext::block
int16_t block[64]
Definition: clearvideo.c:80
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:50
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:417
CLVContext::ac_quant
int ac_quant
Definition: clearvideo.c:79
VLC::table
VLC_TYPE(* table)[2]
code, bits
Definition: vlc.h:28
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
MVInfo::mb_size
int mb_size
Definition: clearvideo.c:55
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:653
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:202