FFmpeg
mss4.c
Go to the documentation of this file.
1 /*
2  * Microsoft Screen 4 (aka Microsoft Expression Encoder 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 4 (aka Microsoft Titanium Screen 2,
25  * aka Microsoft Expression Encoder Screen) decoder
26  */
27 
28 #include "libavutil/mem.h"
29 #include "libavutil/thread.h"
30 #include "libavutil/imgutils.h"
31 
32 #include "avcodec.h"
33 #include "bytestream.h"
34 #include "codec_internal.h"
35 #include "decode.h"
36 #include "get_bits.h"
37 #include "jpegtables.h"
38 #include "mss34dsp.h"
39 #include "unary.h"
40 
41 #define HEADER_SIZE 8
42 
43 enum FrameType {
47 };
48 
49 enum BlockType {
53 };
54 
55 enum CachePos {
56  LEFT = 0,
58  TOP,
59 };
60 
61 static const uint8_t mss4_dc_vlc_lens[2][16] = {
62  { 0, 1, 5, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
63  { 0, 3, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0 }
64 };
65 
66 static const uint8_t vec_len_syms[2][4] = {
67  { 4, 2, 3, 1 },
68  { 4, 1, 2, 3 }
69 };
70 
71 static const uint8_t mss4_vec_entry_vlc_lens[2][16] = {
72  { 0, 2, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
73  { 0, 1, 5, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
74 };
75 
76 static const uint8_t mss4_vec_entry_vlc_syms[2][9] = {
77  { 0, 7, 6, 5, 8, 4, 3, 1, 2 },
78  { 0, 2, 3, 4, 5, 6, 7, 1, 8 }
79 };
80 
81 #define MAX_ENTRIES 162
82 
83 typedef struct MSS4Context {
85 
86  int block[64];
87  uint8_t imgbuf[3][16 * 16];
88 
89  int quality;
90  uint16_t quant_mat[2][64];
91 
92  int *prev_dc[3];
93  ptrdiff_t dc_stride[3];
94  int dc_cache[4][4];
95 
96  int prev_vec[3][4];
97 } MSS4Context;
98 
99 static VLC dc_vlc[2], ac_vlc[2];
100 static VLC vec_entry_vlc[2];
101 
102 static av_cold void mss4_init_vlc(VLC *vlc, unsigned *offset,
103  const uint8_t *lens, const uint8_t *syms)
104 {
105  static VLCElem vlc_buf[2146];
106  uint8_t bits[MAX_ENTRIES];
107  int i, j;
108  int idx = 0;
109 
110  for (i = 0; i < 16; i++) {
111  for (j = 0; j < lens[i]; j++) {
112  bits[idx] = i + 1;
113  idx++;
114  }
115  }
116 
117  vlc->table = &vlc_buf[*offset];
118  vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *offset;
119  ff_vlc_init_from_lengths(vlc, FFMIN(bits[idx - 1], 9), idx,
120  bits, 1, syms, 1, 1,
122  *offset += vlc->table_size;
123 }
124 
125 static av_cold void mss4_init_vlcs(void)
126 {
127  for (unsigned i = 0, offset = 0; i < 2; i++) {
136  }
137 }
138 
139 /* This function returns values in the range
140  * (-range + 1; -range/2] U [range/2; range - 1)
141  * i.e.
142  * nbits = 0 -> 0
143  * nbits = 1 -> -1, 1
144  * nbits = 2 -> -3, -2, 2, 3
145  */
147 {
148  int val;
149 
150  if (!nbits)
151  return 0;
152 
153  val = get_bits(gb, nbits);
154  if (val < (1 << (nbits - 1)))
155  val -= (1 << nbits) - 1;
156 
157  return val;
158 }
159 
160 static inline int get_coeff(GetBitContext *gb, const VLC *vlc,
161  int nb_bits, int max_depth)
162 {
163  int val = get_vlc2(gb, vlc->table, nb_bits, max_depth);
164 
165  return get_coeff_bits(gb, val);
166 }
167 
169  int *block, int *dc_cache,
170  int bx, int by, uint16_t *quant_mat)
171 {
172  int skip, val, pos = 1, zz_pos, dc;
173 
174  memset(block, 0, sizeof(*block) * 64);
175 
176  dc = get_coeff(gb, dc_vlc, dc_vlc->bits, 2);
177  // DC prediction is the same as in MSS3
178  if (by) {
179  if (bx) {
180  int l, tl, t;
181 
182  l = dc_cache[LEFT];
183  tl = dc_cache[TOP_LEFT];
184  t = dc_cache[TOP];
185 
186  if (FFABS(t - tl) <= FFABS(l - tl))
187  dc += l;
188  else
189  dc += t;
190  } else {
191  dc += dc_cache[TOP];
192  }
193  } else if (bx) {
194  dc += dc_cache[LEFT];
195  }
196  dc_cache[LEFT] = dc;
197  block[0] = dc * quant_mat[0];
198 
199  while (pos < 64) {
200  val = get_vlc2(gb, ac_vlc->table, 9, 2);
201  if (!val)
202  return 0;
203  if (val == -1)
204  return -1;
205  if (val == 0xF0) {
206  pos += 16;
207  continue;
208  }
209  skip = val >> 4;
210  val = get_coeff_bits(gb, val & 0xF);
211  pos += skip;
212  if (pos >= 64)
213  return -1;
214 
215  zz_pos = ff_zigzag_direct[pos];
216  block[zz_pos] = val * quant_mat[zz_pos];
217  pos++;
218  }
219 
220  return pos == 64 ? 0 : -1;
221 }
222 
224  uint8_t *dst[3], int mb_x, int mb_y)
225 {
226  int i, j, k, ret;
227  uint8_t *out = dst[0];
228 
229  for (j = 0; j < 2; j++) {
230  for (i = 0; i < 2; i++) {
231  int xpos = mb_x * 2 + i;
232  c->dc_cache[j][TOP_LEFT] = c->dc_cache[j][TOP];
233  c->dc_cache[j][TOP] = c->prev_dc[0][mb_x * 2 + i];
234  ret = mss4_decode_dct(gb, &dc_vlc[0], &ac_vlc[0], c->block,
235  c->dc_cache[j],
236  xpos, mb_y * 2 + j, c->quant_mat[0]);
237  if (ret)
238  return ret;
239  c->prev_dc[0][mb_x * 2 + i] = c->dc_cache[j][LEFT];
240 
241  ff_mss34_dct_put(out + xpos * 8, c->pic->linesize[0],
242  c->block);
243  }
244  out += 8 * c->pic->linesize[0];
245  }
246 
247  for (i = 1; i < 3; i++) {
248  c->dc_cache[i + 1][TOP_LEFT] = c->dc_cache[i + 1][TOP];
249  c->dc_cache[i + 1][TOP] = c->prev_dc[i][mb_x];
250  ret = mss4_decode_dct(gb, &dc_vlc[1], &ac_vlc[1],
251  c->block, c->dc_cache[i + 1], mb_x, mb_y,
252  c->quant_mat[1]);
253  if (ret)
254  return ret;
255  c->prev_dc[i][mb_x] = c->dc_cache[i + 1][LEFT];
256 
257  ff_mss34_dct_put(c->imgbuf[i], 8, c->block);
258  out = dst[i] + mb_x * 16;
259  // Since the DCT block is coded as YUV420 and the whole frame as YUV444,
260  // we need to scale chroma.
261  for (j = 0; j < 16; j++) {
262  for (k = 0; k < 8; k++)
263  AV_WN16A(out + k * 2, c->imgbuf[i][k + (j & ~1) * 4] * 0x101);
264  out += c->pic->linesize[i];
265  }
266  }
267 
268  return 0;
269 }
270 
271 static void read_vec_pos(GetBitContext *gb, int *vec_pos, int *sel_flag,
272  int *sel_len, int *prev)
273 {
274  int i, y_flag = 0;
275 
276  for (i = 2; i >= 0; i--) {
277  if (!sel_flag[i]) {
278  vec_pos[i] = 0;
279  continue;
280  }
281  if ((!i && !y_flag) || get_bits1(gb)) {
282  if (sel_len[i] > 0) {
283  int pval = prev[i];
284  vec_pos[i] = get_bits(gb, sel_len[i]);
285  if (vec_pos[i] >= pval)
286  vec_pos[i]++;
287  } else {
288  vec_pos[i] = !prev[i];
289  }
290  y_flag = 1;
291  } else {
292  vec_pos[i] = prev[i];
293  }
294  }
295 }
296 
297 static int get_value_cached(GetBitContext *gb, int vec_pos, uint8_t *vec,
298  int vec_size, int component, int shift, int *prev)
299 {
300  if (vec_pos < vec_size)
301  return vec[vec_pos];
302  if (!get_bits1(gb))
303  return prev[component];
304  prev[component] = get_bits(gb, 8 - shift) << shift;
305  return prev[component];
306 }
307 
308 #define MKVAL(vals) ((vals)[0] | ((vals)[1] << 3) | ((vals)[2] << 6))
309 
310 /* Image mode - the hardest to comprehend MSS4 coding mode.
311  *
312  * In this mode all three 16x16 blocks are coded together with a method
313  * remotely similar to the methods employed in MSS1-MSS3.
314  * The idea is that every component has a vector of 1-4 most common symbols
315  * and an escape mode for reading new value from the bitstream. Decoding
316  * consists of retrieving pixel values from the vector or reading new ones
317  * from the bitstream; depending on flags read from the bitstream, these vector
318  * positions can be updated or reused from the state of the previous line
319  * or previous pixel.
320  */
322  uint8_t *picdst[3], int mb_x, int mb_y)
323 {
324  uint8_t vec[3][4];
325  int vec_len[3];
326  int sel_len[3], sel_flag[3];
327  int i, j, k, mode, split;
328  int prev_vec1 = 0, prev_split = 0;
329  int vals[3] = { 0 };
330  int prev_pix[3] = { 0 };
331  int prev_mode[16] = { 0 };
332  uint8_t *dst[3];
333 
334  const int val_shift = ctx->quality == 100 ? 0 : 2;
335 
336  for (i = 0; i < 3; i++)
337  dst[i] = ctx->imgbuf[i];
338 
339  for (i = 0; i < 3; i++) {
340  vec_len[i] = vec_len_syms[!!i][get_unary(gb, 0, 3)];
341  for (j = 0; j < vec_len[i]; j++) {
342  vec[i][j] = get_coeff(gb, &vec_entry_vlc[!!i], 5, 1);
343  vec[i][j] += ctx->prev_vec[i][j];
344  ctx->prev_vec[i][j] = vec[i][j];
345  }
346  sel_flag[i] = vec_len[i] > 1;
347  sel_len[i] = vec_len[i] > 2 ? vec_len[i] - 2 : 0;
348  }
349 
350  for (j = 0; j < 16; j++) {
351  if (get_bits1(gb)) {
352  split = 0;
353  if (get_bits1(gb)) {
354  prev_mode[0] = 0;
355  vals[0] = vals[1] = vals[2] = 0;
356  mode = 2;
357  } else {
358  mode = get_bits1(gb);
359  if (mode)
360  split = get_bits(gb, 4);
361  }
362  for (i = 0; i < 16; i++) {
363  if (mode <= 1) {
364  vals[0] = prev_mode[i] & 7;
365  vals[1] = (prev_mode[i] >> 3) & 7;
366  vals[2] = prev_mode[i] >> 6;
367  if (mode == 1 && i == split) {
368  read_vec_pos(gb, vals, sel_flag, sel_len, vals);
369  }
370  } else if (mode == 2) {
371  if (get_bits1(gb))
372  read_vec_pos(gb, vals, sel_flag, sel_len, vals);
373  }
374  for (k = 0; k < 3; k++)
375  *dst[k]++ = get_value_cached(gb, vals[k], vec[k],
376  vec_len[k], k,
377  val_shift, prev_pix);
378  prev_mode[i] = MKVAL(vals);
379  }
380  } else {
381  if (get_bits1(gb)) {
382  split = get_bits(gb, 4);
383  if (split >= prev_split)
384  split++;
385  prev_split = split;
386  } else {
387  split = prev_split;
388  }
389  if (split) {
390  vals[0] = prev_mode[0] & 7;
391  vals[1] = (prev_mode[0] >> 3) & 7;
392  vals[2] = prev_mode[0] >> 6;
393  for (i = 0; i < 3; i++) {
394  for (k = 0; k < split; k++) {
395  *dst[i]++ = get_value_cached(gb, vals[i], vec[i],
396  vec_len[i], i, val_shift,
397  prev_pix);
398  prev_mode[k] = MKVAL(vals);
399  }
400  }
401  }
402 
403  if (split != 16) {
404  vals[0] = prev_vec1 & 7;
405  vals[1] = (prev_vec1 >> 3) & 7;
406  vals[2] = prev_vec1 >> 6;
407  if (get_bits1(gb)) {
408  read_vec_pos(gb, vals, sel_flag, sel_len, vals);
409  prev_vec1 = MKVAL(vals);
410  }
411  for (i = 0; i < 3; i++) {
412  for (k = 0; k < 16 - split; k++) {
413  *dst[i]++ = get_value_cached(gb, vals[i], vec[i],
414  vec_len[i], i, val_shift,
415  prev_pix);
416  prev_mode[split + k] = MKVAL(vals);
417  }
418  }
419  }
420  }
421  }
422 
423  for (i = 0; i < 3; i++)
424  for (j = 0; j < 16; j++)
425  memcpy(picdst[i] + mb_x * 16 + j * ctx->pic->linesize[i],
426  ctx->imgbuf[i] + j * 16, 16);
427 
428  return 0;
429 }
430 
431 static inline void mss4_update_dc_cache(MSS4Context *c, int mb_x)
432 {
433  int i;
434 
435  c->dc_cache[0][TOP] = c->prev_dc[0][mb_x * 2 + 1];
436  c->dc_cache[0][LEFT] = 0;
437  c->dc_cache[1][TOP] = 0;
438  c->dc_cache[1][LEFT] = 0;
439 
440  for (i = 0; i < 2; i++)
441  c->prev_dc[0][mb_x * 2 + i] = 0;
442 
443  for (i = 1; i < 3; i++) {
444  c->dc_cache[i + 1][TOP] = c->prev_dc[i][mb_x];
445  c->dc_cache[i + 1][LEFT] = 0;
446  c->prev_dc[i][mb_x] = 0;
447  }
448 }
449 
450 static int mss4_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
451  int *got_frame, AVPacket *avpkt)
452 {
453  const uint8_t *buf = avpkt->data;
454  int buf_size = avpkt->size;
455  MSS4Context *c = avctx->priv_data;
456  GetBitContext gb;
457  GetByteContext bc;
458  uint8_t *dst[3];
460  int x, y, i, mb_width, mb_height, blk_type;
461  int ret;
462 
463  if (buf_size < HEADER_SIZE) {
464  av_log(avctx, AV_LOG_ERROR,
465  "Frame should have at least %d bytes, got %d instead\n",
466  HEADER_SIZE, buf_size);
467  return AVERROR_INVALIDDATA;
468  }
469 
470  bytestream2_init(&bc, buf, buf_size);
471  width = bytestream2_get_be16(&bc);
472  height = bytestream2_get_be16(&bc);
473  bytestream2_skip(&bc, 2);
474  quality = bytestream2_get_byte(&bc);
475  frame_type = bytestream2_get_byte(&bc);
476 
477  if (width > avctx->width ||
478  height != avctx->height) {
479  av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d\n",
480  width, height);
481  return AVERROR_INVALIDDATA;
482  }
483  if (av_image_check_size2(width, height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0)
484  return AVERROR_INVALIDDATA;
485 
486  if (quality < 1 || quality > 100) {
487  av_log(avctx, AV_LOG_ERROR, "Invalid quality setting %d\n", quality);
488  return AVERROR_INVALIDDATA;
489  }
490  if ((frame_type & ~3) || frame_type == 3) {
491  av_log(avctx, AV_LOG_ERROR, "Invalid frame type %d\n", frame_type);
492  return AVERROR_INVALIDDATA;
493  }
494 
496  av_log(avctx, AV_LOG_ERROR,
497  "Empty frame found but it is not a skip frame.\n");
498  return AVERROR_INVALIDDATA;
499  }
500  mb_width = FFALIGN(width, 16) >> 4;
501  mb_height = FFALIGN(height, 16) >> 4;
502 
503  if (frame_type != SKIP_FRAME && 8*buf_size < 8*HEADER_SIZE + mb_width*mb_height)
504  return AVERROR_INVALIDDATA;
505 
506  if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0)
507  return ret;
508  if (frame_type == INTRA_FRAME)
509  c->pic->flags |= AV_FRAME_FLAG_KEY;
510  else
511  c->pic->flags &= ~AV_FRAME_FLAG_KEY;
512  c->pic->pict_type = (frame_type == INTRA_FRAME) ? AV_PICTURE_TYPE_I
514  if (frame_type == SKIP_FRAME) {
515  *got_frame = 1;
516  if ((ret = av_frame_ref(rframe, c->pic)) < 0)
517  return ret;
518 
519  return buf_size;
520  }
521 
522  if (c->quality != quality) {
523  c->quality = quality;
524  for (i = 0; i < 2; i++)
525  ff_mss34_gen_quant_mat(c->quant_mat[i], quality, !i);
526  }
527 
528  if ((ret = init_get_bits8(&gb, buf + HEADER_SIZE, buf_size - HEADER_SIZE)) < 0)
529  return ret;
530  dst[0] = c->pic->data[0];
531  dst[1] = c->pic->data[1];
532  dst[2] = c->pic->data[2];
533 
534  memset(c->prev_vec, 0, sizeof(c->prev_vec));
535  for (y = 0; y < mb_height; y++) {
536  memset(c->dc_cache, 0, sizeof(c->dc_cache));
537  for (x = 0; x < mb_width; x++) {
538  blk_type = decode012(&gb);
539  switch (blk_type) {
540  case DCT_BLOCK:
541  if (mss4_decode_dct_block(c, &gb, dst, x, y) < 0) {
542  av_log(avctx, AV_LOG_ERROR,
543  "Error decoding DCT block %d,%d\n",
544  x, y);
545  return AVERROR_INVALIDDATA;
546  }
547  break;
548  case IMAGE_BLOCK:
549  if (mss4_decode_image_block(c, &gb, dst, x, y) < 0) {
550  av_log(avctx, AV_LOG_ERROR,
551  "Error decoding VQ block %d,%d\n",
552  x, y);
553  return AVERROR_INVALIDDATA;
554  }
555  break;
556  case SKIP_BLOCK:
557  if (frame_type == INTRA_FRAME) {
558  av_log(avctx, AV_LOG_ERROR, "Skip block in intra frame\n");
559  return AVERROR_INVALIDDATA;
560  }
561  break;
562  }
563  if (blk_type != DCT_BLOCK)
565  }
566  dst[0] += c->pic->linesize[0] * 16;
567  dst[1] += c->pic->linesize[1] * 16;
568  dst[2] += c->pic->linesize[2] * 16;
569  }
570 
571  if ((ret = av_frame_ref(rframe, c->pic)) < 0)
572  return ret;
573 
574  *got_frame = 1;
575 
576  return buf_size;
577 }
578 
580 {
581  MSS4Context * const c = avctx->priv_data;
582  int i;
583 
584  av_frame_free(&c->pic);
585  for (i = 0; i < 3; i++)
586  av_freep(&c->prev_dc[i]);
587 
588  return 0;
589 }
590 
592 {
593  static AVOnce init_static_once = AV_ONCE_INIT;
594  MSS4Context * const c = avctx->priv_data;
595  int i;
596 
597  for (i = 0; i < 3; i++) {
598  c->dc_stride[i] = FFALIGN(avctx->width, 16) >> (2 + !!i);
599  c->prev_dc[i] = av_malloc_array(c->dc_stride[i], sizeof(**c->prev_dc));
600  if (!c->prev_dc[i]) {
601  av_log(avctx, AV_LOG_ERROR, "Cannot allocate buffer\n");
602  return AVERROR(ENOMEM);
603  }
604  }
605 
606  c->pic = av_frame_alloc();
607  if (!c->pic)
608  return AVERROR(ENOMEM);
609 
610  avctx->pix_fmt = AV_PIX_FMT_YUV444P;
611 
612  ff_thread_once(&init_static_once, mss4_init_vlcs);
613 
614  return 0;
615 }
616 
618  .p.name = "mts2",
619  CODEC_LONG_NAME("MS Expression Encoder Screen"),
620  .p.type = AVMEDIA_TYPE_VIDEO,
621  .p.id = AV_CODEC_ID_MTS2,
622  .priv_data_size = sizeof(MSS4Context),
624  .close = mss4_decode_end,
626  .p.capabilities = AV_CODEC_CAP_DR1,
627  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
628 };
ff_mss34_gen_quant_mat
void ff_mss34_gen_quant_mat(uint16_t *qmat, int quality, int luma)
Generate quantisation matrix for given quality.
Definition: mss34dsp.c:27
ff_mts2_decoder
const FFCodec ff_mts2_decoder
Definition: mss4.c:617
ff_vlc_init_from_lengths
int ff_vlc_init_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:306
jpegtables.h
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:43
ac_vlc
static VLC ac_vlc[2]
Definition: mss4.c:99
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
MSS4Context
Definition: mss4.c:83
MSS4Context::prev_dc
int * prev_dc[3]
Definition: mss4.c:92
out
FILE * out
Definition: movenc.c:55
GetByteContext
Definition: bytestream.h:33
thread.h
MKVAL
#define MKVAL(vals)
Definition: mss4.c:308
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:162
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
AVPacket::data
uint8_t * data
Definition: packet.h:539
mss4_dc_vlc_lens
static const uint8_t mss4_dc_vlc_lens[2][16]
Definition: mss4.c:61
BlockType
BlockType
Definition: mss3.c:70
FFCodec
Definition: codec_internal.h:127
get_coeff_bits
static av_always_inline int get_coeff_bits(GetBitContext *gb, int nbits)
Definition: mss4.c:146
mss4_decode_frame
static int mss4_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt)
Definition: mss4.c:450
ff_mjpeg_bits_ac_chrominance
const uint8_t ff_mjpeg_bits_ac_chrominance[]
Definition: jpegtabs.h:66
DCT_BLOCK
@ DCT_BLOCK
Definition: mss4.c:51
quality
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about quality
Definition: rate_distortion.txt:12
SKIP_FRAME
@ SKIP_FRAME
Definition: mss4.c:46
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:335
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
GetBitContext
Definition: get_bits.h:108
mss4_decode_end
static av_cold int mss4_decode_end(AVCodecContext *avctx)
Definition: mss4.c:579
val
static double val(void *priv, double ch)
Definition: aeval.c:77
av_image_check_size2
int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of a plane of an image with...
Definition: imgutils.c:289
mss4_decode_dct_block
static int mss4_decode_dct_block(MSS4Context *c, GetBitContext *gb, uint8_t *dst[3], int mb_x, int mb_y)
Definition: mss4.c:223
INTRA_FRAME
@ INTRA_FRAME
Definition: mss4.c:44
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:150
ff_thread_once
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:205
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
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:545
mss4_decode_dct
static int mss4_decode_dct(GetBitContext *gb, VLC *dc_vlc, VLC *ac_vlc, int *block, int *dc_cache, int bx, int by, uint16_t *quant_mat)
Definition: mss4.c:168
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:640
mss4_init_vlcs
static av_cold void mss4_init_vlcs(void)
Definition: mss4.c:125
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:311
read_vec_pos
static void read_vec_pos(GetBitContext *gb, int *vec_pos, int *sel_flag, int *sel_len, int *prev)
Definition: mss4.c:271
SKIP_BLOCK
@ SKIP_BLOCK
Definition: mss4.c:50
get_coeff
static int get_coeff(GetBitContext *gb, const VLC *vlc, int nb_bits, int max_depth)
Definition: mss4.c:160
bits
uint8_t bits
Definition: vp3data.h:128
LEFT
@ LEFT
Definition: mss4.c:56
mss4_vec_entry_vlc_syms
static const uint8_t mss4_vec_entry_vlc_syms[2][9]
Definition: mss4.c:76
ctx
AVFormatContext * ctx
Definition: movenc.c:49
decode.h
get_bits.h
AV_WN16A
#define AV_WN16A(p, v)
Definition: intreadwrite.h:530
AVCodecContext::max_pixels
int64_t max_pixels
The number of pixels per image to maximally accept.
Definition: avcodec.h:1945
mss4_decode_image_block
static int mss4_decode_image_block(MSS4Context *ctx, GetBitContext *gb, uint8_t *picdst[3], int mb_x, int mb_y)
Definition: mss4.c:321
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:296
FrameType
FrameType
G723.1 frame types.
Definition: g723_1.h:63
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
IMAGE_BLOCK
@ IMAGE_BLOCK
Definition: mss4.c:52
AV_ONCE_INIT
#define AV_ONCE_INIT
Definition: thread.h:203
NULL
#define NULL
Definition: coverity.c:32
MSS4Context::pic
AVFrame * pic
Definition: mss4.c:84
INTER_FRAME
@ INTER_FRAME
Definition: mss4.c:45
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:388
vec_entry_vlc
static VLC vec_entry_vlc[2]
Definition: mss4.c:100
mss4_vec_entry_vlc_lens
static const uint8_t mss4_vec_entry_vlc_lens[2][16]
Definition: mss4.c:71
ff_mjpeg_val_ac_chrominance
const uint8_t ff_mjpeg_val_ac_chrominance[]
Definition: jpegtabs.h:69
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:652
AVOnce
#define AVOnce
Definition: thread.h:202
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
get_unary
static int get_unary(GetBitContext *gb, int stop, int len)
Get unary code of limited length.
Definition: unary.h:46
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
mss34dsp.h
VLC::table_allocated
int table_allocated
Definition: vlc.h:39
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
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
ff_mjpeg_val_ac_luminance
const uint8_t ff_mjpeg_val_ac_luminance[]
Definition: jpegtabs.h:42
AVPacket::size
int size
Definition: packet.h:540
dc
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff) *mv_scale Intra DC Prediction block[y][x] dc[1]
Definition: snow.txt:400
height
#define height
Definition: dsp.h:85
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:388
MSS4Context::prev_vec
int prev_vec[3][4]
Definition: mss4.c:96
codec_internal.h
get_value_cached
static int get_value_cached(GetBitContext *gb, int vec_pos, uint8_t *vec, int vec_size, int component, int shift, int *prev)
Definition: mss4.c:297
shift
static int shift(int a, int b)
Definition: bonk.c:261
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
ff_mjpeg_bits_ac_luminance
const uint8_t ff_mjpeg_bits_ac_luminance[]
Definition: jpegtabs.h:40
VLCElem
Definition: vlc.h:32
MAX_ENTRIES
#define MAX_ENTRIES
Definition: mss4.c:81
split
static char * split(char *message, char delim)
Definition: af_channelmap.c:89
mss4_init_vlc
static av_cold void mss4_init_vlc(VLC *vlc, unsigned *offset, const uint8_t *lens, const uint8_t *syms)
Definition: mss4.c:102
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
MSS4Context::quality
int quality
Definition: mss4.c:89
unary.h
HEADER_SIZE
#define HEADER_SIZE
Definition: mss4.c:41
MSS4Context::dc_cache
int dc_cache[4][4]
Definition: mss4.c:94
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
frame_type
frame_type
Definition: jpeg2000_parser.c:31
AV_CODEC_ID_MTS2
@ AV_CODEC_ID_MTS2
Definition: codec_id.h:219
decode012
static int BS_FUNC() decode012(BSCTX *bc)
Return decoded truncated unary code for the values 0, 1, 2.
Definition: bitstream_template.h:436
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
MSS4Context::dc_stride
ptrdiff_t dc_stride[3]
Definition: mss4.c:93
dc_vlc
static VLC dc_vlc[2]
Definition: mss4.c:99
AVCodecContext::height
int height
Definition: avcodec.h:624
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:663
MSS4Context::quant_mat
uint16_t quant_mat[2][64]
Definition: mss4.c:90
avcodec.h
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
VLC::bits
int bits
Definition: vlc.h:37
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:1815
ret
ret
Definition: filter_design.txt:187
pos
unsigned int pos
Definition: spdifenc.c:414
vec_len_syms
static const uint8_t vec_len_syms[2][4]
Definition: mss4.c:66
AVCodecContext
main external API structure.
Definition: avcodec.h:451
VLC_INIT_STATIC_OVERLONG
#define VLC_INIT_STATIC_OVERLONG
Definition: vlc.h:183
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
TOP_LEFT
@ TOP_LEFT
Definition: mss4.c:57
VLC
Definition: vlc.h:36
MSS4Context::imgbuf
uint8_t imgbuf[3][16 *16]
Definition: mss4.c:87
mss4_update_dc_cache
static void mss4_update_dc_cache(MSS4Context *c, int mb_x)
Definition: mss4.c:431
VLC::table
VLCElem * table
Definition: vlc.h:38
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
VLC::table_size
int table_size
Definition: vlc.h:39
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:280
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
TOP
@ TOP
Definition: mss4.c:58
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:478
AVPacket
This structure stores compressed data.
Definition: packet.h:516
MSS4Context::block
int block[64]
Definition: mss4.c:86
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:624
bytestream.h
imgutils.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
width
#define width
Definition: dsp.h:85
ff_mss34_dct_put
void ff_mss34_dct_put(uint8_t *dst, ptrdiff_t stride, int *block)
Transform and output DCT block.
Definition: mss34dsp.c:69
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:375
mss4_decode_init
static av_cold int mss4_decode_init(AVCodecContext *avctx)
Definition: mss4.c:591
CachePos
CachePos
Definition: mss4.c:55