FFmpeg
vmnc.c
Go to the documentation of this file.
1 /*
2  * VMware Screen Codec (VMnc) decoder
3  * Copyright (c) 2006 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  * VMware Screen Codec (VMnc) decoder
25  * As Alex Beregszaszi discovered, this is effectively RFB data dump
26  */
27 
28 #include "libavutil/common.h"
29 #include "avcodec.h"
30 #include "codec_internal.h"
31 #include "decode.h"
32 #include "bytestream.h"
33 
34 enum EncTypes {
35  MAGIC_WMVd = 0x574D5664,
42 };
43 
45  HT_RAW = 1, // tile is raw
46  HT_BKG = 2, // background color is present
47  HT_FG = 4, // foreground color is present
48  HT_SUB = 8, // subrects are present
49  HT_CLR = 16 // each subrect has own color
50 };
51 
52 /*
53  * Decoder context
54  */
55 typedef struct VmncContext {
58 
59  int bpp;
60  int bpp2;
61  int bigendian;
62  uint8_t pal[768];
63  int width, height;
65 
66  /* cursor data */
67  int cur_w, cur_h;
68  int cur_x, cur_y;
69  int cur_hx, cur_hy;
70  uint8_t *curbits, *curmask;
71  uint8_t *screendta;
72 } VmncContext;
73 
74 /* read pixel value from stream */
75 static av_always_inline int vmnc_get_pixel(GetByteContext *gb, int bpp, int be)
76 {
77  switch (bpp * 2 + be) {
78  case 2:
79  case 3:
80  return bytestream2_get_byte(gb);
81  case 4:
82  return bytestream2_get_le16(gb);
83  case 5:
84  return bytestream2_get_be16(gb);
85  case 8:
86  return bytestream2_get_le32(gb);
87  case 9:
88  return bytestream2_get_be32(gb);
89  default: return 0;
90  }
91 }
92 
93 static void load_cursor(VmncContext *c)
94 {
95  int i, j, p;
96  const int bpp = c->bpp2;
97  uint8_t *dst8 = c->curbits;
98  uint16_t *dst16 = (uint16_t *)c->curbits;
99  uint32_t *dst32 = (uint32_t *)c->curbits;
100 
101  for (j = 0; j < c->cur_h; j++) {
102  for (i = 0; i < c->cur_w; i++) {
103  p = vmnc_get_pixel(&c->gb, bpp, c->bigendian);
104  if (bpp == 1)
105  *dst8++ = p;
106  if (bpp == 2)
107  *dst16++ = p;
108  if (bpp == 4)
109  *dst32++ = p;
110  }
111  }
112  dst8 = c->curmask;
113  dst16 = (uint16_t*)c->curmask;
114  dst32 = (uint32_t*)c->curmask;
115  for (j = 0; j < c->cur_h; j++) {
116  for (i = 0; i < c->cur_w; i++) {
117  p = vmnc_get_pixel(&c->gb, bpp, c->bigendian);
118  if (bpp == 1)
119  *dst8++ = p;
120  if (bpp == 2)
121  *dst16++ = p;
122  if (bpp == 4)
123  *dst32++ = p;
124  }
125  }
126 }
127 
128 static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy)
129 {
130  int i, j;
131  int w, h, x, y;
132  w = c->cur_w;
133  if (c->width < c->cur_x + c->cur_w)
134  w = c->width - c->cur_x;
135  h = c->cur_h;
136  if (c->height < c->cur_y + c->cur_h)
137  h = c->height - c->cur_y;
138  x = c->cur_x;
139  y = c->cur_y;
140  if (x < 0) {
141  w += x;
142  x = 0;
143  }
144  if (y < 0) {
145  h += y;
146  y = 0;
147  }
148 
149  if ((w < 1) || (h < 1))
150  return;
151  dst += x * c->bpp2 + y * stride;
152 
153  if (c->bpp2 == 1) {
154  uint8_t *cd = c->curbits, *msk = c->curmask;
155  for (j = 0; j < h; j++) {
156  for (i = 0; i < w; i++)
157  dst[i] = (dst[i] & cd[i]) ^ msk[i];
158  msk += c->cur_w;
159  cd += c->cur_w;
160  dst += stride;
161  }
162  } else if (c->bpp2 == 2) {
163  uint16_t *cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask;
164  uint16_t *dst2;
165  for (j = 0; j < h; j++) {
166  dst2 = (uint16_t*)dst;
167  for (i = 0; i < w; i++)
168  dst2[i] = (dst2[i] & cd[i]) ^ msk[i];
169  msk += c->cur_w;
170  cd += c->cur_w;
171  dst += stride;
172  }
173  } else if (c->bpp2 == 4) {
174  uint32_t *cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask;
175  uint32_t *dst2;
176  for (j = 0; j < h; j++) {
177  dst2 = (uint32_t*)dst;
178  for (i = 0; i < w; i++)
179  dst2[i] = (dst2[i] & cd[i]) ^ msk[i];
180  msk += c->cur_w;
181  cd += c->cur_w;
182  dst += stride;
183  }
184  }
185 }
186 
187 /* fill rectangle with given color */
188 static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy,
189  int w, int h, int color,
190  int bpp, int stride)
191 {
192  int i, j;
193  dst += dx * bpp + dy * stride;
194  if (bpp == 1) {
195  for (j = 0; j < h; j++) {
196  memset(dst, color, w);
197  dst += stride;
198  }
199  } else if (bpp == 2) {
200  uint16_t *dst2;
201  for (j = 0; j < h; j++) {
202  dst2 = (uint16_t*)dst;
203  for (i = 0; i < w; i++)
204  *dst2++ = color;
205  dst += stride;
206  }
207  } else if (bpp == 4) {
208  uint32_t *dst2;
209  for (j = 0; j < h; j++) {
210  dst2 = (uint32_t*)dst;
211  for (i = 0; i < w; i++)
212  dst2[i] = color;
213  dst += stride;
214  }
215  }
216 }
217 
218 static av_always_inline void paint_raw(uint8_t *dst, int w, int h,
219  GetByteContext *gb, int bpp,
220  int be, int stride)
221 {
222  int i, j, p;
223  for (j = 0; j < h; j++) {
224  for (i = 0; i < w; i++) {
225  p = vmnc_get_pixel(gb, bpp, be);
226  switch (bpp) {
227  case 1:
228  dst[i] = p;
229  break;
230  case 2:
231  ((uint16_t*)dst)[i] = p;
232  break;
233  case 4:
234  ((uint32_t*)dst)[i] = p;
235  break;
236  }
237  }
238  dst += stride;
239  }
240 }
241 
242 static int decode_hextile(VmncContext *c, uint8_t* dst, GetByteContext *gb,
243  int w, int h, int stride)
244 {
245  int i, j, k;
246  int bg = 0, fg = 0, rects, color, flags, xy, wh;
247  const int bpp = c->bpp2;
248  uint8_t *dst2;
249  int bw = 16, bh = 16;
250 
251  for (j = 0; j < h; j += 16) {
252  dst2 = dst;
253  bw = 16;
254  if (j + 16 > h)
255  bh = h - j;
256  for (i = 0; i < w; i += 16, dst2 += 16 * bpp) {
257  if (bytestream2_get_bytes_left(gb) <= 0) {
258  av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
259  return AVERROR_INVALIDDATA;
260  }
261  if (i + 16 > w)
262  bw = w - i;
263  flags = bytestream2_get_byte(gb);
264  if (flags & HT_RAW) {
265  if (bytestream2_get_bytes_left(gb) < bw * bh * bpp) {
266  av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
267  return AVERROR_INVALIDDATA;
268  }
269  paint_raw(dst2, bw, bh, gb, bpp, c->bigendian, stride);
270  } else {
271  if (flags & HT_BKG)
272  bg = vmnc_get_pixel(gb, bpp, c->bigendian);
273  if (flags & HT_FG)
274  fg = vmnc_get_pixel(gb, bpp, c->bigendian);
275  rects = 0;
276  if (flags & HT_SUB)
277  rects = bytestream2_get_byte(gb);
278  color = !!(flags & HT_CLR);
279 
280  paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride);
281 
282  if (bytestream2_get_bytes_left(gb) < rects * (color * bpp + 2)) {
283  av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
284  return AVERROR_INVALIDDATA;
285  }
286  for (k = 0; k < rects; k++) {
287  int rect_x, rect_y, rect_w, rect_h;
288  if (color)
289  fg = vmnc_get_pixel(gb, bpp, c->bigendian);
290  xy = bytestream2_get_byte(gb);
291  wh = bytestream2_get_byte(gb);
292 
293  rect_x = xy >> 4;
294  rect_y = xy & 0xF;
295  rect_w = (wh >> 4) + 1;
296  rect_h = (wh & 0xF) + 1;
297 
298  if (rect_x + rect_w > w - i || rect_y + rect_h > h - j) {
299  av_log(c->avctx, AV_LOG_ERROR, "Rectangle outside picture\n");
300  return AVERROR_INVALIDDATA;
301  }
302 
303  paint_rect(dst2, rect_x, rect_y,
304  rect_w, rect_h, fg, bpp, stride);
305  }
306  }
307  }
308  dst += stride * 16;
309  }
310  return 0;
311 }
312 
314 {
315  av_freep(&c->curbits);
316  av_freep(&c->curmask);
317  av_freep(&c->screendta);
318  c->cur_w = c->cur_h = 0;
319  c->cur_hx = c->cur_hy = 0;
320 
321 }
322 
323 static int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
324  int *got_frame, AVPacket *avpkt)
325 {
326  const uint8_t *buf = avpkt->data;
327  int buf_size = avpkt->size;
328  VmncContext * const c = avctx->priv_data;
329  GetByteContext *gb = &c->gb;
330  uint8_t *outptr;
331  int dx, dy, w, h, depth, enc, chunks, res, size_left, ret;
332 
333  bytestream2_init(gb, buf, buf_size);
334  bytestream2_skip(gb, 2);
335  chunks = bytestream2_get_be16(gb);
336  if (12LL * chunks > bytestream2_get_bytes_left(gb))
337  return AVERROR_INVALIDDATA;
338 
339  if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0)
340  return ret;
341 
342  c->pic->key_frame = 0;
343  c->pic->pict_type = AV_PICTURE_TYPE_P;
344 
345  // restore screen after cursor
346  if (c->screendta) {
347  int i;
348  w = c->cur_w;
349  if (c->width < c->cur_x + w)
350  w = c->width - c->cur_x;
351  h = c->cur_h;
352  if (c->height < c->cur_y + h)
353  h = c->height - c->cur_y;
354  dx = c->cur_x;
355  if (dx < 0) {
356  w += dx;
357  dx = 0;
358  }
359  dy = c->cur_y;
360  if (dy < 0) {
361  h += dy;
362  dy = 0;
363  }
364  if ((w > 0) && (h > 0)) {
365  outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
366  for (i = 0; i < h; i++) {
367  memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2,
368  w * c->bpp2);
369  outptr += c->pic->linesize[0];
370  }
371  }
372  }
373 
374  while (chunks--) {
375  if (bytestream2_get_bytes_left(gb) < 12) {
376  av_log(avctx, AV_LOG_ERROR, "Premature end of data!\n");
377  return -1;
378  }
379  dx = bytestream2_get_be16(gb);
380  dy = bytestream2_get_be16(gb);
381  w = bytestream2_get_be16(gb);
382  h = bytestream2_get_be16(gb);
383  enc = bytestream2_get_be32(gb);
384  if ((dx + w > c->width) || (dy + h > c->height)) {
385  av_log(avctx, AV_LOG_ERROR,
386  "Incorrect frame size: %ix%i+%ix%i of %ix%i\n",
387  w, h, dx, dy, c->width, c->height);
388  return AVERROR_INVALIDDATA;
389  }
390  outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
391  size_left = bytestream2_get_bytes_left(gb);
392  switch (enc) {
393  case MAGIC_WMVd: // cursor
394  if (w*(int64_t)h*c->bpp2 > INT_MAX/2 - 2) {
395  av_log(avctx, AV_LOG_ERROR, "dimensions too large\n");
396  return AVERROR_INVALIDDATA;
397  }
398  if (size_left < 2 + w * h * c->bpp2 * 2) {
399  av_log(avctx, AV_LOG_ERROR,
400  "Premature end of data! (need %i got %i)\n",
401  2 + w * h * c->bpp2 * 2, size_left);
402  return AVERROR_INVALIDDATA;
403  }
404  bytestream2_skip(gb, 2);
405  c->cur_w = w;
406  c->cur_h = h;
407  c->cur_hx = dx;
408  c->cur_hy = dy;
409  if ((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) {
410  av_log(avctx, AV_LOG_ERROR,
411  "Cursor hot spot is not in image: "
412  "%ix%i of %ix%i cursor size\n",
413  c->cur_hx, c->cur_hy, c->cur_w, c->cur_h);
414  c->cur_hx = c->cur_hy = 0;
415  }
416  if (c->cur_w * c->cur_h >= INT_MAX / c->bpp2) {
417  reset_buffers(c);
418  return AVERROR(EINVAL);
419  } else {
420  int screen_size = c->cur_w * c->cur_h * c->bpp2;
421  if ((ret = av_reallocp(&c->curbits, screen_size)) < 0 ||
422  (ret = av_reallocp(&c->curmask, screen_size)) < 0 ||
423  (ret = av_reallocp(&c->screendta, screen_size)) < 0) {
424  reset_buffers(c);
425  return ret;
426  }
427  }
428  load_cursor(c);
429  break;
430  case MAGIC_WMVe: // unknown
431  bytestream2_skip(gb, 2);
432  break;
433  case MAGIC_WMVf: // update cursor position
434  c->cur_x = dx - c->cur_hx;
435  c->cur_y = dy - c->cur_hy;
436  break;
437  case MAGIC_WMVg: // unknown
438  bytestream2_skip(gb, 10);
439  break;
440  case MAGIC_WMVh: // unknown
441  bytestream2_skip(gb, 4);
442  break;
443  case MAGIC_WMVi: // ServerInitialization struct
444  c->pic->key_frame = 1;
445  c->pic->pict_type = AV_PICTURE_TYPE_I;
446  depth = bytestream2_get_byte(gb);
447  if (depth != c->bpp) {
448  av_log(avctx, AV_LOG_INFO,
449  "Depth mismatch. Container %i bpp, "
450  "Frame data: %i bpp\n",
451  c->bpp, depth);
452  }
453  bytestream2_skip(gb, 1);
454  c->bigendian = bytestream2_get_byte(gb);
455  if (c->bigendian & (~1)) {
456  av_log(avctx, AV_LOG_INFO,
457  "Invalid header: bigendian flag = %i\n", c->bigendian);
458  return AVERROR_INVALIDDATA;
459  }
460  //skip the rest of pixel format data
461  bytestream2_skip(gb, 13);
462  break;
463  case MAGIC_WMVj: // unknown
464  bytestream2_skip(gb, 2);
465  break;
466  case 0x00000000: // raw rectangle data
467  if (size_left < w * h * c->bpp2) {
468  av_log(avctx, AV_LOG_ERROR,
469  "Premature end of data! (need %i got %i)\n",
470  w * h * c->bpp2, size_left);
471  return AVERROR_INVALIDDATA;
472  }
473  paint_raw(outptr, w, h, gb, c->bpp2, c->bigendian,
474  c->pic->linesize[0]);
475  break;
476  case 0x00000005: // HexTile encoded rectangle
477  res = decode_hextile(c, outptr, gb, w, h, c->pic->linesize[0]);
478  if (res < 0)
479  return res;
480  break;
481  default:
482  av_log(avctx, AV_LOG_ERROR, "Unsupported block type 0x%08X\n", enc);
483  chunks = 0; // leave chunks decoding loop
484  }
485  }
486  if (c->screendta) {
487  int i;
488  // save screen data before painting cursor
489  w = c->cur_w;
490  if (c->width < c->cur_x + w)
491  w = c->width - c->cur_x;
492  h = c->cur_h;
493  if (c->height < c->cur_y + h)
494  h = c->height - c->cur_y;
495  dx = c->cur_x;
496  if (dx < 0) {
497  w += dx;
498  dx = 0;
499  }
500  dy = c->cur_y;
501  if (dy < 0) {
502  h += dy;
503  dy = 0;
504  }
505  if ((w > 0) && (h > 0)) {
506  outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
507  for (i = 0; i < h; i++) {
508  memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr,
509  w * c->bpp2);
510  outptr += c->pic->linesize[0];
511  }
512  outptr = c->pic->data[0];
513  put_cursor(outptr, c->pic->linesize[0], c, c->cur_x, c->cur_y);
514  }
515  }
516  *got_frame = 1;
517  if ((ret = av_frame_ref(rframe, c->pic)) < 0)
518  return ret;
519 
520  /* always report that the buffer was completely consumed */
521  return buf_size;
522 }
523 
525 {
526  VmncContext * const c = avctx->priv_data;
527 
528  c->avctx = avctx;
529  c->width = avctx->width;
530  c->height = avctx->height;
531  c->bpp = avctx->bits_per_coded_sample;
532 
533  switch (c->bpp) {
534  case 8:
535  avctx->pix_fmt = AV_PIX_FMT_PAL8;
536  break;
537  case 16:
538  avctx->pix_fmt = AV_PIX_FMT_RGB555;
539  break;
540  case 24:
541  /* 24 bits is not technically supported, but some clients might
542  * mistakenly set it, so let's assume they actually meant 32 bits */
543  c->bpp = 32;
544  case 32:
545  avctx->pix_fmt = AV_PIX_FMT_0RGB32;
546  break;
547  default:
548  av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", c->bpp);
549  return AVERROR_INVALIDDATA;
550  }
551  c->bpp2 = c->bpp / 8;
552 
553  c->pic = av_frame_alloc();
554  if (!c->pic)
555  return AVERROR(ENOMEM);
556 
557  return 0;
558 }
559 
561 {
562  VmncContext * const c = avctx->priv_data;
563 
564  av_frame_free(&c->pic);
565 
566  av_freep(&c->curbits);
567  av_freep(&c->curmask);
568  av_freep(&c->screendta);
569  return 0;
570 }
571 
573  .p.name = "vmnc",
574  CODEC_LONG_NAME("VMware Screen Codec / VMware Video"),
575  .p.type = AVMEDIA_TYPE_VIDEO,
576  .p.id = AV_CODEC_ID_VMNC,
577  .priv_data_size = sizeof(VmncContext),
578  .init = decode_init,
579  .close = decode_end,
581  .p.capabilities = AV_CODEC_CAP_DR1,
582 };
EncTypes
EncTypes
Definition: vmnc.c:34
be
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 be(in the first position) for now. Options ------- Then comes the options array. This is what will define the user accessible options. For example
paint_rect
static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, int w, int h, int color, int bpp, int stride)
Definition: vmnc.c:188
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
MAGIC_WMVh
@ MAGIC_WMVh
Definition: vmnc.c:39
VmncContext::pic
AVFrame * pic
Definition: vmnc.c:57
color
Definition: vf_paletteuse.c:601
GetByteContext
Definition: bytestream.h:33
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:116
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
w
uint8_t w
Definition: llviddspenc.c:38
VmncContext::screendta
uint8_t * screendta
Definition: vmnc.c:71
AVPacket::data
uint8_t * data
Definition: packet.h:374
MAGIC_WMVg
@ MAGIC_WMVg
Definition: vmnc.c:38
decode_end
static av_cold int decode_end(AVCodecContext *avctx)
Definition: vmnc.c:560
FFCodec
Definition: codec_internal.h:119
HT_CLR
@ HT_CLR
Definition: vmnc.c:49
decode_init
static av_cold int decode_init(AVCodecContext *avctx)
Definition: vmnc.c:524
init
static int init
Definition: av_tx.c:47
HT_SUB
@ HT_SUB
Definition: vmnc.c:48
VmncContext::cur_hy
int cur_hy
Definition: vmnc.c:69
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:123
VmncContext::bpp
int bpp
Definition: vmnc.c:59
VmncContext::curbits
uint8_t * curbits
Definition: vmnc.c:70
MAGIC_WMVe
@ MAGIC_WMVe
Definition: vmnc.c:36
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:104
HT_BKG
@ HT_BKG
Definition: vmnc.c:46
decode_hextile
static int decode_hextile(VmncContext *c, uint8_t *dst, GetByteContext *gb, int w, int h, int stride)
Definition: vmnc.c:242
MAGIC_WMVd
@ MAGIC_WMVd
Definition: vmnc.c:35
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
VmncContext::bigendian
int bigendian
Definition: vmnc.c:61
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:279
VmncContext::gb
GetByteContext gb
Definition: vmnc.c:64
MAGIC_WMVf
@ MAGIC_WMVf
Definition: vmnc.c:37
decode.h
VmncContext::cur_hx
int cur_hx
Definition: vmnc.c:69
decode_frame
static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt)
Definition: vmnc.c:323
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:264
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
VmncContext::cur_h
int cur_h
Definition: vmnc.c:67
paint_raw
static av_always_inline void paint_raw(uint8_t *dst, int w, int h, GetByteContext *gb, int bpp, int be, int stride)
Definition: vmnc.c:218
VmncContext::curmask
uint8_t * curmask
Definition: vmnc.c:70
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:375
av_frame_ref
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:353
codec_internal.h
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:94
av_reallocp
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:186
VmncContext::cur_x
int cur_x
Definition: vmnc.c:68
HexTile_Flags
HexTile_Flags
Definition: vmnc.c:44
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:1463
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
HT_FG
@ HT_FG
Definition: vmnc.c:47
vmnc_get_pixel
static av_always_inline int vmnc_get_pixel(GetByteContext *gb, int bpp, int be)
Definition: vmnc.c:75
common.h
AV_PIX_FMT_RGB555
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:413
av_always_inline
#define av_always_inline
Definition: attributes.h:49
VmncContext::width
int width
Definition: vmnc.c:63
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:211
AVCodecContext::height
int height
Definition: avcodec.h:571
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:608
avcodec.h
VmncContext::pal
uint8_t pal[768]
Definition: vmnc.c:62
stride
#define stride
Definition: h264pred_template.c:537
MAGIC_WMVj
@ MAGIC_WMVj
Definition: vmnc.c:41
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
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:1568
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_0RGB32
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:402
VmncContext
Definition: vmnc.c:55
HT_RAW
@ HT_RAW
Definition: vmnc.c:45
put_cursor
static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy)
Definition: vmnc.c:128
AVCodecContext
main external API structure.
Definition: avcodec.h:398
VmncContext::cur_w
int cur_w
Definition: vmnc.c:67
VmncContext::avctx
AVCodecContext * avctx
Definition: vmnc.c:56
reset_buffers
static void reset_buffers(VmncContext *c)
Definition: vmnc.c:313
AV_CODEC_ID_VMNC
@ AV_CODEC_ID_VMNC
Definition: codec_id.h:141
VmncContext::bpp2
int bpp2
Definition: vmnc.c:60
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
load_cursor
static void load_cursor(VmncContext *c)
Definition: vmnc.c:93
ff_vmnc_decoder
const FFCodec ff_vmnc_decoder
Definition: vmnc.c:572
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:425
AVPacket
This structure stores compressed data.
Definition: packet.h:351
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
VmncContext::height
int height
Definition: vmnc.c:63
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:571
bytestream.h
VmncContext::cur_y
int cur_y
Definition: vmnc.c:68
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
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
h
h
Definition: vp9dsp_template.c:2038
MAGIC_WMVi
@ MAGIC_WMVi
Definition: vmnc.c:40