FFmpeg  4.4.7
rasc.c
Go to the documentation of this file.
1 /*
2  * RemotelyAnywhere Screen Capture decoder
3  *
4  * Copyright (c) 2018 Paul B Mahol
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "libavutil/avassert.h"
28 #include "libavutil/imgutils.h"
29 #include "libavutil/opt.h"
30 
31 #include "avcodec.h"
32 #include "bytestream.h"
33 #include "internal.h"
34 
35 #include <zlib.h>
36 
37 #define KBND MKTAG('K', 'B', 'N', 'D')
38 #define FINT MKTAG('F', 'I', 'N', 'T')
39 #define INIT MKTAG('I', 'N', 'I', 'T')
40 #define BNDL MKTAG('B', 'N', 'D', 'L')
41 #define KFRM MKTAG('K', 'F', 'R', 'M')
42 #define DLTA MKTAG('D', 'L', 'T', 'A')
43 #define MOUS MKTAG('M', 'O', 'U', 'S')
44 #define MPOS MKTAG('M', 'P', 'O', 'S')
45 #define MOVE MKTAG('M', 'O', 'V', 'E')
46 #define EMPT MKTAG('E', 'M', 'P', 'T')
47 
48 typedef struct RASCContext {
49  AVClass *class;
55  unsigned int mv_scratch_size;
58  unsigned cursor_w;
59  unsigned cursor_h;
60  unsigned cursor_x;
61  unsigned cursor_y;
62  int stride;
63  int bpp;
64  z_stream zstream;
68 } RASCContext;
69 
70 static void clear_plane(AVCodecContext *avctx, AVFrame *frame)
71 {
72  RASCContext *s = avctx->priv_data;
73  uint8_t *dst = frame->data[0];
74 
75  if (!dst)
76  return;
77 
78  for (int y = 0; y < avctx->height; y++) {
79  memset(dst, 0, avctx->width * s->bpp);
80  dst += frame->linesize[0];
81  }
82 }
83 
84 static void copy_plane(AVCodecContext *avctx, AVFrame *src, AVFrame *dst)
85 {
86  RASCContext *s = avctx->priv_data;
87  uint8_t *srcp = src->data[0];
88  uint8_t *dstp = dst->data[0];
89 
90  for (int y = 0; y < avctx->height; y++) {
91  memcpy(dstp, srcp, s->stride);
92  srcp += src->linesize[0];
93  dstp += dst->linesize[0];
94  }
95 }
96 
97 static int init_frames(AVCodecContext *avctx)
98 {
99  RASCContext *s = avctx->priv_data;
100  int ret;
101 
102  av_frame_unref(s->frame1);
103  av_frame_unref(s->frame2);
104  if ((ret = ff_get_buffer(avctx, s->frame1, 0)) < 0)
105  return ret;
106 
107  if ((ret = ff_get_buffer(avctx, s->frame2, 0)) < 0)
108  return ret;
109 
110  clear_plane(avctx, s->frame2);
111  clear_plane(avctx, s->frame1);
112 
113  return 0;
114 }
115 
116 static int decode_fint(AVCodecContext *avctx,
117  const AVPacket *avpkt, unsigned size)
118 {
119  RASCContext *s = avctx->priv_data;
120  GetByteContext *gb = &s->gb;
121  unsigned w, h, fmt;
122  int ret;
123 
124  if (bytestream2_peek_le32(gb) != 0x65) {
125  if (!s->frame2->data[0] || !s->frame1->data[0])
126  return AVERROR_INVALIDDATA;
127 
128  clear_plane(avctx, s->frame2);
129  clear_plane(avctx, s->frame1);
130  return 0;
131  }
132  if (bytestream2_get_bytes_left(gb) < 72)
133  return AVERROR_INVALIDDATA;
134 
135  bytestream2_skip(gb, 8);
136  w = bytestream2_get_le32(gb);
137  h = bytestream2_get_le32(gb);
138  bytestream2_skip(gb, 30);
139  fmt = bytestream2_get_le16(gb);
140  bytestream2_skip(gb, 24);
141 
142  switch (fmt) {
143  case 8: s->stride = FFALIGN(w, 4);
144  s->bpp = 1;
145  fmt = AV_PIX_FMT_PAL8; break;
146  case 16: s->stride = w * 2;
147  s->bpp = 2;
148  fmt = AV_PIX_FMT_RGB555LE; break;
149  case 32: s->stride = w * 4;
150  s->bpp = 4;
151  fmt = AV_PIX_FMT_BGR0; break;
152  default: return AVERROR_INVALIDDATA;
153  }
154 
155  ret = ff_set_dimensions(avctx, w, h);
156  if (ret < 0)
157  return ret;
158  avctx->width = w;
159  avctx->height = h;
160  avctx->pix_fmt = fmt;
161 
162  ret = init_frames(avctx);
163  if (ret < 0)
164  return ret;
165 
166  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
167  uint32_t *pal = (uint32_t *)s->frame2->data[1];
168 
169  for (int i = 0; i < 256; i++)
170  pal[i] = bytestream2_get_le32(gb) | 0xFF000000u;
171  }
172 
173  return 0;
174 }
175 
176 static int decode_zlib(AVCodecContext *avctx, const AVPacket *avpkt,
177  unsigned size, unsigned uncompressed_size)
178 {
179  RASCContext *s = avctx->priv_data;
180  GetByteContext *gb = &s->gb;
181  int zret;
182 
183  zret = inflateReset(&s->zstream);
184  if (zret != Z_OK) {
185  av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
186  return AVERROR_EXTERNAL;
187  }
188 
189  av_fast_padded_malloc(&s->delta, &s->delta_size, uncompressed_size);
190  if (!s->delta)
191  return AVERROR(ENOMEM);
192 
193  s->zstream.next_in = avpkt->data + bytestream2_tell(gb);
194  s->zstream.avail_in = FFMIN(size, bytestream2_get_bytes_left(gb));
195 
196  s->zstream.next_out = s->delta;
197  s->zstream.avail_out = s->delta_size;
198 
199  zret = inflate(&s->zstream, Z_FINISH);
200  if (zret != Z_STREAM_END) {
201  av_log(avctx, AV_LOG_ERROR,
202  "Inflate failed with return code: %d.\n", zret);
203  return AVERROR_INVALIDDATA;
204  }
205 
206  return 0;
207 }
208 
209 static int decode_move(AVCodecContext *avctx,
210  const AVPacket *avpkt, unsigned size)
211 {
212  RASCContext *s = avctx->priv_data;
213  GetByteContext *gb = &s->gb;
215  unsigned pos, compression, nb_moves;
216  unsigned uncompressed_size;
217  int ret;
218 
219  pos = bytestream2_tell(gb);
220  bytestream2_skip(gb, 8);
221  nb_moves = bytestream2_get_le32(gb);
222  bytestream2_skip(gb, 8);
223  compression = bytestream2_get_le32(gb);
224 
225  if (nb_moves > INT32_MAX / 16 || nb_moves > avctx->width * avctx->height)
226  return AVERROR_INVALIDDATA;
227 
228  uncompressed_size = 16 * nb_moves;
229 
230  if (compression == 1) {
231  ret = decode_zlib(avctx, avpkt,
232  size - (bytestream2_tell(gb) - pos),
233  uncompressed_size);
234  if (ret < 0)
235  return ret;
236  bytestream2_init(&mc, s->delta, uncompressed_size);
237  } else if (compression == 0) {
238  bytestream2_init(&mc, avpkt->data + bytestream2_tell(gb),
240  } else if (compression == 2) {
241  avpriv_request_sample(avctx, "compression %d", compression);
242  return AVERROR_PATCHWELCOME;
243  } else {
244  return AVERROR_INVALIDDATA;
245  }
246 
247  if (bytestream2_get_bytes_left(&mc) < uncompressed_size)
248  return AVERROR_INVALIDDATA;
249 
250  for (int i = 0; i < nb_moves; i++) {
251  int type, start_x, start_y, end_x, end_y, mov_x, mov_y;
252  uint8_t *e2, *b1, *b2;
253  int w, h;
254 
255  type = bytestream2_get_le16(&mc);
256  start_x = bytestream2_get_le16(&mc);
257  start_y = bytestream2_get_le16(&mc);
258  end_x = bytestream2_get_le16(&mc);
259  end_y = bytestream2_get_le16(&mc);
260  mov_x = bytestream2_get_le16(&mc);
261  mov_y = bytestream2_get_le16(&mc);
262  bytestream2_skip(&mc, 2);
263 
264  if (start_x >= avctx->width || start_y >= avctx->height ||
265  end_x >= avctx->width || end_y >= avctx->height ||
266  mov_x >= avctx->width || mov_y >= avctx->height) {
267  continue;
268  }
269 
270  if (start_x >= end_x || start_y >= end_y)
271  continue;
272 
273  w = end_x - start_x;
274  h = end_y - start_y;
275 
276  if (mov_x + w > avctx->width || mov_y + h > avctx->height)
277  continue;
278 
279  if (!s->frame2->data[0] || !s->frame1->data[0])
280  return AVERROR_INVALIDDATA;
281 
282  b1 = s->frame1->data[0] + s->frame1->linesize[0] * (start_y + h - 1) + start_x * s->bpp;
283  b2 = s->frame2->data[0] + s->frame2->linesize[0] * (start_y + h - 1) + start_x * s->bpp;
284  e2 = s->frame2->data[0] + s->frame2->linesize[0] * (mov_y + h - 1) + mov_x * s->bpp;
285 
286  if (type == 2) {
287  for (int j = 0; j < h; j++) {
288  memcpy(b1, b2, w * s->bpp);
289  b1 -= s->frame1->linesize[0];
290  b2 -= s->frame2->linesize[0];
291  }
292  } else if (type == 1) {
293  for (int j = 0; j < h; j++) {
294  memset(b2, 0, w * s->bpp);
295  b2 -= s->frame2->linesize[0];
296  }
297  } else if (type == 0) {
298  av_fast_padded_malloc(&s->mv_scratch, &s->mv_scratch_size, w * h * s->bpp);
299  uint8_t *buffer = s->mv_scratch;
300  if (!buffer)
301  return AVERROR(ENOMEM);
302 
303  for (int j = 0; j < h; j++) {
304  memcpy(buffer + j * w * s->bpp, e2, w * s->bpp);
305  e2 -= s->frame2->linesize[0];
306  }
307 
308  for (int j = 0; j < h; j++) {
309  memcpy(b2, buffer + j * w * s->bpp, w * s->bpp);
310  b2 -= s->frame2->linesize[0];
311  }
312  } else {
313  return AVERROR_INVALIDDATA;
314  }
315  }
316 
317  bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
318 
319  return 0;
320 }
321 
322 #define NEXT_LINE \
323  if (cx >= w * s->bpp) { \
324  cx = 0; \
325  cy--; \
326  b1 -= s->frame1->linesize[0]; \
327  b2 -= s->frame2->linesize[0]; \
328  } \
329  len--;
330 
331 static int decode_dlta(AVCodecContext *avctx,
332  const AVPacket *avpkt, unsigned size)
333 {
334  RASCContext *s = avctx->priv_data;
335  GetByteContext *gb = &s->gb;
337  unsigned uncompressed_size, pos;
338  unsigned x, y, w, h;
339  int ret, cx, cy, compression;
340  uint8_t *b1, *b2;
341 
342  pos = bytestream2_tell(gb);
343  bytestream2_skip(gb, 12);
344  uncompressed_size = bytestream2_get_le32(gb);
345  x = bytestream2_get_le32(gb);
346  y = bytestream2_get_le32(gb);
347  w = bytestream2_get_le32(gb);
348  h = bytestream2_get_le32(gb);
349 
350  if (x >= avctx->width || y >= avctx->height ||
351  w > avctx->width || h > avctx->height)
352  return AVERROR_INVALIDDATA;
353 
354  if (x + w > avctx->width || y + h > avctx->height)
355  return AVERROR_INVALIDDATA;
356 
357  bytestream2_skip(gb, 4);
358  compression = bytestream2_get_le32(gb);
359 
360  if (compression == 1) {
361  if (w * h * s->bpp * 3 < uncompressed_size)
362  return AVERROR_INVALIDDATA;
363  ret = decode_zlib(avctx, avpkt, size, uncompressed_size);
364  if (ret < 0)
365  return ret;
366  bytestream2_init(&dc, s->delta, uncompressed_size);
367  } else if (compression == 0) {
368  if (bytestream2_get_bytes_left(gb) < uncompressed_size)
369  return AVERROR_INVALIDDATA;
370  bytestream2_init(&dc, avpkt->data + bytestream2_tell(gb),
371  uncompressed_size);
372  } else if (compression == 2) {
373  avpriv_request_sample(avctx, "compression %d", compression);
374  return AVERROR_PATCHWELCOME;
375  } else {
376  return AVERROR_INVALIDDATA;
377  }
378 
379  if (!s->frame2->data[0] || !s->frame1->data[0])
380  return AVERROR_INVALIDDATA;
381 
382  b1 = s->frame1->data[0] + s->frame1->linesize[0] * (y + h - 1) + x * s->bpp;
383  b2 = s->frame2->data[0] + s->frame2->linesize[0] * (y + h - 1) + x * s->bpp;
384  cx = 0, cy = h;
385  while (bytestream2_get_bytes_left(&dc) > 0) {
386  int type = bytestream2_get_byte(&dc);
387  int len = bytestream2_get_byte(&dc);
388  unsigned fill;
389 
390  switch (type) {
391  case 1:
392  while (len > 0 && cy > 0) {
393  cx++;
394  NEXT_LINE
395  }
396  break;
397  case 2:
398  while (len > 0 && cy > 0) {
399  int v0 = b1[cx];
400  int v1 = b2[cx];
401 
402  b2[cx] = v0;
403  b1[cx] = v1;
404  cx++;
405  NEXT_LINE
406  }
407  break;
408  case 3:
409  while (len > 0 && cy > 0) {
410  fill = bytestream2_get_byte(&dc);
411  b1[cx] = b2[cx];
412  b2[cx] = fill;
413  cx++;
414  NEXT_LINE
415  }
416  break;
417  case 4:
418  fill = bytestream2_get_byte(&dc);
419  while (len > 0 && cy > 0) {
420  AV_WL32(b1 + cx, AV_RL32(b2 + cx));
421  AV_WL32(b2 + cx, fill);
422  cx++;
423  NEXT_LINE
424  }
425  break;
426  case 7:
427  fill = bytestream2_get_le32(&dc);
428  while (len > 0 && cy > 0) {
429  AV_WL32(b1 + cx, AV_RL32(b2 + cx));
430  AV_WL32(b2 + cx, fill);
431  cx += 4;
432  NEXT_LINE
433  }
434  break;
435  case 10:
436  while (len > 0 && cy > 0) {
437  cx += 4;
438  NEXT_LINE
439  }
440  break;
441  case 12:
442  while (len > 0 && cy > 0) {
443  unsigned v0, v1;
444 
445  v0 = AV_RL32(b2 + cx);
446  v1 = AV_RL32(b1 + cx);
447  AV_WL32(b2 + cx, v1);
448  AV_WL32(b1 + cx, v0);
449  cx += 4;
450  NEXT_LINE
451  }
452  break;
453  case 13:
454  while (len > 0 && cy > 0) {
455  fill = bytestream2_get_le32(&dc);
456  AV_WL32(b1 + cx, AV_RL32(b2 + cx));
457  AV_WL32(b2 + cx, fill);
458  cx += 4;
459  NEXT_LINE
460  }
461  break;
462  default:
463  avpriv_request_sample(avctx, "runlen %d", type);
464  return AVERROR_INVALIDDATA;
465  }
466  }
467 
468  bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
469 
470  return 0;
471 }
472 
473 static int decode_kfrm(AVCodecContext *avctx,
474  const AVPacket *avpkt, unsigned size)
475 {
476  RASCContext *s = avctx->priv_data;
477  GetByteContext *gb = &s->gb;
478  uint8_t *dst;
479  unsigned pos;
480  int zret, ret;
481 
482  pos = bytestream2_tell(gb);
483  if (bytestream2_peek_le32(gb) == 0x65) {
484  ret = decode_fint(avctx, avpkt, size);
485  if (ret < 0)
486  return ret;
487  }
488 
489  if (!s->frame2->data[0])
490  return AVERROR_INVALIDDATA;
491 
492  zret = inflateReset(&s->zstream);
493  if (zret != Z_OK) {
494  av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
495  return AVERROR_EXTERNAL;
496  }
497 
498  s->zstream.next_in = avpkt->data + bytestream2_tell(gb);
499  s->zstream.avail_in = bytestream2_get_bytes_left(gb);
500 
501  dst = s->frame2->data[0] + (avctx->height - 1) * s->frame2->linesize[0];
502  for (int i = 0; i < avctx->height; i++) {
503  s->zstream.next_out = dst;
504  s->zstream.avail_out = s->stride;
505 
506  zret = inflate(&s->zstream, Z_SYNC_FLUSH);
507  if (zret != Z_OK && zret != Z_STREAM_END) {
508  av_log(avctx, AV_LOG_ERROR,
509  "Inflate failed with return code: %d.\n", zret);
510  return AVERROR_INVALIDDATA;
511  }
512 
513  dst -= s->frame2->linesize[0];
514  }
515 
516  dst = s->frame1->data[0] + (avctx->height - 1) * s->frame1->linesize[0];
517  for (int i = 0; i < avctx->height; i++) {
518  s->zstream.next_out = dst;
519  s->zstream.avail_out = s->stride;
520 
521  zret = inflate(&s->zstream, Z_SYNC_FLUSH);
522  if (zret != Z_OK && zret != Z_STREAM_END) {
523  av_log(avctx, AV_LOG_ERROR,
524  "Inflate failed with return code: %d.\n", zret);
525  return AVERROR_INVALIDDATA;
526  }
527 
528  dst -= s->frame1->linesize[0];
529  }
530 
531  bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
532 
533  return 0;
534 }
535 
536 static int decode_mous(AVCodecContext *avctx,
537  const AVPacket *avpkt, unsigned size)
538 {
539  RASCContext *s = avctx->priv_data;
540  GetByteContext *gb = &s->gb;
541  unsigned w, h, pos, uncompressed_size;
542  int ret;
543 
544  pos = bytestream2_tell(gb);
545  bytestream2_skip(gb, 8);
546  w = bytestream2_get_le32(gb);
547  h = bytestream2_get_le32(gb);
548  bytestream2_skip(gb, 12);
549  uncompressed_size = bytestream2_get_le32(gb);
550 
551  if (w > avctx->width || h > avctx->height)
552  return AVERROR_INVALIDDATA;
553 
554  if (uncompressed_size != 3 * w * h)
555  return AVERROR_INVALIDDATA;
556 
557  av_fast_padded_malloc(&s->cursor, &s->cursor_size, uncompressed_size);
558  if (!s->cursor)
559  return AVERROR(ENOMEM);
560 
561  ret = decode_zlib(avctx, avpkt,
562  size - (bytestream2_tell(gb) - pos),
563  uncompressed_size);
564  if (ret < 0)
565  return ret;
566  memcpy(s->cursor, s->delta, uncompressed_size);
567 
568  bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
569 
570  s->cursor_w = w;
571  s->cursor_h = h;
572 
573  return 0;
574 }
575 
576 static int decode_mpos(AVCodecContext *avctx,
577  const AVPacket *avpkt, unsigned size)
578 {
579  RASCContext *s = avctx->priv_data;
580  GetByteContext *gb = &s->gb;
581  unsigned pos;
582 
583  pos = bytestream2_tell(gb);
584  bytestream2_skip(gb, 8);
585  s->cursor_x = bytestream2_get_le32(gb);
586  s->cursor_y = bytestream2_get_le32(gb);
587 
588  bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
589 
590  return 0;
591 }
592 
593 static void draw_cursor(AVCodecContext *avctx)
594 {
595  RASCContext *s = avctx->priv_data;
596  uint8_t *dst, *pal;
597 
598  if (!s->cursor)
599  return;
600 
601  if (s->cursor_x >= avctx->width || s->cursor_y >= avctx->height)
602  return;
603 
604  if (s->cursor_x + s->cursor_w > avctx->width ||
605  s->cursor_y + s->cursor_h > avctx->height)
606  return;
607 
608  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
609  pal = s->frame->data[1];
610  for (int i = 0; i < s->cursor_h; i++) {
611  for (int j = 0; j < s->cursor_w; j++) {
612  int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
613  int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
614  int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
615  int best = INT_MAX;
616  int index = 0;
617  int dist;
618 
619  if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
620  continue;
621 
622  dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + (s->cursor_x + j);
623  for (int k = 0; k < 256; k++) {
624  int pr = pal[k * 4 + 0];
625  int pg = pal[k * 4 + 1];
626  int pb = pal[k * 4 + 2];
627 
628  dist = FFABS(cr - pr) + FFABS(cg - pg) + FFABS(cb - pb);
629  if (dist < best) {
630  best = dist;
631  index = k;
632  }
633  }
634  dst[0] = index;
635  }
636  }
637  } else if (avctx->pix_fmt == AV_PIX_FMT_RGB555LE) {
638  for (int i = 0; i < s->cursor_h; i++) {
639  for (int j = 0; j < s->cursor_w; j++) {
640  int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
641  int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
642  int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
643 
644  if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
645  continue;
646 
647  cr >>= 3; cg >>=3; cb >>= 3;
648  dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + 2 * (s->cursor_x + j);
649  AV_WL16(dst, cr | cg << 5 | cb << 10);
650  }
651  }
652  } else if (avctx->pix_fmt == AV_PIX_FMT_BGR0) {
653  for (int i = 0; i < s->cursor_h; i++) {
654  for (int j = 0; j < s->cursor_w; j++) {
655  int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
656  int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
657  int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
658 
659  if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
660  continue;
661 
662  dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + 4 * (s->cursor_x + j);
663  dst[0] = cb;
664  dst[1] = cg;
665  dst[2] = cr;
666  }
667  }
668  }
669 }
670 
671 static int decode_frame(AVCodecContext *avctx,
672  void *data, int *got_frame,
673  AVPacket *avpkt)
674 {
675  RASCContext *s = avctx->priv_data;
676  GetByteContext *gb = &s->gb;
677  int ret, intra = 0;
678  AVFrame *frame = data;
679 
680  bytestream2_init(gb, avpkt->data, avpkt->size);
681 
682  if (bytestream2_peek_le32(gb) == EMPT)
683  return avpkt->size;
684 
685  s->frame = frame;
686 
687  while (bytestream2_get_bytes_left(gb) > 0) {
688  unsigned type, size = 0;
689 
690  if (bytestream2_get_bytes_left(gb) < 8)
691  return AVERROR_INVALIDDATA;
692 
693  type = bytestream2_get_le32(gb);
694  if (type == KBND || type == BNDL) {
695  intra = type == KBND;
696  type = bytestream2_get_le32(gb);
697  }
698 
699  size = bytestream2_get_le32(gb);
701  return AVERROR_INVALIDDATA;
702 
703  switch (type) {
704  case FINT:
705  case INIT:
706  ret = decode_fint(avctx, avpkt, size);
707  break;
708  case KFRM:
709  ret = decode_kfrm(avctx, avpkt, size);
710  break;
711  case DLTA:
712  ret = decode_dlta(avctx, avpkt, size);
713  break;
714  case MOVE:
715  ret = decode_move(avctx, avpkt, size);
716  break;
717  case MOUS:
718  ret = decode_mous(avctx, avpkt, size);
719  break;
720  case MPOS:
721  ret = decode_mpos(avctx, avpkt, size);
722  break;
723  default:
724  bytestream2_skip(gb, size);
725  ret = 0;
726  }
727 
728  if (ret < 0)
729  return ret;
730  }
731 
732  if (!s->frame2->data[0] || !s->frame1->data[0])
733  return AVERROR_INVALIDDATA;
734 
735  if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0)
736  return ret;
737 
738  copy_plane(avctx, s->frame2, s->frame);
739  if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
740  memcpy(s->frame->data[1], s->frame2->data[1], 1024);
741  if (!s->skip_cursor)
742  draw_cursor(avctx);
743 
744  s->frame->key_frame = intra;
745  s->frame->pict_type = intra ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
746 
747  *got_frame = 1;
748 
749  return avpkt->size;
750 }
751 
753 {
754  RASCContext *s = avctx->priv_data;
755  int zret;
756 
757  s->zstream.zalloc = Z_NULL;
758  s->zstream.zfree = Z_NULL;
759  s->zstream.opaque = Z_NULL;
760  zret = inflateInit(&s->zstream);
761  if (zret != Z_OK) {
762  av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
763  return AVERROR_EXTERNAL;
764  }
765 
766  s->frame1 = av_frame_alloc();
767  s->frame2 = av_frame_alloc();
768  if (!s->frame1 || !s->frame2)
769  return AVERROR(ENOMEM);
770 
771  return 0;
772 }
773 
775 {
776  RASCContext *s = avctx->priv_data;
777 
778  av_freep(&s->cursor);
779  s->cursor_size = 0;
780  av_freep(&s->delta);
781  s->delta_size = 0;
782  av_freep(&s->mv_scratch);
783  s->mv_scratch_size = 0;
784  av_frame_free(&s->frame1);
785  av_frame_free(&s->frame2);
786  inflateEnd(&s->zstream);
787 
788  return 0;
789 }
790 
791 static void decode_flush(AVCodecContext *avctx)
792 {
793  RASCContext *s = avctx->priv_data;
794 
795  clear_plane(avctx, s->frame1);
796  clear_plane(avctx, s->frame2);
797 }
798 
799 static const AVOption options[] = {
800 { "skip_cursor", "skip the cursor", offsetof(RASCContext, skip_cursor), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM },
801 { NULL },
802 };
803 
804 static const AVClass rasc_decoder_class = {
805  .class_name = "rasc decoder",
806  .item_name = av_default_item_name,
807  .option = options,
808  .version = LIBAVUTIL_VERSION_INT,
809 };
810 
812  .name = "rasc",
813  .long_name = NULL_IF_CONFIG_SMALL("RemotelyAnywhere Screen Capture"),
814  .type = AVMEDIA_TYPE_VIDEO,
815  .id = AV_CODEC_ID_RASC,
816  .priv_data_size = sizeof(RASCContext),
817  .init = decode_init,
818  .close = decode_close,
819  .decode = decode_frame,
820  .flush = decode_flush,
821  .capabilities = AV_CODEC_CAP_DR1,
822  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
824  .priv_class = &rasc_decoder_class,
825 };
static void flush(AVCodecContext *avctx)
#define av_cold
Definition: attributes.h:88
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> dc
uint8_t
simple assert() macros that are a bit more flexible than ISO C assert().
Libavcodec external API header.
#define AV_RL32
Definition: intreadwrite.h:146
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:192
#define s(width, name)
Definition: cbs_vp9.c:257
#define FFMIN(a, b)
Definition: common.h:105
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
#define NULL
Definition: coverity.c:32
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1900
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
static AVFrame * frame
@ AV_OPT_TYPE_BOOL
Definition: opt.h:242
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
@ AV_CODEC_ID_RASC
Definition: codec_id.h:290
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional AV_INPUT_BUFFER_PADDING_SIZE at the end w...
Definition: utils.c:50
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AVERROR(e)
Definition: error.h:43
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:275
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
int index
Definition: gxfenc.c:89
for(j=16;j >0;--j)
cl_device_type type
misc image utilities
int i
Definition: input.c:407
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:41
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:49
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:84
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
uint8_t w
Definition: llviddspenc.c:39
#define FFALIGN(x, a)
Definition: macros.h:48
const char data[16]
Definition: mxf.c:142
AVOptions.
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding
Definition: opt.h:279
#define AV_OPT_FLAG_VIDEO_PARAM
Definition: opt.h:281
@ AV_PIX_FMT_BGR0
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
Definition: pixfmt.h:240
@ AV_PIX_FMT_RGB555LE
packed RGB 5:5:5, 16bpp, (msb)1X 5R 5G 5B(lsb), little-endian, X=unused/undefined
Definition: pixfmt.h:108
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
static int decode_mpos(AVCodecContext *avctx, const AVPacket *avpkt, unsigned size)
Definition: rasc.c:576
static int decode_move(AVCodecContext *avctx, const AVPacket *avpkt, unsigned size)
Definition: rasc.c:209
#define DLTA
Definition: rasc.c:42
static int decode_kfrm(AVCodecContext *avctx, const AVPacket *avpkt, unsigned size)
Definition: rasc.c:473
#define MOVE
Definition: rasc.c:45
static const AVOption options[]
Definition: rasc.c:799
static av_cold int decode_close(AVCodecContext *avctx)
Definition: rasc.c:774
static int init_frames(AVCodecContext *avctx)
Definition: rasc.c:97
static const AVClass rasc_decoder_class
Definition: rasc.c:804
static int decode_mous(AVCodecContext *avctx, const AVPacket *avpkt, unsigned size)
Definition: rasc.c:536
static av_cold int decode_init(AVCodecContext *avctx)
Definition: rasc.c:752
#define BNDL
Definition: rasc.c:40
static void copy_plane(AVCodecContext *avctx, AVFrame *src, AVFrame *dst)
Definition: rasc.c:84
AVCodec ff_rasc_decoder
Definition: rasc.c:811
#define EMPT
Definition: rasc.c:46
static int decode_fint(AVCodecContext *avctx, const AVPacket *avpkt, unsigned size)
Definition: rasc.c:116
#define MPOS
Definition: rasc.c:44
static int decode_zlib(AVCodecContext *avctx, const AVPacket *avpkt, unsigned size, unsigned uncompressed_size)
Definition: rasc.c:176
#define INIT
Definition: rasc.c:39
static void clear_plane(AVCodecContext *avctx, AVFrame *frame)
Definition: rasc.c:70
#define KFRM
Definition: rasc.c:41
static void decode_flush(AVCodecContext *avctx)
Definition: rasc.c:791
#define NEXT_LINE
Definition: rasc.c:322
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: rasc.c:671
#define FINT
Definition: rasc.c:38
static void draw_cursor(AVCodecContext *avctx)
Definition: rasc.c:593
#define MOUS
Definition: rasc.c:43
#define KBND
Definition: rasc.c:37
static int decode_dlta(AVCodecContext *avctx, const AVPacket *avpkt, unsigned size)
Definition: rasc.c:331
#define v0
Definition: regdef.h:26
static char buffer[20]
Definition: seek.c:32
unsigned int pos
Definition: spdifenc.c:412
Describe the class of an AVClass context structure.
Definition: log.h:67
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
main external API structure.
Definition: avcodec.h:536
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
int width
picture width / height.
Definition: avcodec.h:709
void * priv_data
Definition: avcodec.h:563
AVCodec.
Definition: codec.h:197
const char * name
Name of the codec implementation.
Definition: codec.h:204
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
AVOption.
Definition: opt.h:248
This structure stores compressed data.
Definition: packet.h:346
int size
Definition: packet.h:370
uint8_t * data
Definition: packet.h:369
AVFrame * frame2
Definition: rasc.c:67
unsigned cursor_w
Definition: rasc.c:58
z_stream zstream
Definition: rasc.c:64
GetByteContext gb
Definition: rasc.c:51
int cursor_size
Definition: rasc.c:57
AVFrame * frame
Definition: rasc.c:65
int delta_size
Definition: rasc.c:53
unsigned cursor_x
Definition: rasc.c:60
int stride
Definition: rasc.c:62
int skip_cursor
Definition: rasc.c:50
uint8_t * cursor
Definition: rasc.c:56
uint8_t * mv_scratch
Definition: rasc.c:54
int bpp
Definition: rasc.c:63
unsigned int mv_scratch_size
Definition: rasc.c:55
uint8_t * delta
Definition: rasc.c:52
unsigned cursor_h
Definition: rasc.c:59
AVFrame * frame1
Definition: rasc.c:66
unsigned cursor_y
Definition: rasc.c:61
#define avpriv_request_sample(...)
#define av_freep(p)
#define av_log(a,...)
#define src
Definition: vp8dsp.c:255
int size
#define mc
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:216
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:215
if(ret< 0)
Definition: vf_mcdeint.c:282
static void inflate(uint8_t *dst, const uint8_t *p1, int width, int threshold, const uint8_t *coordinates[], int coord, int maxc)
Definition: vf_neighbor.c:198
static double b1(void *priv, double x, double y)
Definition: vf_xfade.c:1665
static double b2(void *priv, double x, double y)
Definition: vf_xfade.c:1666
int len