Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 12 Sep 2011 18:49:20 +0000 (20:49 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 12 Sep 2011 19:01:12 +0000 (21:01 +0200)
* qatar/master:
  adpcm: split ADPCM encoders and decoders into separate files.
  doc/avconv: fix typo.
  rv34: check that subsequent slices have the same type as first one.
  smacker demuxer: handle possible av_realloc() failure.
  lavfi: add split filter from soc.
  lavfi: add showinfo filter
  libxavs: add private options corresponding to deprecated global options

Conflicts:
Changelog
libavcodec/adpcm.c
libavfilter/avfilter.h
libavfilter/vf_showinfo.c
libavfilter/vf_split.c
libavformat/smacker.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
doc/avconv.texi
libavcodec/Makefile
libavcodec/adpcm.c
libavcodec/adpcm.h [new file with mode: 0644]
libavcodec/adpcm_data.c [new file with mode: 0644]
libavcodec/adpcm_data.h [new file with mode: 0644]
libavcodec/adpcmenc.c [new file with mode: 0644]
libavcodec/libxavs.c
libavcodec/rv34.c
libavfilter/vf_showinfo.c
libavformat/smacker.c

index 8cf5cfd..5cc2589 100644 (file)
@@ -30,7 +30,7 @@ As a general rule, options are applied to the next specified
 file. Therefore, order is important, and you can have the same
 option on the command line multiple times. Each occurrence is
 then applied to the next input or output file.
-Exceptions from this rule are the global options (e.g. vebosity level),
+Exceptions from this rule are the global options (e.g. verbosity level),
 which should be specified first.
 
 @itemize
index 741a9b3..17cc1b4 100644 (file)
@@ -499,10 +499,10 @@ OBJS-$(CONFIG_PCM_U32LE_ENCODER)          += pcm.o
 OBJS-$(CONFIG_PCM_ZORK_DECODER)           += pcm.o
 OBJS-$(CONFIG_PCM_ZORK_ENCODER)           += pcm.o
 
-OBJS-$(CONFIG_ADPCM_4XM_DECODER)          += adpcm.o
+OBJS-$(CONFIG_ADPCM_4XM_DECODER)          += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_ADX_DECODER)          += adxdec.o
 OBJS-$(CONFIG_ADPCM_ADX_ENCODER)          += adxenc.o
-OBJS-$(CONFIG_ADPCM_CT_DECODER)           += adpcm.o
+OBJS-$(CONFIG_ADPCM_CT_DECODER)           += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_EA_DECODER)           += adpcm.o
 OBJS-$(CONFIG_ADPCM_EA_MAXIS_XA_DECODER)  += adpcm.o
 OBJS-$(CONFIG_ADPCM_EA_R1_DECODER)        += adpcm.o
@@ -513,29 +513,29 @@ OBJS-$(CONFIG_ADPCM_G722_DECODER)         += g722.o
 OBJS-$(CONFIG_ADPCM_G722_ENCODER)         += g722.o
 OBJS-$(CONFIG_ADPCM_G726_DECODER)         += g726.o
 OBJS-$(CONFIG_ADPCM_G726_ENCODER)         += g726.o
-OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER)      += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER)      += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER)      += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER)  += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER)  += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER)      += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER)       += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER)       += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER)   += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER)      += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER)      += adpcm.o
-OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER)       += adpcm.o
-OBJS-$(CONFIG_ADPCM_MS_DECODER)           += adpcm.o
-OBJS-$(CONFIG_ADPCM_MS_ENCODER)           += adpcm.o
+OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER)      += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER)      += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER)      += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER)  += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER)  += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_ISS_DECODER)      += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER)       += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER)       += adpcmenc.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER)   += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER)      += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER)      += adpcmenc.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER)       += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_MS_DECODER)           += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_MS_ENCODER)           += adpcmenc.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_SBPRO_2_DECODER)      += adpcm.o
 OBJS-$(CONFIG_ADPCM_SBPRO_3_DECODER)      += adpcm.o
 OBJS-$(CONFIG_ADPCM_SBPRO_4_DECODER)      += adpcm.o
-OBJS-$(CONFIG_ADPCM_SWF_DECODER)          += adpcm.o
-OBJS-$(CONFIG_ADPCM_SWF_ENCODER)          += adpcm.o
+OBJS-$(CONFIG_ADPCM_SWF_DECODER)          += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_SWF_ENCODER)          += adpcmenc.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_THP_DECODER)          += adpcm.o
 OBJS-$(CONFIG_ADPCM_XA_DECODER)           += adpcm.o
-OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER)       += adpcm.o
-OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER)       += adpcm.o
+OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER)       += adpcm.o adpcm_data.o
+OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER)       += adpcmenc.o adpcm_data.o
 
 # libavformat dependencies
 OBJS-$(CONFIG_ADTS_MUXER)              += mpeg4audio.o
index 4e12993..77e1ef6 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * ADPCM codecs
  * Copyright (c) 2001-2003 The ffmpeg Project
  *
  * This file is part of FFmpeg.
 #include "get_bits.h"
 #include "put_bits.h"
 #include "bytestream.h"
+#include "adpcm.h"
+#include "adpcm_data.h"
 
 /**
  * @file
- * ADPCM codecs.
+ * ADPCM decoders
  * First version by Francois Revol (revol@free.fr)
  * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
  *   by Mike Melanson (melanson@pcisys.net)
  * readstr http://www.geocities.co.jp/Playtown/2004/
  */
 
-#define BLKSIZE 1024
-
-/* step_table[] and index_table[] are from the ADPCM reference source */
-/* This is the index table: */
-static const int index_table[16] = {
-    -1, -1, -1, -1, 2, 4, 6, 8,
-    -1, -1, -1, -1, 2, 4, 6, 8,
-};
-
-/**
- * This is the step table. Note that many programs use slight deviations from
- * this table, but such deviations are negligible:
- */
-static const int step_table[89] = {
-    7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
-    19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
-    50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
-    130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
-    337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
-    876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
-    2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
-    5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
-    15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
-};
-
-/* These are for MS-ADPCM */
-/* AdaptationTable[], AdaptCoeff1[], and AdaptCoeff2[] are from libsndfile */
-static const int AdaptationTable[] = {
-        230, 230, 230, 230, 307, 409, 512, 614,
-        768, 614, 512, 409, 307, 230, 230, 230
-};
-
-/** Divided by 4 to fit in 8-bit integers */
-static const uint8_t AdaptCoeff1[] = {
-        64, 128, 0, 48, 60, 115, 98
-};
-
-/** Divided by 4 to fit in 8-bit integers */
-static const int8_t AdaptCoeff2[] = {
-        0, -64, 0, 16, 0, -52, -58
-};
-
 /* These are for CD-ROM XA ADPCM */
 static const int xa_adpcm_table[5][2] = {
    {   0,   0 },
@@ -118,668 +77,15 @@ static const int swf_index_tables[4][16] = {
     /*5*/ { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 }
 };
 
-static const int yamaha_indexscale[] = {
-    230, 230, 230, 230, 307, 409, 512, 614,
-    230, 230, 230, 230, 307, 409, 512, 614
-};
-
-static const int yamaha_difflookup[] = {
-    1, 3, 5, 7, 9, 11, 13, 15,
-    -1, -3, -5, -7, -9, -11, -13, -15
-};
-
 /* end of tables */
 
-typedef struct ADPCMChannelStatus {
-    int predictor;
-    short int step_index;
-    int step;
-    /* for encoding */
-    int prev_sample;
-
-    /* MS version */
-    short sample1;
-    short sample2;
-    int coeff1;
-    int coeff2;
-    int idelta;
-} ADPCMChannelStatus;
-
-typedef struct TrellisPath {
-    int nibble;
-    int prev;
-} TrellisPath;
-
-typedef struct TrellisNode {
-    uint32_t ssd;
-    int path;
-    int sample1;
-    int sample2;
-    int step;
-} TrellisNode;
-
-typedef struct ADPCMContext {
+typedef struct ADPCMDecodeContext {
     ADPCMChannelStatus status[6];
-    TrellisPath *paths;
-    TrellisNode *node_buf;
-    TrellisNode **nodep_buf;
-    uint8_t *trellis_hash;
-} ADPCMContext;
-
-#define FREEZE_INTERVAL 128
-
-/* XXX: implement encoding */
-
-#if CONFIG_ENCODERS
-static av_cold int adpcm_encode_init(AVCodecContext *avctx)
-{
-    ADPCMContext *s = avctx->priv_data;
-    uint8_t *extradata;
-    int i;
-    if (avctx->channels > 2)
-        return -1; /* only stereo or mono =) */
-
-    if(avctx->trellis && (unsigned)avctx->trellis > 16U){
-        av_log(avctx, AV_LOG_ERROR, "invalid trellis size\n");
-        return -1;
-    }
-
-    if (avctx->trellis) {
-        int frontier = 1 << avctx->trellis;
-        int max_paths =  frontier * FREEZE_INTERVAL;
-        FF_ALLOC_OR_GOTO(avctx, s->paths,     max_paths * sizeof(*s->paths), error);
-        FF_ALLOC_OR_GOTO(avctx, s->node_buf,  2 * frontier * sizeof(*s->node_buf), error);
-        FF_ALLOC_OR_GOTO(avctx, s->nodep_buf, 2 * frontier * sizeof(*s->nodep_buf), error);
-        FF_ALLOC_OR_GOTO(avctx, s->trellis_hash, 65536 * sizeof(*s->trellis_hash), error);
-    }
-
-    switch(avctx->codec->id) {
-    case CODEC_ID_ADPCM_IMA_WAV:
-        avctx->frame_size = (BLKSIZE - 4 * avctx->channels) * 8 / (4 * avctx->channels) + 1; /* each 16 bits sample gives one nibble */
-                                                             /* and we have 4 bytes per channel overhead */
-        avctx->block_align = BLKSIZE;
-        avctx->bits_per_coded_sample = 4;
-        /* seems frame_size isn't taken into account... have to buffer the samples :-( */
-        break;
-    case CODEC_ID_ADPCM_IMA_QT:
-        avctx->frame_size = 64;
-        avctx->block_align = 34 * avctx->channels;
-        break;
-    case CODEC_ID_ADPCM_MS:
-        avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 / avctx->channels + 2; /* each 16 bits sample gives one nibble */
-                                                             /* and we have 7 bytes per channel overhead */
-        avctx->block_align = BLKSIZE;
-        avctx->bits_per_coded_sample = 4;
-        avctx->extradata_size = 32;
-        extradata = avctx->extradata = av_malloc(avctx->extradata_size);
-        if (!extradata)
-            return AVERROR(ENOMEM);
-        bytestream_put_le16(&extradata, avctx->frame_size);
-        bytestream_put_le16(&extradata, 7); /* wNumCoef */
-        for (i = 0; i < 7; i++) {
-            bytestream_put_le16(&extradata, AdaptCoeff1[i] * 4);
-            bytestream_put_le16(&extradata, AdaptCoeff2[i] * 4);
-        }
-        break;
-    case CODEC_ID_ADPCM_YAMAHA:
-        avctx->frame_size = BLKSIZE * avctx->channels;
-        avctx->block_align = BLKSIZE;
-        break;
-    case CODEC_ID_ADPCM_SWF:
-        if (avctx->sample_rate != 11025 &&
-            avctx->sample_rate != 22050 &&
-            avctx->sample_rate != 44100) {
-            av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, 22050 or 44100\n");
-            goto error;
-        }
-        avctx->frame_size = 512 * (avctx->sample_rate / 11025);
-        break;
-    default:
-        goto error;
-    }
-
-    avctx->coded_frame= avcodec_alloc_frame();
-    avctx->coded_frame->key_frame= 1;
-
-    return 0;
-error:
-    av_freep(&s->paths);
-    av_freep(&s->node_buf);
-    av_freep(&s->nodep_buf);
-    av_freep(&s->trellis_hash);
-    return -1;
-}
-
-static av_cold int adpcm_encode_close(AVCodecContext *avctx)
-{
-    ADPCMContext *s = avctx->priv_data;
-    av_freep(&avctx->coded_frame);
-    av_freep(&s->paths);
-    av_freep(&s->node_buf);
-    av_freep(&s->nodep_buf);
-    av_freep(&s->trellis_hash);
-
-    return 0;
-}
-
-
-static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c, short sample)
-{
-    int delta = sample - c->prev_sample;
-    int nibble = FFMIN(7, abs(delta)*4/step_table[c->step_index]) + (delta<0)*8;
-    c->prev_sample += ((step_table[c->step_index] * yamaha_difflookup[nibble]) / 8);
-    c->prev_sample = av_clip_int16(c->prev_sample);
-    c->step_index = av_clip(c->step_index + index_table[nibble], 0, 88);
-    return nibble;
-}
-
-static inline unsigned char adpcm_ima_qt_compress_sample(ADPCMChannelStatus *c, short sample)
-{
-    int delta = sample - c->prev_sample;
-    int diff, step = step_table[c->step_index];
-    int nibble = 8*(delta < 0);
-
-    delta= abs(delta);
-    diff = delta + (step >> 3);
-
-    if (delta >= step) {
-        nibble |= 4;
-        delta -= step;
-    }
-    step >>= 1;
-    if (delta >= step) {
-        nibble |= 2;
-        delta -= step;
-    }
-    step >>= 1;
-    if (delta >= step) {
-        nibble |= 1;
-        delta -= step;
-    }
-    diff -= delta;
-
-    if (nibble & 8)
-        c->prev_sample -= diff;
-    else
-        c->prev_sample += diff;
-
-    c->prev_sample = av_clip_int16(c->prev_sample);
-    c->step_index = av_clip(c->step_index + index_table[nibble], 0, 88);
-
-    return nibble;
-}
-
-static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c, short sample)
-{
-    int predictor, nibble, bias;
-
-    predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 64;
-
-    nibble= sample - predictor;
-    if(nibble>=0) bias= c->idelta/2;
-    else          bias=-c->idelta/2;
-
-    nibble= (nibble + bias) / c->idelta;
-    nibble= av_clip(nibble, -8, 7)&0x0F;
-
-    predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta;
-
-    c->sample2 = c->sample1;
-    c->sample1 = av_clip_int16(predictor);
-
-    c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8;
-    if (c->idelta < 16) c->idelta = 16;
-
-    return nibble;
-}
-
-static inline unsigned char adpcm_yamaha_compress_sample(ADPCMChannelStatus *c, short sample)
-{
-    int nibble, delta;
-
-    if(!c->step) {
-        c->predictor = 0;
-        c->step = 127;
-    }
-
-    delta = sample - c->predictor;
-
-    nibble = FFMIN(7, abs(delta)*4/c->step) + (delta<0)*8;
-
-    c->predictor += ((c->step * yamaha_difflookup[nibble]) / 8);
-    c->predictor = av_clip_int16(c->predictor);
-    c->step = (c->step * yamaha_indexscale[nibble]) >> 8;
-    c->step = av_clip(c->step, 127, 24567);
-
-    return nibble;
-}
-
-static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples,
-                                   uint8_t *dst, ADPCMChannelStatus *c, int n)
-{
-    //FIXME 6% faster if frontier is a compile-time constant
-    ADPCMContext *s = avctx->priv_data;
-    const int frontier = 1 << avctx->trellis;
-    const int stride = avctx->channels;
-    const int version = avctx->codec->id;
-    TrellisPath *paths = s->paths, *p;
-    TrellisNode *node_buf = s->node_buf;
-    TrellisNode **nodep_buf = s->nodep_buf;
-    TrellisNode **nodes = nodep_buf; // nodes[] is always sorted by .ssd
-    TrellisNode **nodes_next = nodep_buf + frontier;
-    int pathn = 0, froze = -1, i, j, k, generation = 0;
-    uint8_t *hash = s->trellis_hash;
-    memset(hash, 0xff, 65536 * sizeof(*hash));
-
-    memset(nodep_buf, 0, 2 * frontier * sizeof(*nodep_buf));
-    nodes[0] = node_buf + frontier;
-    nodes[0]->ssd = 0;
-    nodes[0]->path = 0;
-    nodes[0]->step = c->step_index;
-    nodes[0]->sample1 = c->sample1;
-    nodes[0]->sample2 = c->sample2;
-    if((version == CODEC_ID_ADPCM_IMA_WAV) || (version == CODEC_ID_ADPCM_IMA_QT) || (version == CODEC_ID_ADPCM_SWF))
-        nodes[0]->sample1 = c->prev_sample;
-    if(version == CODEC_ID_ADPCM_MS)
-        nodes[0]->step = c->idelta;
-    if(version == CODEC_ID_ADPCM_YAMAHA) {
-        if(c->step == 0) {
-            nodes[0]->step = 127;
-            nodes[0]->sample1 = 0;
-        } else {
-            nodes[0]->step = c->step;
-            nodes[0]->sample1 = c->predictor;
-        }
-    }
-
-    for(i=0; i<n; i++) {
-        TrellisNode *t = node_buf + frontier*(i&1);
-        TrellisNode **u;
-        int sample = samples[i*stride];
-        int heap_pos = 0;
-        memset(nodes_next, 0, frontier*sizeof(TrellisNode*));
-        for(j=0; j<frontier && nodes[j]; j++) {
-            // higher j have higher ssd already, so they're likely to yield a suboptimal next sample too
-            const int range = (j < frontier/2) ? 1 : 0;
-            const int step = nodes[j]->step;
-            int nidx;
-            if(version == CODEC_ID_ADPCM_MS) {
-                const int predictor = ((nodes[j]->sample1 * c->coeff1) + (nodes[j]->sample2 * c->coeff2)) / 64;
-                const int div = (sample - predictor) / step;
-                const int nmin = av_clip(div-range, -8, 6);
-                const int nmax = av_clip(div+range, -7, 7);
-                for(nidx=nmin; nidx<=nmax; nidx++) {
-                    const int nibble = nidx & 0xf;
-                    int dec_sample = predictor + nidx * step;
-#define STORE_NODE(NAME, STEP_INDEX)\
-                    int d;\
-                    uint32_t ssd;\
-                    int pos;\
-                    TrellisNode *u;\
-                    uint8_t *h;\
-                    dec_sample = av_clip_int16(dec_sample);\
-                    d = sample - dec_sample;\
-                    ssd = nodes[j]->ssd + d*d;\
-                    /* Check for wraparound, skip such samples completely. \
-                     * Note, changing ssd to a 64 bit variable would be \
-                     * simpler, avoiding this check, but it's slower on \
-                     * x86 32 bit at the moment. */\
-                    if (ssd < nodes[j]->ssd)\
-                        goto next_##NAME;\
-                    /* Collapse any two states with the same previous sample value. \
-                     * One could also distinguish states by step and by 2nd to last
-                     * sample, but the effects of that are negligible.
-                     * Since nodes in the previous generation are iterated
-                     * through a heap, they're roughly ordered from better to
-                     * worse, but not strictly ordered. Therefore, an earlier
-                     * node with the same sample value is better in most cases
-                     * (and thus the current is skipped), but not strictly
-                     * in all cases. Only skipping samples where ssd >=
-                     * ssd of the earlier node with the same sample gives
-                     * slightly worse quality, though, for some reason. */ \
-                    h = &hash[(uint16_t) dec_sample];\
-                    if (*h == generation)\
-                        goto next_##NAME;\
-                    if (heap_pos < frontier) {\
-                        pos = heap_pos++;\
-                    } else {\
-                        /* Try to replace one of the leaf nodes with the new \
-                         * one, but try a different slot each time. */\
-                        pos = (frontier >> 1) + (heap_pos & ((frontier >> 1) - 1));\
-                        if (ssd > nodes_next[pos]->ssd)\
-                            goto next_##NAME;\
-                        heap_pos++;\
-                    }\
-                    *h = generation;\
-                    u = nodes_next[pos];\
-                    if(!u) {\
-                        assert(pathn < FREEZE_INTERVAL<<avctx->trellis);\
-                        u = t++;\
-                        nodes_next[pos] = u;\
-                        u->path = pathn++;\
-                    }\
-                    u->ssd = ssd;\
-                    u->step = STEP_INDEX;\
-                    u->sample2 = nodes[j]->sample1;\
-                    u->sample1 = dec_sample;\
-                    paths[u->path].nibble = nibble;\
-                    paths[u->path].prev = nodes[j]->path;\
-                    /* Sift the newly inserted node up in the heap to \
-                     * restore the heap property. */\
-                    while (pos > 0) {\
-                        int parent = (pos - 1) >> 1;\
-                        if (nodes_next[parent]->ssd <= ssd)\
-                            break;\
-                        FFSWAP(TrellisNode*, nodes_next[parent], nodes_next[pos]);\
-                        pos = parent;\
-                    }\
-                    next_##NAME:;
-                    STORE_NODE(ms, FFMAX(16, (AdaptationTable[nibble] * step) >> 8));
-                }
-            } else if((version == CODEC_ID_ADPCM_IMA_WAV)|| (version == CODEC_ID_ADPCM_IMA_QT)|| (version == CODEC_ID_ADPCM_SWF)) {
-#define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\
-                const int predictor = nodes[j]->sample1;\
-                const int div = (sample - predictor) * 4 / STEP_TABLE;\
-                int nmin = av_clip(div-range, -7, 6);\
-                int nmax = av_clip(div+range, -6, 7);\
-                if(nmin<=0) nmin--; /* distinguish -0 from +0 */\
-                if(nmax<0) nmax--;\
-                for(nidx=nmin; nidx<=nmax; nidx++) {\
-                    const int nibble = nidx<0 ? 7-nidx : nidx;\
-                    int dec_sample = predictor + (STEP_TABLE * yamaha_difflookup[nibble]) / 8;\
-                    STORE_NODE(NAME, STEP_INDEX);\
-                }
-                LOOP_NODES(ima, step_table[step], av_clip(step + index_table[nibble], 0, 88));
-            } else { //CODEC_ID_ADPCM_YAMAHA
-                LOOP_NODES(yamaha, step, av_clip((step * yamaha_indexscale[nibble]) >> 8, 127, 24567));
-#undef LOOP_NODES
-#undef STORE_NODE
-            }
-        }
-
-        u = nodes;
-        nodes = nodes_next;
-        nodes_next = u;
-
-        generation++;
-        if (generation == 255) {
-            memset(hash, 0xff, 65536 * sizeof(*hash));
-            generation = 0;
-        }
-
-        // prevent overflow
-        if(nodes[0]->ssd > (1<<28)) {
-            for(j=1; j<frontier && nodes[j]; j++)
-                nodes[j]->ssd -= nodes[0]->ssd;
-            nodes[0]->ssd = 0;
-        }
-
-        // merge old paths to save memory
-        if(i == froze + FREEZE_INTERVAL) {
-            p = &paths[nodes[0]->path];
-            for(k=i; k>froze; k--) {
-                dst[k] = p->nibble;
-                p = &paths[p->prev];
-            }
-            froze = i;
-            pathn = 0;
-            // other nodes might use paths that don't coincide with the frozen one.
-            // checking which nodes do so is too slow, so just kill them all.
-            // this also slightly improves quality, but I don't know why.
-            memset(nodes+1, 0, (frontier-1)*sizeof(TrellisNode*));
-        }
-    }
-
-    p = &paths[nodes[0]->path];
-    for(i=n-1; i>froze; i--) {
-        dst[i] = p->nibble;
-        p = &paths[p->prev];
-    }
-
-    c->predictor = nodes[0]->sample1;
-    c->sample1 = nodes[0]->sample1;
-    c->sample2 = nodes[0]->sample2;
-    c->step_index = nodes[0]->step;
-    c->step = nodes[0]->step;
-    c->idelta = nodes[0]->step;
-}
-
-static int adpcm_encode_frame(AVCodecContext *avctx,
-                            unsigned char *frame, int buf_size, void *data)
-{
-    int n, i, st;
-    short *samples;
-    unsigned char *dst;
-    ADPCMContext *c = avctx->priv_data;
-    uint8_t *buf;
-
-    dst = frame;
-    samples = (short *)data;
-    st= avctx->channels == 2;
-/*    n = (BLKSIZE - 4 * avctx->channels) / (2 * 8 * avctx->channels); */
-
-    switch(avctx->codec->id) {
-    case CODEC_ID_ADPCM_IMA_WAV:
-        n = avctx->frame_size / 8;
-            c->status[0].prev_sample = (signed short)samples[0]; /* XXX */
-/*            c->status[0].step_index = 0; *//* XXX: not sure how to init the state machine */
-            bytestream_put_le16(&dst, c->status[0].prev_sample);
-            *dst++ = (unsigned char)c->status[0].step_index;
-            *dst++ = 0; /* unknown */
-            samples++;
-            if (avctx->channels == 2) {
-                c->status[1].prev_sample = (signed short)samples[0];
-/*                c->status[1].step_index = 0; */
-                bytestream_put_le16(&dst, c->status[1].prev_sample);
-                *dst++ = (unsigned char)c->status[1].step_index;
-                *dst++ = 0;
-                samples++;
-            }
-
-            /* stereo: 4 bytes (8 samples) for left, 4 bytes for right, 4 bytes left, ... */
-            if(avctx->trellis > 0) {
-                FF_ALLOC_OR_GOTO(avctx, buf, 2*n*8, error);
-                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n*8);
-                if(avctx->channels == 2)
-                    adpcm_compress_trellis(avctx, samples+1, buf + n*8, &c->status[1], n*8);
-                for(i=0; i<n; i++) {
-                    *dst++ = buf[8*i+0] | (buf[8*i+1] << 4);
-                    *dst++ = buf[8*i+2] | (buf[8*i+3] << 4);
-                    *dst++ = buf[8*i+4] | (buf[8*i+5] << 4);
-                    *dst++ = buf[8*i+6] | (buf[8*i+7] << 4);
-                    if (avctx->channels == 2) {
-                        uint8_t *buf1 = buf + n*8;
-                        *dst++ = buf1[8*i+0] | (buf1[8*i+1] << 4);
-                        *dst++ = buf1[8*i+2] | (buf1[8*i+3] << 4);
-                        *dst++ = buf1[8*i+4] | (buf1[8*i+5] << 4);
-                        *dst++ = buf1[8*i+6] | (buf1[8*i+7] << 4);
-                    }
-                }
-                av_free(buf);
-            } else
-            for (; n>0; n--) {
-                *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]);
-                *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels]) << 4;
-                dst++;
-                *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]);
-                *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4;
-                dst++;
-                *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]);
-                *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4;
-                dst++;
-                *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]);
-                *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4;
-                dst++;
-                /* right channel */
-                if (avctx->channels == 2) {
-                    *dst = adpcm_ima_compress_sample(&c->status[1], samples[1]);
-                    *dst |= adpcm_ima_compress_sample(&c->status[1], samples[3]) << 4;
-                    dst++;
-                    *dst = adpcm_ima_compress_sample(&c->status[1], samples[5]);
-                    *dst |= adpcm_ima_compress_sample(&c->status[1], samples[7]) << 4;
-                    dst++;
-                    *dst = adpcm_ima_compress_sample(&c->status[1], samples[9]);
-                    *dst |= adpcm_ima_compress_sample(&c->status[1], samples[11]) << 4;
-                    dst++;
-                    *dst = adpcm_ima_compress_sample(&c->status[1], samples[13]);
-                    *dst |= adpcm_ima_compress_sample(&c->status[1], samples[15]) << 4;
-                    dst++;
-                }
-                samples += 8 * avctx->channels;
-            }
-        break;
-    case CODEC_ID_ADPCM_IMA_QT:
-    {
-        int ch, i;
-        PutBitContext pb;
-        init_put_bits(&pb, dst, buf_size*8);
-
-        for(ch=0; ch<avctx->channels; ch++){
-            put_bits(&pb, 9, (c->status[ch].prev_sample + 0x10000) >> 7);
-            put_bits(&pb, 7, c->status[ch].step_index);
-            if(avctx->trellis > 0) {
-                uint8_t buf[64];
-                adpcm_compress_trellis(avctx, samples+ch, buf, &c->status[ch], 64);
-                for(i=0; i<64; i++)
-                    put_bits(&pb, 4, buf[i^1]);
-            } else {
-                for (i=0; i<64; i+=2){
-                    int t1, t2;
-                    t1 = adpcm_ima_qt_compress_sample(&c->status[ch], samples[avctx->channels*(i+0)+ch]);
-                    t2 = adpcm_ima_qt_compress_sample(&c->status[ch], samples[avctx->channels*(i+1)+ch]);
-                    put_bits(&pb, 4, t2);
-                    put_bits(&pb, 4, t1);
-                }
-            }
-        }
-
-        flush_put_bits(&pb);
-        dst += put_bits_count(&pb)>>3;
-        break;
-    }
-    case CODEC_ID_ADPCM_SWF:
-    {
-        int i;
-        PutBitContext pb;
-        init_put_bits(&pb, dst, buf_size*8);
-
-        n = avctx->frame_size-1;
-
-        //Store AdpcmCodeSize
-        put_bits(&pb, 2, 2);                //Set 4bits flash adpcm format
-
-        //Init the encoder state
-        for(i=0; i<avctx->channels; i++){
-            c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63); // clip step so it fits 6 bits
-            put_sbits(&pb, 16, samples[i]);
-            put_bits(&pb, 6, c->status[i].step_index);
-            c->status[i].prev_sample = (signed short)samples[i];
-        }
-
-        if(avctx->trellis > 0) {
-            FF_ALLOC_OR_GOTO(avctx, buf, 2*n, error);
-            adpcm_compress_trellis(avctx, samples+2, buf, &c->status[0], n);
-            if (avctx->channels == 2)
-                adpcm_compress_trellis(avctx, samples+3, buf+n, &c->status[1], n);
-            for(i=0; i<n; i++) {
-                put_bits(&pb, 4, buf[i]);
-                if (avctx->channels == 2)
-                    put_bits(&pb, 4, buf[n+i]);
-            }
-            av_free(buf);
-        } else {
-            for (i=1; i<avctx->frame_size; i++) {
-                put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels*i]));
-                if (avctx->channels == 2)
-                    put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1], samples[2*i+1]));
-            }
-        }
-        flush_put_bits(&pb);
-        dst += put_bits_count(&pb)>>3;
-        break;
-    }
-    case CODEC_ID_ADPCM_MS:
-        for(i=0; i<avctx->channels; i++){
-            int predictor=0;
-
-            *dst++ = predictor;
-            c->status[i].coeff1 = AdaptCoeff1[predictor];
-            c->status[i].coeff2 = AdaptCoeff2[predictor];
-        }
-        for(i=0; i<avctx->channels; i++){
-            if (c->status[i].idelta < 16)
-                c->status[i].idelta = 16;
-
-            bytestream_put_le16(&dst, c->status[i].idelta);
-        }
-        for(i=0; i<avctx->channels; i++){
-            c->status[i].sample2= *samples++;
-        }
-        for(i=0; i<avctx->channels; i++){
-            c->status[i].sample1= *samples++;
-
-            bytestream_put_le16(&dst, c->status[i].sample1);
-        }
-        for(i=0; i<avctx->channels; i++)
-            bytestream_put_le16(&dst, c->status[i].sample2);
-
-        if(avctx->trellis > 0) {
-            int n = avctx->block_align - 7*avctx->channels;
-            FF_ALLOC_OR_GOTO(avctx, buf, 2*n, error);
-            if(avctx->channels == 1) {
-                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
-                for(i=0; i<n; i+=2)
-                    *dst++ = (buf[i] << 4) | buf[i+1];
-            } else {
-                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
-                adpcm_compress_trellis(avctx, samples+1, buf+n, &c->status[1], n);
-                for(i=0; i<n; i++)
-                    *dst++ = (buf[i] << 4) | buf[n+i];
-            }
-            av_free(buf);
-        } else
-        for(i=7*avctx->channels; i<avctx->block_align; i++) {
-            int nibble;
-            nibble = adpcm_ms_compress_sample(&c->status[ 0], *samples++)<<4;
-            nibble|= adpcm_ms_compress_sample(&c->status[st], *samples++);
-            *dst++ = nibble;
-        }
-        break;
-    case CODEC_ID_ADPCM_YAMAHA:
-        n = avctx->frame_size / 2;
-        if(avctx->trellis > 0) {
-            FF_ALLOC_OR_GOTO(avctx, buf, 2*n*2, error);
-            n *= 2;
-            if(avctx->channels == 1) {
-                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
-                for(i=0; i<n; i+=2)
-                    *dst++ = buf[i] | (buf[i+1] << 4);
-            } else {
-                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
-                adpcm_compress_trellis(avctx, samples+1, buf+n, &c->status[1], n);
-                for(i=0; i<n; i++)
-                    *dst++ = buf[i] | (buf[n+i] << 4);
-            }
-            av_free(buf);
-        } else
-            for (n *= avctx->channels; n>0; n--) {
-                int nibble;
-                nibble  = adpcm_yamaha_compress_sample(&c->status[ 0], *samples++);
-                nibble |= adpcm_yamaha_compress_sample(&c->status[st], *samples++) << 4;
-                *dst++ = nibble;
-            }
-        break;
-    default:
-    error:
-        return -1;
-    }
-    return dst - frame;
-}
-#endif //CONFIG_ENCODERS
+} ADPCMDecodeContext;
 
 static av_cold int adpcm_decode_init(AVCodecContext * avctx)
 {
-    ADPCMContext *c = avctx->priv_data;
+    ADPCMDecodeContext *c = avctx->priv_data;
     unsigned int max_channels = 2;
 
     switch(avctx->codec->id) {
@@ -823,8 +129,8 @@ static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble,
     int predictor;
     int sign, delta, diff, step;
 
-    step = step_table[c->step_index];
-    step_index = c->step_index + index_table[(unsigned)nibble];
+    step = ff_adpcm_step_table[c->step_index];
+    step_index = c->step_index + ff_adpcm_index_table[(unsigned)nibble];
     if (step_index < 0) step_index = 0;
     else if (step_index > 88) step_index = 88;
 
@@ -850,8 +156,8 @@ static inline int adpcm_ima_qt_expand_nibble(ADPCMChannelStatus *c, int nibble,
     int predictor;
     int diff, step;
 
-    step = step_table[c->step_index];
-    step_index = c->step_index + index_table[nibble];
+    step = ff_adpcm_step_table[c->step_index];
+    step_index = c->step_index + ff_adpcm_index_table[nibble];
     step_index = av_clip(step_index, 0, 88);
 
     diff = step >> 3;
@@ -879,7 +185,7 @@ static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble)
 
     c->sample2 = c->sample1;
     c->sample1 = av_clip_int16(predictor);
-    c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8;
+    c->idelta = (ff_adpcm_AdaptationTable[(int)nibble] * c->idelta) >> 8;
     if (c->idelta < 16) c->idelta = 16;
 
     return c->sample1;
@@ -900,7 +206,7 @@ static inline short adpcm_ct_expand_nibble(ADPCMChannelStatus *c, char nibble)
     c->predictor = ((c->predictor * 254) >> 8) + (sign ? -diff : diff);
     c->predictor = av_clip_int16(c->predictor);
     /* calculate new step and clamp it to range 511..32767 */
-    new_step = (AdaptationTable[nibble & 7] * c->step) >> 8;
+    new_step = (ff_adpcm_AdaptationTable[nibble & 7] * c->step) >> 8;
     c->step = av_clip(new_step, 511, 32767);
 
     return (short)c->predictor;
@@ -933,9 +239,9 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c
         c->step = 127;
     }
 
-    c->predictor += (c->step * yamaha_difflookup[nibble]) / 8;
+    c->predictor += (c->step * ff_adpcm_yamaha_difflookup[nibble]) / 8;
     c->predictor = av_clip_int16(c->predictor);
-    c->step = (c->step * yamaha_indexscale[nibble]) >> 8;
+    c->step = (c->step * ff_adpcm_yamaha_indexscale[nibble]) >> 8;
     c->step = av_clip(c->step, 127, 24567);
     return c->predictor;
 }
@@ -1027,7 +333,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
-    ADPCMContext *c = avctx->priv_data;
+    ADPCMDecodeContext *c = avctx->priv_data;
     ADPCMChannelStatus *cs;
     int n, m, channel, i;
     int block_predictor[2];
@@ -1183,10 +489,10 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
         if (st){
             c->status[1].idelta = (int16_t)bytestream_get_le16(&src);
         }
-        c->status[0].coeff1 = AdaptCoeff1[block_predictor[0]];
-        c->status[0].coeff2 = AdaptCoeff2[block_predictor[0]];
-        c->status[1].coeff1 = AdaptCoeff1[block_predictor[1]];
-        c->status[1].coeff2 = AdaptCoeff2[block_predictor[1]];
+        c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor[0]];
+        c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor[0]];
+        c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor[1]];
+        c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor[1]];
 
         c->status[0].sample1 = bytestream_get_le16(&src);
         if (st) c->status[1].sample1 = bytestream_get_le16(&src);
@@ -1655,7 +961,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
                 for (i = 0; i < avctx->channels; i++) {
                     // similar to IMA adpcm
                     int delta = get_bits(&gb, nb_bits);
-                    int step = step_table[c->status[i].step_index];
+                    int step = ff_adpcm_step_table[c->status[i].step_index];
                     long vpdiff = 0; // vpdiff = (delta+0.5)*step/4
                     int k = k0;
 
@@ -1774,44 +1080,18 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
 }
 
 
-
-#if CONFIG_ENCODERS
-#define ADPCM_ENCODER(id,name,long_name_)       \
-AVCodec ff_ ## name ## _encoder = {             \
-    #name,                                      \
-    AVMEDIA_TYPE_AUDIO,                         \
-    id,                                         \
-    sizeof(ADPCMContext),                       \
-    adpcm_encode_init,                          \
-    adpcm_encode_frame,                         \
-    adpcm_encode_close,                         \
-    NULL,                                       \
-    .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, \
-    .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
-}
-#else
-#define ADPCM_ENCODER(id,name,long_name_)
-#endif
-
-#if CONFIG_DECODERS
 #define ADPCM_DECODER(id,name,long_name_)       \
 AVCodec ff_ ## name ## _decoder = {             \
     #name,                                      \
     AVMEDIA_TYPE_AUDIO,                         \
     id,                                         \
-    sizeof(ADPCMContext),                       \
+    sizeof(ADPCMDecodeContext),                 \
     adpcm_decode_init,                          \
     NULL,                                       \
     NULL,                                       \
     adpcm_decode_frame,                         \
     .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
 }
-#else
-#define ADPCM_DECODER(id,name,long_name_)
-#endif
-
-#define ADPCM_CODEC(id,name,long_name_)         \
-    ADPCM_ENCODER(id,name,long_name_); ADPCM_DECODER(id,name,long_name_)
 
 /* Note: Do not forget to add new entries to the Makefile as well. */
 ADPCM_DECODER(CODEC_ID_ADPCM_4XM, adpcm_4xm, "ADPCM 4X Movie");
@@ -1828,15 +1108,15 @@ ADPCM_DECODER(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4, "ADPCM IMA Duck DK4");
 ADPCM_DECODER(CODEC_ID_ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs, "ADPCM IMA Electronic Arts EACS");
 ADPCM_DECODER(CODEC_ID_ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead, "ADPCM IMA Electronic Arts SEAD");
 ADPCM_DECODER(CODEC_ID_ADPCM_IMA_ISS, adpcm_ima_iss, "ADPCM IMA Funcom ISS");
-ADPCM_CODEC  (CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, "ADPCM IMA QuickTime");
+ADPCM_DECODER(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, "ADPCM IMA QuickTime");
 ADPCM_DECODER(CODEC_ID_ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG");
-ADPCM_CODEC  (CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, "ADPCM IMA WAV");
+ADPCM_DECODER(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, "ADPCM IMA WAV");
 ADPCM_DECODER(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws, "ADPCM IMA Westwood");
-ADPCM_CODEC  (CODEC_ID_ADPCM_MS, adpcm_ms, "ADPCM Microsoft");
+ADPCM_DECODER(CODEC_ID_ADPCM_MS, adpcm_ms, "ADPCM Microsoft");
 ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2, "ADPCM Sound Blaster Pro 2-bit");
 ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3, "ADPCM Sound Blaster Pro 2.6-bit");
 ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4, "ADPCM Sound Blaster Pro 4-bit");
-ADPCM_CODEC  (CODEC_ID_ADPCM_SWF, adpcm_swf, "ADPCM Shockwave Flash");
+ADPCM_DECODER(CODEC_ID_ADPCM_SWF, adpcm_swf, "ADPCM Shockwave Flash");
 ADPCM_DECODER(CODEC_ID_ADPCM_THP, adpcm_thp, "ADPCM Nintendo Gamecube THP");
 ADPCM_DECODER(CODEC_ID_ADPCM_XA, adpcm_xa, "ADPCM CDROM XA");
-ADPCM_CODEC  (CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, "ADPCM Yamaha");
+ADPCM_DECODER(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, "ADPCM Yamaha");
diff --git a/libavcodec/adpcm.h b/libavcodec/adpcm.h
new file mode 100644 (file)
index 0000000..475719a
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2001-2003 The ffmpeg Project
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * ADPCM encoder/decoder common header.
+ */
+
+#ifndef AVCODEC_ADPCM_H
+#define AVCODEC_ADPCM_H
+
+#define BLKSIZE 1024
+
+typedef struct ADPCMChannelStatus {
+    int predictor;
+    short int step_index;
+    int step;
+    /* for encoding */
+    int prev_sample;
+
+    /* MS version */
+    short sample1;
+    short sample2;
+    int coeff1;
+    int coeff2;
+    int idelta;
+} ADPCMChannelStatus;
+
+#endif /* AVCODEC_ADPCM_H */
diff --git a/libavcodec/adpcm_data.c b/libavcodec/adpcm_data.c
new file mode 100644 (file)
index 0000000..3654a8d
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2003 The ffmpeg Project
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * ADPCM tables
+ */
+
+#include <stdint.h>
+
+/* ff_adpcm_step_table[] and ff_adpcm_index_table[] are from the ADPCM
+   reference source */
+/* This is the index table: */
+const int8_t ff_adpcm_index_table[16] = {
+    -1, -1, -1, -1, 2, 4, 6, 8,
+    -1, -1, -1, -1, 2, 4, 6, 8,
+};
+
+/**
+ * This is the step table. Note that many programs use slight deviations from
+ * this table, but such deviations are negligible:
+ */
+const int16_t ff_adpcm_step_table[89] = {
+    7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+    19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+    50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+    130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+    337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+    876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+    2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+    5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+    15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
+/* These are for MS-ADPCM */
+/* ff_adpcm_AdaptationTable[], ff_adpcm_AdaptCoeff1[], and
+   ff_adpcm_AdaptCoeff2[] are from libsndfile */
+const int16_t ff_adpcm_AdaptationTable[] = {
+        230, 230, 230, 230, 307, 409, 512, 614,
+        768, 614, 512, 409, 307, 230, 230, 230
+};
+
+/** Divided by 4 to fit in 8-bit integers */
+const uint8_t ff_adpcm_AdaptCoeff1[] = {
+        64, 128, 0, 48, 60, 115, 98
+};
+
+/** Divided by 4 to fit in 8-bit integers */
+const int8_t ff_adpcm_AdaptCoeff2[] = {
+        0, -64, 0, 16, 0, -52, -58
+};
+
+const int16_t ff_adpcm_yamaha_indexscale[] = {
+    230, 230, 230, 230, 307, 409, 512, 614,
+    230, 230, 230, 230, 307, 409, 512, 614
+};
+
+const int8_t ff_adpcm_yamaha_difflookup[] = {
+    1, 3, 5, 7, 9, 11, 13, 15,
+    -1, -3, -5, -7, -9, -11, -13, -15
+};
diff --git a/libavcodec/adpcm_data.h b/libavcodec/adpcm_data.h
new file mode 100644 (file)
index 0000000..2aa7df5
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2001-2003 The ffmpeg Project
+ *
+ * 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
+ */
+
+/**
+ * @file
+ * ADPCM tables
+ */
+
+#ifndef AVCODEC_ADPCM_DATA_H
+#define AVCODEC_ADPCM_DATA_H
+
+extern const int8_t  ff_adpcm_index_table[16];
+extern const int16_t ff_adpcm_step_table[89];
+extern const int16_t ff_adpcm_AdaptationTable[];
+extern const uint8_t ff_adpcm_AdaptCoeff1[];
+extern const int8_t  ff_adpcm_AdaptCoeff2[];
+extern const int16_t ff_adpcm_yamaha_indexscale[];
+extern const int8_t  ff_adpcm_yamaha_difflookup[];
+
+#endif /* AVCODEC_ADPCM_DATA_H */
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c
new file mode 100644 (file)
index 0000000..c39bab8
--- /dev/null
@@ -0,0 +1,691 @@
+/*
+ * Copyright (c) 2001-2003 The ffmpeg Project
+ *
+ * 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 "avcodec.h"
+#include "get_bits.h"
+#include "put_bits.h"
+#include "bytestream.h"
+#include "adpcm.h"
+#include "adpcm_data.h"
+
+/**
+ * @file
+ * ADPCM encoders
+ * First version by Francois Revol (revol@free.fr)
+ * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
+ *   by Mike Melanson (melanson@pcisys.net)
+ *
+ * Reference documents:
+ * http://www.pcisys.net/~melanson/codecs/simpleaudio.html
+ * http://www.geocities.com/SiliconValley/8682/aud3.txt
+ * http://openquicktime.sourceforge.net/plugins.htm
+ * XAnim sources (xa_codec.c) http://www.rasnaimaging.com/people/lapus/download.html
+ * http://www.cs.ucla.edu/~leec/mediabench/applications.html
+ * SoX source code http://home.sprynet.com/~cbagwell/sox.html
+ */
+
+typedef struct TrellisPath {
+    int nibble;
+    int prev;
+} TrellisPath;
+
+typedef struct TrellisNode {
+    uint32_t ssd;
+    int path;
+    int sample1;
+    int sample2;
+    int step;
+} TrellisNode;
+
+typedef struct ADPCMEncodeContext {
+    ADPCMChannelStatus status[6];
+    TrellisPath *paths;
+    TrellisNode *node_buf;
+    TrellisNode **nodep_buf;
+    uint8_t *trellis_hash;
+} ADPCMEncodeContext;
+
+#define FREEZE_INTERVAL 128
+
+static av_cold int adpcm_encode_init(AVCodecContext *avctx)
+{
+    ADPCMEncodeContext *s = avctx->priv_data;
+    uint8_t *extradata;
+    int i;
+    if (avctx->channels > 2)
+        return -1; /* only stereo or mono =) */
+
+    if(avctx->trellis && (unsigned)avctx->trellis > 16U){
+        av_log(avctx, AV_LOG_ERROR, "invalid trellis size\n");
+        return -1;
+    }
+
+    if (avctx->trellis) {
+        int frontier = 1 << avctx->trellis;
+        int max_paths =  frontier * FREEZE_INTERVAL;
+        FF_ALLOC_OR_GOTO(avctx, s->paths,     max_paths * sizeof(*s->paths), error);
+        FF_ALLOC_OR_GOTO(avctx, s->node_buf,  2 * frontier * sizeof(*s->node_buf), error);
+        FF_ALLOC_OR_GOTO(avctx, s->nodep_buf, 2 * frontier * sizeof(*s->nodep_buf), error);
+        FF_ALLOC_OR_GOTO(avctx, s->trellis_hash, 65536 * sizeof(*s->trellis_hash), error);
+    }
+
+    switch(avctx->codec->id) {
+    case CODEC_ID_ADPCM_IMA_WAV:
+        avctx->frame_size = (BLKSIZE - 4 * avctx->channels) * 8 / (4 * avctx->channels) + 1; /* each 16 bits sample gives one nibble */
+                                                             /* and we have 4 bytes per channel overhead */
+        avctx->block_align = BLKSIZE;
+        avctx->bits_per_coded_sample = 4;
+        /* seems frame_size isn't taken into account... have to buffer the samples :-( */
+        break;
+    case CODEC_ID_ADPCM_IMA_QT:
+        avctx->frame_size = 64;
+        avctx->block_align = 34 * avctx->channels;
+        break;
+    case CODEC_ID_ADPCM_MS:
+        avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 / avctx->channels + 2; /* each 16 bits sample gives one nibble */
+                                                             /* and we have 7 bytes per channel overhead */
+        avctx->block_align = BLKSIZE;
+        avctx->bits_per_coded_sample = 4;
+        avctx->extradata_size = 32;
+        extradata = avctx->extradata = av_malloc(avctx->extradata_size);
+        if (!extradata)
+            return AVERROR(ENOMEM);
+        bytestream_put_le16(&extradata, avctx->frame_size);
+        bytestream_put_le16(&extradata, 7); /* wNumCoef */
+        for (i = 0; i < 7; i++) {
+            bytestream_put_le16(&extradata, ff_adpcm_AdaptCoeff1[i] * 4);
+            bytestream_put_le16(&extradata, ff_adpcm_AdaptCoeff2[i] * 4);
+        }
+        break;
+    case CODEC_ID_ADPCM_YAMAHA:
+        avctx->frame_size = BLKSIZE * avctx->channels;
+        avctx->block_align = BLKSIZE;
+        break;
+    case CODEC_ID_ADPCM_SWF:
+        if (avctx->sample_rate != 11025 &&
+            avctx->sample_rate != 22050 &&
+            avctx->sample_rate != 44100) {
+            av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, 22050 or 44100\n");
+            goto error;
+        }
+        avctx->frame_size = 512 * (avctx->sample_rate / 11025);
+        break;
+    default:
+        goto error;
+    }
+
+    avctx->coded_frame= avcodec_alloc_frame();
+    avctx->coded_frame->key_frame= 1;
+
+    return 0;
+error:
+    av_freep(&s->paths);
+    av_freep(&s->node_buf);
+    av_freep(&s->nodep_buf);
+    av_freep(&s->trellis_hash);
+    return -1;
+}
+
+static av_cold int adpcm_encode_close(AVCodecContext *avctx)
+{
+    ADPCMEncodeContext *s = avctx->priv_data;
+    av_freep(&avctx->coded_frame);
+    av_freep(&s->paths);
+    av_freep(&s->node_buf);
+    av_freep(&s->nodep_buf);
+    av_freep(&s->trellis_hash);
+
+    return 0;
+}
+
+
+static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c, short sample)
+{
+    int delta = sample - c->prev_sample;
+    int nibble = FFMIN(7, abs(delta)*4/ff_adpcm_step_table[c->step_index]) + (delta<0)*8;
+    c->prev_sample += ((ff_adpcm_step_table[c->step_index] * ff_adpcm_yamaha_difflookup[nibble]) / 8);
+    c->prev_sample = av_clip_int16(c->prev_sample);
+    c->step_index = av_clip(c->step_index + ff_adpcm_index_table[nibble], 0, 88);
+    return nibble;
+}
+
+static inline unsigned char adpcm_ima_qt_compress_sample(ADPCMChannelStatus *c, short sample)
+{
+    int delta = sample - c->prev_sample;
+    int diff, step = ff_adpcm_step_table[c->step_index];
+    int nibble = 8*(delta < 0);
+
+    delta= abs(delta);
+    diff = delta + (step >> 3);
+
+    if (delta >= step) {
+        nibble |= 4;
+        delta -= step;
+    }
+    step >>= 1;
+    if (delta >= step) {
+        nibble |= 2;
+        delta -= step;
+    }
+    step >>= 1;
+    if (delta >= step) {
+        nibble |= 1;
+        delta -= step;
+    }
+    diff -= delta;
+
+    if (nibble & 8)
+        c->prev_sample -= diff;
+    else
+        c->prev_sample += diff;
+
+    c->prev_sample = av_clip_int16(c->prev_sample);
+    c->step_index = av_clip(c->step_index + ff_adpcm_index_table[nibble], 0, 88);
+
+    return nibble;
+}
+
+static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c, short sample)
+{
+    int predictor, nibble, bias;
+
+    predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 64;
+
+    nibble= sample - predictor;
+    if(nibble>=0) bias= c->idelta/2;
+    else          bias=-c->idelta/2;
+
+    nibble= (nibble + bias) / c->idelta;
+    nibble= av_clip(nibble, -8, 7)&0x0F;
+
+    predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta;
+
+    c->sample2 = c->sample1;
+    c->sample1 = av_clip_int16(predictor);
+
+    c->idelta = (ff_adpcm_AdaptationTable[(int)nibble] * c->idelta) >> 8;
+    if (c->idelta < 16) c->idelta = 16;
+
+    return nibble;
+}
+
+static inline unsigned char adpcm_yamaha_compress_sample(ADPCMChannelStatus *c, short sample)
+{
+    int nibble, delta;
+
+    if(!c->step) {
+        c->predictor = 0;
+        c->step = 127;
+    }
+
+    delta = sample - c->predictor;
+
+    nibble = FFMIN(7, abs(delta)*4/c->step) + (delta<0)*8;
+
+    c->predictor += ((c->step * ff_adpcm_yamaha_difflookup[nibble]) / 8);
+    c->predictor = av_clip_int16(c->predictor);
+    c->step = (c->step * ff_adpcm_yamaha_indexscale[nibble]) >> 8;
+    c->step = av_clip(c->step, 127, 24567);
+
+    return nibble;
+}
+
+static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples,
+                                   uint8_t *dst, ADPCMChannelStatus *c, int n)
+{
+    //FIXME 6% faster if frontier is a compile-time constant
+    ADPCMEncodeContext *s = avctx->priv_data;
+    const int frontier = 1 << avctx->trellis;
+    const int stride = avctx->channels;
+    const int version = avctx->codec->id;
+    TrellisPath *paths = s->paths, *p;
+    TrellisNode *node_buf = s->node_buf;
+    TrellisNode **nodep_buf = s->nodep_buf;
+    TrellisNode **nodes = nodep_buf; // nodes[] is always sorted by .ssd
+    TrellisNode **nodes_next = nodep_buf + frontier;
+    int pathn = 0, froze = -1, i, j, k, generation = 0;
+    uint8_t *hash = s->trellis_hash;
+    memset(hash, 0xff, 65536 * sizeof(*hash));
+
+    memset(nodep_buf, 0, 2 * frontier * sizeof(*nodep_buf));
+    nodes[0] = node_buf + frontier;
+    nodes[0]->ssd = 0;
+    nodes[0]->path = 0;
+    nodes[0]->step = c->step_index;
+    nodes[0]->sample1 = c->sample1;
+    nodes[0]->sample2 = c->sample2;
+    if((version == CODEC_ID_ADPCM_IMA_WAV) || (version == CODEC_ID_ADPCM_IMA_QT) || (version == CODEC_ID_ADPCM_SWF))
+        nodes[0]->sample1 = c->prev_sample;
+    if(version == CODEC_ID_ADPCM_MS)
+        nodes[0]->step = c->idelta;
+    if(version == CODEC_ID_ADPCM_YAMAHA) {
+        if(c->step == 0) {
+            nodes[0]->step = 127;
+            nodes[0]->sample1 = 0;
+        } else {
+            nodes[0]->step = c->step;
+            nodes[0]->sample1 = c->predictor;
+        }
+    }
+
+    for(i=0; i<n; i++) {
+        TrellisNode *t = node_buf + frontier*(i&1);
+        TrellisNode **u;
+        int sample = samples[i*stride];
+        int heap_pos = 0;
+        memset(nodes_next, 0, frontier*sizeof(TrellisNode*));
+        for(j=0; j<frontier && nodes[j]; j++) {
+            // higher j have higher ssd already, so they're likely to yield a suboptimal next sample too
+            const int range = (j < frontier/2) ? 1 : 0;
+            const int step = nodes[j]->step;
+            int nidx;
+            if(version == CODEC_ID_ADPCM_MS) {
+                const int predictor = ((nodes[j]->sample1 * c->coeff1) + (nodes[j]->sample2 * c->coeff2)) / 64;
+                const int div = (sample - predictor) / step;
+                const int nmin = av_clip(div-range, -8, 6);
+                const int nmax = av_clip(div+range, -7, 7);
+                for(nidx=nmin; nidx<=nmax; nidx++) {
+                    const int nibble = nidx & 0xf;
+                    int dec_sample = predictor + nidx * step;
+#define STORE_NODE(NAME, STEP_INDEX)\
+                    int d;\
+                    uint32_t ssd;\
+                    int pos;\
+                    TrellisNode *u;\
+                    uint8_t *h;\
+                    dec_sample = av_clip_int16(dec_sample);\
+                    d = sample - dec_sample;\
+                    ssd = nodes[j]->ssd + d*d;\
+                    /* Check for wraparound, skip such samples completely. \
+                     * Note, changing ssd to a 64 bit variable would be \
+                     * simpler, avoiding this check, but it's slower on \
+                     * x86 32 bit at the moment. */\
+                    if (ssd < nodes[j]->ssd)\
+                        goto next_##NAME;\
+                    /* Collapse any two states with the same previous sample value. \
+                     * One could also distinguish states by step and by 2nd to last
+                     * sample, but the effects of that are negligible.
+                     * Since nodes in the previous generation are iterated
+                     * through a heap, they're roughly ordered from better to
+                     * worse, but not strictly ordered. Therefore, an earlier
+                     * node with the same sample value is better in most cases
+                     * (and thus the current is skipped), but not strictly
+                     * in all cases. Only skipping samples where ssd >=
+                     * ssd of the earlier node with the same sample gives
+                     * slightly worse quality, though, for some reason. */ \
+                    h = &hash[(uint16_t) dec_sample];\
+                    if (*h == generation)\
+                        goto next_##NAME;\
+                    if (heap_pos < frontier) {\
+                        pos = heap_pos++;\
+                    } else {\
+                        /* Try to replace one of the leaf nodes with the new \
+                         * one, but try a different slot each time. */\
+                        pos = (frontier >> 1) + (heap_pos & ((frontier >> 1) - 1));\
+                        if (ssd > nodes_next[pos]->ssd)\
+                            goto next_##NAME;\
+                        heap_pos++;\
+                    }\
+                    *h = generation;\
+                    u = nodes_next[pos];\
+                    if(!u) {\
+                        assert(pathn < FREEZE_INTERVAL<<avctx->trellis);\
+                        u = t++;\
+                        nodes_next[pos] = u;\
+                        u->path = pathn++;\
+                    }\
+                    u->ssd = ssd;\
+                    u->step = STEP_INDEX;\
+                    u->sample2 = nodes[j]->sample1;\
+                    u->sample1 = dec_sample;\
+                    paths[u->path].nibble = nibble;\
+                    paths[u->path].prev = nodes[j]->path;\
+                    /* Sift the newly inserted node up in the heap to \
+                     * restore the heap property. */\
+                    while (pos > 0) {\
+                        int parent = (pos - 1) >> 1;\
+                        if (nodes_next[parent]->ssd <= ssd)\
+                            break;\
+                        FFSWAP(TrellisNode*, nodes_next[parent], nodes_next[pos]);\
+                        pos = parent;\
+                    }\
+                    next_##NAME:;
+                    STORE_NODE(ms, FFMAX(16, (ff_adpcm_AdaptationTable[nibble] * step) >> 8));
+                }
+            } else if((version == CODEC_ID_ADPCM_IMA_WAV)|| (version == CODEC_ID_ADPCM_IMA_QT)|| (version == CODEC_ID_ADPCM_SWF)) {
+#define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\
+                const int predictor = nodes[j]->sample1;\
+                const int div = (sample - predictor) * 4 / STEP_TABLE;\
+                int nmin = av_clip(div-range, -7, 6);\
+                int nmax = av_clip(div+range, -6, 7);\
+                if(nmin<=0) nmin--; /* distinguish -0 from +0 */\
+                if(nmax<0) nmax--;\
+                for(nidx=nmin; nidx<=nmax; nidx++) {\
+                    const int nibble = nidx<0 ? 7-nidx : nidx;\
+                    int dec_sample = predictor + (STEP_TABLE * ff_adpcm_yamaha_difflookup[nibble]) / 8;\
+                    STORE_NODE(NAME, STEP_INDEX);\
+                }
+                LOOP_NODES(ima, ff_adpcm_step_table[step], av_clip(step + ff_adpcm_index_table[nibble], 0, 88));
+            } else { //CODEC_ID_ADPCM_YAMAHA
+                LOOP_NODES(yamaha, step, av_clip((step * ff_adpcm_yamaha_indexscale[nibble]) >> 8, 127, 24567));
+#undef LOOP_NODES
+#undef STORE_NODE
+            }
+        }
+
+        u = nodes;
+        nodes = nodes_next;
+        nodes_next = u;
+
+        generation++;
+        if (generation == 255) {
+            memset(hash, 0xff, 65536 * sizeof(*hash));
+            generation = 0;
+        }
+
+        // prevent overflow
+        if(nodes[0]->ssd > (1<<28)) {
+            for(j=1; j<frontier && nodes[j]; j++)
+                nodes[j]->ssd -= nodes[0]->ssd;
+            nodes[0]->ssd = 0;
+        }
+
+        // merge old paths to save memory
+        if(i == froze + FREEZE_INTERVAL) {
+            p = &paths[nodes[0]->path];
+            for(k=i; k>froze; k--) {
+                dst[k] = p->nibble;
+                p = &paths[p->prev];
+            }
+            froze = i;
+            pathn = 0;
+            // other nodes might use paths that don't coincide with the frozen one.
+            // checking which nodes do so is too slow, so just kill them all.
+            // this also slightly improves quality, but I don't know why.
+            memset(nodes+1, 0, (frontier-1)*sizeof(TrellisNode*));
+        }
+    }
+
+    p = &paths[nodes[0]->path];
+    for(i=n-1; i>froze; i--) {
+        dst[i] = p->nibble;
+        p = &paths[p->prev];
+    }
+
+    c->predictor = nodes[0]->sample1;
+    c->sample1 = nodes[0]->sample1;
+    c->sample2 = nodes[0]->sample2;
+    c->step_index = nodes[0]->step;
+    c->step = nodes[0]->step;
+    c->idelta = nodes[0]->step;
+}
+
+static int adpcm_encode_frame(AVCodecContext *avctx,
+                            unsigned char *frame, int buf_size, void *data)
+{
+    int n, i, st;
+    short *samples;
+    unsigned char *dst;
+    ADPCMEncodeContext *c = avctx->priv_data;
+    uint8_t *buf;
+
+    dst = frame;
+    samples = (short *)data;
+    st= avctx->channels == 2;
+/*    n = (BLKSIZE - 4 * avctx->channels) / (2 * 8 * avctx->channels); */
+
+    switch(avctx->codec->id) {
+    case CODEC_ID_ADPCM_IMA_WAV:
+        n = avctx->frame_size / 8;
+            c->status[0].prev_sample = (signed short)samples[0]; /* XXX */
+/*            c->status[0].step_index = 0; *//* XXX: not sure how to init the state machine */
+            bytestream_put_le16(&dst, c->status[0].prev_sample);
+            *dst++ = (unsigned char)c->status[0].step_index;
+            *dst++ = 0; /* unknown */
+            samples++;
+            if (avctx->channels == 2) {
+                c->status[1].prev_sample = (signed short)samples[0];
+/*                c->status[1].step_index = 0; */
+                bytestream_put_le16(&dst, c->status[1].prev_sample);
+                *dst++ = (unsigned char)c->status[1].step_index;
+                *dst++ = 0;
+                samples++;
+            }
+
+            /* stereo: 4 bytes (8 samples) for left, 4 bytes for right, 4 bytes left, ... */
+            if(avctx->trellis > 0) {
+                FF_ALLOC_OR_GOTO(avctx, buf, 2*n*8, error);
+                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n*8);
+                if(avctx->channels == 2)
+                    adpcm_compress_trellis(avctx, samples+1, buf + n*8, &c->status[1], n*8);
+                for(i=0; i<n; i++) {
+                    *dst++ = buf[8*i+0] | (buf[8*i+1] << 4);
+                    *dst++ = buf[8*i+2] | (buf[8*i+3] << 4);
+                    *dst++ = buf[8*i+4] | (buf[8*i+5] << 4);
+                    *dst++ = buf[8*i+6] | (buf[8*i+7] << 4);
+                    if (avctx->channels == 2) {
+                        uint8_t *buf1 = buf + n*8;
+                        *dst++ = buf1[8*i+0] | (buf1[8*i+1] << 4);
+                        *dst++ = buf1[8*i+2] | (buf1[8*i+3] << 4);
+                        *dst++ = buf1[8*i+4] | (buf1[8*i+5] << 4);
+                        *dst++ = buf1[8*i+6] | (buf1[8*i+7] << 4);
+                    }
+                }
+                av_free(buf);
+            } else
+            for (; n>0; n--) {
+                *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]);
+                *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels]) << 4;
+                dst++;
+                *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]);
+                *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4;
+                dst++;
+                *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]);
+                *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4;
+                dst++;
+                *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]);
+                *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4;
+                dst++;
+                /* right channel */
+                if (avctx->channels == 2) {
+                    *dst = adpcm_ima_compress_sample(&c->status[1], samples[1]);
+                    *dst |= adpcm_ima_compress_sample(&c->status[1], samples[3]) << 4;
+                    dst++;
+                    *dst = adpcm_ima_compress_sample(&c->status[1], samples[5]);
+                    *dst |= adpcm_ima_compress_sample(&c->status[1], samples[7]) << 4;
+                    dst++;
+                    *dst = adpcm_ima_compress_sample(&c->status[1], samples[9]);
+                    *dst |= adpcm_ima_compress_sample(&c->status[1], samples[11]) << 4;
+                    dst++;
+                    *dst = adpcm_ima_compress_sample(&c->status[1], samples[13]);
+                    *dst |= adpcm_ima_compress_sample(&c->status[1], samples[15]) << 4;
+                    dst++;
+                }
+                samples += 8 * avctx->channels;
+            }
+        break;
+    case CODEC_ID_ADPCM_IMA_QT:
+    {
+        int ch, i;
+        PutBitContext pb;
+        init_put_bits(&pb, dst, buf_size*8);
+
+        for(ch=0; ch<avctx->channels; ch++){
+            put_bits(&pb, 9, (c->status[ch].prev_sample + 0x10000) >> 7);
+            put_bits(&pb, 7, c->status[ch].step_index);
+            if(avctx->trellis > 0) {
+                uint8_t buf[64];
+                adpcm_compress_trellis(avctx, samples+ch, buf, &c->status[ch], 64);
+                for(i=0; i<64; i++)
+                    put_bits(&pb, 4, buf[i^1]);
+            } else {
+                for (i=0; i<64; i+=2){
+                    int t1, t2;
+                    t1 = adpcm_ima_qt_compress_sample(&c->status[ch], samples[avctx->channels*(i+0)+ch]);
+                    t2 = adpcm_ima_qt_compress_sample(&c->status[ch], samples[avctx->channels*(i+1)+ch]);
+                    put_bits(&pb, 4, t2);
+                    put_bits(&pb, 4, t1);
+                }
+            }
+        }
+
+        flush_put_bits(&pb);
+        dst += put_bits_count(&pb)>>3;
+        break;
+    }
+    case CODEC_ID_ADPCM_SWF:
+    {
+        int i;
+        PutBitContext pb;
+        init_put_bits(&pb, dst, buf_size*8);
+
+        n = avctx->frame_size-1;
+
+        //Store AdpcmCodeSize
+        put_bits(&pb, 2, 2);                //Set 4bits flash adpcm format
+
+        //Init the encoder state
+        for(i=0; i<avctx->channels; i++){
+            c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63); // clip step so it fits 6 bits
+            put_sbits(&pb, 16, samples[i]);
+            put_bits(&pb, 6, c->status[i].step_index);
+            c->status[i].prev_sample = (signed short)samples[i];
+        }
+
+        if(avctx->trellis > 0) {
+            FF_ALLOC_OR_GOTO(avctx, buf, 2*n, error);
+            adpcm_compress_trellis(avctx, samples+2, buf, &c->status[0], n);
+            if (avctx->channels == 2)
+                adpcm_compress_trellis(avctx, samples+3, buf+n, &c->status[1], n);
+            for(i=0; i<n; i++) {
+                put_bits(&pb, 4, buf[i]);
+                if (avctx->channels == 2)
+                    put_bits(&pb, 4, buf[n+i]);
+            }
+            av_free(buf);
+        } else {
+            for (i=1; i<avctx->frame_size; i++) {
+                put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels*i]));
+                if (avctx->channels == 2)
+                    put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1], samples[2*i+1]));
+            }
+        }
+        flush_put_bits(&pb);
+        dst += put_bits_count(&pb)>>3;
+        break;
+    }
+    case CODEC_ID_ADPCM_MS:
+        for(i=0; i<avctx->channels; i++){
+            int predictor=0;
+
+            *dst++ = predictor;
+            c->status[i].coeff1 = ff_adpcm_AdaptCoeff1[predictor];
+            c->status[i].coeff2 = ff_adpcm_AdaptCoeff2[predictor];
+        }
+        for(i=0; i<avctx->channels; i++){
+            if (c->status[i].idelta < 16)
+                c->status[i].idelta = 16;
+
+            bytestream_put_le16(&dst, c->status[i].idelta);
+        }
+        for(i=0; i<avctx->channels; i++){
+            c->status[i].sample2= *samples++;
+        }
+        for(i=0; i<avctx->channels; i++){
+            c->status[i].sample1= *samples++;
+
+            bytestream_put_le16(&dst, c->status[i].sample1);
+        }
+        for(i=0; i<avctx->channels; i++)
+            bytestream_put_le16(&dst, c->status[i].sample2);
+
+        if(avctx->trellis > 0) {
+            int n = avctx->block_align - 7*avctx->channels;
+            FF_ALLOC_OR_GOTO(avctx, buf, 2*n, error);
+            if(avctx->channels == 1) {
+                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
+                for(i=0; i<n; i+=2)
+                    *dst++ = (buf[i] << 4) | buf[i+1];
+            } else {
+                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
+                adpcm_compress_trellis(avctx, samples+1, buf+n, &c->status[1], n);
+                for(i=0; i<n; i++)
+                    *dst++ = (buf[i] << 4) | buf[n+i];
+            }
+            av_free(buf);
+        } else
+        for(i=7*avctx->channels; i<avctx->block_align; i++) {
+            int nibble;
+            nibble = adpcm_ms_compress_sample(&c->status[ 0], *samples++)<<4;
+            nibble|= adpcm_ms_compress_sample(&c->status[st], *samples++);
+            *dst++ = nibble;
+        }
+        break;
+    case CODEC_ID_ADPCM_YAMAHA:
+        n = avctx->frame_size / 2;
+        if(avctx->trellis > 0) {
+            FF_ALLOC_OR_GOTO(avctx, buf, 2*n*2, error);
+            n *= 2;
+            if(avctx->channels == 1) {
+                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
+                for(i=0; i<n; i+=2)
+                    *dst++ = buf[i] | (buf[i+1] << 4);
+            } else {
+                adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n);
+                adpcm_compress_trellis(avctx, samples+1, buf+n, &c->status[1], n);
+                for(i=0; i<n; i++)
+                    *dst++ = buf[i] | (buf[n+i] << 4);
+            }
+            av_free(buf);
+        } else
+            for (n *= avctx->channels; n>0; n--) {
+                int nibble;
+                nibble  = adpcm_yamaha_compress_sample(&c->status[ 0], *samples++);
+                nibble |= adpcm_yamaha_compress_sample(&c->status[st], *samples++) << 4;
+                *dst++ = nibble;
+            }
+        break;
+    default:
+    error:
+        return -1;
+    }
+    return dst - frame;
+}
+
+
+#define ADPCM_ENCODER(id,name,long_name_)       \
+AVCodec ff_ ## name ## _encoder = {             \
+    #name,                                      \
+    AVMEDIA_TYPE_AUDIO,                         \
+    id,                                         \
+    sizeof(ADPCMEncodeContext),                 \
+    adpcm_encode_init,                          \
+    adpcm_encode_frame,                         \
+    adpcm_encode_close,                         \
+    NULL,                                       \
+    .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, \
+    .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
+}
+
+ADPCM_ENCODER(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, "ADPCM IMA QuickTime");
+ADPCM_ENCODER(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, "ADPCM IMA WAV");
+ADPCM_ENCODER(CODEC_ID_ADPCM_MS, adpcm_ms, "ADPCM Microsoft");
+ADPCM_ENCODER(CODEC_ID_ADPCM_SWF, adpcm_swf, "ADPCM Shockwave Flash");
+ADPCM_ENCODER(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, "ADPCM Yamaha");
index 4b604bd..3a35a46 100644 (file)
 #include <string.h>
 #include <math.h>
 #include <stdint.h>
+#include <float.h>
 #include <xavs.h>
 #include "avcodec.h"
+#include "internal.h"
+#include "libavutil/opt.h"
 
 #define END_OF_STREAM 0x001
 
@@ -41,6 +44,15 @@ typedef struct XavsContext {
     int             sei_size;
     AVFrame         out_pic;
     int             end_of_stream;
+    float crf;
+    int cqp;
+    int b_bias;
+    float cplxblur;
+    int direct_pred;
+    int aud;
+    int fast_pskip;
+    int mbtree;
+    int mixed_refs;
 } XavsContext;
 
 static void XAVS_log(void *p, int level, const char *fmt, va_list args)
@@ -181,13 +193,17 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
     x4->params.pf_log               = XAVS_log;
     x4->params.p_log_private        = avctx;
     x4->params.i_keyint_max         = avctx->gop_size;
-    x4->params.rc.i_bitrate         = avctx->bit_rate       / 1000;
+    if (avctx->bit_rate) {
+        x4->params.rc.i_bitrate   = avctx->bit_rate / 1000;
+        x4->params.rc.i_rc_method = XAVS_RC_ABR;
+    }
     x4->params.rc.i_vbv_buffer_size = avctx->rc_buffer_size / 1000;
     x4->params.rc.i_vbv_max_bitrate = avctx->rc_max_rate    / 1000;
     x4->params.rc.b_stat_write      = avctx->flags & CODEC_FLAG_PASS1;
     if (avctx->flags & CODEC_FLAG_PASS2) {
         x4->params.rc.b_stat_read = 1;
     } else {
+#if FF_API_X264_GLOBAL_OPTS
         if (avctx->crf) {
             x4->params.rc.i_rc_method   = XAVS_RC_CRF;
             x4->params.rc.f_rf_constant = avctx->crf;
@@ -195,19 +211,63 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
             x4->params.rc.i_rc_method   = XAVS_RC_CQP;
             x4->params.rc.i_qp_constant = avctx->cqp;
         }
+#endif
+
+        if (x4->crf >= 0) {
+            x4->params.rc.i_rc_method   = XAVS_RC_CRF;
+            x4->params.rc.f_rf_constant = x4->crf;
+        } else if (x4->cqp >= 0) {
+            x4->params.rc.i_rc_method   = XAVS_RC_CQP;
+            x4->params.rc.i_qp_constant = x4->cqp;
+        }
     }
 
-    /* if neither crf nor cqp modes are selected we have to enable the RC */
-    /* we do it this way because we cannot check if the bitrate has been set */
-    if (!(avctx->crf || (avctx->cqp > -1)))
-        x4->params.rc.i_rc_method = XAVS_RC_ABR;
+#if FF_API_X264_GLOBAL_OPTS
+    if (avctx->bframebias)
+        x4->params.i_bframe_bias              = avctx->bframebias;
+    if (avctx->deblockalpha)
+        x4->params.i_deblocking_filter_alphac0 = avctx->deblockalpha;
+    if (avctx->deblockbeta)
+        x4->params.i_deblocking_filter_beta    = avctx->deblockbeta;
+    if (avctx->complexityblur >= 0)
+        x4->params.rc.f_complexity_blur        = avctx->complexityblur;
+    if (avctx->directpred >= 0)
+        x4->params.analyse.i_direct_mv_pred    = avctx->directpred;
+    if (avctx->partitions) {
+        if (avctx->partitions & XAVS_PART_I8X8)
+            x4->params.analyse.inter |= XAVS_ANALYSE_I8x8;
+        if (avctx->partitions & XAVS_PART_P8X8)
+            x4->params.analyse.inter |= XAVS_ANALYSE_PSUB16x16;
+        if (avctx->partitions & XAVS_PART_B8X8)
+            x4->params.analyse.inter |= XAVS_ANALYSE_BSUB16x16;
+    }
+    x4->params.rc.b_mb_tree               = !!(avctx->flags2 & CODEC_FLAG2_MBTREE);
+    x4->params.b_aud          = avctx->flags2 & CODEC_FLAG2_AUD;
+    x4->params.analyse.b_mixed_references = avctx->flags2 & CODEC_FLAG2_MIXED_REFS;
+    x4->params.analyse.b_fast_pskip       = avctx->flags2 & CODEC_FLAG2_FASTPSKIP;
+    x4->params.analyse.b_weighted_bipred = avctx->flags2 & CODEC_FLAG2_WPRED;
+#endif
+
+    if (x4->aud >= 0)
+        x4->params.b_aud                      = x4->aud;
+    if (x4->mbtree >= 0)
+        x4->params.rc.b_mb_tree               = x4->mbtree;
+    if (x4->direct_pred >= 0)
+        x4->params.analyse.i_direct_mv_pred   = x4->direct_pred;
+    if (x4->fast_pskip >= 0)
+        x4->params.analyse.b_fast_pskip       = x4->fast_pskip;
+    if (x4->mixed_refs >= 0)
+        x4->params.analyse.b_mixed_references = x4->mixed_refs;
+    if (x4->b_bias != INT_MIN)
+        x4->params.i_bframe_bias              = x4->b_bias;
+    if (x4->cplxblur >= 0)
+        x4->params.rc.f_complexity_blur = x4->cplxblur;
 
     x4->params.i_bframe          = avctx->max_b_frames;
     /* cabac is not included in AVS JiZhun Profile */
     x4->params.b_cabac           = 0;
 
     x4->params.i_bframe_adaptive = avctx->b_frame_strategy;
-    x4->params.i_bframe_bias     = avctx->bframebias;
 
     avctx->has_b_frames          = !!avctx->max_b_frames;
 
@@ -220,8 +280,6 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
     x4->params.i_scenecut_threshold        = avctx->scenechange_threshold;
 
    // x4->params.b_deblocking_filter       = avctx->flags & CODEC_FLAG_LOOP_FILTER;
-    x4->params.i_deblocking_filter_alphac0 = avctx->deblockalpha;
-    x4->params.i_deblocking_filter_beta    = avctx->deblockbeta;
 
     x4->params.rc.i_qp_min                 = avctx->qmin;
     x4->params.rc.i_qp_max                 = avctx->qmax;
@@ -229,7 +287,6 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
 
     x4->params.rc.f_qcompress       = avctx->qcompress; /* 0.0 => cbr, 1.0 => constant qp */
     x4->params.rc.f_qblur           = avctx->qblur;     /* temporally blur quants */
-    x4->params.rc.f_complexity_blur = avctx->complexityblur;
 
     x4->params.i_frame_reference    = avctx->refs;
 
@@ -241,20 +298,6 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
     x4->params.i_fps_num            = avctx->time_base.den;
     x4->params.i_fps_den            = avctx->time_base.num;
     x4->params.analyse.inter        = XAVS_ANALYSE_I8x8 |XAVS_ANALYSE_PSUB16x16| XAVS_ANALYSE_BSUB16x16;
-    if (avctx->partitions) {
-        if (avctx->partitions & XAVS_PART_I8X8)
-            x4->params.analyse.inter |= XAVS_ANALYSE_I8x8;
-
-        if (avctx->partitions & XAVS_PART_P8X8)
-            x4->params.analyse.inter |= XAVS_ANALYSE_PSUB16x16;
-
-        if (avctx->partitions & XAVS_PART_B8X8)
-            x4->params.analyse.inter |= XAVS_ANALYSE_BSUB16x16;
-    }
-
-    x4->params.analyse.i_direct_mv_pred  = avctx->directpred;
-
-    x4->params.analyse.b_weighted_bipred = avctx->flags2 & CODEC_FLAG2_WPRED;
 
     switch (avctx->me_method) {
          case  ME_EPZS:
@@ -279,11 +322,9 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
     x4->params.analyse.i_me_range = avctx->me_range;
     x4->params.analyse.i_subpel_refine    = avctx->me_subpel_quality;
 
-    x4->params.analyse.b_mixed_references = avctx->flags2 & CODEC_FLAG2_MIXED_REFS;
     x4->params.analyse.b_chroma_me        = avctx->me_cmp & FF_CMP_CHROMA;
     /* AVS P2 only enables 8x8 transform */
     x4->params.analyse.b_transform_8x8    = 1; //avctx->flags2 & CODEC_FLAG2_8X8DCT;
-    x4->params.analyse.b_fast_pskip       = avctx->flags2 & CODEC_FLAG2_FASTPSKIP;
 
     x4->params.analyse.i_trellis          = avctx->trellis;
     x4->params.analyse.i_noise_reduction  = avctx->noise_reduction;
@@ -303,14 +344,12 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
 
     /* TAG:do we have MB tree RC method */
     /* what is the RC method we are now using? Default NO */
-    x4->params.rc.b_mb_tree               = !!(avctx->flags2 & CODEC_FLAG2_MBTREE);
     x4->params.rc.f_ip_factor             = 1 / fabs(avctx->i_quant_factor);
     x4->params.rc.f_pb_factor             = avctx->b_quant_factor;
     x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset;
 
     x4->params.analyse.b_psnr = avctx->flags & CODEC_FLAG_PSNR;
     x4->params.i_log_level    = XAVS_LOG_DEBUG;
-    x4->params.b_aud          = avctx->flags2 & CODEC_FLAG2_AUD;
     x4->params.i_threads      = avctx->thread_count;
     x4->params.b_interlaced   = avctx->flags & CODEC_FLAG_INTERLACED_DCT;
 
@@ -336,6 +375,37 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
     return 0;
 }
 
+#define OFFSET(x) offsetof(XavsContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "crf",           "Select the quality for constant quality mode",    OFFSET(crf),           FF_OPT_TYPE_FLOAT,  {-1 }, -1, FLT_MAX, VE },
+    { "qp",            "Constant quantization parameter rate control method",OFFSET(cqp),        FF_OPT_TYPE_INT,    {-1 }, -1, INT_MAX, VE },
+    { "b-bias",        "Influences how often B-frames are used",          OFFSET(b_bias),        FF_OPT_TYPE_INT,    {INT_MIN}, INT_MIN, INT_MAX, VE },
+    { "cplxblur",      "Reduce fluctuations in QP (before curve compression)", OFFSET(cplxblur), FF_OPT_TYPE_FLOAT,  {-1 }, -1, FLT_MAX, VE},
+    { "direct-pred",   "Direct MV prediction mode",                       OFFSET(direct_pred),   FF_OPT_TYPE_INT,    {-1 }, -1, INT_MAX, VE, "direct-pred" },
+    { "none",          NULL,      0,    FF_OPT_TYPE_CONST, { XAVS_DIRECT_PRED_NONE },     0, 0, VE, "direct-pred" },
+    { "spatial",       NULL,      0,    FF_OPT_TYPE_CONST, { XAVS_DIRECT_PRED_SPATIAL },  0, 0, VE, "direct-pred" },
+    { "temporal",      NULL,      0,    FF_OPT_TYPE_CONST, { XAVS_DIRECT_PRED_TEMPORAL }, 0, 0, VE, "direct-pred" },
+    { "auto",          NULL,      0,    FF_OPT_TYPE_CONST, { XAVS_DIRECT_PRED_AUTO },     0, 0, VE, "direct-pred" },
+    { "aud",           "Use access unit delimiters.",                     OFFSET(aud),           FF_OPT_TYPE_INT,    {-1 }, -1, 1, VE},
+    { "mbtree",        "Use macroblock tree ratecontrol.",                OFFSET(mbtree),        FF_OPT_TYPE_INT,    {-1 }, -1, 1, VE},
+    { "mixed-refs",    "One reference per partition, as opposed to one reference per macroblock", OFFSET(mixed_refs), FF_OPT_TYPE_INT, {-1}, -1, 1, VE },
+    { "fast-pskip",    NULL,                                              OFFSET(fast_pskip),    FF_OPT_TYPE_INT,    {-1 }, -1, 1, VE},
+    { NULL },
+};
+
+static const AVClass class = {
+    .class_name = "libxavs",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVCodecDefault xavs_defaults[] = {
+    { "b",                "0" },
+    { NULL },
+};
+
 AVCodec ff_libxavs_encoder = {
     .name           = "libxavs",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -347,5 +417,7 @@ AVCodec ff_libxavs_encoder = {
     .capabilities   = CODEC_CAP_DELAY,
     .pix_fmts       = (const enum PixelFormat[]) { PIX_FMT_YUV420P, PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("libxavs - the Chinese Audio Video Standard Encoder"),
+    .priv_class     = &class,
+    .defaults       = xavs_defaults,
 };
 
index 2af66a5..6c51186 100644 (file)
@@ -1336,6 +1336,13 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
             }
         }
         s->mb_x = s->mb_y = 0;
+    } else {
+        int slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
+
+        if (slice_type != s->pict_type) {
+            av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
+            return AVERROR_INVALIDDATA;
+        }
     }
 
     r->si.end = end;
index 82aa3b9..9ce50f4 100644 (file)
@@ -19,7 +19,7 @@
 
 /**
  * @file
- * filter fow showing textual video frame information
+ * filter for showing textual video frame information
  */
 
 #include "libavutil/adler32.h"
index ba55946..347ee4e 100644 (file)
@@ -286,15 +286,16 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
         for(i = 0; i < 7; i++) {
             if(flags & 1) {
                 int size;
+                uint8_t *tmpbuf;
+
                 size = avio_rl32(s->pb) - 4;
                 frame_size -= size;
                 frame_size -= 4;
                 smk->curstream++;
-                smk->bufs[smk->curstream] = av_realloc(smk->bufs[smk->curstream], size);
-                if (!smk->bufs[smk->curstream]) {
-                    smk->buf_sizes[smk->curstream] = 0;
+                tmpbuf = av_realloc(smk->bufs[smk->curstream], size);
+                if (!tmpbuf)
                     return AVERROR(ENOMEM);
-                }
+                smk->bufs[smk->curstream] = tmpbuf;
                 smk->buf_sizes[smk->curstream] = size;
                 ret = avio_read(s->pb, smk->bufs[smk->curstream], size);
                 if(ret != size)