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

Paul B Mahol onemda at gmail.com
Sat Sep 8 13:57:23 EEST 2018


On 9/7/18, Michael Niedermayer <michael at niedermayer.cc> wrote:
> 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.
>

Will apply with that removed.


More information about the ffmpeg-devel mailing list