[FFmpeg-trac] #3525(undetermined:new): AAC to PCM produced a lot of noise!

FFmpeg trac at avcodec.org
Thu Apr 3 03:22:05 CEST 2014


#3525: AAC to PCM produced a lot of noise!
-------------------------------------+-------------------------------------
             Reporter:  kaienfr      |                     Type:  defect
               Status:  new          |                 Priority:  critical
            Component:               |                  Version:  git-
  undetermined                       |  master
             Keywords:               |               Blocked By:
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
 In git-master ffmpeg, converting a AAC audio to PCM produced a lot of
 noise, even we did resampling from AV_SAMPLE_FMT_FLTP to
 AV_SAMPLE_FMT_S16.

 While in old ffmpeg, aac is converted directly into 16-bit PCM and without
 any noise. Is it a bug or something? I'd like to know how to produce a
 proper PCM in the new version of ffmpeg? Thanks a lot!

 Here is the information about my test AAC audio which reads by new ffmpeg:

 {{{
 Stream #0:0: Audio: aac, 44100 Hz, stereo, fltp, 122 kb/s
 }}}
 (the format fltp is shown as s16 in old ffmpeg, and flt in decoder)

 I've tried three ways to resampling the output FLTP to S16LE,
 1. using swr_convert
 2. using avresample_convert
 3. convert manualy

 But all of them yield the same result. The sound quality is really too
 bad, very slow and out of tune, with a lot of noise too.

 My resampling code is as follows, please have a look what's missing

 {{{
 void resampling(AVFrame* frame_, AVCodecContext* pCodecCtx, int64_t
 want_sample_rate, uint8_t* outbuf){
     SwrContext      *swrCtx_ = 0;
     AVAudioResampleContext *avr = 0;

     // Initializing the sample rate convert. We only really use it to
 convert float output into int.
     int64_t wanted_channel_layout = AV_CH_LAYOUT_STEREO;

 #ifdef AV_SAMPLEING
     avr = avresample_alloc_context();
     av_opt_set_int(avr, "in_channel_layout", frame_->channel_layout, 0);
     av_opt_set_int(avr, "out_channel_layout", wanted_channel_layout, 0);
     av_opt_set_int(avr, "in_sample_rate", frame_->sample_rate, 0);
     av_opt_set_int(avr, "out_sample_rate", 44100, 0);
     av_opt_set_int(avr, "in_sample_fmt", pCodecCtx->sample_fmt, 0);
 //AV_SAMPLE_FMT_FLTP
     av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
     av_opt_set_int(avr, "internal_sample_fmt", pCodecCtx->sample_fmt, 0);
     avresample_open(avr);
     avresample_convert(avr, &outbuf, frame_->linesize[0],
 frame_->nb_samples, frame_->extended_data, frame_->linesize[0],
 frame_->nb_samples);
     avresample_close(avr);
     return;
 #endif

 #ifdef USER_SAMPLEING
     if (pCodecCtx->sample_fmt == AV_SAMPLE_FMT_FLTP)
     {
             int nb_samples = frame_->nb_samples;
             int channels = frame_->channels;
             int outputBufferLen = nb_samples & channels * 2;
             auto outputBuffer = (int16_t*)outbuf;

             for (int i = 0; i < nb_samples; i++)
             {
                     for (int c = 0; c < channels; c++)
                     {
                             float* extended_data =
 (float*)frame_->extended_data[c];
                             float sample = extended_data[i];
                             if (sample < -1.0f) sample = -1.0f;
                             else if (sample > 1.0f) sample = 1.0f;
                             outputBuffer[i * channels + c] =
 (int16_t)round(sample * 32767.0f);
                     }
             }
             return;
     }
 #endif
     swrCtx_ = swr_alloc_set_opts(
             NULL, //swrCtx_,
             wanted_channel_layout,
             AV_SAMPLE_FMT_S16,
             want_sample_rate,
             pCodecCtx->channel_layout,
             pCodecCtx->sample_fmt,
             pCodecCtx->sample_rate,
             0,
             NULL);

     if (!swrCtx_ || swr_init(swrCtx_) < 0) {
             printf("swr_init: Failed to initialize the resampling
 context");
             return;
     }

     // convert audio to AV_SAMPLE_FMT_S16
     int swrRet = swr_convert(swrCtx_, &outbuf, frame_->nb_samples, (const
 uint8_t **)frame_->extended_data, frame_->nb_samples);
     if (swrRet < 0) {
             printf("swr_convert: Error while converting %d", swrRet);
             return;
     }
 }

 }}}

 I've also noticed that in ffplay, the aac audio is playing without noise.
 So what is the problem it could be? what is the right way of the
 conversion? is there something wrong in in decode part or resampling part
 or something else (such as we must use filter...)? Please help!

 Thanks a lot in advance!

--
Ticket URL: <https://trac.ffmpeg.org/ticket/3525>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list