2 * RemotelyAnywhere Screen Capture decoder
4 * Copyright (c) 2018 Paul B Mahol
6 * This file is part of FFmpeg.
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.
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.
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
26 #include "libavutil/mem.h"
27 #include "libavutil/opt.h"
30 #include "bytestream.h"
31 #include "codec_internal.h"
33 #include "zlib_wrapper.h"
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')
48 typedef struct RASCContext
{
68 static void clear_plane(AVCodecContext
*avctx
, AVFrame
*frame
)
70 RASCContext
*s
= avctx
->priv_data
;
71 uint8_t *dst
= frame
->data
[0];
76 for (int y
= 0; y
< avctx
->height
; y
++) {
77 memset(dst
, 0, avctx
->width
* s
->bpp
);
78 dst
+= frame
->linesize
[0];
82 static void copy_plane(AVCodecContext
*avctx
, AVFrame
*src
, AVFrame
*dst
)
84 RASCContext
*s
= avctx
->priv_data
;
85 uint8_t *srcp
= src
->data
[0];
86 uint8_t *dstp
= dst
->data
[0];
88 for (int y
= 0; y
< avctx
->height
; y
++) {
89 memcpy(dstp
, srcp
, s
->stride
);
90 srcp
+= src
->linesize
[0];
91 dstp
+= dst
->linesize
[0];
95 static int init_frames(AVCodecContext
*avctx
)
97 RASCContext
*s
= avctx
->priv_data
;
100 av_frame_unref(s
->frame1
);
101 av_frame_unref(s
->frame2
);
102 if ((ret
= ff_get_buffer(avctx
, s
->frame1
, 0)) < 0)
105 if ((ret
= ff_get_buffer(avctx
, s
->frame2
, 0)) < 0)
108 clear_plane(avctx
, s
->frame2
);
109 clear_plane(avctx
, s
->frame1
);
114 static int decode_fint(AVCodecContext
*avctx
,
115 const AVPacket
*avpkt
, unsigned size
)
117 RASCContext
*s
= avctx
->priv_data
;
118 GetByteContext
*gb
= &s
->gb
;
122 if (bytestream2_peek_le32(gb
) != 0x65) {
123 if (!s
->frame2
->data
[0] || !s
->frame1
->data
[0])
124 return AVERROR_INVALIDDATA
;
126 clear_plane(avctx
, s
->frame2
);
127 clear_plane(avctx
, s
->frame1
);
130 if (bytestream2_get_bytes_left(gb
) < 72)
131 return AVERROR_INVALIDDATA
;
133 bytestream2_skip(gb
, 8);
134 w
= bytestream2_get_le32(gb
);
135 h
= bytestream2_get_le32(gb
);
136 bytestream2_skip(gb
, 30);
137 fmt
= bytestream2_get_le16(gb
);
138 bytestream2_skip(gb
, 24);
141 case 8: s
->stride
= FFALIGN(w
, 4);
143 fmt
= AV_PIX_FMT_PAL8
; break;
144 case 16: s
->stride
= w
* 2;
146 fmt
= AV_PIX_FMT_RGB555LE
; break;
147 case 32: s
->stride
= w
* 4;
149 fmt
= AV_PIX_FMT_BGR0
; break;
150 default: return AVERROR_INVALIDDATA
;
153 ret
= ff_set_dimensions(avctx
, w
, h
);
158 avctx
->pix_fmt
= fmt
;
160 ret
= init_frames(avctx
);
164 if (avctx
->pix_fmt
== AV_PIX_FMT_PAL8
) {
165 uint32_t *pal
= (uint32_t *)s
->frame2
->data
[1];
167 for (int i
= 0; i
< 256; i
++)
168 pal
[i
] = bytestream2_get_le32(gb
) | 0xFF000000u
;
174 static int decode_zlib(AVCodecContext
*avctx
, const AVPacket
*avpkt
,
175 unsigned size
, unsigned uncompressed_size
)
177 RASCContext
*s
= avctx
->priv_data
;
178 z_stream
*const zstream
= &s
->zstream
.zstream
;
179 GetByteContext
*gb
= &s
->gb
;
182 zret
= inflateReset(zstream
);
184 av_log(avctx
, AV_LOG_ERROR
, "Inflate reset error: %d\n", zret
);
185 return AVERROR_EXTERNAL
;
188 av_fast_padded_malloc(&s
->delta
, &s
->delta_size
, uncompressed_size
);
190 return AVERROR(ENOMEM
);
192 zstream
->next_in
= avpkt
->data
+ bytestream2_tell(gb
);
193 zstream
->avail_in
= FFMIN(size
, bytestream2_get_bytes_left(gb
));
195 zstream
->next_out
= s
->delta
;
196 zstream
->avail_out
= s
->delta_size
;
198 zret
= inflate(zstream
, Z_FINISH
);
199 if (zret
!= Z_STREAM_END
) {
200 av_log(avctx
, AV_LOG_ERROR
,
201 "Inflate failed with return code: %d.\n", zret
);
202 return AVERROR_INVALIDDATA
;
208 static int decode_move(AVCodecContext
*avctx
,
209 const AVPacket
*avpkt
, unsigned size
)
211 RASCContext
*s
= avctx
->priv_data
;
212 GetByteContext
*gb
= &s
->gb
;
214 unsigned pos
, compression
, nb_moves
;
215 unsigned uncompressed_size
;
218 pos
= bytestream2_tell(gb
);
219 bytestream2_skip(gb
, 8);
220 nb_moves
= bytestream2_get_le32(gb
);
221 bytestream2_skip(gb
, 8);
222 compression
= bytestream2_get_le32(gb
);
224 if (nb_moves
> INT32_MAX
/ 16 || nb_moves
> avctx
->width
* avctx
->height
)
225 return AVERROR_INVALIDDATA
;
227 uncompressed_size
= 16 * nb_moves
;
229 if (compression
== 1) {
230 ret
= decode_zlib(avctx
, avpkt
,
231 size
- (bytestream2_tell(gb
) - pos
),
235 bytestream2_init(&mc
, s
->delta
, uncompressed_size
);
236 } else if (compression
== 0) {
237 bytestream2_init(&mc
, avpkt
->data
+ bytestream2_tell(gb
),
238 bytestream2_get_bytes_left(gb
));
239 } else if (compression
== 2) {
240 avpriv_request_sample(avctx
, "compression %d", compression
);
241 return AVERROR_PATCHWELCOME
;
243 return AVERROR_INVALIDDATA
;
246 if (bytestream2_get_bytes_left(&mc
) < uncompressed_size
)
247 return AVERROR_INVALIDDATA
;
249 for (int i
= 0; i
< nb_moves
; i
++) {
250 int type
, start_x
, start_y
, end_x
, end_y
, mov_x
, mov_y
;
251 uint8_t *e2
, *b1
, *b2
;
254 type
= bytestream2_get_le16(&mc
);
255 start_x
= bytestream2_get_le16(&mc
);
256 start_y
= bytestream2_get_le16(&mc
);
257 end_x
= bytestream2_get_le16(&mc
);
258 end_y
= bytestream2_get_le16(&mc
);
259 mov_x
= bytestream2_get_le16(&mc
);
260 mov_y
= bytestream2_get_le16(&mc
);
261 bytestream2_skip(&mc
, 2);
263 if (start_x
>= avctx
->width
|| start_y
>= avctx
->height
||
264 end_x
>= avctx
->width
|| end_y
>= avctx
->height
||
265 mov_x
>= avctx
->width
|| mov_y
>= avctx
->height
) {
269 if (start_x
>= end_x
|| start_y
>= end_y
)
275 if (mov_x
+ w
> avctx
->width
|| mov_y
+ h
> avctx
->height
)
278 if (!s
->frame2
->data
[0] || !s
->frame1
->data
[0])
279 return AVERROR_INVALIDDATA
;
281 b1
= s
->frame1
->data
[0] + s
->frame1
->linesize
[0] * (start_y
+ h
- 1) + start_x
* s
->bpp
;
282 b2
= s
->frame2
->data
[0] + s
->frame2
->linesize
[0] * (start_y
+ h
- 1) + start_x
* s
->bpp
;
283 e2
= s
->frame2
->data
[0] + s
->frame2
->linesize
[0] * (mov_y
+ h
- 1) + mov_x
* s
->bpp
;
286 for (int j
= 0; j
< h
; j
++) {
287 memcpy(b1
, b2
, w
* s
->bpp
);
288 b1
-= s
->frame1
->linesize
[0];
289 b2
-= s
->frame2
->linesize
[0];
291 } else if (type
== 1) {
292 for (int j
= 0; j
< h
; j
++) {
293 memset(b2
, 0, w
* s
->bpp
);
294 b2
-= s
->frame2
->linesize
[0];
296 } else if (type
== 0) {
299 av_fast_padded_malloc(&s
->delta
, &s
->delta_size
, w
* h
* s
->bpp
);
302 return AVERROR(ENOMEM
);
304 for (int j
= 0; j
< h
; j
++) {
305 memcpy(buffer
+ j
* w
* s
->bpp
, e2
, w
* s
->bpp
);
306 e2
-= s
->frame2
->linesize
[0];
309 for (int j
= 0; j
< h
; j
++) {
310 memcpy(b2
, buffer
+ j
* w
* s
->bpp
, w
* s
->bpp
);
311 b2
-= s
->frame2
->linesize
[0];
314 return AVERROR_INVALIDDATA
;
318 bytestream2_skip(gb
, size
- (bytestream2_tell(gb
) - pos
));
324 if (cx >= w * s->bpp) { \
327 b1 -= s->frame1->linesize[0]; \
328 b2 -= s->frame2->linesize[0]; \
332 static int decode_dlta(AVCodecContext
*avctx
,
333 const AVPacket
*avpkt
, unsigned size
)
335 RASCContext
*s
= avctx
->priv_data
;
336 GetByteContext
*gb
= &s
->gb
;
338 unsigned uncompressed_size
, pos
;
340 int ret
, cx
, cy
, compression
;
343 pos
= bytestream2_tell(gb
);
344 bytestream2_skip(gb
, 12);
345 uncompressed_size
= bytestream2_get_le32(gb
);
346 x
= bytestream2_get_le32(gb
);
347 y
= bytestream2_get_le32(gb
);
348 w
= bytestream2_get_le32(gb
);
349 h
= bytestream2_get_le32(gb
);
351 if (x
>= avctx
->width
|| y
>= avctx
->height
||
352 w
> avctx
->width
|| h
> avctx
->height
)
353 return AVERROR_INVALIDDATA
;
355 if (x
+ w
> avctx
->width
|| y
+ h
> avctx
->height
)
356 return AVERROR_INVALIDDATA
;
358 bytestream2_skip(gb
, 4);
359 compression
= bytestream2_get_le32(gb
);
361 if (compression
== 1) {
362 if (w
* h
* s
->bpp
* 3 < uncompressed_size
)
363 return AVERROR_INVALIDDATA
;
364 ret
= decode_zlib(avctx
, avpkt
, size
, uncompressed_size
);
367 bytestream2_init(&dc
, s
->delta
, uncompressed_size
);
368 } else if (compression
== 0) {
369 if (bytestream2_get_bytes_left(gb
) < uncompressed_size
)
370 return AVERROR_INVALIDDATA
;
371 bytestream2_init(&dc
, avpkt
->data
+ bytestream2_tell(gb
),
373 } else if (compression
== 2) {
374 avpriv_request_sample(avctx
, "compression %d", compression
);
375 return AVERROR_PATCHWELCOME
;
377 return AVERROR_INVALIDDATA
;
380 if (!s
->frame2
->data
[0] || !s
->frame1
->data
[0])
381 return AVERROR_INVALIDDATA
;
383 b1
= s
->frame1
->data
[0] + s
->frame1
->linesize
[0] * (int)(y
+ h
- 1) + ((int)x
) * s
->bpp
;
384 b2
= s
->frame2
->data
[0] + s
->frame2
->linesize
[0] * (int)(y
+ h
- 1) + ((int)x
) * s
->bpp
;
386 while (bytestream2_get_bytes_left(&dc
) > 0) {
387 int type
= bytestream2_get_byte(&dc
);
388 int len
= bytestream2_get_byte(&dc
);
393 while (len
> 0 && cy
> 0) {
399 while (len
> 0 && cy
> 0) {
410 while (len
> 0 && cy
> 0) {
411 fill
= bytestream2_get_byte(&dc
);
419 fill
= bytestream2_get_byte(&dc
);
420 while (len
> 0 && cy
> 0) {
421 AV_WL32(b1
+ cx
, AV_RL32(b2
+ cx
));
422 AV_WL32(b2
+ cx
, fill
);
428 fill
= bytestream2_get_le32(&dc
);
429 while (len
> 0 && cy
> 0) {
430 AV_WL32(b1
+ cx
, AV_RL32(b2
+ cx
));
431 AV_WL32(b2
+ cx
, fill
);
437 while (len
> 0 && cy
> 0) {
443 while (len
> 0 && cy
> 0) {
446 v0
= AV_RL32(b2
+ cx
);
447 v1
= AV_RL32(b1
+ cx
);
448 AV_WL32(b2
+ cx
, v1
);
449 AV_WL32(b1
+ cx
, v0
);
455 while (len
> 0 && cy
> 0) {
456 fill
= bytestream2_get_le32(&dc
);
457 AV_WL32(b1
+ cx
, AV_RL32(b2
+ cx
));
458 AV_WL32(b2
+ cx
, fill
);
464 avpriv_request_sample(avctx
, "runlen %d", type
);
465 return AVERROR_INVALIDDATA
;
469 bytestream2_skip(gb
, size
- (bytestream2_tell(gb
) - pos
));
474 static int decode_kfrm(AVCodecContext
*avctx
,
475 const AVPacket
*avpkt
, unsigned size
)
477 RASCContext
*s
= avctx
->priv_data
;
478 z_stream
*const zstream
= &s
->zstream
.zstream
;
479 GetByteContext
*gb
= &s
->gb
;
484 pos
= bytestream2_tell(gb
);
485 if (bytestream2_peek_le32(gb
) == 0x65) {
486 ret
= decode_fint(avctx
, avpkt
, size
);
491 if (!s
->frame2
->data
[0])
492 return AVERROR_INVALIDDATA
;
494 zret
= inflateReset(zstream
);
496 av_log(avctx
, AV_LOG_ERROR
, "Inflate reset error: %d\n", zret
);
497 return AVERROR_EXTERNAL
;
500 zstream
->next_in
= avpkt
->data
+ bytestream2_tell(gb
);
501 zstream
->avail_in
= bytestream2_get_bytes_left(gb
);
503 dst
= s
->frame2
->data
[0] + (avctx
->height
- 1) * s
->frame2
->linesize
[0];
504 for (int i
= 0; i
< avctx
->height
; i
++) {
505 zstream
->next_out
= dst
;
506 zstream
->avail_out
= s
->stride
;
508 zret
= inflate(zstream
, Z_SYNC_FLUSH
);
509 if (zret
!= Z_OK
&& zret
!= Z_STREAM_END
) {
510 av_log(avctx
, AV_LOG_ERROR
,
511 "Inflate failed with return code: %d.\n", zret
);
512 return AVERROR_INVALIDDATA
;
515 dst
-= s
->frame2
->linesize
[0];
518 dst
= s
->frame1
->data
[0] + (avctx
->height
- 1) * s
->frame1
->linesize
[0];
519 for (int i
= 0; i
< avctx
->height
; i
++) {
520 zstream
->next_out
= dst
;
521 zstream
->avail_out
= s
->stride
;
523 zret
= inflate(zstream
, Z_SYNC_FLUSH
);
524 if (zret
!= Z_OK
&& zret
!= Z_STREAM_END
) {
525 av_log(avctx
, AV_LOG_ERROR
,
526 "Inflate failed with return code: %d.\n", zret
);
527 return AVERROR_INVALIDDATA
;
530 dst
-= s
->frame1
->linesize
[0];
533 bytestream2_skip(gb
, size
- (bytestream2_tell(gb
) - pos
));
538 static int decode_mous(AVCodecContext
*avctx
,
539 const AVPacket
*avpkt
, unsigned size
)
541 RASCContext
*s
= avctx
->priv_data
;
542 GetByteContext
*gb
= &s
->gb
;
543 unsigned w
, h
, pos
, uncompressed_size
;
546 pos
= bytestream2_tell(gb
);
547 bytestream2_skip(gb
, 8);
548 w
= bytestream2_get_le32(gb
);
549 h
= bytestream2_get_le32(gb
);
550 bytestream2_skip(gb
, 12);
551 uncompressed_size
= bytestream2_get_le32(gb
);
553 if (w
> avctx
->width
|| h
> avctx
->height
)
554 return AVERROR_INVALIDDATA
;
556 if (uncompressed_size
!= 3 * w
* h
)
557 return AVERROR_INVALIDDATA
;
559 av_fast_padded_malloc(&s
->cursor
, &s
->cursor_size
, uncompressed_size
);
561 return AVERROR(ENOMEM
);
563 ret
= decode_zlib(avctx
, avpkt
,
564 size
- (bytestream2_tell(gb
) - pos
),
568 memcpy(s
->cursor
, s
->delta
, uncompressed_size
);
570 bytestream2_skip(gb
, size
- (bytestream2_tell(gb
) - pos
));
578 static int decode_mpos(AVCodecContext
*avctx
,
579 const AVPacket
*avpkt
, unsigned size
)
581 RASCContext
*s
= avctx
->priv_data
;
582 GetByteContext
*gb
= &s
->gb
;
585 pos
= bytestream2_tell(gb
);
586 bytestream2_skip(gb
, 8);
587 s
->cursor_x
= bytestream2_get_le32(gb
);
588 s
->cursor_y
= bytestream2_get_le32(gb
);
590 bytestream2_skip(gb
, size
- (bytestream2_tell(gb
) - pos
));
595 static void draw_cursor(AVCodecContext
*avctx
)
597 RASCContext
*s
= avctx
->priv_data
;
603 if (s
->cursor_x
>= avctx
->width
|| s
->cursor_y
>= avctx
->height
)
606 if (s
->cursor_x
+ s
->cursor_w
> avctx
->width
||
607 s
->cursor_y
+ s
->cursor_h
> avctx
->height
)
610 if (avctx
->pix_fmt
== AV_PIX_FMT_PAL8
) {
611 pal
= s
->frame
->data
[1];
612 for (int i
= 0; i
< s
->cursor_h
; i
++) {
613 for (int j
= 0; j
< s
->cursor_w
; j
++) {
614 int cr
= s
->cursor
[3 * s
->cursor_w
* (s
->cursor_h
- i
- 1) + 3 * j
+ 0];
615 int cg
= s
->cursor
[3 * s
->cursor_w
* (s
->cursor_h
- i
- 1) + 3 * j
+ 1];
616 int cb
= s
->cursor
[3 * s
->cursor_w
* (s
->cursor_h
- i
- 1) + 3 * j
+ 2];
621 if (cr
== s
->cursor
[0] && cg
== s
->cursor
[1] && cb
== s
->cursor
[2])
624 dst
= s
->frame
->data
[0] + s
->frame
->linesize
[0] * (int)(s
->cursor_y
+ i
) + (int)(s
->cursor_x
+ j
);
625 for (int k
= 0; k
< 256; k
++) {
626 int pr
= pal
[k
* 4 + 0];
627 int pg
= pal
[k
* 4 + 1];
628 int pb
= pal
[k
* 4 + 2];
630 dist
= FFABS(cr
- pr
) + FFABS(cg
- pg
) + FFABS(cb
- pb
);
639 } else if (avctx
->pix_fmt
== AV_PIX_FMT_RGB555LE
) {
640 for (int i
= 0; i
< s
->cursor_h
; i
++) {
641 for (int j
= 0; j
< s
->cursor_w
; j
++) {
642 int cr
= s
->cursor
[3 * s
->cursor_w
* (s
->cursor_h
- i
- 1) + 3 * j
+ 0];
643 int cg
= s
->cursor
[3 * s
->cursor_w
* (s
->cursor_h
- i
- 1) + 3 * j
+ 1];
644 int cb
= s
->cursor
[3 * s
->cursor_w
* (s
->cursor_h
- i
- 1) + 3 * j
+ 2];
646 if (cr
== s
->cursor
[0] && cg
== s
->cursor
[1] && cb
== s
->cursor
[2])
649 cr
>>= 3; cg
>>=3; cb
>>= 3;
650 dst
= s
->frame
->data
[0] + s
->frame
->linesize
[0] * (int)(s
->cursor_y
+ i
) + 2 * (s
->cursor_x
+ j
);
651 AV_WL16(dst
, cr
| cg
<< 5 | cb
<< 10);
654 } else if (avctx
->pix_fmt
== AV_PIX_FMT_BGR0
) {
655 for (int i
= 0; i
< s
->cursor_h
; i
++) {
656 for (int j
= 0; j
< s
->cursor_w
; j
++) {
657 int cr
= s
->cursor
[3 * s
->cursor_w
* (s
->cursor_h
- i
- 1) + 3 * j
+ 0];
658 int cg
= s
->cursor
[3 * s
->cursor_w
* (s
->cursor_h
- i
- 1) + 3 * j
+ 1];
659 int cb
= s
->cursor
[3 * s
->cursor_w
* (s
->cursor_h
- i
- 1) + 3 * j
+ 2];
661 if (cr
== s
->cursor
[0] && cg
== s
->cursor
[1] && cb
== s
->cursor
[2])
664 dst
= s
->frame
->data
[0] + s
->frame
->linesize
[0] * (int)(s
->cursor_y
+ i
) + 4 * (s
->cursor_x
+ j
);
673 static int decode_frame(AVCodecContext
*avctx
, AVFrame
*frame
,
674 int *got_frame
, AVPacket
*avpkt
)
676 RASCContext
*s
= avctx
->priv_data
;
677 GetByteContext
*gb
= &s
->gb
;
680 bytestream2_init(gb
, avpkt
->data
, avpkt
->size
);
682 if (bytestream2_peek_le32(gb
) == EMPT
)
687 while (bytestream2_get_bytes_left(gb
) > 0) {
688 unsigned type
, size
= 0;
690 if (bytestream2_get_bytes_left(gb
) < 8)
691 return AVERROR_INVALIDDATA
;
693 type
= bytestream2_get_le32(gb
);
694 if (type
== KBND
|| type
== BNDL
) {
695 intra
= type
== KBND
;
696 type
= bytestream2_get_le32(gb
);
699 size
= bytestream2_get_le32(gb
);
700 if (bytestream2_get_bytes_left(gb
) < size
)
701 return AVERROR_INVALIDDATA
;
706 ret
= decode_fint(avctx
, avpkt
, size
);
709 ret
= decode_kfrm(avctx
, avpkt
, size
);
712 ret
= decode_dlta(avctx
, avpkt
, size
);
715 ret
= decode_move(avctx
, avpkt
, size
);
718 ret
= decode_mous(avctx
, avpkt
, size
);
721 ret
= decode_mpos(avctx
, avpkt
, size
);
724 bytestream2_skip(gb
, size
);
732 if (!s
->frame2
->data
[0] || !s
->frame1
->data
[0])
733 return AVERROR_INVALIDDATA
;
735 if ((ret
= ff_get_buffer(avctx
, s
->frame
, 0)) < 0)
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);
745 s
->frame
->flags
|= AV_FRAME_FLAG_KEY
;
747 s
->frame
->flags
&= ~AV_FRAME_FLAG_KEY
;
748 s
->frame
->pict_type
= intra
? AV_PICTURE_TYPE_I
: AV_PICTURE_TYPE_P
;
755 static av_cold
int decode_init(AVCodecContext
*avctx
)
757 RASCContext
*s
= avctx
->priv_data
;
759 s
->frame1
= av_frame_alloc();
760 s
->frame2
= av_frame_alloc();
761 if (!s
->frame1
|| !s
->frame2
)
762 return AVERROR(ENOMEM
);
764 return ff_inflate_init(&s
->zstream
, avctx
);
767 static av_cold
int decode_close(AVCodecContext
*avctx
)
769 RASCContext
*s
= avctx
->priv_data
;
771 av_freep(&s
->cursor
);
775 av_frame_free(&s
->frame1
);
776 av_frame_free(&s
->frame2
);
777 ff_inflate_end(&s
->zstream
);
782 static void decode_flush(AVCodecContext
*avctx
)
784 RASCContext
*s
= avctx
->priv_data
;
786 clear_plane(avctx
, s
->frame1
);
787 clear_plane(avctx
, s
->frame2
);
790 static const AVOption options
[] = {
791 { "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
},
795 static const AVClass rasc_decoder_class
= {
796 .class_name
= "rasc decoder",
797 .item_name
= av_default_item_name
,
799 .version
= LIBAVUTIL_VERSION_INT
,
802 const FFCodec ff_rasc_decoder
= {
804 CODEC_LONG_NAME("RemotelyAnywhere Screen Capture"),
805 .p
.type
= AVMEDIA_TYPE_VIDEO
,
806 .p
.id
= AV_CODEC_ID_RASC
,
807 .priv_data_size
= sizeof(RASCContext
),
809 .close
= decode_close
,
810 FF_CODEC_DECODE_CB(decode_frame
),
811 .flush
= decode_flush
,
812 .p
.capabilities
= AV_CODEC_CAP_DR1
,
813 .caps_internal
= FF_CODEC_CAP_INIT_CLEANUP
,
814 .p
.priv_class
= &rasc_decoder_class
,