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