[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