From 701eec2a7e742fa0fcc375a6c3784ac012100d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= Date: Tue, 26 Dec 2023 14:32:20 +0100 Subject: [PATCH 5/6] lavc: Add ADPCM IMA CRYO APC encoder No trellis quantization yet --- Changelog | 1 + doc/general_contents.texi | 2 +- libavcodec/adpcmenc.c | 33 +++++++++++++++++++++++++++++++++ libavcodec/allcodecs.c | 1 + libavcodec/version.h | 2 +- tests/fate/acodec.mak | 2 ++ tests/ref/acodec/adpcm-ima_apc | 4 ++++ 7 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 tests/ref/acodec/adpcm-ima_apc diff --git a/Changelog b/Changelog index 31c9e25be6..586ccd1a9c 100644 --- a/Changelog +++ b/Changelog @@ -14,6 +14,7 @@ version : - D3D12VA hardware accelerated H264, HEVC, VP9, AV1, MPEG-2 and VC1 decoding - tiltandshift filter - CRYO APC muxer +- ADPCM IMA APC encoder version 6.1: - libaribcaption decoder diff --git a/doc/general_contents.texi b/doc/general_contents.texi index df31edd060..9f450dc794 100644 --- a/doc/general_contents.texi +++ b/doc/general_contents.texi @@ -1188,7 +1188,7 @@ following image formats are supported: @item ADPCM IMA Acorn Replay @tab @tab X @item ADPCM IMA AMV @tab X @tab X @tab Used in AMV files -@item ADPCM IMA APC @tab @tab X +@item ADPCM IMA APC @tab X @tab X @tab Codec used in games by Cryo Interactive @item ADPCM IMA Cunning Developments @tab @tab X @item ADPCM IMA Electronic Arts EACS @tab @tab X diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index 7f18fc2daf..7abd71541d 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -74,6 +74,7 @@ typedef struct ADPCMEncodeContext { TrellisNode *node_buf; TrellisNode **nodep_buf; uint8_t *trellis_hash; + int extradata_updated; } ADPCMEncodeContext; #define FREEZE_INTERVAL 128 @@ -157,6 +158,15 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) bytestream_put_le16(&extradata, ff_adpcm_AdaptCoeff2[i] * 4); } ) /* End of CASE */ + CASE(ADPCM_IMA_APC, + if (avctx->trellis) { + av_log(avctx, AV_LOG_ERROR, "trellis encoding not implemented for CRYO APC\n"); + return AVERROR_PATCHWELCOME; + } + //extradata will be output in adpcm_encode_frame() + avctx->frame_size = s->block_size * 2 / channels; + avctx->block_align = s->block_size; + ) /* End of CASE */ CASE(ADPCM_YAMAHA, avctx->frame_size = s->block_size * 2 / channels; avctx->block_align = s->block_size; @@ -622,6 +632,28 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, dst = avpkt->data; switch(avctx->codec->id) { + CASE(ADPCM_IMA_APC, + //initialize predictors using initial samples + if (!c->extradata_updated) { + uint8_t *side_data = av_packet_new_side_data( + avpkt, AV_PKT_DATA_NEW_EXTRADATA, 8); + + if (!side_data) { + return AVERROR(ENOMEM); + } + + for (int ch = 0; ch < channels; ch++) { + c->status[ch].prev_sample = samples[ch]; + bytestream_put_le32(&side_data, c->status[ch].prev_sample); + } + c->extradata_updated = 1; + } + for (int i = 0; i < frame->nb_samples*channels/2; i++) { + uint8_t l = adpcm_ima_compress_sample(&c->status[0], samples[2*i+0]); + uint8_t r = adpcm_ima_compress_sample(&c->status[st], samples[2*i+1]); + *dst++ = (l<<4) | r; + } + ) /* End of CASE */ CASE(ADPCM_IMA_WAV, int blocks = (frame->nb_samples - 1) / 8; @@ -1027,6 +1059,7 @@ ADPCM_ENCODER(ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, 0, ADPCM_ENCODER(ADPCM_IMA_SSI, adpcm_ima_ssi, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Simon & Schuster Interactive") ADPCM_ENCODER(ADPCM_IMA_WAV, adpcm_ima_wav, sample_fmts_p, 0, "ADPCM IMA WAV") ADPCM_ENCODER(ADPCM_IMA_WS, adpcm_ima_ws, sample_fmts, AV_CODEC_CAP_SMALL_LAST_FRAME, "ADPCM IMA Westwood") +ADPCM_ENCODER(ADPCM_IMA_APC, adpcm_ima_apc, sample_fmts, 0, "ADPCM IMA CRYO APC") ADPCM_ENCODER(ADPCM_MS, adpcm_ms, sample_fmts, 0, "ADPCM Microsoft") ADPCM_ENCODER(ADPCM_SWF, adpcm_swf, sample_fmts, 0, "ADPCM Shockwave Flash") ADPCM_ENCODER(ADPCM_YAMAHA, adpcm_yamaha, sample_fmts, 0, "ADPCM Yamaha") diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index b0f004e15c..34662a88f3 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -669,6 +669,7 @@ extern const FFCodec ff_adpcm_ima_amv_encoder; extern const FFCodec ff_adpcm_ima_alp_decoder; extern const FFCodec ff_adpcm_ima_alp_encoder; extern const FFCodec ff_adpcm_ima_apc_decoder; +extern const FFCodec ff_adpcm_ima_apc_encoder; extern const FFCodec ff_adpcm_ima_apm_decoder; extern const FFCodec ff_adpcm_ima_apm_encoder; extern const FFCodec ff_adpcm_ima_cunning_decoder; diff --git a/libavcodec/version.h b/libavcodec/version.h index 34b059a8a9..376388c5bb 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #include "version_major.h" -#define LIBAVCODEC_VERSION_MINOR 36 +#define LIBAVCODEC_VERSION_MINOR 37 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak index 7b09e3bd63..e7e3ae5ab8 100644 --- a/tests/fate/acodec.mak +++ b/tests/fate/acodec.mak @@ -48,6 +48,7 @@ fate-acodec-pcm-f%be: FMT = au FATE_ACODEC_ADPCM_RESAMPLE-$(call ENCDEC, ADPCM_ADX, ADX) += adx FATE_ACODEC_ADPCM_RESAMPLE-$(call ENCDEC, ADPCM_ARGO, ARGO_ASF) += argo +FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_APC, APC) += ima_apc FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_APM, APM) += ima_apm FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_ALP, ALP) += ima_alp FATE_ACODEC_ADPCM_RESAMPLE-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt @@ -69,6 +70,7 @@ fate-acodec-adpcm-%: CODEC = adpcm_$(@:fate-acodec-adpcm-%=%) fate-acodec-adpcm-adx: FMT = adx fate-acodec-adpcm-argo: FMT = argo_asf +fate-acodec-adpcm-ima_apc: FMT = apc fate-acodec-adpcm-ima_apm: FMT = apm fate-acodec-adpcm-ima_qt: FMT = aiff fate-acodec-adpcm-ima_ssi: FMT = kvag diff --git a/tests/ref/acodec/adpcm-ima_apc b/tests/ref/acodec/adpcm-ima_apc new file mode 100644 index 0000000000..f168734c78 --- /dev/null +++ b/tests/ref/acodec/adpcm-ima_apc @@ -0,0 +1,4 @@ +45aca515c679bb0c315df766432d5630 *tests/data/fate/acodec-adpcm-ima_apc.apc +265248 tests/data/fate/acodec-adpcm-ima_apc.apc +03fc41cf61b7a160359147cd6363562a *tests/data/fate/acodec-adpcm-ima_apc.out.wav +stddev: 904.04 PSNR: 37.21 MAXDIFF:34026 bytes: 1058400/ 1060864 -- 2.39.2