From 8af0b279ad0c25425d075498f60b0770528687a2 Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <ceffmpeg@gmail.com>
Date: Mon, 19 Aug 2019 23:34:37 +0200
Subject: [PATCH] lavc/g729dec: Support decoding Sipro ACELP.KELVIN.
Fixes ticket #4799.
Analyzed-by: Aleksandr Ustinov
---
Changelog | 3 +++
configure | 1 +
doc/general.texi | 1 +
libavcodec/allcodecs.c | 1 +
libavcodec/avcodec.h | 1 +
libavcodec/codec_desc.c | 6 ++++++
libavcodec/g729_parser.c | 5 +++--
libavcodec/g729dec.c | 21 +++++++++++++++++++--
libavcodec/version.h | 2 +-
libavformat/riff.c | 1 +
10 files changed, 37 insertions(+), 5 deletions(-)
@@ -1,6 +1,9 @@
Entries are sorted chronologically from oldest to youngest within each release,
releases are sorted from youngest to oldest.
+version <next>:
+- support Sipro ACELP.KELVIN decoding
+
version 4.2:
- tpad filter
- AV1 decoding support through libdav1d
@@ -2635,6 +2635,7 @@ ac3_decoder_select="ac3_parser ac3dsp bswapdsp fmtconvert mdct"
ac3_fixed_decoder_select="ac3_parser ac3dsp bswapdsp mdct"
ac3_encoder_select="ac3dsp audiodsp mdct me_cmp"
ac3_fixed_encoder_select="ac3dsp audiodsp mdct me_cmp"
+acelp_kelvin_decoder_select="g729_decoder"
adpcm_g722_decoder_select="g722dsp"
adpcm_g722_encoder_select="g722dsp"
aic_decoder_select="golomb idctdsp"
@@ -1057,6 +1057,7 @@ following image formats are supported:
@item AAC+ @tab E @tab IX
@tab encoding supported through external library libfdk-aac
@item AC-3 @tab IX @tab IX
+@item ACELP.KELVIN @tab @tab X
@item ADPCM 4X Movie @tab @tab X
@item APDCM Yamaha AICA @tab @tab X
@item ADPCM CDROM XA @tab @tab X
@@ -32,6 +32,7 @@
extern AVCodec ff_a64multi_encoder;
extern AVCodec ff_a64multi5_encoder;
extern AVCodec ff_aasc_decoder;
+extern AVCodec ff_acelp_kelvin_decoder;
extern AVCodec ff_aic_decoder;
extern AVCodec ff_alias_pix_encoder;
extern AVCodec ff_alias_pix_decoder;
@@ -629,6 +629,7 @@ enum AVCodecID {
AV_CODEC_ID_ON2AVC,
AV_CODEC_ID_DSS_SP,
AV_CODEC_ID_CODEC2,
+ AV_CODEC_ID_ACELP_KELVIN,
AV_CODEC_ID_FFWAVESYNTH = 0x15800,
AV_CODEC_ID_SONIC,
@@ -2834,6 +2834,12 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("codec2 (very low bitrate speech codec)"),
.props = AV_CODEC_PROP_LOSSY,
},
+ {
+ .id = AV_CODEC_ID_ACELP_KELVIN,
+ .name = "ACELP.KELVIN",
+ .long_name = NULL_IF_CONFIG_SMALL("Sipro ACELP.KELVIN"),
+ .props = AV_CODEC_PROP_LOSSY,
+ },
{
.id = AV_CODEC_ID_FFWAVESYNTH,
.type = AVMEDIA_TYPE_AUDIO,
@@ -45,9 +45,10 @@ static int g729_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
int next;
if (!s->block_size) {
- av_assert1(avctx->codec_id == AV_CODEC_ID_G729);
/* FIXME: replace this heuristic block_size with more precise estimate */
s->block_size = (avctx->bit_rate < 8000) ? G729D_6K4_BLOCK_SIZE : G729_8K_BLOCK_SIZE;
+ if (avctx->codec_id == AV_CODEC_ID_ACELP_KELVIN)
+ s->block_size++;
s->block_size *= avctx->channels;
s->duration = avctx->frame_size;
}
@@ -76,7 +77,7 @@ static int g729_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
}
AVCodecParser ff_g729_parser = {
- .codec_ids = { AV_CODEC_ID_G729 },
+ .codec_ids = { AV_CODEC_ID_G729, AV_CODEC_ID_ACELP_KELVIN },
.priv_data_size = sizeof(G729ParseContext),
.parser_parse = g729_parse,
.parser_close = ff_parse_close,
@@ -424,7 +424,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
return ret;
- if (buf_size % (G729_8K_BLOCK_SIZE * avctx->channels) == 0) {
+ if (buf_size % ((G729_8K_BLOCK_SIZE + (avctx->codec_id == AV_CODEC_ID_ACELP_KELVIN)) * avctx->channels) == 0) {
packet_type = FORMAT_G729_8K;
format = &format_g729_8k;
//Reset voice decision
@@ -445,6 +445,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
int bad_pitch = 0; ///< parity check failed
int is_periodic = 0; ///< whether one of the subframes is declared as periodic or not
out_frame = (int16_t*)frame->data[c];
+ if (avctx->codec_id == AV_CODEC_ID_ACELP_KELVIN) {
+ if (*buf != ((avctx->channels - 1 - c) * 0x80 | 2))
+ avpriv_request_sample(avctx, "First byte value %x for channel %d", *buf, c);
+ buf++;
+ }
for (i = 0; i < buf_size; i++)
frame_erasure |= buf[i];
@@ -727,7 +732,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
}
*got_frame_ptr = 1;
- return packet_type == FORMAT_G729_8K ? G729_8K_BLOCK_SIZE * avctx->channels : G729D_6K4_BLOCK_SIZE * avctx->channels;
+ return packet_type == FORMAT_G729_8K ? (G729_8K_BLOCK_SIZE + (avctx->codec_id == AV_CODEC_ID_ACELP_KELVIN)) * avctx->channels : G729D_6K4_BLOCK_SIZE * avctx->channels;
}
static av_cold int decode_close(AVCodecContext *avctx)
@@ -749,3 +754,15 @@ AVCodec ff_g729_decoder = {
.close = decode_close,
.capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
};
+
+AVCodec ff_acelp_kelvin_decoder = {
+ .name = "ACELP.KELVIN",
+ .long_name = NULL_IF_CONFIG_SMALL("Sipro ACELP.KELVIN"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_ACELP_KELVIN,
+ .priv_data_size = sizeof(G729Context),
+ .init = decoder_init,
+ .decode = decode_frame,
+ .close = decode_close,
+ .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1,
+};
@@ -28,7 +28,7 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 58
-#define LIBAVCODEC_VERSION_MINOR 55
+#define LIBAVCODEC_VERSION_MINOR 56
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@@ -534,6 +534,7 @@ const AVCodecTag ff_codec_wav_tags[] = {
{ AV_CODEC_ID_AAC, 0x00ff },
{ AV_CODEC_ID_G723_1, 0x0111 },
{ AV_CODEC_ID_SIPR, 0x0130 },
+ { AV_CODEC_ID_ACELP_KELVIN, 0x0135 },
{ AV_CODEC_ID_WMAV1, 0x0160 },
{ AV_CODEC_ID_WMAV2, 0x0161 },
{ AV_CODEC_ID_WMAPRO, 0x0162 },
--
2.22.0