diff mbox

[FFmpeg-devel] lavc/g729dec: Support decoding ACELP.KELVIN

Message ID CAB0OVGrFA0hF5su-GhJhacXG=CgmZh609Q3f9wfChp35LYd21w@mail.gmail.com
State Accepted
Headers show

Commit Message

Carl Eugen Hoyos Aug. 22, 2019, 10:12 a.m. UTC
Am Mo., 19. Aug. 2019 um 23:37 Uhr schrieb Carl Eugen Hoyos
<ceffmpeg@gmail.com>:
>
> Hi!
>
> Attached patch fixes tickets #4799 and #8081, thanks to Paul for his help.

New patch attached.

Carl Eugen

Comments

Paul B Mahol Aug. 23, 2019, 7:14 a.m. UTC | #1
allcodecs.c entry is in wrong section, it should be audio one but yours is
in video section.
the avcodec.h entry may contradict with next libav entry so better move it
bellow hcom.

Rest looks OK.

On Thu, Aug 22, 2019 at 12:13 PM Carl Eugen Hoyos <ceffmpeg@gmail.com>
wrote:

> Am Mo., 19. Aug. 2019 um 23:37 Uhr schrieb Carl Eugen Hoyos
> <ceffmpeg@gmail.com>:
> >
> > Hi!
> >
> > Attached patch fixes tickets #4799 and #8081, thanks to Paul for his
> help.
>
> New patch attached.
>
> Carl Eugen
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Carl Eugen Hoyos Sept. 16, 2019, 7:02 p.m. UTC | #2
Am Fr., 23. Aug. 2019 um 09:14 Uhr schrieb Paul B Mahol <onemda@gmail.com>:
>
> allcodecs.c entry is in wrong section, it should be audio one but yours is
> in video section.
> the avcodec.h entry may contradict with next libav entry so better move it
> bellow hcom.

Pushed with these changes.

Thank you!

Carl Eugen
diff mbox

Patch

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(-)

diff --git a/Changelog b/Changelog
index 52096eed0e..1c0ceddb4c 100644
--- a/Changelog
+++ b/Changelog
@@ -5,6 +5,7 @@  version <next>:
 - v360 filter
 - Intel QSV-accelerated MJPEG decoding
 - Intel QSV-accelerated VP9 decoding
+- support Sipro ACELP.KELVIN decoding
 
 version 4.2:
 - tpad filter
diff --git a/doc/general.texi b/doc/general.texi
index 3c0c803449..d90588c63a 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -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
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index e49188357b..ff4004f39a 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -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
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index d2f9a39ce5..5936cdc467 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -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;
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index d234271c5b..7ec4014d8b 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -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,
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 4d033c20ff..716e278b93 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -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,
diff --git a/libavcodec/g729_parser.c b/libavcodec/g729_parser.c
index 9982dbfffc..5a57025d62 100644
--- a/libavcodec/g729_parser.c
+++ b/libavcodec/g729_parser.c
@@ -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,
diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c
index 2e4756b805..5a5da5b03c 100644
--- a/libavcodec/g729dec.c
+++ b/libavcodec/g729dec.c
@@ -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,
+};
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 43c8cdb59f..ed767c8867 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -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, \
diff --git a/libavformat/riff.c b/libavformat/riff.c
index e755ad8d5f..27518216a6 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -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