FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mss3.c
Go to the documentation of this file.
1 /*
2  * Microsoft Screen 3 (aka Microsoft ATC Screen) decoder
3  * Copyright (c) 2012 Konstantin Shishkov
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * Microsoft Screen 3 (aka Microsoft ATC Screen) decoder
25  */
26 
27 #include "avcodec.h"
28 #include "bytestream.h"
29 #include "dsputil.h"
30 #include "mss34dsp.h"
31 
32 #define HEADER_SIZE 27
33 
34 #define MODEL2_SCALE 13
35 #define MODEL_SCALE 15
36 #define MODEL256_SEC_SCALE 9
37 
38 typedef struct Model2 {
42 } Model2;
43 
44 typedef struct Model {
45  int weights[16], freqs[16];
46  int num_syms;
49 } Model;
50 
51 typedef struct Model256 {
52  int weights[256], freqs[256];
54  int secondary[68];
55  int sec_size;
57 } Model256;
58 
59 #define RAC_BOTTOM 0x01000000
60 typedef struct RangeCoder {
61  const uint8_t *src, *src_end;
62 
63  uint32_t range, low;
64  int got_error;
65 } RangeCoder;
66 
67 enum BlockType {
73 };
74 
75 typedef struct BlockTypeContext {
76  int last_type;
79 
80 typedef struct FillBlockCoder {
81  int fill_val;
84 
85 typedef struct ImageBlockCoder {
90 
91 typedef struct DCTBlockCoder {
92  int *prev_dc;
95  int quality;
96  uint16_t qmat[64];
100 } DCTBlockCoder;
101 
102 typedef struct HaarBlockCoder {
107 
108 typedef struct MSS3Context {
111 
119 
120  int dctblock[64];
121  int hblock[16 * 16];
122 } MSS3Context;
123 
124 
125 static void model2_reset(Model2 *m)
126 {
127  m->zero_weight = 1;
128  m->total_weight = 2;
129  m->zero_freq = 0x1000;
130  m->total_freq = 0x2000;
131  m->upd_val = 4;
132  m->till_rescale = 4;
133 }
134 
135 static void model2_update(Model2 *m, int bit)
136 {
137  unsigned scale;
138 
139  if (!bit)
140  m->zero_weight++;
141  m->till_rescale--;
142  if (m->till_rescale)
143  return;
144 
145  m->total_weight += m->upd_val;
146  if (m->total_weight > 0x2000) {
147  m->total_weight = (m->total_weight + 1) >> 1;
148  m->zero_weight = (m->zero_weight + 1) >> 1;
149  if (m->total_weight == m->zero_weight)
150  m->total_weight = m->zero_weight + 1;
151  }
152  m->upd_val = m->upd_val * 5 >> 2;
153  if (m->upd_val > 64)
154  m->upd_val = 64;
155  scale = 0x80000000u / m->total_weight;
156  m->zero_freq = m->zero_weight * scale >> 18;
157  m->total_freq = m->total_weight * scale >> 18;
158  m->till_rescale = m->upd_val;
159 }
160 
161 static void model_update(Model *m, int val)
162 {
163  int i, sum = 0;
164  unsigned scale;
165 
166  m->weights[val]++;
167  m->till_rescale--;
168  if (m->till_rescale)
169  return;
170  m->tot_weight += m->upd_val;
171 
172  if (m->tot_weight > 0x8000) {
173  m->tot_weight = 0;
174  for (i = 0; i < m->num_syms; i++) {
175  m->weights[i] = (m->weights[i] + 1) >> 1;
176  m->tot_weight += m->weights[i];
177  }
178  }
179  scale = 0x80000000u / m->tot_weight;
180  for (i = 0; i < m->num_syms; i++) {
181  m->freqs[i] = sum * scale >> 16;
182  sum += m->weights[i];
183  }
184 
185  m->upd_val = m->upd_val * 5 >> 2;
186  if (m->upd_val > m->max_upd_val)
187  m->upd_val = m->max_upd_val;
188  m->till_rescale = m->upd_val;
189 }
190 
191 static void model_reset(Model *m)
192 {
193  int i;
194 
195  m->tot_weight = 0;
196  for (i = 0; i < m->num_syms - 1; i++)
197  m->weights[i] = 1;
198  m->weights[m->num_syms - 1] = 0;
199 
200  m->upd_val = m->num_syms;
201  m->till_rescale = 1;
202  model_update(m, m->num_syms - 1);
203  m->till_rescale =
204  m->upd_val = (m->num_syms + 6) >> 1;
205 }
206 
207 static av_cold void model_init(Model *m, int num_syms)
208 {
209  m->num_syms = num_syms;
210  m->max_upd_val = 8 * num_syms + 48;
211 
212  model_reset(m);
213 }
214 
215 static void model256_update(Model256 *m, int val)
216 {
217  int i, sum = 0;
218  unsigned scale;
219  int send, sidx = 1;
220 
221  m->weights[val]++;
222  m->till_rescale--;
223  if (m->till_rescale)
224  return;
225  m->tot_weight += m->upd_val;
226 
227  if (m->tot_weight > 0x8000) {
228  m->tot_weight = 0;
229  for (i = 0; i < 256; i++) {
230  m->weights[i] = (m->weights[i] + 1) >> 1;
231  m->tot_weight += m->weights[i];
232  }
233  }
234  scale = 0x80000000u / m->tot_weight;
235  m->secondary[0] = 0;
236  for (i = 0; i < 256; i++) {
237  m->freqs[i] = sum * scale >> 16;
238  sum += m->weights[i];
239  send = m->freqs[i] >> MODEL256_SEC_SCALE;
240  while (sidx <= send)
241  m->secondary[sidx++] = i - 1;
242  }
243  while (sidx < m->sec_size)
244  m->secondary[sidx++] = 255;
245 
246  m->upd_val = m->upd_val * 5 >> 2;
247  if (m->upd_val > m->max_upd_val)
248  m->upd_val = m->max_upd_val;
249  m->till_rescale = m->upd_val;
250 }
251 
252 static void model256_reset(Model256 *m)
253 {
254  int i;
255 
256  for (i = 0; i < 255; i++)
257  m->weights[i] = 1;
258  m->weights[255] = 0;
259 
260  m->tot_weight = 0;
261  m->upd_val = 256;
262  m->till_rescale = 1;
263  model256_update(m, 255);
264  m->till_rescale =
265  m->upd_val = (256 + 6) >> 1;
266 }
267 
269 {
270  m->max_upd_val = 8 * 256 + 48;
271  m->sec_size = (1 << 6) + 2;
272 
273  model256_reset(m);
274 }
275 
276 static void rac_init(RangeCoder *c, const uint8_t *src, int size)
277 {
278  int i;
279 
280  c->src = src;
281  c->src_end = src + size;
282  c->low = 0;
283  for (i = 0; i < FFMIN(size, 4); i++)
284  c->low = (c->low << 8) | *c->src++;
285  c->range = 0xFFFFFFFF;
286  c->got_error = 0;
287 }
288 
290 {
291  for (;;) {
292  c->range <<= 8;
293  c->low <<= 8;
294  if (c->src < c->src_end) {
295  c->low |= *c->src++;
296  } else if (!c->low) {
297  c->got_error = 1;
298  c->low = 1;
299  }
300  if (c->range >= RAC_BOTTOM)
301  return;
302  }
303 }
304 
306 {
307  int bit;
308 
309  c->range >>= 1;
310 
311  bit = (c->range <= c->low);
312  if (bit)
313  c->low -= c->range;
314 
315  if (c->range < RAC_BOTTOM)
316  rac_normalise(c);
317 
318  return bit;
319 }
320 
321 static int rac_get_bits(RangeCoder *c, int nbits)
322 {
323  int val;
324 
325  c->range >>= nbits;
326  val = c->low / c->range;
327  c->low -= c->range * val;
328 
329  if (c->range < RAC_BOTTOM)
330  rac_normalise(c);
331 
332  return val;
333 }
334 
336 {
337  int bit, helper;
338 
339  helper = m->zero_freq * (c->range >> MODEL2_SCALE);
340  bit = (c->low >= helper);
341  if (bit) {
342  c->low -= helper;
343  c->range -= helper;
344  } else {
345  c->range = helper;
346  }
347 
348  if (c->range < RAC_BOTTOM)
349  rac_normalise(c);
350 
351  model2_update(m, bit);
352 
353  return bit;
354 }
355 
357 {
358  int prob, prob2, helper, val;
359  int end, end2;
360 
361  prob = 0;
362  prob2 = c->range;
363  c->range >>= MODEL_SCALE;
364  val = 0;
365  end = m->num_syms >> 1;
366  end2 = m->num_syms;
367  do {
368  helper = m->freqs[end] * c->range;
369  if (helper <= c->low) {
370  val = end;
371  prob = helper;
372  } else {
373  end2 = end;
374  prob2 = helper;
375  }
376  end = (end2 + val) >> 1;
377  } while (end != val);
378  c->low -= prob;
379  c->range = prob2 - prob;
380  if (c->range < RAC_BOTTOM)
381  rac_normalise(c);
382 
383  model_update(m, val);
384 
385  return val;
386 }
387 
389 {
390  int prob, prob2, helper, val;
391  int start, end;
392  int ssym;
393 
394  prob2 = c->range;
395  c->range >>= MODEL_SCALE;
396 
397  helper = c->low / c->range;
398  ssym = helper >> MODEL256_SEC_SCALE;
399  val = m->secondary[ssym];
400 
401  end = start = m->secondary[ssym + 1] + 1;
402  while (end > val + 1) {
403  ssym = (end + val) >> 1;
404  if (m->freqs[ssym] <= helper) {
405  end = start;
406  val = ssym;
407  } else {
408  end = (end + val) >> 1;
409  start = ssym;
410  }
411  }
412  prob = m->freqs[val] * c->range;
413  if (val != 255)
414  prob2 = m->freqs[val + 1] * c->range;
415 
416  c->low -= prob;
417  c->range = prob2 - prob;
418  if (c->range < RAC_BOTTOM)
419  rac_normalise(c);
420 
421  model256_update(m, val);
422 
423  return val;
424 }
425 
427 {
428  bt->last_type = rac_get_model_sym(c, &bt->bt_model[bt->last_type]);
429 
430  return bt->last_type;
431 }
432 
434 {
435  int val, sign;
436 
437  val = rac_get_model_sym(c, m);
438  if (val) {
439  sign = rac_get_bit(c);
440  if (val > 1) {
441  val--;
442  val = (1 << val) + rac_get_bits(c, val);
443  }
444  if (!sign)
445  val = -val;
446  }
447 
448  return val;
449 }
450 
452  uint8_t *dst, int stride, int block_size)
453 {
454  int i;
455 
456  fc->fill_val += decode_coeff(c, &fc->coef_model);
457 
458  for (i = 0; i < block_size; i++, dst += stride)
459  memset(dst, fc->fill_val, block_size);
460 }
461 
463  uint8_t *dst, int stride, int block_size)
464 {
465  int i, j;
466  int vec_size;
467  int vec[4];
468  int prev_line[16];
469  int A, B, C;
470 
471  vec_size = rac_get_model_sym(c, &ic->vec_size_model) + 2;
472  for (i = 0; i < vec_size; i++)
473  vec[i] = rac_get_model256_sym(c, &ic->vec_entry_model);
474  for (; i < 4; i++)
475  vec[i] = 0;
476  memset(prev_line, 0, sizeof(prev_line));
477 
478  for (j = 0; j < block_size; j++) {
479  A = 0;
480  B = 0;
481  for (i = 0; i < block_size; i++) {
482  C = B;
483  B = prev_line[i];
484  A = rac_get_model_sym(c, &ic->vq_model[A + B * 5 + C * 25]);
485 
486  prev_line[i] = A;
487  if (A < 4)
488  dst[i] = vec[A];
489  else
490  dst[i] = rac_get_model256_sym(c, &ic->esc_model);
491  }
492  dst += stride;
493  }
494 }
495 
496 static int decode_dct(RangeCoder *c, DCTBlockCoder *bc, int *block,
497  int bx, int by)
498 {
499  int skip, val, sign, pos = 1, zz_pos, dc;
500  int blk_pos = bx + by * bc->prev_dc_stride;
501 
502  memset(block, 0, sizeof(*block) * 64);
503 
504  dc = decode_coeff(c, &bc->dc_model);
505  if (by) {
506  if (bx) {
507  int l, tl, t;
508 
509  l = bc->prev_dc[blk_pos - 1];
510  tl = bc->prev_dc[blk_pos - 1 - bc->prev_dc_stride];
511  t = bc->prev_dc[blk_pos - bc->prev_dc_stride];
512 
513  if (FFABS(t - tl) <= FFABS(l - tl))
514  dc += l;
515  else
516  dc += t;
517  } else {
518  dc += bc->prev_dc[blk_pos - bc->prev_dc_stride];
519  }
520  } else if (bx) {
521  dc += bc->prev_dc[bx - 1];
522  }
523  bc->prev_dc[blk_pos] = dc;
524  block[0] = dc * bc->qmat[0];
525 
526  while (pos < 64) {
527  val = rac_get_model256_sym(c, &bc->ac_model);
528  if (!val)
529  return 0;
530  if (val == 0xF0) {
531  pos += 16;
532  continue;
533  }
534  skip = val >> 4;
535  val = val & 0xF;
536  if (!val)
537  return -1;
538  pos += skip;
539  if (pos >= 64)
540  return -1;
541 
542  sign = rac_get_model2_sym(c, &bc->sign_model);
543  if (val > 1) {
544  val--;
545  val = (1 << val) + rac_get_bits(c, val);
546  }
547  if (!sign)
548  val = -val;
549 
550  zz_pos = ff_zigzag_direct[pos];
551  block[zz_pos] = val * bc->qmat[zz_pos];
552  pos++;
553  }
554 
555  return pos == 64 ? 0 : -1;
556 }
557 
559  uint8_t *dst, int stride, int block_size,
560  int *block, int mb_x, int mb_y)
561 {
562  int i, j;
563  int bx, by;
564  int nblocks = block_size >> 3;
565 
566  bx = mb_x * nblocks;
567  by = mb_y * nblocks;
568 
569  for (j = 0; j < nblocks; j++) {
570  for (i = 0; i < nblocks; i++) {
571  if (decode_dct(c, bc, block, bx + i, by + j)) {
572  c->got_error = 1;
573  return;
574  }
575  ff_mss34_dct_put(dst + i * 8, stride, block);
576  }
577  dst += 8 * stride;
578  }
579 }
580 
582  uint8_t *dst, int stride, int block_size,
583  int *block)
584 {
585  const int hsize = block_size >> 1;
586  int A, B, C, D, t1, t2, t3, t4;
587  int i, j;
588 
589  for (j = 0; j < block_size; j++) {
590  for (i = 0; i < block_size; i++) {
591  if (i < hsize && j < hsize)
592  block[i] = rac_get_model256_sym(c, &hc->coef_model);
593  else
594  block[i] = decode_coeff(c, &hc->coef_hi_model);
595  block[i] *= hc->scale;
596  }
597  block += block_size;
598  }
599  block -= block_size * block_size;
600 
601  for (j = 0; j < hsize; j++) {
602  for (i = 0; i < hsize; i++) {
603  A = block[i];
604  B = block[i + hsize];
605  C = block[i + hsize * block_size];
606  D = block[i + hsize * block_size + hsize];
607 
608  t1 = A - B;
609  t2 = C - D;
610  t3 = A + B;
611  t4 = C + D;
612  dst[i * 2] = av_clip_uint8(t1 - t2);
613  dst[i * 2 + stride] = av_clip_uint8(t1 + t2);
614  dst[i * 2 + 1] = av_clip_uint8(t3 - t4);
615  dst[i * 2 + 1 + stride] = av_clip_uint8(t3 + t4);
616  }
617  block += block_size;
618  dst += stride * 2;
619  }
620 }
621 
622 static void reset_coders(MSS3Context *ctx, int quality)
623 {
624  int i, j;
625 
626  for (i = 0; i < 3; i++) {
627  ctx->btype[i].last_type = SKIP_BLOCK;
628  for (j = 0; j < 5; j++)
629  model_reset(&ctx->btype[i].bt_model[j]);
630  ctx->fill_coder[i].fill_val = 0;
635  for (j = 0; j < 125; j++)
636  model_reset(&ctx->image_coder[i].vq_model[j]);
637  if (ctx->dct_coder[i].quality != quality) {
638  ctx->dct_coder[i].quality = quality;
639  ff_mss34_gen_quant_mat(ctx->dct_coder[i].qmat, quality, !i);
640  }
641  memset(ctx->dct_coder[i].prev_dc, 0,
642  sizeof(*ctx->dct_coder[i].prev_dc) *
643  ctx->dct_coder[i].prev_dc_stride *
644  ctx->dct_coder[i].prev_dc_height);
645  model_reset(&ctx->dct_coder[i].dc_model);
648  if (ctx->haar_coder[i].quality != quality) {
649  ctx->haar_coder[i].quality = quality;
650  ctx->haar_coder[i].scale = 17 - 7 * quality / 50;
651  }
654  }
655 }
656 
657 static av_cold void init_coders(MSS3Context *ctx)
658 {
659  int i, j;
660 
661  for (i = 0; i < 3; i++) {
662  for (j = 0; j < 5; j++)
663  model_init(&ctx->btype[i].bt_model[j], 5);
664  model_init(&ctx->fill_coder[i].coef_model, 12);
668  for (j = 0; j < 125; j++)
669  model_init(&ctx->image_coder[i].vq_model[j], 5);
670  model_init(&ctx->dct_coder[i].dc_model, 12);
671  model256_init(&ctx->dct_coder[i].ac_model);
672  model_init(&ctx->haar_coder[i].coef_hi_model, 12);
674  }
675 }
676 
677 static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
678  AVPacket *avpkt)
679 {
680  const uint8_t *buf = avpkt->data;
681  int buf_size = avpkt->size;
682  MSS3Context *c = avctx->priv_data;
683  RangeCoder *acoder = &c->coder;
684  GetByteContext gb;
685  uint8_t *dst[3];
686  int dec_width, dec_height, dec_x, dec_y, quality, keyframe;
687  int x, y, i, mb_width, mb_height, blk_size, btype;
688  int ret;
689 
690  if (buf_size < HEADER_SIZE) {
691  av_log(avctx, AV_LOG_ERROR,
692  "Frame should have at least %d bytes, got %d instead\n",
693  HEADER_SIZE, buf_size);
694  return AVERROR_INVALIDDATA;
695  }
696 
697  bytestream2_init(&gb, buf, buf_size);
698  keyframe = bytestream2_get_be32(&gb);
699  if (keyframe & ~0x301) {
700  av_log(avctx, AV_LOG_ERROR, "Invalid frame type %X\n", keyframe);
701  return AVERROR_INVALIDDATA;
702  }
703  keyframe = !(keyframe & 1);
704  bytestream2_skip(&gb, 6);
705  dec_x = bytestream2_get_be16(&gb);
706  dec_y = bytestream2_get_be16(&gb);
707  dec_width = bytestream2_get_be16(&gb);
708  dec_height = bytestream2_get_be16(&gb);
709 
710  if (dec_x + dec_width > avctx->width ||
711  dec_y + dec_height > avctx->height ||
712  (dec_width | dec_height) & 0xF) {
713  av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d +%d,%d\n",
714  dec_width, dec_height, dec_x, dec_y);
715  return AVERROR_INVALIDDATA;
716  }
717  bytestream2_skip(&gb, 4);
718  quality = bytestream2_get_byte(&gb);
719  if (quality < 1 || quality > 100) {
720  av_log(avctx, AV_LOG_ERROR, "Invalid quality setting %d\n", quality);
721  return AVERROR_INVALIDDATA;
722  }
723  bytestream2_skip(&gb, 4);
724 
725  if (keyframe && !bytestream2_get_bytes_left(&gb)) {
726  av_log(avctx, AV_LOG_ERROR, "Keyframe without data found\n");
727  return AVERROR_INVALIDDATA;
728  }
729  if (!keyframe && c->got_error)
730  return buf_size;
731  c->got_error = 0;
732 
733  c->pic.reference = 3;
736  if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
737  av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
738  return ret;
739  }
740  c->pic.key_frame = keyframe;
742  if (!bytestream2_get_bytes_left(&gb)) {
743  *got_frame = 1;
744  *(AVFrame*)data = c->pic;
745 
746  return buf_size;
747  }
748 
749  reset_coders(c, quality);
750 
751  rac_init(acoder, buf + HEADER_SIZE, buf_size - HEADER_SIZE);
752 
753  mb_width = dec_width >> 4;
754  mb_height = dec_height >> 4;
755  dst[0] = c->pic.data[0] + dec_x + dec_y * c->pic.linesize[0];
756  dst[1] = c->pic.data[1] + dec_x / 2 + (dec_y / 2) * c->pic.linesize[1];
757  dst[2] = c->pic.data[2] + dec_x / 2 + (dec_y / 2) * c->pic.linesize[2];
758  for (y = 0; y < mb_height; y++) {
759  for (x = 0; x < mb_width; x++) {
760  for (i = 0; i < 3; i++) {
761  blk_size = 8 << !i;
762 
763  btype = decode_block_type(acoder, c->btype + i);
764  switch (btype) {
765  case FILL_BLOCK:
766  decode_fill_block(acoder, c->fill_coder + i,
767  dst[i] + x * blk_size,
768  c->pic.linesize[i], blk_size);
769  break;
770  case IMAGE_BLOCK:
771  decode_image_block(acoder, c->image_coder + i,
772  dst[i] + x * blk_size,
773  c->pic.linesize[i], blk_size);
774  break;
775  case DCT_BLOCK:
776  decode_dct_block(acoder, c->dct_coder + i,
777  dst[i] + x * blk_size,
778  c->pic.linesize[i], blk_size,
779  c->dctblock, x, y);
780  break;
781  case HAAR_BLOCK:
782  decode_haar_block(acoder, c->haar_coder + i,
783  dst[i] + x * blk_size,
784  c->pic.linesize[i], blk_size,
785  c->hblock);
786  break;
787  }
788  if (c->got_error || acoder->got_error) {
789  av_log(avctx, AV_LOG_ERROR, "Error decoding block %d,%d\n",
790  x, y);
791  c->got_error = 1;
792  return AVERROR_INVALIDDATA;
793  }
794  }
795  }
796  dst[0] += c->pic.linesize[0] * 16;
797  dst[1] += c->pic.linesize[1] * 8;
798  dst[2] += c->pic.linesize[2] * 8;
799  }
800 
801  *got_frame = 1;
802  *(AVFrame*)data = c->pic;
803 
804  return buf_size;
805 }
806 
808 {
809  MSS3Context * const c = avctx->priv_data;
810  int i;
811 
812  c->avctx = avctx;
813 
814  if ((avctx->width & 0xF) || (avctx->height & 0xF)) {
815  av_log(avctx, AV_LOG_ERROR,
816  "Image dimensions should be a multiple of 16.\n");
817  return AVERROR_INVALIDDATA;
818  }
819 
820  c->got_error = 0;
821  for (i = 0; i < 3; i++) {
822  int b_width = avctx->width >> (2 + !!i);
823  int b_height = avctx->height >> (2 + !!i);
824  c->dct_coder[i].prev_dc_stride = b_width;
825  c->dct_coder[i].prev_dc_height = b_height;
826  c->dct_coder[i].prev_dc = av_malloc(sizeof(*c->dct_coder[i].prev_dc) *
827  b_width * b_height);
828  if (!c->dct_coder[i].prev_dc) {
829  av_log(avctx, AV_LOG_ERROR, "Cannot allocate buffer\n");
830  while (i >= 0) {
831  av_freep(&c->dct_coder[i].prev_dc);
832  i--;
833  }
834  return AVERROR(ENOMEM);
835  }
836  }
837 
838  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
839  avctx->coded_frame = &c->pic;
840 
841  init_coders(c);
842 
843  return 0;
844 }
845 
847 {
848  MSS3Context * const c = avctx->priv_data;
849  int i;
850 
851  if (c->pic.data[0])
852  avctx->release_buffer(avctx, &c->pic);
853  for (i = 0; i < 3; i++)
854  av_freep(&c->dct_coder[i].prev_dc);
855 
856  return 0;
857 }
858 
860  .name = "msa1",
861  .type = AVMEDIA_TYPE_VIDEO,
862  .id = AV_CODEC_ID_MSA1,
863  .priv_data_size = sizeof(MSS3Context),
867  .capabilities = CODEC_CAP_DR1,
868  .long_name = NULL_IF_CONFIG_SMALL("MS ATC Screen"),
869 };