lavc/g729dec: Support decoding Sipro ACELP.KELVIN.
authorCarl Eugen Hoyos <ceffmpeg@gmail.com>
Mon, 16 Sep 2019 18:57:53 +0000 (20:57 +0200)
committerCarl Eugen Hoyos <ceffmpeg@gmail.com>
Mon, 16 Sep 2019 18:57:53 +0000 (20:57 +0200)
Fixes ticket #4799.
Analyzed-by: Aleksandr Ustinov
Changelog
doc/general.texi
libavcodec/Makefile
libavcodec/allcodecs.c
libavcodec/avcodec.h
libavcodec/codec_desc.c
libavcodec/g729_parser.c
libavcodec/g729dec.c
libavcodec/version.h
libavformat/riff.c

index 4b29e01..08b7464 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -9,6 +9,7 @@ version <next>:
 - Supoort AMD AMF encoder on Linux (via Vulkan)
 - IMM5 video decoder
 - ZeroMQ protocol
+- support Sipro ACELP.KELVIN decoding
 
 
 version 4.2:
index 2744c23..79a23e1 100644 (file)
@@ -1067,6 +1067,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
index 6bc4383..37a84a6 100644 (file)
@@ -173,6 +173,7 @@ OBJS-$(CONFIG_AC3_FIXED_DECODER)       += ac3dec_fixed.o ac3dec_data.o ac3.o kbd
 OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc_float.o ac3enc.o ac3tab.o \
                                           ac3.o kbdwin.o
 OBJS-$(CONFIG_AC3_FIXED_ENCODER)       += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o
+OBJS-$(CONFIG_ACELP_KELVIN_DECODER)    += g729dec.o lsp.o celp_math.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o
 OBJS-$(CONFIG_AGM_DECODER)             += agm.o
 OBJS-$(CONFIG_AIC_DECODER)             += aic.o
 OBJS-$(CONFIG_ALAC_DECODER)            += alac.o alac_data.o alacdsp.o
index d5dfba1..41f6801 100644 (file)
@@ -388,6 +388,7 @@ extern AVCodec ff_ac3_encoder;
 extern AVCodec ff_ac3_decoder;
 extern AVCodec ff_ac3_fixed_encoder;
 extern AVCodec ff_ac3_fixed_decoder;
+extern AVCodec ff_acelp_kelvin_decoder;
 extern AVCodec ff_alac_encoder;
 extern AVCodec ff_alac_decoder;
 extern AVCodec ff_als_decoder;
index de4feb6..0ec3e73 100644 (file)
@@ -653,6 +653,7 @@ enum AVCodecID {
     AV_CODEC_ID_SBC,
     AV_CODEC_ID_ATRAC9,
     AV_CODEC_ID_HCOM,
+    AV_CODEC_ID_ACELP_KELVIN,
 
     /* subtitle codecs */
     AV_CODEC_ID_FIRST_SUBTITLE = 0x17000,          ///< A dummy ID pointing at the start of subtitle codecs.
index e6373be..d2c6863 100644 (file)
@@ -2992,6 +2992,12 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("HCOM Audio"),
         .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,
+    },
 
     /* subtitle codecs */
     {
index 9982dbf..5a57025 100644 (file)
@@ -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,
index 2e4756b..2595171 100644 (file)
@@ -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,
+};
index 5748d31..c7a2bd0 100644 (file)
@@ -28,8 +28,8 @@
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR  58
-#define LIBAVCODEC_VERSION_MINOR  56
-#define LIBAVCODEC_VERSION_MICRO 102
+#define LIBAVCODEC_VERSION_MINOR  57
+#define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
index f2c04f8..048a79e 100644 (file)
@@ -540,6 +540,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 },