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