diff options
author | Aidan Richmond <aidan.is@hotmail.co.uk> | 2021-04-25 21:00:00 +0100 |
---|---|---|
committer | Zane van Iperen <zane@zanevaniperen.com> | 2021-04-26 19:56:32 +1000 |
commit | a0fd55c206cea0af3a688c62ca7bf9001d1b8b4b (patch) | |
tree | c40cfc491174a8425a6dcc1d644d956537a7302b /libavcodec/adpcmenc.c | |
parent | 50442540d07aa7734c2df8459c711531c21d325e (diff) | |
download | ffmpeg-a0fd55c206cea0af3a688c62ca7bf9001d1b8b4b.tar.gz |
avcodec/adpcmenc: Adds encoder for Westwood ADPCM.
Signed-off-by: Aidan Richmond <aidan.is@hotmail.co.uk>
Signed-off-by: Zane van Iperen <zane@zanevaniperen.com>
Diffstat (limited to 'libavcodec/adpcmenc.c')
-rw-r--r-- | libavcodec/adpcmenc.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index 9dc77d519a..752cae5cf4 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -94,7 +94,8 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) if (avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_SSI || avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_APM || - avctx->codec->id == AV_CODEC_ID_ADPCM_ARGO) { + avctx->codec->id == AV_CODEC_ID_ADPCM_ARGO || + avctx->codec->id == AV_CODEC_ID_ADPCM_IMA_WS) { /* * The current trellis implementation doesn't work for extended * runs of samples without periodic resets. Disallow it. @@ -192,6 +193,11 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) avctx->frame_size = 32; avctx->block_align = 17 * avctx->channels; break; + case AV_CODEC_ID_ADPCM_IMA_WS: + /* each 16 bits sample gives one nibble */ + avctx->frame_size = s->block_size * 2 / avctx->channels; + avctx->block_align = s->block_size; + break; default: return AVERROR(EINVAL); } @@ -594,7 +600,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_SSI || avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_ALP || - avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_APM) + avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_APM || + avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_WS) pkt_size = (frame->nb_samples * avctx->channels) / 2; else pkt_size = avctx->block_align; @@ -929,6 +936,26 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, flush_put_bits(&pb); break; } + case AV_CODEC_ID_ADPCM_IMA_WS: + { + PutBitContext pb; + init_put_bits(&pb, dst, pkt_size); + + av_assert0(avctx->trellis == 0); + for (n = frame->nb_samples / 2; n > 0; n--) { + /* stereo: 1 byte (2 samples) for left, 1 byte for right */ + for (ch = 0; ch < avctx->channels; ch++) { + int t1, t2; + t1 = adpcm_ima_compress_sample(&c->status[ch], *samples++); + t2 = adpcm_ima_compress_sample(&c->status[ch], samples[st]); + put_bits(&pb, 4, t2); + put_bits(&pb, 4, t1); + } + samples += avctx->channels; + } + flush_put_bits(&pb); + break; + } default: return AVERROR(EINVAL); } @@ -990,6 +1017,7 @@ ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_ALP, adpcm_ima_alp, sample_fmts, AV_CODEC_ ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, 0, "ADPCM IMA QuickTime"); ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_SSI, adpcm_ima_ssi, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Simon & Schuster Interactive"); ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, sample_fmts_p, 0, "ADPCM IMA WAV"); +ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Westwood"); ADPCM_ENCODER(AV_CODEC_ID_ADPCM_MS, adpcm_ms, sample_fmts, 0, "ADPCM Microsoft"); ADPCM_ENCODER(AV_CODEC_ID_ADPCM_SWF, adpcm_swf, sample_fmts, 0, "ADPCM Shockwave Flash"); ADPCM_ENCODER(AV_CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, sample_fmts, 0, "ADPCM Yamaha"); |