From 32cc6a96f80b5406e8327d912c8fc38812e6a664 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= <[email protected]>
Date: Fri, 23 Nov 2018 15:15:02 +0100
Subject: [PATCH 3/3] Add ADPCM IMA CRYO APC encoder
No trellis quantization yet
---
Changelog | 1 +
libavcodec/adpcmenc.c | 33 +++++++++++++++++++++++++++++++++
libavcodec/allcodecs.c | 1 +
libavcodec/version.h | 4 ++--
tests/fate/acodec.mak | 2 ++
tests/ref/acodec/adpcm-ima_apc | 4 ++++
6 files changed, 43 insertions(+), 2 deletions(-)
create mode 100644 tests/ref/acodec/adpcm-ima_apc
diff --git a/Changelog b/Changelog
index f678feed65..e6ae0c1187 100644
--- a/Changelog
+++ b/Changelog
@@ -11,6 +11,7 @@ version <next>:
- dhav demuxer
- PCM-DVD encoder
- CRYO APC muxer
+- ADPCM IMA CRYO APC encoder
version 4.1:
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c
index 668939c778..0d757d5b46 100644
--- a/libavcodec/adpcmenc.c
+++ b/libavcodec/adpcmenc.c
@@ -54,6 +54,7 @@ typedef struct ADPCMEncodeContext {
TrellisNode *node_buf;
TrellisNode **nodep_buf;
uint8_t *trellis_hash;
+ int extradata_updated;
} ADPCMEncodeContext;
#define FREEZE_INTERVAL 128
@@ -124,6 +125,15 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx)
bytestream_put_le16(&extradata, ff_adpcm_AdaptCoeff2[i] * 4);
}
break;
+ case AV_CODEC_ID_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 = BLKSIZE * 2 / avctx->channels;
+ avctx->block_align = BLKSIZE;
+ break;
case AV_CODEC_ID_ADPCM_YAMAHA:
avctx->frame_size = BLKSIZE * 2 / avctx->channels;
avctx->block_align = BLKSIZE;
@@ -491,6 +501,28 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
dst = avpkt->data;
switch(avctx->codec->id) {
+ case AV_CODEC_ID_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 (ch = 0; ch < avctx->channels; ch++) {
+ c->status[ch].prev_sample = samples[ch];
+ bytestream_put_le32(&side_data, c->status[ch].prev_sample);
+ }
+ c->extradata_updated = 1;
+ }
+ for (i = 0; i < frame->nb_samples*avctx->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;
+ }
+ break;
case AV_CODEC_ID_ADPCM_IMA_WAV:
{
int blocks, j;
@@ -721,6 +753,7 @@ AVCodec ff_ ## name_ ## _encoder = { \
ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt, sample_fmts_p, "ADPCM IMA QuickTime");
ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav, sample_fmts_p, "ADPCM IMA WAV");
+ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_APC, adpcm_ima_apc, sample_fmts, "ADPCM IMA CRYO APC");
ADPCM_ENCODER(AV_CODEC_ID_ADPCM_MS, adpcm_ms, sample_fmts, "ADPCM Microsoft");
ADPCM_ENCODER(AV_CODEC_ID_ADPCM_SWF, adpcm_swf, sample_fmts, "ADPCM Shockwave Flash");
ADPCM_ENCODER(AV_CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha, sample_fmts, "ADPCM Yamaha");
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index d70646e91a..873f236531 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -586,6 +586,7 @@ extern AVCodec ff_adpcm_g726_decoder;
extern AVCodec ff_adpcm_g726le_encoder;
extern AVCodec ff_adpcm_g726le_decoder;
extern AVCodec ff_adpcm_ima_amv_decoder;
+extern AVCodec ff_adpcm_ima_apc_encoder;
extern AVCodec ff_adpcm_ima_apc_decoder;
extern AVCodec ff_adpcm_ima_dat4_decoder;
extern AVCodec ff_adpcm_ima_dk3_decoder;
diff --git a/libavcodec/version.h b/libavcodec/version.h
index f758093582..5677a7feba 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,8 +28,8 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 58
-#define LIBAVCODEC_VERSION_MINOR 41
-#define LIBAVCODEC_VERSION_MICRO 101
+#define LIBAVCODEC_VERSION_MINOR 42
+#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak
index 80d26de0f9..69bfa6940e 100644
--- a/tests/fate/acodec.mak
+++ b/tests/fate/acodec.mak
@@ -45,6 +45,7 @@ fate-acodec-pcm-u%le: FMT = nut
fate-acodec-pcm-f%be: FMT = au
FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_ADX, ADX) += adx
+FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_APC, APC) += ima_apc
FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_QT, AIFF) += ima_qt
FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_IMA_WAV, WAV) += ima_wav
FATE_ACODEC_ADPCM-$(call ENCDEC, ADPCM_MS, WAV) += ms
@@ -58,6 +59,7 @@ fate-acodec-adpcm: $(FATE_ACODEC_ADPCM)
fate-acodec-adpcm-%: CODEC = adpcm_$(@:fate-acodec-adpcm-%=%)
fate-acodec-adpcm-adx: FMT = adx
+fate-acodec-adpcm-ima_apc: FMT = apc
fate-acodec-adpcm-ima_qt: FMT = aiff
fate-acodec-adpcm-ima_wav: FMT = wav
fate-acodec-adpcm-ms: FMT = wav
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.11.0
_______________________________________________
ffmpeg-devel mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel