On Mon, Dec 03, 2012 at 11:55:11AM -0500, Justin Ruggles wrote:
> From: Paul B Mahol <one...@gmail.com>
> 
> Signed-off-by: Paul B Mahol <one...@gmail.com>
> Signed-off-by: Justin Ruggles <justin.rugg...@gmail.com>
> ---
>  Changelog                |    1 +
>  configure                |    1 +
>  doc/general.texi         |    2 +
>  libavcodec/Makefile      |    2 +
>  libavcodec/allcodecs.c   |    2 +
>  libavcodec/avcodec.h     |    1 +
>  libavcodec/codec_desc.c  |    7 +
>  libavcodec/tak.c         |  159 ++++++++
>  libavcodec/tak.h         |  160 ++++++++
>  libavcodec/tak_parser.c  |  128 ++++++
>  libavcodec/takdec.c      |  963 
> ++++++++++++++++++++++++++++++++++++++++++++++
>  libavcodec/version.h     |    2 +-
>  libavformat/Makefile     |    1 +
>  libavformat/allformats.c |    1 +
>  libavformat/takdec.c     |  186 +++++++++
>  libavformat/version.h    |    2 +-
>  16 files changed, 1616 insertions(+), 2 deletions(-)
>  create mode 100644 libavcodec/tak.c
>  create mode 100644 libavcodec/tak.h
>  create mode 100644 libavcodec/tak_parser.c
>  create mode 100644 libavcodec/takdec.c
>  create mode 100644 libavformat/takdec.c
> 
> diff --git a/Changelog b/Changelog
> index 33e55a5..6e672ed 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -4,6 +4,7 @@ releases are sorted from youngest to oldest.
>  version <next>:
>  - ashowinfo audio filter
>  - 24-bit FLAC encoding
> +- TAK demuxer, decoder and parser

not-even-diego-nano-nit: I'd rather list it in processing order
(demuxer, parser, decoder), otherwise it sounds like "and the most important -
parser!" to me.

> diff --git a/libavcodec/tak.c b/libavcodec/tak.c
> new file mode 100644
> index 0000000..6113b55
> --- /dev/null
> +++ b/libavcodec/tak.c
> @@ -0,0 +1,159 @@
> +/*
> + * TAK common code
> + * Copyright (c) 2012 Paul B Mahol
> + *
> + * This file is part of Libav.
> + *
> + * Libav 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.
> + *
> + * Libav 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 Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +#include "libavutil/bswap.h"
> +#include "libavutil/crc.h"
> +#include "libavutil/intreadwrite.h"
> +#include "tak.h"
> +
> +static const uint16_t frame_duration_type_quants[] = {
> +    3, 4, 6, 8, 4096, 8192, 16384, 512, 1024, 2048,
> +};
> +
> +static int tak_get_nb_samples(int sample_rate, enum TAKFrameSizeType type)
> +{
> +    int nb_samples, max_nb_samples;
> +
> +    if (type <= TAK_FST_250ms) {
> +        nb_samples     = sample_rate * frame_duration_type_quants[type] >>
> +                         TAK_FRAME_DURATION_QUANT_SHIFT;
> +        max_nb_samples = 16384;
> +    } else if (type < FF_ARRAY_ELEMS(frame_duration_type_quants)) {
> +        nb_samples     = frame_duration_type_quants[type];
> +        max_nb_samples = sample_rate *
> +                         frame_duration_type_quants[TAK_FST_250ms] >>
> +                         TAK_FRAME_DURATION_QUANT_SHIFT;
> +    } else {
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    if (nb_samples <= 0 || nb_samples > max_nb_samples)
> +        return AVERROR_INVALIDDATA;
> +
> +    return nb_samples;
> +}
> +
> +static int crc_init = 0;
> +#if CONFIG_SMALL
> +#define CRC_TABLE_SIZE 257
> +#else
> +#define CRC_TABLE_SIZE 1024
> +#endif
> +static AVCRC crc_24[CRC_TABLE_SIZE];
> +
> +av_cold void ff_tak_init_crc(void)
> +{
> +    if (!crc_init) {
> +        av_crc_init(crc_24, 0, 24, 0x864CFBU, sizeof(crc_24));
> +        crc_init = 1;
> +    }
> +}
> +
> +int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size)
> +{
> +    uint32_t crc, CRC;
> +
> +    if (buf_size < 4)
> +        return AVERROR_INVALIDDATA;
> +    buf_size -= 3;
> +
> +    CRC = av_bswap32(AV_RL24(buf + buf_size)) >> 8;
> +    crc = av_crc(crc_24, 0xCE04B7U, buf, buf_size);
> +    if (CRC != crc)
> +        return AVERROR_INVALIDDATA;
> +
> +    return 0;
> +}
> +
> +void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s)
> +{
> +    uint64_t channel_mask = 0;
> +    int frame_type, i;
> +
> +    s->codec = get_bits(gb, TAK_ENCODER_CODEC_BITS);
> +    skip_bits(gb, TAK_ENCODER_PROFILE_BITS);
> +
> +    frame_type = get_bits(gb, TAK_SIZE_FRAME_DURATION_BITS);
> +    s->samples = get_bits_longlong(gb, TAK_SIZE_SAMPLES_NUM_BITS);
> +
> +    s->data_type   = get_bits(gb, TAK_FORMAT_DATA_TYPE_BITS);
> +    s->sample_rate = get_bits(gb, TAK_FORMAT_SAMPLE_RATE_BITS) +
> +                     TAK_SAMPLE_RATE_MIN;
> +    s->bps         = get_bits(gb, TAK_FORMAT_BPS_BITS) +
> +                     TAK_BPS_MIN;
> +    s->channels    = get_bits(gb, TAK_FORMAT_CHANNEL_BITS) +
> +                     TAK_CHANNELS_MIN;
> +
> +    if (get_bits1(gb)) {
> +        skip_bits(gb, TAK_FORMAT_VALID_BITS);
> +        if (get_bits1(gb)) {
> +            for (i = 0; i < s->channels; i++) {
> +                int value = get_bits(gb, TAK_FORMAT_CH_LAYOUT_BITS);
> +
> +                if (value > 0 && value <= 18)
> +                    channel_mask |= 1 << (value - 1);
> +            }
> +        }
> +    }
> +
> +    s->ch_layout     = channel_mask;
> +    s->frame_samples = tak_get_nb_samples(s->sample_rate, frame_type);
> +}
> +
> +#define FRAME_IS_LAST       1
> +#define FRAME_HAVE_INFO     2
> +#define FRAME_HAVE_METADATA 4
> +
> +int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
> +                               TAKStreamInfo *ti, int log_level_offset)
> +{
> +    int flags;
> +
> +    if (get_bits(gb, TAK_FRAME_HEADER_SYNC_ID_BITS) != 
> TAK_FRAME_HEADER_SYNC_ID) {
> +        av_log(avctx, AV_LOG_ERROR + log_level_offset, "missing sync id\n");
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    flags         = get_bits(gb, TAK_FRAME_HEADER_FLAGS_BITS);
> +    ti->frame_num = get_bits(gb, TAK_FRAME_HEADER_NO_BITS);
> +
> +    if (flags & FRAME_IS_LAST) {
> +        ti->last_frame_samples = get_bits(gb, 
> TAK_FRAME_HEADER_SAMPLE_COUNT_BITS) + 1;
> +        skip_bits(gb, 2);
> +    } else {
> +        ti->last_frame_samples = 0;
> +    }
> +
> +    if (flags & FRAME_HAVE_INFO) {
> +        avpriv_tak_parse_streaminfo(gb, ti);
> +
> +        if (get_bits(gb, 6))
> +            skip_bits(gb, 25);
> +        align_get_bits(gb);
> +    }
> +
> +    if (flags & FRAME_HAVE_METADATA)
> +        return AVERROR_INVALIDDATA;

Anton would object ;)
I wonder if that's like empty frames in WavPack containing metadata only or
simply unsupported frames.

> +
> +    skip_bits(gb, 24);
> +
> +    return 0;
> +}
[header and parser - no comments]
> diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c
> new file mode 100644
> index 0000000..0d80d44
> --- /dev/null
> +++ b/libavcodec/takdec.c
> @@ -0,0 +1,963 @@
> +/*
> + * TAK decoder
> + * Copyright (c) 2012 Paul B Mahol
> + *
> + * This file is part of Libav.
> + *
> + * Libav 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.
> + *
> + * Libav 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 Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +/**
> + * @file
> + * TAK (Tom's lossless Audio Kompressor) decoder
> + * @author Paul B Mahol
> + */
> +
> +#include "libavutil/samplefmt.h"
> +#include "tak.h"
> +#include "avcodec.h"
> +#include "dsputil.h"
> +#include "unary.h"
> +
> +#define MAX_SUBFRAMES     8                         // max number of 
> subframes per channel
> +#define MAX_PREDICTORS  256
> +
> +typedef struct MCDParam {
> +    int8_t present;                                 // decorrelation 
> parameter availability for this channel
> +    int8_t index;                                   // index into array of 
> decorrelation types
> +    int8_t chan1;
> +    int8_t chan2;
> +} MCDParam;
> +
> +typedef struct TAKDecContext {
> +    AVCodecContext *avctx;                          // parent AVCodecContext
> +    AVFrame         frame;                          // AVFrame for decoded 
> output
> +    DSPContext      dsp;
> +    TAKStreamInfo   ti;
> +    GetBitContext   gb;                             // bitstream reader 
> initialized to start at the current frame
> +
> +    int             uval;
> +    int             nb_samples;                     // number of samples in 
> the current frame
> +    uint8_t        *decode_buffer;
> +    unsigned int    decode_buffer_size;
> +    int32_t        *decoded[TAK_MAX_CHANNELS];      // decoded samples for 
> each channel
> +
> +    int8_t          lpc_mode[TAK_MAX_CHANNELS];
> +    int8_t          sample_shift[TAK_MAX_CHANNELS]; // shift applied to 
> every sample in the channel
> +    int             subframe_scale;
> +
> +    int8_t          dmode;                          // channel decorrelation 
> type in the current frame
> +
> +    MCDParam        mcdparams[TAK_MAX_CHANNELS];    // multichannel 
> decorrelation parameters
> +
> +    int16_t        *residues;
> +    unsigned int    residues_buf_size;
> +} TAKDecContext;
> +
> +static const int8_t mc_dmodes[] = { 1, 3, 4, 6, };
> +
> +static const uint16_t predictor_sizes[] = {
> +    4, 8, 12, 16, 24, 32, 48, 64, 80, 96, 128, 160, 192, 224, 256, 0,
> +};
> +
> +static const struct CParam {
> +    int init;
> +    int escape;
> +    int scale;
> +    int aescape;
> +    int bias;
> +} xcodes[50] = {
> +    { 0x01, 0x0000001, 0x0000001, 0x0000003, 0x0000008 },
> +    { 0x02, 0x0000003, 0x0000001, 0x0000007, 0x0000006 },
> +    { 0x03, 0x0000005, 0x0000002, 0x000000E, 0x000000D },
> +    { 0x03, 0x0000003, 0x0000003, 0x000000D, 0x0000018 },
> +    { 0x04, 0x000000B, 0x0000004, 0x000001C, 0x0000019 },
> +    { 0x04, 0x0000006, 0x0000006, 0x000001A, 0x0000030 },
> +    { 0x05, 0x0000016, 0x0000008, 0x0000038, 0x0000032 },
> +    { 0x05, 0x000000C, 0x000000C, 0x0000034, 0x0000060 },
> +    { 0x06, 0x000002C, 0x0000010, 0x0000070, 0x0000064 },
> +    { 0x06, 0x0000018, 0x0000018, 0x0000068, 0x00000C0 },
> +    { 0x07, 0x0000058, 0x0000020, 0x00000E0, 0x00000C8 },
> +    { 0x07, 0x0000030, 0x0000030, 0x00000D0, 0x0000180 },
> +    { 0x08, 0x00000B0, 0x0000040, 0x00001C0, 0x0000190 },
> +    { 0x08, 0x0000060, 0x0000060, 0x00001A0, 0x0000300 },
> +    { 0x09, 0x0000160, 0x0000080, 0x0000380, 0x0000320 },
> +    { 0x09, 0x00000C0, 0x00000C0, 0x0000340, 0x0000600 },
> +    { 0x0A, 0x00002C0, 0x0000100, 0x0000700, 0x0000640 },
> +    { 0x0A, 0x0000180, 0x0000180, 0x0000680, 0x0000C00 },
> +    { 0x0B, 0x0000580, 0x0000200, 0x0000E00, 0x0000C80 },
> +    { 0x0B, 0x0000300, 0x0000300, 0x0000D00, 0x0001800 },
> +    { 0x0C, 0x0000B00, 0x0000400, 0x0001C00, 0x0001900 },
> +    { 0x0C, 0x0000600, 0x0000600, 0x0001A00, 0x0003000 },
> +    { 0x0D, 0x0001600, 0x0000800, 0x0003800, 0x0003200 },
> +    { 0x0D, 0x0000C00, 0x0000C00, 0x0003400, 0x0006000 },
> +    { 0x0E, 0x0002C00, 0x0001000, 0x0007000, 0x0006400 },
> +    { 0x0E, 0x0001800, 0x0001800, 0x0006800, 0x000C000 },
> +    { 0x0F, 0x0005800, 0x0002000, 0x000E000, 0x000C800 },
> +    { 0x0F, 0x0003000, 0x0003000, 0x000D000, 0x0018000 },
> +    { 0x10, 0x000B000, 0x0004000, 0x001C000, 0x0019000 },
> +    { 0x10, 0x0006000, 0x0006000, 0x001A000, 0x0030000 },
> +    { 0x11, 0x0016000, 0x0008000, 0x0038000, 0x0032000 },
> +    { 0x11, 0x000C000, 0x000C000, 0x0034000, 0x0060000 },
> +    { 0x12, 0x002C000, 0x0010000, 0x0070000, 0x0064000 },
> +    { 0x12, 0x0018000, 0x0018000, 0x0068000, 0x00C0000 },
> +    { 0x13, 0x0058000, 0x0020000, 0x00E0000, 0x00C8000 },
> +    { 0x13, 0x0030000, 0x0030000, 0x00D0000, 0x0180000 },
> +    { 0x14, 0x00B0000, 0x0040000, 0x01C0000, 0x0190000 },
> +    { 0x14, 0x0060000, 0x0060000, 0x01A0000, 0x0300000 },
> +    { 0x15, 0x0160000, 0x0080000, 0x0380000, 0x0320000 },
> +    { 0x15, 0x00C0000, 0x00C0000, 0x0340000, 0x0600000 },
> +    { 0x16, 0x02C0000, 0x0100000, 0x0700000, 0x0640000 },
> +    { 0x16, 0x0180000, 0x0180000, 0x0680000, 0x0C00000 },
> +    { 0x17, 0x0580000, 0x0200000, 0x0E00000, 0x0C80000 },
> +    { 0x17, 0x0300000, 0x0300000, 0x0D00000, 0x1800000 },
> +    { 0x18, 0x0B00000, 0x0400000, 0x1C00000, 0x1900000 },
> +    { 0x18, 0x0600000, 0x0600000, 0x1A00000, 0x3000000 },
> +    { 0x19, 0x1600000, 0x0800000, 0x3800000, 0x3200000 },
> +    { 0x19, 0x0C00000, 0x0C00000, 0x3400000, 0x6000000 },
> +    { 0x1A, 0x2C00000, 0x1000000, 0x7000000, 0x6400000 },
> +    { 0x1A, 0x1800000, 0x1800000, 0x6800000, 0xC000000 },
> +};
> +
> +static av_cold void tak_init_static_data(AVCodec *codec)
> +{
> +    ff_tak_init_crc();
> +}
> +
> +static int set_bps_params(AVCodecContext *avctx)
> +{
> +    switch (avctx->bits_per_coded_sample) {
> +    case 8:
> +        avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
> +        break;
> +    case 16:
> +        avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
> +        break;
> +    case 24:
> +        avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
> +        break;
> +    default:
> +        av_log(avctx, AV_LOG_ERROR, "unsupported bits per sample: %d\n",
> +               avctx->bits_per_coded_sample);
> +        return AVERROR_INVALIDDATA;
> +    }
> +    avctx->bits_per_raw_sample = avctx->bits_per_coded_sample;
> +
> +    return 0;
> +}
> +
> +static void set_sample_rate_params(AVCodecContext *avctx)
> +{
> +    TAKDecContext *s  = avctx->priv_data;
> +    int shift         = 3 - (avctx->sample_rate / 11025);
> +    shift             = FFMAX(0, shift);
> +    s->uval           = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << shift;
> +    s->subframe_scale = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << 1;
> +}
> +
> +static av_cold int tak_decode_init(AVCodecContext *avctx)
> +{
> +    TAKDecContext *s = avctx->priv_data;
> +
> +    ff_dsputil_init(&s->dsp, avctx);
> +
> +    s->avctx = avctx;
> +    avcodec_get_frame_defaults(&s->frame);
> +    avctx->coded_frame = &s->frame;
> +
> +    set_sample_rate_params(avctx);
> +
> +    return set_bps_params(avctx);
> +}
> +
> +static int get_code(GetBitContext *gb, int nbits)
> +{
> +    if (nbits == 1) {
> +        skip_bits1(gb);

looks like very effective coding

> +        return 0;
> +    } else {
> +        return get_sbits(gb, nbits);
> +    }
> +}
> +
[the rest of decoder looks good enough]
> diff --git a/libavformat/takdec.c b/libavformat/takdec.c
> new file mode 100644
> index 0000000..e1034d6
> --- /dev/null
> +++ b/libavformat/takdec.c
> @@ -0,0 +1,186 @@
> +/*
> + * Raw TAK demuxer
> + * Copyright (c) 2012 Paul B Mahol
> + *
> + * This file is part of Libav.
> + *
> + * Libav 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.
> + *
> + * Libav 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 Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +#include "libavcodec/tak.h"
> +#include "avformat.h"
> +#include "internal.h"
> +#include "rawdec.h"
> +#include "apetag.h"
> +
> +typedef struct TAKDemuxContext {
> +    int     mlast_frame;
> +    int64_t data_end;
> +} TAKDemuxContext;
> +
> +static int tak_probe(AVProbeData *p)
> +{
> +    if (!memcmp(p->buf, "tBaK", 4))
> +        return AVPROBE_SCORE_MAX / 2;
> +    return 0;
> +}
> +
> +static int tak_read_header(AVFormatContext *s)
> +{
> +    TAKDemuxContext *tc = s->priv_data;
> +    AVIOContext *pb     = s->pb;
> +    GetBitContext gb;
> +    AVStream *st;
> +    uint8_t *buffer = NULL;
> +    int ret;
> +
> +    st = avformat_new_stream(s, 0);
> +    if (!st)
> +        return AVERROR(ENOMEM);
> +
> +    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
> +    st->codec->codec_id   = AV_CODEC_ID_TAK;
> +    st->need_parsing      = AVSTREAM_PARSE_FULL;
> +
> +    tc->mlast_frame = 0;
> +    if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) {
> +        avio_seek(pb, -4, SEEK_CUR);
> +        return 0;
> +    }
> +
> +    while (!pb->eof_reached) {
> +        enum TAKMetaDataType type;
> +        int size;
> +
> +        type = avio_r8(pb) & 0x7f;
> +        size = avio_rl24(pb);
> +
> +        switch (type) {
> +        case TAK_METADATA_STREAMINFO:
> +        case TAK_METADATA_LAST_FRAME:
> +        case TAK_METADATA_ENCODER:
> +            buffer = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
> +            if (!buffer)
> +                return AVERROR(ENOMEM);
> +
> +            if (avio_read(pb, buffer, size) != size) {
> +                av_freep(&buffer);
> +                return AVERROR(EIO);
> +            }
> +
> +            init_get_bits(&gb, buffer, size * 8);
> +            break;
> +        case TAK_METADATA_MD5: {
> +            uint8_t md5[16];
> +            int i;
> +
> +            if (size != 19)
> +                return AVERROR_INVALIDDATA;
> +            avio_read(pb, md5, 16);
> +            avio_skip(pb, 3);
> +            av_log(s, AV_LOG_VERBOSE, "MD5=");
> +            for (i = 0; i < 16; i++)
> +                av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]);
> +            av_log(s, AV_LOG_VERBOSE, "\n");
> +            break;
> +        }
> +        case TAK_METADATA_END: {
> +            int64_t curpos = avio_tell(pb);
> +
> +            if (pb->seekable) {
> +                ff_ape_parse_tag(s);
> +                avio_seek(pb, curpos, SEEK_SET);
> +            }
> +
> +            tc->data_end += curpos;
> +            return 0;
> +            break;

I smell some redundancy here

> +        }
> +        default:
> +            ret = avio_skip(pb, size);
> +            if (ret < 0)
> +                return ret;
> +        }
> +
> +        if (type == TAK_METADATA_STREAMINFO) {
> +            TAKStreamInfo ti;
> +
> +            avpriv_tak_parse_streaminfo(&gb, &ti);
> +            if (ti.samples > 0)
> +                st->duration = ti.samples;
> +            st->codec->bits_per_coded_sample = ti.bps;
> +            if (ti.ch_layout)
> +                st->codec->channel_layout = ti.ch_layout;
> +            st->codec->sample_rate           = ti.sample_rate;
> +            st->codec->channels              = ti.channels;
> +            st->start_time                   = 0;
> +            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
> +            st->codec->extradata             = buffer;
> +            st->codec->extradata_size        = size;
> +            buffer                           = NULL;
> +        } else if (type == TAK_METADATA_LAST_FRAME) {
> +            if (size != 11)
> +                return AVERROR_INVALIDDATA;
> +            tc->mlast_frame = 1;
> +            tc->data_end    = get_bits_longlong(&gb, 
> TAK_LAST_FRAME_POS_BITS) +
> +                              get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS);
> +            av_freep(&buffer);
> +        } else if (type == TAK_METADATA_ENCODER) {
> +            av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n",
> +                   get_bits_long(&gb, TAK_ENCODER_VERSION_BITS));
> +            av_freep(&buffer);
> +        }
> +    }
> +
> +    return AVERROR_EOF;
> +}
> +
> +static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
> +{
> +    TAKDemuxContext *tc = s->priv_data;
> +    int ret;
> +
> +    if (tc->mlast_frame) {
> +        AVIOContext *pb = s->pb;
> +        int64_t size, left;
> +
> +        left = tc->data_end - avio_tell(s->pb);
> +        size = FFMIN(left, 1024);
> +        if (size <= 0)
> +            return AVERROR_EOF;
> +
> +        ret = av_get_packet(pb, pkt, size);
> +        if (ret < 0)
> +            return ret;
> +
> +        pkt->stream_index = 0;
> +    } else {
> +        ret = ff_raw_read_partial_packet(s, pkt);
> +    }
> +
> +    return ret;
> +}
> +
> +AVInputFormat ff_tak_demuxer = {
> +    .name           = "tak",
> +    .long_name      = NULL_IF_CONFIG_SMALL("raw TAK"),
> +    .priv_data_size = sizeof(TAKDemuxContext),
> +    .read_probe     = tak_probe,
> +    .read_header    = tak_read_header,
> +    .read_packet    = raw_read_packet,
> +    .flags          = AVFMT_GENERIC_INDEX,
> +    .extensions     = "tak",
> +    .raw_codec_id   = AV_CODEC_ID_TAK,
> +};
> diff --git a/libavformat/version.h b/libavformat/version.h
> index 034fa0a..349ba80 100644
> --- a/libavformat/version.h
> +++ b/libavformat/version.h
> @@ -30,7 +30,7 @@
>  #include "libavutil/avutil.h"
>  
>  #define LIBAVFORMAT_VERSION_MAJOR 54
> -#define LIBAVFORMAT_VERSION_MINOR 19
> +#define LIBAVFORMAT_VERSION_MINOR 20
>  #define LIBAVFORMAT_VERSION_MICRO  0
>  
>  #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
> -- 

in general - LGeTM
_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to