diff mbox

[FFmpeg-devel] lavc/g729dec: Support stereo streams

Message ID CAB0OVGraFKt4OgAKQuJeTBsSrSoaAKTyjq9hhj-3FgMD-4HQ9A@mail.gmail.com
State Accepted
Headers show

Commit Message

Carl Eugen Hoyos Dec. 14, 2018, 2:18 p.m. UTC
2018-12-12 23:44 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
> On 12/12/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>> 2018-12-12 23:30 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>>> On 12/12/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>>> Hi!
>>>>
>>>> Attached patch fixes ticket #4553 for me.
>>>>
>>>> Please comment, Carl Eugen
>>>>
>>>
>>> I do not like what you did to G729Context.
>>
>>> Please rewrite patch.
>>> Move relevant parts into G729ChannelContext chan[2];
>>
>> Which part of the context does not need to be duplicated?
>
> AudioDSPContext adsp;

New patch attached.

Please comment, Carl Eugen

Comments

Paul B Mahol Dec. 14, 2018, 2:52 p.m. UTC | #1
On 12/14/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
> 2018-12-12 23:44 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>> On 12/12/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>> 2018-12-12 23:30 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>>>> On 12/12/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>>>> Hi!
>>>>>
>>>>> Attached patch fixes ticket #4553 for me.
>>>>>
>>>>> Please comment, Carl Eugen
>>>>>
>>>>
>>>> I do not like what you did to G729Context.
>>>
>>>> Please rewrite patch.
>>>> Move relevant parts into G729ChannelContext chan[2];
>>>
>>> Which part of the context does not need to be duplicated?
>>
>> AudioDSPContext adsp;
>
> New patch attached.
>
> Please comment, Carl Eugen
>

No need to alloc channel context, just use fixed size: [2];
Carl Eugen Hoyos Dec. 14, 2018, 3:36 p.m. UTC | #2
2018-12-14 15:52 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
> On 12/14/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>> 2018-12-12 23:44 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>>> On 12/12/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>>> 2018-12-12 23:30 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>>>>> On 12/12/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>>>>> Hi!
>>>>>>
>>>>>> Attached patch fixes ticket #4553 for me.
>>>>>>
>>>>>> Please comment, Carl Eugen
>>>>>>
>>>>>
>>>>> I do not like what you did to G729Context.
>>>>
>>>>> Please rewrite patch.
>>>>> Move relevant parts into G729ChannelContext chan[2];
>>>>
>>>> Which part of the context does not need to be duplicated?
>>>
>>> AudioDSPContext adsp;
>>
>> New patch attached.
>>
>> Please comment, Carl Eugen
>
> No need to alloc channel context, just use fixed size: [2];

I assumed nearly all G.729 streams are mono and given
that this improvement was about avoiding an unneeded
allocation this version would be cleaner.
You don't agree?

Thank you, Carl Eugen
Paul B Mahol Dec. 14, 2018, 3:48 p.m. UTC | #3
On 12/14/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
> 2018-12-14 15:52 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>> On 12/14/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>> 2018-12-12 23:44 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>>>> On 12/12/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>>>> 2018-12-12 23:30 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>>>>>> On 12/12/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>>>>>> Hi!
>>>>>>>
>>>>>>> Attached patch fixes ticket #4553 for me.
>>>>>>>
>>>>>>> Please comment, Carl Eugen
>>>>>>>
>>>>>>
>>>>>> I do not like what you did to G729Context.
>>>>>
>>>>>> Please rewrite patch.
>>>>>> Move relevant parts into G729ChannelContext chan[2];
>>>>>
>>>>> Which part of the context does not need to be duplicated?
>>>>
>>>> AudioDSPContext adsp;
>>>
>>> New patch attached.
>>>
>>> Please comment, Carl Eugen
>>
>> No need to alloc channel context, just use fixed size: [2];
>
> I assumed nearly all G.729 streams are mono and given
> that this improvement was about avoiding an unneeded
> allocation this version would be cleaner.
> You don't agree?

OK, whatever.

>
> Thank you, Carl Eugen
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Carl Eugen Hoyos Dec. 14, 2018, 11:59 p.m. UTC | #4
2018-12-14 16:48 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
> On 12/14/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>> 2018-12-14 15:52 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>>> On 12/14/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>>> 2018-12-12 23:44 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>>>>> On 12/12/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>>>>> 2018-12-12 23:30 GMT+01:00, Paul B Mahol <onemda@gmail.com>:
>>>>>>> On 12/12/18, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>>>>>>>> Hi!
>>>>>>>>
>>>>>>>> Attached patch fixes ticket #4553 for me.
>>>>>>>>
>>>>>>>> Please comment, Carl Eugen
>>>>>>>>
>>>>>>>
>>>>>>> I do not like what you did to G729Context.
>>>>>>
>>>>>>> Please rewrite patch.
>>>>>>> Move relevant parts into G729ChannelContext chan[2];
>>>>>>
>>>>>> Which part of the context does not need to be duplicated?
>>>>>
>>>>> AudioDSPContext adsp;
>>>>
>>>> New patch attached.
>>>>
>>>> Please comment, Carl Eugen
>>>
>>> No need to alloc channel context, just use fixed size: [2];
>>
>> I assumed nearly all G.729 streams are mono and given
>> that this improvement was about avoiding an unneeded
>> allocation this version would be cleaner.
>> You don't agree?
>
> OK, whatever.

Patch applied.

Carl Eugen
diff mbox

Patch

From 9fb106d7ae33f2d182cd5c95ec10a823a344fa93 Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <ceffmpeg@gmail.com>
Date: Fri, 14 Dec 2018 15:16:56 +0100
Subject: [PATCH] lavc/g729dec: Support stereo streams.

Fixes ticket #4553.
---
 libavcodec/g729_parser.c |    1 +
 libavcodec/g729dec.c     |   72 ++++++++++++++++++++++++++++++++--------------
 libavcodec/version.h     |    2 +-
 3 files changed, 53 insertions(+), 22 deletions(-)

diff --git a/libavcodec/g729_parser.c b/libavcodec/g729_parser.c
index d13c990..9982dbf 100644
--- a/libavcodec/g729_parser.c
+++ b/libavcodec/g729_parser.c
@@ -48,6 +48,7 @@  static int g729_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
         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;
+        s->block_size *= avctx->channels;
         s->duration   = avctx->frame_size;
     }
 
diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c
index 2e1bf18..101ce97 100644
--- a/libavcodec/g729dec.c
+++ b/libavcodec/g729dec.c
@@ -100,8 +100,6 @@  typedef struct {
 } G729FormatDescription;
 
 typedef struct {
-    AudioDSPContext adsp;
-
     /// past excitation signal buffer
     int16_t exc_base[2*SUBFRAME_SIZE+PITCH_DELAY_MAX+INTERPOL_LEN];
 
@@ -152,7 +150,13 @@  typedef struct {
 
     /// high-pass filter data (past output)
     int16_t hpf_z[2];
-}  G729Context;
+}  G729ChannelContext;
+
+typedef struct {
+    AudioDSPContext adsp;
+
+    G729ChannelContext *channel_context;
+} G729Context;
 
 static const G729FormatDescription format_g729_8k = {
     .ac_index_bits     = {8,5},
@@ -338,18 +342,25 @@  static int32_t scalarproduct_int16_c(const int16_t * v1, const int16_t * v2, int
 
 static av_cold int decoder_init(AVCodecContext * avctx)
 {
-    G729Context* ctx = avctx->priv_data;
-    int i,k;
+    G729Context *s = avctx->priv_data;
+    G729ChannelContext *ctx;
+    int c,i,k;
 
-    if (avctx->channels != 1) {
-        av_log(avctx, AV_LOG_ERROR, "Only mono sound is supported (requested channels: %d).\n", avctx->channels);
+    if (avctx->channels < 1 || avctx->channels > 2) {
+        av_log(avctx, AV_LOG_ERROR, "Only mono and stereo are supported (requested channels: %d).\n", avctx->channels);
         return AVERROR(EINVAL);
     }
-    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+    avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
 
     /* Both 8kbit/s and 6.4kbit/s modes uses two subframes per frame. */
     avctx->frame_size = SUBFRAME_SIZE << 1;
 
+    ctx =
+    s->channel_context = av_mallocz(sizeof(G729ChannelContext) * avctx->channels);
+    if (!ctx)
+        return AVERROR(ENOMEM);
+
+    for (c = 0; c < avctx->channels; c++) {
     ctx->gain_coeff = 16384; // 1.0 in (1.14)
 
     for (k = 0; k < MA_NP + 1; k++) {
@@ -373,8 +384,11 @@  static av_cold int decoder_init(AVCodecContext * avctx)
     for(i=0; i<4; i++)
         ctx->quant_energy[i] = -14336; // -14 in (5.10)
 
-    ff_audiodsp_init(&ctx->adsp);
-    ctx->adsp.scalarproduct_int16 = scalarproduct_int16_c;
+    ctx++;
+    }
+
+    ff_audiodsp_init(&s->adsp);
+    s->adsp.scalarproduct_int16 = scalarproduct_int16_c;
 
     return 0;
 }
@@ -387,12 +401,11 @@  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
     int16_t *out_frame;
     GetBitContext gb;
     const G729FormatDescription *format;
-    int frame_erasure = 0;    ///< frame erasure detected during decoding
-    int bad_pitch = 0;        ///< parity check failed
-    int i;
+    int c, i;
     int16_t *tmp;
     G729Formats packet_type;
-    G729Context *ctx = avctx->priv_data;
+    G729Context *s = avctx->priv_data;
+    G729ChannelContext *ctx = s->channel_context;
     int16_t lp[2][11];           // (3.12)
     uint8_t ma_predictor;     ///< switched MA predictor of LSP quantizer
     uint8_t quantizer_1st;    ///< first stage vector of quantizer
@@ -405,22 +418,20 @@  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
     int16_t synth[SUBFRAME_SIZE+10]; // fixed-codebook vector
     int j, ret;
     int gain_before, gain_after;
-    int is_periodic = 0;         // whether one of the subframes is declared as periodic or not
     AVFrame *frame = data;
 
     frame->nb_samples = SUBFRAME_SIZE<<1;
     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
-    out_frame = (int16_t*) frame->data[0];
 
-    if (buf_size % 10 == 0) {
+    if (buf_size % (G729_8K_BLOCK_SIZE * avctx->channels) == 0) {
         packet_type = FORMAT_G729_8K;
         format = &format_g729_8k;
         //Reset voice decision
         ctx->onset = 0;
         ctx->voice_decision = DECISION_VOICE;
         av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729 @ 8kbit/s");
-    } else if (buf_size == 8) {
+    } else if (buf_size == G729D_6K4_BLOCK_SIZE * avctx->channels) {
         packet_type = FORMAT_G729D_6K4;
         format = &format_g729d_6k4;
         av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729D @ 6.4kbit/s");
@@ -429,6 +440,12 @@  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
         return AVERROR_INVALIDDATA;
     }
 
+    for (c = 0; c < avctx->channels; c++) {
+    int frame_erasure = 0; ///< frame erasure detected during decoding
+    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];
+
     for (i=0; i < buf_size; i++)
         frame_erasure |= buf[i];
     frame_erasure = !frame_erasure;
@@ -570,7 +587,7 @@  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
             }
 
             /* Decode the fixed-codebook gain. */
-            ctx->past_gain_code[0] = ff_acelp_decode_gain_code(&ctx->adsp, gain_corr_factor,
+            ctx->past_gain_code[0] = ff_acelp_decode_gain_code(&s->adsp, gain_corr_factor,
                                                                fc, MR_ENERGY,
                                                                ctx->quant_energy,
                                                                ma_prediction_coeff,
@@ -660,7 +677,7 @@  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
 
         /* Call postfilter and also update voicing decision for use in next frame. */
         ff_g729_postfilter(
-                &ctx->adsp,
+                &s->adsp,
                 &ctx->ht_prev_data,
                 &is_periodic,
                 &lp[i][0],
@@ -702,8 +719,20 @@  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
     /* Save signal for use in next frame. */
     memmove(ctx->exc_base, ctx->exc_base + 2 * SUBFRAME_SIZE, (PITCH_DELAY_MAX+INTERPOL_LEN)*sizeof(int16_t));
 
+    buf += packet_type == FORMAT_G729_8K ? G729_8K_BLOCK_SIZE : G729D_6K4_BLOCK_SIZE;
+    ctx++;
+    }
+
     *got_frame_ptr = 1;
-    return packet_type == FORMAT_G729_8K ? 10 : 8;
+    return packet_type == FORMAT_G729_8K ? G729_8K_BLOCK_SIZE * avctx->channels : G729D_6K4_BLOCK_SIZE * avctx->channels;
+}
+
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+    G729Context *s = avctx->priv_data;
+    av_freep(&s->channel_context);
+
+    return 0;
 }
 
 AVCodec ff_g729_decoder = {
@@ -714,5 +743,6 @@  AVCodec ff_g729_decoder = {
     .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 5677a7f..9e43338 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@ 
 
 #define LIBAVCODEC_VERSION_MAJOR  58
 #define LIBAVCODEC_VERSION_MINOR  42
-#define LIBAVCODEC_VERSION_MICRO 100
+#define LIBAVCODEC_VERSION_MICRO 101
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
-- 
1.7.10.4