[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