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