[FFmpeg-devel] [PATCH] avcodec: add RemotelyAnywhere Screen Capture decoder

Michael Niedermayer michael at niedermayer.cc
Fri Sep 7 03:16:33 EEST 2018


On Thu, Sep 06, 2018 at 10:05:50PM +0200, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
>  configure               |   1 +
>  libavcodec/Makefile     |   1 +
>  libavcodec/allcodecs.c  |   1 +
>  libavcodec/avcodec.h    |   1 +
>  libavcodec/codec_desc.c |   7 +
>  libavcodec/rasc.c       | 789 ++++++++++++++++++++++++++++++++++++++++
>  libavformat/riff.c      |   1 +
>  7 files changed, 801 insertions(+)
>  create mode 100644 libavcodec/rasc.c
[...]
> +static int decode_dlta(AVCodecContext *avctx,
> +                       AVPacket *avpkt, unsigned size)
> +{
> +    RASCContext *s = avctx->priv_data;
> +    GetByteContext *gb = &s->gb;
> +    GetByteContext dc;
> +    unsigned uncompressed_size, pos;
> +    unsigned x, y, w, h;
> +    int ret, cx, cy, compression;
> +    uint8_t *b1, *b2;
> +
> +    pos = bytestream2_tell(gb);
> +    bytestream2_skip(gb, 12);
> +    uncompressed_size = bytestream2_get_le32(gb);
> +    x = bytestream2_get_le32(gb);
> +    y = bytestream2_get_le32(gb);
> +    w = bytestream2_get_le32(gb);
> +    h = bytestream2_get_le32(gb);
> +
> +    if (x >= avctx->width || y >= avctx->height ||
> +        w > avctx->width || h > avctx->height)
> +        return AVERROR_INVALIDDATA;
> +
> +    if (x + w > avctx->width || y + h > avctx->height)
> +        return AVERROR_INVALIDDATA;
> +
> +    bytestream2_skip(gb, 4);
> +    compression = bytestream2_get_le32(gb);
> +
> +    if (compression == 1) {
> +        ret = decode_zlib(avctx, avpkt, size, uncompressed_size);
> +        if (ret < 0)
> +            return ret;
> +        bytestream2_init(&dc, s->delta, uncompressed_size);
> +    } else if (compression == 0) {
> +        if (bytestream2_get_bytes_left(gb) < uncompressed_size)
> +            return AVERROR_INVALIDDATA;
> +        bytestream2_init(&dc, avpkt->data + bytestream2_tell(gb),
> +                         uncompressed_size);
> +    } else if (compression == 2) {
> +        avpriv_request_sample(avctx, "compression %d", compression);
> +        return AVERROR_PATCHWELCOME;
> +    } else {
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    if (!s->frame2->data[0] || !s->frame1->data[0])
> +        return AVERROR_INVALIDDATA;
> +
> +    b1  = s->frame1->data[0] + s->frame1->linesize[0] * (y + h - 1) + x * s->bpp;
> +    b2  = s->frame2->data[0] + s->frame2->linesize[0] * (y + h - 1) + x * s->bpp;
> +    cx = 0, cy = h;
> +    while (bytestream2_get_bytes_left(&dc) > 0) {
> +        int type = bytestream2_get_byte(&dc);
> +        int len = bytestream2_get_byte(&dc);
> +        unsigned fill;
> +
> +        switch (type) {
> +        case 1:
> +            while (len > 0 && cy > 0) {
> +                cx++;
> +                NEXT_LINE
> +            }
> +            break;
> +        case 2:
> +            while (len > 0 && cy > 0) {
> +                int v0 = b1[cx];
> +                int v1 = b2[cx];
> +
> +                b2[cx] = v0;
> +                b1[cx] = v1;
> +                cx++;
> +                NEXT_LINE
> +            }
> +            break;
> +        case 3:
> +            while (len > 0 && cy > 0) {
> +                fill = bytestream2_get_byte(&dc);
> +                b1[cx] = b2[cx];
> +                b2[cx] = fill;
> +                cx++;
> +                NEXT_LINE
> +            }
> +            break;
> +        case 4:
> +            fill = bytestream2_get_byte(&dc);
> +            while (len > 0 && cy > 0) {
> +                AV_WL32(b1 + cx, AV_RL32(b2 + cx));
> +                AV_WL32(b2 + cx, fill);
> +                cx++;
> +                NEXT_LINE
> +            }
> +            break;
> +        case 7:
> +            fill = bytestream2_get_le32(&dc);
> +            while (len > 0 && cy > 0) {
> +                AV_WL32(b1 + cx, AV_RL32(b2 + cx));
> +                AV_WL32(b2 + cx, fill);
> +                cx += 4;
> +                NEXT_LINE
> +            }
> +            break;
> +        case 10:
> +            while (len > 0 && cy > 0) {
> +                cx += 4;
> +                NEXT_LINE
> +            }
> +            break;
> +        case 12:
> +            while (len > 0 && cy > 0) {
> +                unsigned v0, v1;
> +
> +                v0 = AV_RL32(b2 + cx);
> +                v1 = AV_RL32(b1 + cx);
> +                AV_WL32(b2 + cx, v1);
> +                AV_WL32(b1 + cx, v0);
> +                cx += 4;
> +                NEXT_LINE
> +            }
> +            break;
> +        case 13:
> +            while (len > 0 && cy > 0) {
> +                fill = bytestream2_get_le32(&dc);
> +                AV_WL32(b1 + cx, AV_RL32(b2 + cx));
> +                AV_WL32(b2 + cx, fill);
> +                cx += 4;
> +                NEXT_LINE
> +            }
> +            break;
> +        default:

> +            printf("%d %d\n", type, bytestream2_tell(&dc));
> +            bytestream2_seek(&dc, 0, SEEK_SET);
> +            for (int i = 0; bytestream2_get_bytes_left(&dc) > 0; i++)
> +                printf("%02X ", bytestream2_get_byte(&dc));
> +            printf("\n");

forgotten debug code ? (or it should be av_log())

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Dictatorship: All citizens are under surveillance, all their steps and
actions recorded, for the politicians to enforce control.
Democracy: All politicians are under surveillance, all their steps and
actions recorded, for the citizens to enforce control.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20180907/f38cc849/attachment.sig>


More information about the ffmpeg-devel mailing list