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