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