X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fadpcm.c;h=16e015b0f812eb811f98fbe383cc3c46e3cfe014;hb=a247ac640df3da573cd661065bf53f37863e2b46;hp=8aab07e3344b1c00787ab444a52aef62bc890043;hpb=e550667f614dfd21dadd8a8e4ada806c48349beb;p=ffmpeg diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 8aab07e3344..16e015b0f81 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -103,12 +103,16 @@ typedef struct ADPCMDecodeContext { int has_status; /**< Status flag. Reset to 0 after a flush. */ } ADPCMDecodeContext; +static void adpcm_flush(AVCodecContext *avctx); + static av_cold int adpcm_decode_init(AVCodecContext * avctx) { ADPCMDecodeContext *c = avctx->priv_data; unsigned int min_channels = 1; unsigned int max_channels = 2; + adpcm_flush(avctx); + switch(avctx->codec->id) { case AV_CODEC_ID_ADPCM_IMA_AMV: max_channels = 1; @@ -150,38 +154,10 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) } switch(avctx->codec->id) { - case AV_CODEC_ID_ADPCM_CT: - c->status[0].step = c->status[1].step = 511; - break; case AV_CODEC_ID_ADPCM_IMA_WAV: if (avctx->bits_per_coded_sample < 2 || avctx->bits_per_coded_sample > 5) return AVERROR_INVALIDDATA; break; - case AV_CODEC_ID_ADPCM_IMA_APC: - if (avctx->extradata && avctx->extradata_size >= 8) { - c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata ), 18); - c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 4), 18); - } - break; - case AV_CODEC_ID_ADPCM_IMA_APM: - if (avctx->extradata) { - if (avctx->extradata_size >= 28) { - c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 16), 18); - c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 20), 0, 88); - c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 4), 18); - c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 8), 0, 88); - } else if (avctx->extradata_size >= 16) { - c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 0), 18); - c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 4), 0, 88); - c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 8), 18); - c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 12), 0, 88); - } - } - break; - case AV_CODEC_ID_ADPCM_IMA_WS: - if (avctx->extradata && avctx->extradata_size >= 2) - c->vqa_version = AV_RL16(avctx->extradata); - break; case AV_CODEC_ID_ADPCM_ARGO: if (avctx->bits_per_coded_sample != 4 || avctx->block_align != 17 * avctx->channels) return AVERROR_INVALIDDATA; @@ -227,7 +203,6 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) default: avctx->sample_fmt = AV_SAMPLE_FMT_S16; } - return 0; } @@ -1425,16 +1400,16 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, for (n = nb_samples / 2; n > 0; n--) { int v = bytestream2_get_byteu(&gb); - *smp++ = adpcm_ima_expand_nibble(&c->status[channel], v >> 4 , 3); *smp++ = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3); + *smp++ = adpcm_ima_expand_nibble(&c->status[channel], v >> 4 , 3); } } } else { for (n = nb_samples / 2; n > 0; n--) { for (channel = 0; channel < avctx->channels; channel++) { int v = bytestream2_get_byteu(&gb); - *samples++ = adpcm_ima_expand_nibble(&c->status[channel], v >> 4 , 3); - samples[st] = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3); + samples[st] = adpcm_ima_expand_nibble(&c->status[channel], v >> 4 , 3); } samples += avctx->channels; } @@ -2110,29 +2085,41 @@ static void adpcm_flush(AVCodecContext *avctx) { ADPCMDecodeContext *c = avctx->priv_data; + /* Just nuke the entire state and re-init. */ + memset(c, 0, sizeof(ADPCMDecodeContext)); + switch(avctx->codec_id) { - case AV_CODEC_ID_ADPCM_AICA: - for (int channel = 0; channel < avctx->channels; channel++) - c->status[channel].step = 0; + case AV_CODEC_ID_ADPCM_CT: + c->status[0].step = c->status[1].step = 511; break; - case AV_CODEC_ID_ADPCM_ARGO: - for (int channel = 0; channel < avctx->channels; channel++) { - c->status[channel].sample1 = 0; - c->status[channel].sample2 = 0; + case AV_CODEC_ID_ADPCM_IMA_APC: + if (avctx->extradata && avctx->extradata_size >= 8) { + c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata ), 18); + c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 4), 18); } break; - case AV_CODEC_ID_ADPCM_IMA_ALP: - case AV_CODEC_ID_ADPCM_IMA_CUNNING: - case AV_CODEC_ID_ADPCM_IMA_SSI: - case AV_CODEC_ID_ADPCM_ZORK: - for (int channel = 0; channel < avctx->channels; channel++) { - c->status[channel].predictor = 0; - c->status[channel].step_index = 0; + case AV_CODEC_ID_ADPCM_IMA_APM: + if (avctx->extradata) { + if (avctx->extradata_size >= 28) { + c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 16), 18); + c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 20), 0, 88); + c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 4), 18); + c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 8), 0, 88); + } else if (avctx->extradata_size >= 16) { + c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 0), 18); + c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 4), 0, 88); + c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 8), 18); + c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 12), 0, 88); + } } break; + case AV_CODEC_ID_ADPCM_IMA_WS: + if (avctx->extradata && avctx->extradata_size >= 2) + c->vqa_version = AV_RL16(avctx->extradata); + break; default: /* Other codecs may want to handle this during decoding. */ c->has_status = 0; @@ -2152,7 +2139,7 @@ static const enum AVSampleFormat sample_fmts_both[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }; #define ADPCM_DECODER(id_, sample_fmts_, name_, long_name_) \ -AVCodec ff_ ## name_ ## _decoder = { \ +const AVCodec ff_ ## name_ ## _decoder = { \ .name = #name_, \ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ .type = AVMEDIA_TYPE_AUDIO, \