FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mss12.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Konstantin Shishkov
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * Common functions for Microsoft Screen 1 and 2
24  */
25 
26 #include <inttypes.h>
27 
28 #include "libavutil/intfloat.h"
29 #include "libavutil/intreadwrite.h"
30 #include "avcodec.h"
31 #include "mss12.h"
32 
33 enum SplitMode {
37 };
38 
39 static const int sec_order_sizes[4] = { 1, 7, 6, 1 };
40 
42  TOP_LEFT = 0,
43  TOP,
46 };
47 
49 {
50  int thr;
51 
52  thr = 2 * m->weights[m->num_syms] - 1;
53  thr = ((thr >> 1) + 4 * m->cum_prob[0]) / thr;
54 
55  return FFMIN(thr, 0x3FFF);
56 }
57 
58 static void model_reset(Model *m)
59 {
60  int i;
61 
62  for (i = 0; i <= m->num_syms; i++) {
63  m->weights[i] = 1;
64  m->cum_prob[i] = m->num_syms - i;
65  }
66  m->weights[0] = 0;
67  for (i = 0; i < m->num_syms; i++)
68  m->idx2sym[i + 1] = i;
69 }
70 
71 static av_cold void model_init(Model *m, int num_syms, int thr_weight)
72 {
73  m->num_syms = num_syms;
74  m->thr_weight = thr_weight;
75  m->threshold = num_syms * thr_weight;
76 }
77 
79 {
80  int i;
81  int cum_prob;
82 
83  if (m->thr_weight == THRESH_ADAPTIVE)
85  while (m->cum_prob[0] > m->threshold) {
86  cum_prob = 0;
87  for (i = m->num_syms; i >= 0; i--) {
88  m->cum_prob[i] = cum_prob;
89  m->weights[i] = (m->weights[i] + 1) >> 1;
90  cum_prob += m->weights[i];
91  }
92  }
93 }
94 
96 {
97  int i;
98 
99  if (m->weights[val] == m->weights[val - 1]) {
100  for (i = val; m->weights[i - 1] == m->weights[val]; i--);
101  if (i != val) {
102  int sym1, sym2;
103 
104  sym1 = m->idx2sym[val];
105  sym2 = m->idx2sym[i];
106 
107  m->idx2sym[val] = sym2;
108  m->idx2sym[i] = sym1;
109 
110  val = i;
111  }
112  }
113  m->weights[val]++;
114  for (i = val - 1; i >= 0; i--)
115  m->cum_prob[i]++;
117 }
118 
120 {
121  int i, j;
122 
123  if (!ctx->special_initial_cache)
124  for (i = 0; i < ctx->cache_size; i++)
125  ctx->cache[i] = i;
126  else {
127  ctx->cache[0] = 1;
128  ctx->cache[1] = 2;
129  ctx->cache[2] = 4;
130  }
131 
132  model_reset(&ctx->cache_model);
133  model_reset(&ctx->full_model);
134 
135  for (i = 0; i < 15; i++)
136  for (j = 0; j < 4; j++)
137  model_reset(&ctx->sec_models[i][j]);
138 }
139 
140 static av_cold void pixctx_init(PixContext *ctx, int cache_size,
141  int full_model_syms, int special_initial_cache)
142 {
143  int i, j, k, idx;
144 
145  ctx->cache_size = cache_size + 4;
146  ctx->num_syms = cache_size;
147  ctx->special_initial_cache = special_initial_cache;
148 
149  model_init(&ctx->cache_model, ctx->num_syms + 1, THRESH_LOW);
150  model_init(&ctx->full_model, full_model_syms, THRESH_HIGH);
151 
152  for (i = 0, idx = 0; i < 4; i++)
153  for (j = 0; j < sec_order_sizes[i]; j++, idx++)
154  for (k = 0; k < 4; k++)
155  model_init(&ctx->sec_models[idx][k], 2 + i,
157 }
158 
160  uint8_t *ngb, int num_ngb, int any_ngb)
161 {
162  int i, val, pix;
163 
164  val = acoder->get_model_sym(acoder, &pctx->cache_model);
165  if (val < pctx->num_syms) {
166  if (any_ngb) {
167  int idx, j;
168 
169  idx = 0;
170  for (i = 0; i < pctx->cache_size; i++) {
171  for (j = 0; j < num_ngb; j++)
172  if (pctx->cache[i] == ngb[j])
173  break;
174  if (j == num_ngb) {
175  if (idx == val)
176  break;
177  idx++;
178  }
179  }
180  val = FFMIN(i, pctx->cache_size - 1);
181  }
182  pix = pctx->cache[val];
183  } else {
184  pix = acoder->get_model_sym(acoder, &pctx->full_model);
185  for (i = 0; i < pctx->cache_size - 1; i++)
186  if (pctx->cache[i] == pix)
187  break;
188  val = i;
189  }
190  if (val) {
191  for (i = val; i > 0; i--)
192  pctx->cache[i] = pctx->cache[i - 1];
193  pctx->cache[0] = pix;
194  }
195 
196  return pix;
197 }
198 
200  uint8_t *src, ptrdiff_t stride, int x, int y,
201  int has_right)
202 {
203  uint8_t neighbours[4];
204  uint8_t ref_pix[4];
205  int nlen;
206  int layer = 0, sub;
207  int pix;
208  int i, j;
209 
210  if (!y) {
211  memset(neighbours, src[-1], 4);
212  } else {
213  neighbours[TOP] = src[-stride];
214  if (!x) {
215  neighbours[TOP_LEFT] = neighbours[LEFT] = neighbours[TOP];
216  } else {
217  neighbours[TOP_LEFT] = src[-stride - 1];
218  neighbours[ LEFT] = src[-1];
219  }
220  if (has_right)
221  neighbours[TOP_RIGHT] = src[-stride + 1];
222  else
223  neighbours[TOP_RIGHT] = neighbours[TOP];
224  }
225 
226  sub = 0;
227  if (x >= 2 && src[-2] == neighbours[LEFT])
228  sub = 1;
229  if (y >= 2 && src[-2 * stride] == neighbours[TOP])
230  sub |= 2;
231 
232  nlen = 1;
233  ref_pix[0] = neighbours[0];
234  for (i = 1; i < 4; i++) {
235  for (j = 0; j < nlen; j++)
236  if (ref_pix[j] == neighbours[i])
237  break;
238  if (j == nlen)
239  ref_pix[nlen++] = neighbours[i];
240  }
241 
242  switch (nlen) {
243  case 1:
244  layer = 0;
245  break;
246  case 2:
247  if (neighbours[TOP] == neighbours[TOP_LEFT]) {
248  if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
249  layer = 1;
250  else if (neighbours[LEFT] == neighbours[TOP_LEFT])
251  layer = 2;
252  else
253  layer = 3;
254  } else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT]) {
255  if (neighbours[LEFT] == neighbours[TOP_LEFT])
256  layer = 4;
257  else
258  layer = 5;
259  } else if (neighbours[LEFT] == neighbours[TOP_LEFT]) {
260  layer = 6;
261  } else {
262  layer = 7;
263  }
264  break;
265  case 3:
266  if (neighbours[TOP] == neighbours[TOP_LEFT])
267  layer = 8;
268  else if (neighbours[TOP_RIGHT] == neighbours[TOP_LEFT])
269  layer = 9;
270  else if (neighbours[LEFT] == neighbours[TOP_LEFT])
271  layer = 10;
272  else if (neighbours[TOP_RIGHT] == neighbours[TOP])
273  layer = 11;
274  else if (neighbours[TOP] == neighbours[LEFT])
275  layer = 12;
276  else
277  layer = 13;
278  break;
279  case 4:
280  layer = 14;
281  break;
282  }
283 
284  pix = acoder->get_model_sym(acoder,
285  &pctx->sec_models[layer][sub]);
286  if (pix < nlen)
287  return ref_pix[pix];
288  else
289  return decode_pixel(acoder, pctx, ref_pix, nlen, 1);
290 }
291 
292 static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic,
293  int x, int y, int width, int height, ptrdiff_t stride,
294  ptrdiff_t rgb_stride, PixContext *pctx,
295  const uint32_t *pal)
296 {
297  int i, j, p;
298  uint8_t *rgb_dst = rgb_pic + x * 3 + y * rgb_stride;
299 
300  dst += x + y * stride;
301 
302  for (j = 0; j < height; j++) {
303  for (i = 0; i < width; i++) {
304  if (!i && !j)
305  p = decode_pixel(acoder, pctx, NULL, 0, 0);
306  else
307  p = decode_pixel_in_context(acoder, pctx, dst + i, stride,
308  i, j, width - i - 1);
309  dst[i] = p;
310 
311  if (rgb_pic)
312  AV_WB24(rgb_dst + i * 3, pal[p]);
313  }
314  dst += stride;
315  rgb_dst += rgb_stride;
316  }
317 
318  return 0;
319 }
320 
321 static void copy_rectangles(MSS12Context const *c,
322  int x, int y, int width, int height)
323 {
324  int j;
325 
326  if (c->last_rgb_pic)
327  for (j = y; j < y + height; j++) {
328  memcpy(c->rgb_pic + j * c->rgb_stride + x * 3,
329  c->last_rgb_pic + j * c->rgb_stride + x * 3,
330  width * 3);
331  memcpy(c->pal_pic + j * c->pal_stride + x,
332  c->last_pal_pic + j * c->pal_stride + x,
333  width);
334  }
335 }
336 
338  int x, int y, int width, int height)
339 {
340  if (x + c->mvX < 0 || x + c->mvX + width > c->avctx->width ||
341  y + c->mvY < 0 || y + c->mvY + height > c->avctx->height ||
342  !c->rgb_pic)
343  return -1;
344  else {
345  uint8_t *dst = c->pal_pic + x + y * c->pal_stride;
346  uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * c->rgb_stride;
347  uint8_t *src;
348  uint8_t *rgb_src;
349  int j;
350  x += c->mvX;
351  y += c->mvY;
352  if (c->last_rgb_pic) {
353  src = c->last_pal_pic + x + y * c->pal_stride;
354  rgb_src = c->last_rgb_pic + x * 3 + y * c->rgb_stride;
355  } else {
356  src = c->pal_pic + x + y * c->pal_stride;
357  rgb_src = c->rgb_pic + x * 3 + y * c->rgb_stride;
358  }
359  for (j = 0; j < height; j++) {
360  memmove(dst, src, width);
361  memmove(rgb_dst, rgb_src, width * 3);
362  dst += c->pal_stride;
363  src += c->pal_stride;
364  rgb_dst += c->rgb_stride;
365  rgb_src += c->rgb_stride;
366  }
367  }
368  return 0;
369 }
370 
371 static int decode_region_masked(MSS12Context const *c, ArithCoder *acoder,
372  uint8_t *dst, ptrdiff_t stride, uint8_t *mask,
373  ptrdiff_t mask_stride, int x, int y,
374  int width, int height,
375  PixContext *pctx)
376 {
377  int i, j, p;
378  uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * c->rgb_stride;
379 
380  dst += x + y * stride;
381  mask += x + y * mask_stride;
382 
383  for (j = 0; j < height; j++) {
384  for (i = 0; i < width; i++) {
385  if (c->avctx->err_recognition & AV_EF_EXPLODE &&
386  ( c->rgb_pic && mask[i] != 0x01 && mask[i] != 0x02 && mask[i] != 0x04 ||
387  !c->rgb_pic && mask[i] != 0x80 && mask[i] != 0xFF))
388  return -1;
389 
390  if (mask[i] == 0x02) {
391  copy_rectangles(c, x + i, y + j, 1, 1);
392  } else if (mask[i] == 0x04) {
393  if (motion_compensation(c, x + i, y + j, 1, 1))
394  return -1;
395  } else if (mask[i] != 0x80) {
396  if (!i && !j)
397  p = decode_pixel(acoder, pctx, NULL, 0, 0);
398  else
399  p = decode_pixel_in_context(acoder, pctx, dst + i, stride,
400  i, j, width - i - 1);
401  dst[i] = p;
402  if (c->rgb_pic)
403  AV_WB24(rgb_dst + i * 3, c->pal[p]);
404  }
405  }
406  dst += stride;
407  mask += mask_stride;
408  rgb_dst += c->rgb_stride;
409  }
410 
411  return 0;
412 }
413 
415  int version, int full_model_syms)
416 {
420  model_init(&sc->edge_mode, 2, THRESH_HIGH);
421  model_init(&sc->pivot, 3, THRESH_LOW);
422 
423  pixctx_init(&sc->intra_pix_ctx, 8, full_model_syms, 0);
424 
425  pixctx_init(&sc->inter_pix_ctx, version ? 3 : 2,
426  full_model_syms, version ? 1 : 0);
427 }
428 
430 {
433  model_reset(&sc->split_mode);
434  model_reset(&sc->edge_mode);
435  model_reset(&sc->pivot);
438 }
439 
440 static int decode_pivot(SliceContext *sc, ArithCoder *acoder, int base)
441 {
442  int val, inv;
443 
444  inv = acoder->get_model_sym(acoder, &sc->edge_mode);
445  val = acoder->get_model_sym(acoder, &sc->pivot) + 1;
446 
447  if (val > 2) {
448  if ((base + 1) / 2 - 2 <= 0)
449  return -1;
450 
451  val = acoder->get_number(acoder, (base + 1) / 2 - 2) + 3;
452  }
453 
454  if ((unsigned)val >= base)
455  return -1;
456 
457  return inv ? base - val : val;
458 }
459 
461  int x, int y, int width, int height)
462 {
463  MSS12Context const *c = sc->c;
464  int mode;
465 
466  mode = acoder->get_model_sym(acoder, &sc->intra_region);
467 
468  if (!mode) {
469  int i, j, pix, rgb_pix;
470  ptrdiff_t stride = c->pal_stride;
471  ptrdiff_t rgb_stride = c->rgb_stride;
472  uint8_t *dst = c->pal_pic + x + y * stride;
473  uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * rgb_stride;
474 
475  pix = decode_pixel(acoder, &sc->intra_pix_ctx, NULL, 0, 0);
476  rgb_pix = c->pal[pix];
477  for (i = 0; i < height; i++, dst += stride, rgb_dst += rgb_stride) {
478  memset(dst, pix, width);
479  if (c->rgb_pic)
480  for (j = 0; j < width * 3; j += 3)
481  AV_WB24(rgb_dst + j, rgb_pix);
482  }
483  } else {
484  return decode_region(acoder, c->pal_pic, c->rgb_pic,
485  x, y, width, height, c->pal_stride, c->rgb_stride,
486  &sc->intra_pix_ctx, &c->pal[0]);
487  }
488 
489  return 0;
490 }
491 
493  int x, int y, int width, int height)
494 {
495  MSS12Context const *c = sc->c;
496  int mode;
497 
498  mode = acoder->get_model_sym(acoder, &sc->inter_region);
499 
500  if (!mode) {
501  mode = decode_pixel(acoder, &sc->inter_pix_ctx, NULL, 0, 0);
502 
503  if (c->avctx->err_recognition & AV_EF_EXPLODE &&
504  ( c->rgb_pic && mode != 0x01 && mode != 0x02 && mode != 0x04 ||
505  !c->rgb_pic && mode != 0x80 && mode != 0xFF))
506  return -1;
507 
508  if (mode == 0x02)
509  copy_rectangles(c, x, y, width, height);
510  else if (mode == 0x04)
511  return motion_compensation(c, x, y, width, height);
512  else if (mode != 0x80)
513  return decode_region_intra(sc, acoder, x, y, width, height);
514  } else {
515  if (decode_region(acoder, c->mask, NULL,
516  x, y, width, height, c->mask_stride, 0,
517  &sc->inter_pix_ctx, &c->pal[0]) < 0)
518  return -1;
519  return decode_region_masked(c, acoder, c->pal_pic,
520  c->pal_stride, c->mask,
521  c->mask_stride,
522  x, y, width, height,
523  &sc->intra_pix_ctx);
524  }
525 
526  return 0;
527 }
528 
530  int x, int y, int width, int height)
531 {
532  int mode, pivot;
533 
534  mode = acoder->get_model_sym(acoder, &sc->split_mode);
535 
536  switch (mode) {
537  case SPLIT_VERT:
538  if ((pivot = decode_pivot(sc, acoder, height)) < 1)
539  return -1;
540  if (ff_mss12_decode_rect(sc, acoder, x, y, width, pivot))
541  return -1;
542  if (ff_mss12_decode_rect(sc, acoder, x, y + pivot, width, height - pivot))
543  return -1;
544  break;
545  case SPLIT_HOR:
546  if ((pivot = decode_pivot(sc, acoder, width)) < 1)
547  return -1;
548  if (ff_mss12_decode_rect(sc, acoder, x, y, pivot, height))
549  return -1;
550  if (ff_mss12_decode_rect(sc, acoder, x + pivot, y, width - pivot, height))
551  return -1;
552  break;
553  case SPLIT_NONE:
554  if (sc->c->keyframe)
555  return decode_region_intra(sc, acoder, x, y, width, height);
556  else
557  return decode_region_inter(sc, acoder, x, y, width, height);
558  default:
559  return -1;
560  }
561 
562  return 0;
563 }
564 
566  SliceContext* sc1, SliceContext *sc2)
567 {
568  AVCodecContext *avctx = c->avctx;
569  int i;
570 
571  if (avctx->extradata_size < 52 + 256 * 3) {
572  av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d\n",
573  avctx->extradata_size);
574  return AVERROR_INVALIDDATA;
575  }
576 
577  if (AV_RB32(avctx->extradata) < avctx->extradata_size) {
578  av_log(avctx, AV_LOG_ERROR,
579  "Insufficient extradata size: expected %"PRIu32" got %d\n",
580  AV_RB32(avctx->extradata),
581  avctx->extradata_size);
582  return AVERROR_INVALIDDATA;
583  }
584 
585  avctx->coded_width = FFMAX(AV_RB32(avctx->extradata + 20), avctx->width);
586  avctx->coded_height = FFMAX(AV_RB32(avctx->extradata + 24), avctx->height);
587  if (avctx->coded_width > 4096 || avctx->coded_height > 4096) {
588  av_log(avctx, AV_LOG_ERROR, "Frame dimensions %dx%d too large",
589  avctx->coded_width, avctx->coded_height);
590  return AVERROR_INVALIDDATA;
591  }
592  if (avctx->coded_width < 1 || avctx->coded_height < 1) {
593  av_log(avctx, AV_LOG_ERROR, "Frame dimensions %dx%d too small",
594  avctx->coded_width, avctx->coded_height);
595  return AVERROR_INVALIDDATA;
596  }
597 
598  av_log(avctx, AV_LOG_DEBUG, "Encoder version %"PRIu32".%"PRIu32"\n",
599  AV_RB32(avctx->extradata + 4), AV_RB32(avctx->extradata + 8));
600  if (version != AV_RB32(avctx->extradata + 4) > 1) {
601  av_log(avctx, AV_LOG_ERROR,
602  "Header version doesn't match codec tag\n");
603  return -1;
604  }
605 
606  c->free_colours = AV_RB32(avctx->extradata + 48);
607  if ((unsigned)c->free_colours > 256) {
608  av_log(avctx, AV_LOG_ERROR,
609  "Incorrect number of changeable palette entries: %d\n",
610  c->free_colours);
611  return AVERROR_INVALIDDATA;
612  }
613  av_log(avctx, AV_LOG_DEBUG, "%d free colour(s)\n", c->free_colours);
614 
615  av_log(avctx, AV_LOG_DEBUG, "Display dimensions %"PRIu32"x%"PRIu32"\n",
616  AV_RB32(avctx->extradata + 12), AV_RB32(avctx->extradata + 16));
617  av_log(avctx, AV_LOG_DEBUG, "Coded dimensions %dx%d\n",
618  avctx->coded_width, avctx->coded_height);
619  av_log(avctx, AV_LOG_DEBUG, "%g frames per second\n",
620  av_int2float(AV_RB32(avctx->extradata + 28)));
621  av_log(avctx, AV_LOG_DEBUG, "Bitrate %"PRIu32" bps\n",
622  AV_RB32(avctx->extradata + 32));
623  av_log(avctx, AV_LOG_DEBUG, "Max. lead time %g ms\n",
624  av_int2float(AV_RB32(avctx->extradata + 36)));
625  av_log(avctx, AV_LOG_DEBUG, "Max. lag time %g ms\n",
626  av_int2float(AV_RB32(avctx->extradata + 40)));
627  av_log(avctx, AV_LOG_DEBUG, "Max. seek time %g ms\n",
628  av_int2float(AV_RB32(avctx->extradata + 44)));
629 
630  if (version) {
631  if (avctx->extradata_size < 60 + 256 * 3) {
632  av_log(avctx, AV_LOG_ERROR,
633  "Insufficient extradata size %d for v2\n",
634  avctx->extradata_size);
635  return AVERROR_INVALIDDATA;
636  }
637 
638  c->slice_split = AV_RB32(avctx->extradata + 52);
639  av_log(avctx, AV_LOG_DEBUG, "Slice split %d\n", c->slice_split);
640 
641  c->full_model_syms = AV_RB32(avctx->extradata + 56);
642  if (c->full_model_syms < 2 || c->full_model_syms > 256) {
643  av_log(avctx, AV_LOG_ERROR,
644  "Incorrect number of used colours %d\n",
645  c->full_model_syms);
646  return AVERROR_INVALIDDATA;
647  }
648  av_log(avctx, AV_LOG_DEBUG, "Used colours %d\n",
649  c->full_model_syms);
650  } else {
651  c->slice_split = 0;
652  c->full_model_syms = 256;
653  }
654 
655  for (i = 0; i < 256; i++)
656  c->pal[i] = 0xFFU << 24 | AV_RB24(avctx->extradata + 52 +
657  (version ? 8 : 0) + i * 3);
658 
659  c->mask_stride = FFALIGN(avctx->width, 16);
660  c->mask = av_malloc_array(c->mask_stride, avctx->height);
661  if (!c->mask) {
662  av_log(avctx, AV_LOG_ERROR, "Cannot allocate mask plane\n");
663  return AVERROR(ENOMEM);
664  }
665 
666  sc1->c = c;
667  slicecontext_init(sc1, version, c->full_model_syms);
668  if (c->slice_split) {
669  sc2->c = c;
670  slicecontext_init(sc2, version, c->full_model_syms);
671  }
672  c->corrupted = 1;
673 
674  return 0;
675 }
676 
678 {
679  av_freep(&c->mask);
680 
681  return 0;
682 }
#define NULL
Definition: coverity.c:32
const char const char void * val
Definition: avisynth_c.h:771
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
PixContext inter_pix_ctx
Definition: mss12.h:72
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1963
av_cold int ff_mss12_decode_init(MSS12Context *c, int version, SliceContext *sc1, SliceContext *sc2)
Definition: mss12.c:565
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
Definition: mss12.h:40
int corrupted
Definition: mss12.h:89
static void pixctx_reset(PixContext *ctx)
Definition: mss12.c:119
static int decode_region_inter(SliceContext *sc, ArithCoder *acoder, int x, int y, int width, int height)
Definition: mss12.c:492
int16_t weights[MODEL_MAX_SYMS+1]
Definition: mss12.h:42
int version
Definition: avisynth_c.h:766
uint8_t * rgb_pic
Definition: mss12.h:83
#define src
Definition: vp8dsp.c:254
int thr_weight
Definition: mss12.h:45
int ff_mss12_decode_rect(SliceContext *sc, ArithCoder *acoder, int x, int y, int width, int height)
Definition: mss12.c:529
static const int sec_order_sizes[4]
Definition: mss12.c:39
int slice_split
Definition: mss12.h:90
uint32_t pal[256]
Definition: mss12.h:77
uint8_t
uint8_t * last_pal_pic
Definition: mss12.h:79
#define av_cold
Definition: attributes.h:82
int keyframe
Definition: mss12.h:87
ptrdiff_t rgb_stride
Definition: mss12.h:85
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1876
Model inter_region
Definition: mss12.h:70
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:87
#define height
#define FFALIGN(x, a)
Definition: macros.h:48
Model full_model
Definition: mss12.h:61
#define av_log(a,...)
int(* get_model_sym)(struct ArithCoder *c, Model *m)
Definition: mss12.h:54
Model sec_models[15][4]
Definition: mss12.h:62
static av_cold void slicecontext_init(SliceContext *sc, int version, int full_model_syms)
Definition: mss12.c:414
static int decode_region_intra(SliceContext *sc, ArithCoder *acoder, int x, int y, int width, int height)
Definition: mss12.c:460
Model pivot
Definition: mss12.h:71
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static const uint16_t mask[17]
Definition: lzw.c:38
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
static void model_rescale_weights(Model *m)
Definition: mss12.c:78
int full_model_syms
Definition: mss12.h:91
int mvY
Definition: mss12.h:88
uint16_t width
Definition: gdv.c:47
int cache_size
Definition: mss12.h:59
#define FFMAX(a, b)
Definition: common.h:94
AVCodecContext * avctx
Definition: mss12.h:76
Model edge_mode
Definition: mss12.h:71
static int decode_pivot(SliceContext *sc, ArithCoder *acoder, int base)
Definition: mss12.c:440
static av_cold void pixctx_init(PixContext *ctx, int cache_size, int full_model_syms, int special_initial_cache)
Definition: mss12.c:140
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
Definition: avcodec.h:3050
#define FFMIN(a, b)
Definition: common.h:96
static int model_calc_threshold(Model *m)
Definition: mss12.c:48
PixContext intra_pix_ctx
Definition: mss12.h:72
Definition: mss12.c:45
static int motion_compensation(MSS12Context const *c, int x, int y, int width, int height)
Definition: mss12.c:337
int width
picture width / height.
Definition: avcodec.h:1948
Definition: mss12.c:43
AVFormatContext * ctx
Definition: movenc.c:48
#define AV_WB24(p, d)
Definition: intreadwrite.h:455
ptrdiff_t pal_stride
Definition: mss12.h:80
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: avcodec.h:3061
struct MSS12Context * c
Definition: mss12.h:69
av_cold int ff_mss12_decode_end(MSS12Context *c)
Definition: mss12.c:677
Libavcodec external API header.
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_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:87
ContextDirection
Definition: mss12.c:41
uint8_t * mask
Definition: mss12.h:81
main external API structure.
Definition: avcodec.h:1761
int num_syms
Definition: mss12.h:44
Model cache_model
Definition: mss12.h:61
#define THRESH_ADAPTIVE
Definition: mss12.h:36
int extradata_size
Definition: avcodec.h:1877
int coded_height
Definition: avcodec.h:1963
uint8_t idx2sym[MODEL_MAX_SYMS+1]
Definition: mss12.h:43
static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx, uint8_t *src, ptrdiff_t stride, int x, int y, int has_right)
Definition: mss12.c:199
int special_initial_cache
Definition: mss12.h:63
Definition: mss12.c:42
static av_cold void model_init(Model *m, int num_syms, int thr_weight)
Definition: mss12.c:71
Model split_mode
Definition: mss12.h:71
static void model_reset(Model *m)
Definition: mss12.c:58
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:105
void ff_mss12_slicecontext_reset(SliceContext *sc)
Definition: mss12.c:429
static double c[64]
static av_always_inline int decode_pixel(ArithCoder *acoder, PixContext *pctx, uint8_t *ngb, int num_ngb, int any_ngb)
Definition: mss12.c:159
int threshold
Definition: mss12.h:45
static int decode_region_masked(MSS12Context const *c, ArithCoder *acoder, uint8_t *dst, ptrdiff_t stride, uint8_t *mask, ptrdiff_t mask_stride, int x, int y, int width, int height, PixContext *pctx)
Definition: mss12.c:371
void ff_mss12_model_update(Model *m, int val)
Definition: mss12.c:95
int free_colours
Definition: mss12.h:86
ptrdiff_t mask_stride
Definition: mss12.h:82
uint8_t * last_rgb_pic
Definition: mss12.h:84
static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic, int x, int y, int width, int height, ptrdiff_t stride, ptrdiff_t rgb_stride, PixContext *pctx, const uint32_t *pal)
Definition: mss12.c:292
Model intra_region
Definition: mss12.h:70
#define THRESH_HIGH
Definition: mss12.h:38
#define av_freep(p)
#define av_always_inline
Definition: attributes.h:39
SplitMode
Definition: mss12.c:33
#define av_malloc_array(a, b)
int mvX
Definition: mss12.h:88
#define stride
uint8_t cache[12]
Definition: mss12.h:60
#define THRESH_LOW
Definition: mss12.h:37
int(* get_number)(struct ArithCoder *c, int n)
Definition: mss12.h:55
mode
Use these values in ebur128_init (or'ed).
Definition: ebur128.h:83
int num_syms
Definition: mss12.h:59
uint8_t * pal_pic
Definition: mss12.h:78
static void copy_rectangles(MSS12Context const *c, int x, int y, int width, int height)
Definition: mss12.c:321
int16_t cum_prob[MODEL_MAX_SYMS+1]
Definition: mss12.h:41
Common header for Microsoft Screen 1 and 2.