[FFmpeg-devel] [PATCH] G.729 Frame erasure support for LSF decoding

Michael Niedermayer michaelni
Thu Jun 25 11:43:50 CEST 2009


On Thu, Jun 25, 2009 at 09:22:33AM +0700, Vladimir Voroshilov wrote:
> 2009/6/25 Michael Niedermayer <michaelni at gmx.at>:
> > On Wed, Jun 24, 2009 at 08:18:23PM +0700, Vladimir Voroshilov wrote:
> >> 2009/6/24 Michael Niedermayer <michaelni at gmx.at>:
> >> > On Sat, Jun 20, 2009 at 02:26:59PM +0700, Vladimir Voroshilov wrote:
> >> >
> >> > [...]
> >> >> diff --git ffmpeg-r19218/libavcodec/g729data.h ffmpeg-r19218_v163/libavcodec/g729data.h
> >> >> index a70c705..e202331 100644
> >> >> --- ffmpeg-r19218/libavcodec/g729data.h
> >> >> +++ ffmpeg-r19218_v163/libavcodec/g729data.h
> >> >> @@ -275,4 +275,14 @@ static const int16_t cb_ma_predictor_sum[2][10] = { /* (0.15) */
> >> >> ? ?{14585, 18333, 19772, 17344, 16426, 16459, 15155, 15220, 16043, 15708}
> >> >> ?};
> >> >>
> >> >> +/**
> >> >> + * ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2^27
> >> >> + * ff_g729_cb_ma_predictor_sum_inv[j][i] = ---------------------------------
> >> >> + * ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ff_g720_cb_ma_predictor_sum[j][i]
> >> >> + */
> >> >
> >> > my guess would be that this is also not really "="
> >> >
> >> >
> >> > [...]
> >> >> - ? ?ma_predictor ? ? = get_bits(&gb, 1);
> >> >> - ? ?quantizer_1st ? ?= get_bits(&gb, VQ_1ST_BITS);
> >> >> - ? ?quantizer_2nd_lo = get_bits(&gb, VQ_2ND_BITS);
> >> >> - ? ?quantizer_2nd_hi = get_bits(&gb, VQ_2ND_BITS);
> >> >> +
> >> >> + ? ?if(frame_erasure) {
> >> >> + ? ? ? ?skip_bits(&gb, 1 + VQ_1ST_BITS + VQ_2ND_BITS + VQ_2ND_BITS);
> >> >> +
> >> >> + ? ? ? ?lsf_restore_from_previous(ctx->lsfq, ctx->past_quantizer_outputs,
> >> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ctx->ma_predictor);
> >> >> + ? ?} else {
> >> >> + ? ? ? ?uint8_t quantizer_1st; ? ?///< first stage vector of quantizer
> >> >> + ? ? ? ?uint8_t quantizer_2nd_lo; ///< second stage lower vector of quantizer (size in bits)
> >> >> + ? ? ? ?uint8_t quantizer_2nd_hi; ///< second stage higher vector of quantizer (size in bits)
> >> >> +
> >> >> + ? ? ? ?ctx->ma_predictor = get_bits(&gb, 1);
> >> >> + ? ? ? ?quantizer_1st ? ? = get_bits(&gb, VQ_1ST_BITS);
> >> >> + ? ? ? ?quantizer_2nd_lo ?= get_bits(&gb, VQ_2ND_BITS);
> >> >> + ? ? ? ?quantizer_2nd_hi ?= get_bits(&gb, VQ_2ND_BITS);
> >> >>
> >> >
> >> > reindent besides i dont like the change, its useless to replace them
> >> > by skip
> >>
> >> I though this version is more clean due to localized usage of variables.
> >> It also shows that in erasure case reading of quantizer values is not used.
> >>
> >> here is my early version without skip, but with two variables per MA
> >> predictor (current/prev values).
> >
> > [...]
> >
> >> @@ -162,6 +164,27 @@ static void lsf_decode(int16_t* lsfq, int16_t* past_quantizer_outputs[MA_NP + 1]
> >> ? ? ?ff_acelp_reorder_lsf(lsfq, LSFQ_DIFF_MIN, LSFQ_MIN, LSFQ_MAX, 10);
> >> ?}
> >>
> >> +static void lsf_restore_from_previous(int16_t* lsfq,
> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int16_t* past_quantizer_outputs[MA_NP + 1],
> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int ma_predictor_prev)
> >> +{
> >> + ? ?int16_t* quantizer_output = past_quantizer_outputs[MA_NP];
> >> + ? ?int i,k;
> >> +
> >> + ? ?for (i = 0; i < 10; i++) {
> >> + ? ? ? ?int tmp = lsfq[i] << 15;
> >> +
> >> + ? ? ? ?for (k = 0; k < MA_NP; k++)
> >> + ? ? ? ? ? ?tmp -= past_quantizer_outputs[k][i] * cb_ma_predictor[ma_predictor_prev][k][i];
> >> +
> >> + ? ? ? ?quantizer_output[i] = ((tmp >> 15) * cb_ma_predictor_sum_inv[ma_predictor_prev][i]) >> 12;
> >> + ? ?}
> >> +
> >> + ? ?/* Rotate past_quantizer_outputs. */
> >> + ? ?memmove(past_quantizer_outputs + 1, past_quantizer_outputs, MA_NP * sizeof(int16_t*));
> >> + ? ?past_quantizer_outputs[0] = quantizer_output;
> >> +}
> >
> > this code is duplicated
> 
> Fixed.
> 
> 
> -- 
> Regards,
> Vladimir Voroshilov     mailto:voroshil at gmail.com
> JID: voroshil at gmail.com, voroshil at jabber.ru
> ICQ: 95587719

>  g729data.h |    5 +++++
>  g729dec.c  |   35 +++++++++++++++++++++++++++++++----
>  2 files changed, 36 insertions(+), 4 deletions(-)
> 9b703bec58c166bc06b1ffbb94f4297cb7499639  0001-Frame-erasure-support-for-LSF-decoding.171.patch
> From 70858592b30d234b8d64be6950d8038e6d36bbc7 Mon Sep 17 00:00:00 2001
> From: Vladimir Voroshilov <voroshil at gmail.com>
> Date: Thu, 11 Jun 2009 12:30:46 +0700
> Subject: [PATCH 01/25] Frame erasure support for LSF decoding
> 
> 
> diff --git ffmpeg-r19260/libavcodec/g729data.h ffmpeg-r19260_v171/libavcodec/g729data.h
> index 1d64553..02d0b93 100644
> --- ffmpeg-r19260/libavcodec/g729data.h
> +++ ffmpeg-r19260_v171/libavcodec/g729data.h
> @@ -268,6 +268,11 @@ static const int16_t cb_ma_predictor_sum[2][10] = { /* (0.15) */
>    {14585, 18333, 19772, 17344, 16426, 16459, 15155, 15220, 16043, 15708}
>  };
>  
> +static const int16_t cb_ma_predictor_sum_inv[2][10] = { /* (3.12) */
> +  {17210, 15888, 16357, 16183, 16516, 15833, 15888, 15421, 14840, 15597},
> +  { 9202,  7320,  6788,  7738,  8170,  8154,  8856,  8818,  8366,  8544}
> +};
> +
>  /**
>   * initial LSP coefficients belongs to virtual frame preceding  the
>   * first frame of the stream

> diff --git ffmpeg-r19260/libavcodec/g729dec.c ffmpeg-r19260_v171/libavcodec/g729dec.c
> index 628aee0..baf8a08 100644
> --- ffmpeg-r19260/libavcodec/g729dec.c
> +++ ffmpeg-r19260_v171/libavcodec/g729dec.c
> @@ -88,6 +88,8 @@ typedef struct {
>      int16_t lsfq[10];           ///< (2.13) quantized LSF coefficients from previous frame
>      int16_t lsp_buf[2][10];     ///< (0.15) LSP coefficients (previous and current frames) (3.2.5)
>      int16_t *lsp[2];            ///< pointers to lsp_buf
> +
> +    int ma_predictor;           ///< switched MA predictor of LSP quantizer
>  }  G729Context;
>  
>  static const G729FormatDescription format_g729_8k = {

this change looks unneeded


> @@ -155,13 +157,26 @@ static void lsf_decode(int16_t* lsfq, int16_t* past_quantizer_outputs[MA_NP + 1]
>          lsfq[i] = sum >> 15;
>      }
>  
> -    /* Rotate past_quantizer_outputs. */
> -    memmove(past_quantizer_outputs + 1, past_quantizer_outputs, MA_NP * sizeof(int16_t*));
> -    past_quantizer_outputs[0] = quantizer_output;
> -
>      ff_acelp_reorder_lsf(lsfq, LSFQ_DIFF_MIN, LSFQ_MIN, LSFQ_MAX, 10);
>  }
>  
> +static void lsf_restore_from_previous(int16_t* lsfq,
> +                                      int16_t* past_quantizer_outputs[MA_NP + 1],
> +                                      int ma_predictor_prev)
> +{
> +    int16_t* quantizer_output = past_quantizer_outputs[MA_NP];
> +    int i,k;
> +
> +    for (i = 0; i < 10; i++) {
> +        int tmp = lsfq[i] << 15;
> +
> +        for (k = 0; k < MA_NP; k++)
> +            tmp -= past_quantizer_outputs[k][i] * cb_ma_predictor[ma_predictor_prev][k][i];
> +
> +        quantizer_output[i] = ((tmp >> 15) * cb_ma_predictor_sum_inv[ma_predictor_prev][i]) >> 12;
> +    }
> +}

this code still is practically the same as lsf_decode()
also what is lsf_restore_from_previous supposed to mean?
the function _GUESSES_ values of a damaged (erased) frame nothing is restored
and a russian-english dictionary might be a good idea if you dont see
why restored is just the wrong word
of course i might also be misunderstanding the spec and maybe this is used
for more than damaged frames but thats how i understand it currently

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

While the State exists there can be no freedom; when there is freedom there
will be no State. -- Vladimir Lenin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090625/edac4bf3/attachment.pgp>



More information about the ffmpeg-devel mailing list