[FFmpeg-devel] [PATCH] avcodec: add Brooktree ProSumer Video decoder

Michael Niedermayer michael at niedermayer.cc
Thu Aug 23 14:59:05 EEST 2018


On Wed, Aug 22, 2018 at 06:00:54PM +0200, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
>  libavcodec/Makefile     |   1 +
>  libavcodec/allcodecs.c  |   1 +
>  libavcodec/avcodec.h    |   1 +
>  libavcodec/codec_desc.c |   7 +
>  libavcodec/prosumer.c   | 405 ++++++++++++++++++++++++++++++++++++++++
>  libavformat/riff.c      |   1 +
>  6 files changed, 416 insertions(+)
>  create mode 100644 libavcodec/prosumer.c
> 
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index f0c8226283..9a309c348e 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -515,6 +515,7 @@ OBJS-$(CONFIG_PRORES_DECODER)          += proresdec2.o proresdsp.o proresdata.o
>  OBJS-$(CONFIG_PRORES_ENCODER)          += proresenc_anatoliy.o
>  OBJS-$(CONFIG_PRORES_AW_ENCODER)       += proresenc_anatoliy.o
>  OBJS-$(CONFIG_PRORES_KS_ENCODER)       += proresenc_kostya.o proresdata.o
> +OBJS-$(CONFIG_PROSUMER_DECODER)        += prosumer.o
>  OBJS-$(CONFIG_PSD_DECODER)             += psd.o
>  OBJS-$(CONFIG_PTX_DECODER)             += ptx.o
>  OBJS-$(CONFIG_QCELP_DECODER)           += qcelpdec.o                     \
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index fd35fc1d0b..b1d1ef26c0 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -235,6 +235,7 @@ extern AVCodec ff_prores_encoder;
>  extern AVCodec ff_prores_decoder;
>  extern AVCodec ff_prores_aw_encoder;
>  extern AVCodec ff_prores_ks_encoder;
> +extern AVCodec ff_prosumer_decoder;
>  extern AVCodec ff_psd_decoder;
>  extern AVCodec ff_ptx_decoder;
>  extern AVCodec ff_qdraw_decoder;
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 31e50d5a94..2a4be2ca4f 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -448,6 +448,7 @@ enum AVCodecID {
>      AV_CODEC_ID_GDV,
>      AV_CODEC_ID_FITS,
>      AV_CODEC_ID_IMM4,
> +    AV_CODEC_ID_PROSUMER,
>  
>      /* various PCM "codecs" */
>      AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
> diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
> index af66b35d2b..e611183599 100644
> --- a/libavcodec/codec_desc.c
> +++ b/libavcodec/codec_desc.c
> @@ -1661,6 +1661,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
>          .long_name = NULL_IF_CONFIG_SMALL("Infinity IMM4"),
>          .props     = AV_CODEC_PROP_LOSSY,
>      },
> +    {
> +        .id        = AV_CODEC_ID_PROSUMER,
> +        .type      = AVMEDIA_TYPE_VIDEO,
> +        .name      = "prosumer",
> +        .long_name = NULL_IF_CONFIG_SMALL("Brooktree ProSumer Video"),
> +        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
> +    },
>  
>      /* various PCM "codecs" */
>      {
> diff --git a/libavcodec/prosumer.c b/libavcodec/prosumer.c
> new file mode 100644
> index 0000000000..7b9d5e7bdb
> --- /dev/null
> +++ b/libavcodec/prosumer.c
> @@ -0,0 +1,405 @@
> +/*
> + * Brooktree ProSumer Video decoder
> + * Copyright (c) 2018 Paul B Mahol
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "libavutil/imgutils.h"
> +#include "libavutil/internal.h"
> +#include "libavutil/intreadwrite.h"
> +#include "libavutil/mem.h"
> +
> +#include "avcodec.h"
> +#include "bytestream.h"
> +#include "internal.h"
> +
> +typedef struct ProSumerContext {
> +    GetByteContext gb;
> +    PutByteContext pb;
> +
> +    unsigned stride;
> +    unsigned size;
> +    unsigned lut[0x10000];
> +    uint8_t *table_b;
> +    uint8_t *decbuffer;
> +} ProSumerContext;
> +
> +#define PAIR(high, low) (((uint64_t)(high)<<sizeof(high)*8) | low)
> +
> +static int decompress(GetByteContext *gb, int size, PutByteContext *pb, const unsigned *lut)
> +{
> +    int i, pos, idx, cnt, fill;
> +    unsigned a, b, c;
> +
> +    bytestream2_skip(gb, 32);
> +    cnt = 4;
> +    a = bytestream2_get_le32(gb);
> +    idx = a >> 20;
> +    b = lut[2 * idx];
> +
> +    while (1) {
> +        if (((b & 0xFF00u) != 0x8000u) || (b & 0xFFu)) {
> +            if ((b & 0xFF00u) != 0x8000u) {
> +                bytestream2_put_le16(pb, b);
> +            } else if (b & 0xFFu) {
> +                idx = 0;
> +                for (i = 0; i < (b & 0xFFu); i++)
> +                    bytestream2_put_le32(pb, 0);
> +            }
> +            c = b >> 16;
> +            if (c & 0xFF00u) {
> +                c = (((c >> 8) & 0xFFu) | (c & 0xFF00)) & 0xF00F;
> +                fill = lut[2 * idx + 1];
> +                if ((c & 0xFF00u) == 0x1000) {
> +                    bytestream2_put_le16(pb, fill);
> +                    c &= 0xFFFF00FFu;
> +                } else {
> +                    bytestream2_put_le32(pb, fill);
> +                    c &= 0xFFFF00FFu;
> +                }
> +            }
> +            while (c) {
> +                a <<= 4;
> +                cnt--;
> +                if (!cnt) {
> +                    if (bytestream2_get_bytes_left(gb) <= 0) {
> +                        if (!a)
> +                            return 0;
> +                        cnt = 4;
> +                    } else {
> +                        pos = bytestream2_tell(gb) ^ 2;
> +                        bytestream2_seek(gb, pos, SEEK_SET);
> +                        AV_WN16(&a, bytestream2_peek_le16(gb));
> +                        pos = pos ^ 2;
> +                        bytestream2_seek(gb, pos, SEEK_SET);
> +                        bytestream2_skip(gb, 2);
> +                        cnt = 4;
> +                    }
> +                }
> +                c--;
> +            }
> +            idx = a >> 20;
> +            b = lut[2 * idx];
> +            continue;
> +        }
> +        idx = 2;
> +        while (idx) {
> +            a <<= 4;
> +            cnt--;
> +            if (cnt) {
> +                idx--;
> +                continue;
> +            }
> +            if (bytestream2_get_bytes_left(gb) <= 0) {
> +                if (a) {
> +                    cnt = 4;
> +                    idx--;
> +                    continue;
> +                }
> +                return 0;
> +            }
> +            pos = bytestream2_tell(gb) ^ 2;
> +            bytestream2_seek(gb, pos, SEEK_SET);
> +            AV_WN16(&a, bytestream2_peek_le16(gb));
> +            pos = pos ^ 2;
> +            bytestream2_seek(gb, pos, SEEK_SET);
> +            bytestream2_skip(gb, 2);
> +            cnt = 4;
> +            idx--;
> +        }

> +        b = PAIR(4, a) >> 16;

I think this assumes sizeof(int) == 4, this is not guranteed it could be 8


[...]
-- 
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/20180823/8a24ca1d/attachment.sig>


More information about the ffmpeg-devel mailing list