title: libav filter aformat not converting properly to new sample rate
body: <p>I made a test bench application to test LibAV's FilterGraph. I would like to use it (among other filters) to convert any given audio track to signed 16bit stereo PCM (<code>s16</code>) at 48kHz sample rate. Currently my test sound file is located here: <a href="https://commons.wikimedia.org/wiki/File:Median_test.ogg" rel="nofollow noreferrer">https://commons.wikimedia.org/wiki/File:Median_test.ogg</a>
  The conversion is fine when I take the files 44,100Hz sample rate and make <a href="https://libav.org/documentation/libavfilter.html#aformat" rel="nofollow noreferrer">afromat</a> return that exact sample rate. However, when attempting to convert to 48000Hz, there is noticeable popping.</p>
  
  <p>Looking at the waveform generated, it appears to be rather crudely converting the audio file by spacing out the wave form over time and leaving the generated spaces with 0's.</p>
  
  <p>To my knowledge, and the documentation, <code>aformat</code> should be creating <code>resample</code> as needed to handle this type of situation <a href="https://libav.org/documentation/libavfilter.html#resample" rel="nofollow noreferrer">as specified here</a>.</p>
  
  <p>The code I am using is shown below. Taking in <code>../test.ogg</code> and outputting <code>../out_filter.raw</code> as 16bit PCM @ 48000Hz.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;libavformat/avformat.h&gt;
  #include &lt;libavfilter/avfilter.h&gt;
  #include &lt;libavfilter/buffersink.h&gt;
  #include &lt;libavfilter/buffersrc.h&gt;
  #include &lt;libavutil/channel_layout.h&gt;
  #include &lt;libavcodec/avcodec.h&gt;
  #include &lt;libavformat/avformat.h&gt;
  
  #define BUFFER_SIZE 4096
  
  FILE *fh;
  
  int read_packet(void *opaque, uint8_t *buf, int buff_size) {
      return (int) fread(buf, 1, (size_t) buff_size, fh);
  }
  
  int perform_decoding() {
  #define out_rate 48000
  #define out_layout AV_CH_LAYOUT_STEREO
  #define out_format AV_SAMPLE_FMT_S16
  
      AVFormatContext *ctx = avformat_alloc_context();
      uint8_t *buffer = av_malloc(BUFFER_SIZE);
      AVIOContext *aioctx = avio_alloc_context(
              buffer,       // Buffer
              BUFFER_SIZE,  // Buffer size
              0,            // write_flag
              NULL,         // opaque
              read_packet,  // read_packet
              NULL,         // write_packet
              NULL          // seek
      );
      ctx-&gt;pb = aioctx;
      avformat_open_input(&amp;ctx, "stream", NULL, NULL);
      if (avformat_find_stream_info(ctx, NULL) &lt; 0) {
          fprintf(stderr, "Resampler has read the stream info.\n");
          return -1;
      }
  
      int audio_stream_index = -1;
      AVStream *stream = NULL;
      for (int i = 0; i &lt; ctx-&gt;nb_streams; i++) {
          stream = ctx-&gt;streams[i];
          if (stream-&gt;codec-&gt;codec_type == AVMEDIA_TYPE_AUDIO) {
              audio_stream_index = i;
              break;
          }
      }
      if (audio_stream_index == -1) {
          fprintf(stderr, "Could not find the audio stream.\n");
          return -1;
      }
  
      AVCodecContext *cctx = stream-&gt;codec;
      AVCodecParameters *params = stream-&gt;codecpar;
  #define in_rate params-&gt;sample_rate
  #define in_layout params-&gt;channel_layout
  #define in_format params-&gt;format
  
      AVCodec *codec = avcodec_find_decoder(cctx-&gt;codec_id);
      if (codec == NULL) {
          fprintf(stderr, "Codec not found.\n");
          return -1;
      }
  
      if (avcodec_open2(cctx, codec, NULL) &lt; 0) {
          fprintf(stderr, "error: avcodec_open2()\n");
          return -1;
      }
  
      AVPacket packet;
      av_init_packet(&amp;packet);
      packet.data = NULL;
      packet.size = 0;
  
      AVFrame *frame = av_frame_alloc();
  
      FILE *out = fopen("../out_filter.raw", "wb");
  
  
      /// { FILTER
      AVFilterGraph *filter_graph = NULL;
      filter_graph = avfilter_graph_alloc();
      if (!filter_graph) {
          av_log(NULL, AV_LOG_ERROR, "unable to create filter graph: out of memory\n");
          return -1;
      }
  
      AVFilterContext *abuffer_ctx = NULL;
      AVFilterContext *volume_ctx = NULL;
      AVFilterContext *aformat_ctx = NULL;
      AVFilterContext *abuffersink_ctx = NULL;
      const AVFilter *abuffer = avfilter_get_by_name("abuffer");
      const AVFilter *volume = avfilter_get_by_name("volume");
      const AVFilter *aformat = avfilter_get_by_name("aformat");
      const AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
  
      int err;
      char strbuf[512];
      // create abuffer filter
      AVCodecContext *avctx = cctx;
      AVRational time_base = cctx-&gt;time_base;
      snprintf(strbuf, sizeof(strbuf),
               "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"
                       PRIx64,
               time_base.num, time_base.den, in_rate,
               av_get_sample_fmt_name(avctx-&gt;sample_fmt),
               avctx-&gt;channel_layout);
      fprintf(stderr, "abuffer: %s\n", strbuf);
      err = avfilter_graph_create_filter(&amp;abuffer_ctx, abuffer,
                                         NULL, strbuf, NULL, filter_graph);
      if (err &lt; 0) {
          av_log(NULL, AV_LOG_ERROR, "error initializing abuffer filter\n");
          return err;
      }
      // create volume filter
      double vol = 0.2;
      snprintf(strbuf, sizeof(strbuf), "volume=%f", vol);
      fprintf(stderr, "volume: %s\n", strbuf);
      err = avfilter_graph_create_filter(&amp;volume_ctx, volume, NULL, strbuf, NULL, filter_graph);
      if (err &lt; 0) {
          av_log(NULL, AV_LOG_ERROR, "error initializing volume filter\n");
          return err;
      }
      // create aformat filter
      snprintf(strbuf, sizeof(strbuf),
               "sample_fmts=%s:sample_rates=%d:channel_layouts=0x%" PRIx64,
               av_get_sample_fmt_name(out_format), out_rate, (uint64_t) out_layout);
      fprintf(stderr, "aformat: %s\n", strbuf);
      err = avfilter_graph_create_filter(&amp;aformat_ctx, aformat, NULL, strbuf, NULL, filter_graph);
      if (err &lt; 0) {
          av_log(NULL, AV_LOG_ERROR, "unable to create aformat filter\n");
          return err;
      }
      // create abuffersink filter
      err = avfilter_graph_create_filter(&amp;abuffersink_ctx, abuffersink, NULL, NULL, NULL, filter_graph);
      if (err &lt; 0) {
          av_log(NULL, AV_LOG_ERROR, "unable to create aformat filter\n");
          return err;
      }
  
      // connect inputs and outputs
      if (err &gt;= 0) err = avfilter_link(abuffer_ctx, 0, volume_ctx, 0);
      if (err &gt;= 0) err = avfilter_link(volume_ctx, 0, aformat_ctx, 0);
      if (err &gt;= 0) err = avfilter_link(aformat_ctx, 0, abuffersink_ctx, 0);
      if (err &lt; 0) {
          av_log(NULL, AV_LOG_ERROR, "error connecting filters\n");
          return err;
      }
      err = avfilter_graph_config(filter_graph, NULL);
      if (err &lt; 0) {
          av_log(NULL, AV_LOG_ERROR, "error configuring the filter graph\n");
          return err;
      }
      /// } FILTER
  
      while (av_read_frame(ctx, &amp;packet) &gt;= 0) { /// Fetch a packet
          if (packet.stream_index != audio_stream_index) {
              continue;
          }
  
          /// Decode packet to frame V1
          avcodec_send_packet(cctx, &amp;packet); /// Toss the packet into the codec context
          av_frame_unref(frame);
          avcodec_receive_frame(cctx, frame); /// Pull out a frame
          if (frame-&gt;nb_samples == 0) {
              av_packet_unref(&amp;packet);
              continue;
          }
  
          AVFrame *oframe = NULL;
  
          oframe = av_frame_alloc();
          if (!oframe) {
              av_log(NULL, AV_LOG_ERROR, "error allocating oframe\n");
              return 1;
          }
  
          /// Push the audio data from decoded frame into the filtergraph
          err = av_buffersrc_write_frame(abuffer_ctx, frame);
          if (err &lt; 0) {
              av_log(NULL, AV_LOG_ERROR, "error writing frame to buffersrc\n");
              return -1;
          }
          /// Pull filtered audio from the filtergraph
          for (;;) {
              err = av_buffersink_get_frame(abuffersink_ctx, oframe);
              if (err == AVERROR_EOF || err == AVERROR(EAGAIN))
                  break;
              if (err &lt; 0) {
                  av_log(NULL, AV_LOG_ERROR, "error reading buffer from buffersink\n");
                  return -1;
              }
              int nb_channels = av_get_channel_layout_nb_channels(frame-&gt;channel_layout);
              int bytes_per_sample = av_get_bytes_per_sample(frame-&gt;format);
              int data_size = frame-&gt;nb_samples * nb_channels * bytes_per_sample;
              fwrite(oframe-&gt;data[0], 1, (size_t) data_size, out);
          }
  
          av_free_packet(&amp;packet);
      }
  
      return 0;
  }
  
  int main() {
      avcodec_register_all();
      av_register_all();
      avformat_network_init();
      avfilter_register_all();
  
      fh = fopen("../test.ogg", "rb");
      if (fh == NULL) {
          printf("Cannot open the file.\n");
          return -1;
      }
      int ret = perform_decoding();
      if (ret != 0) {
          return ret;
      }
      printf("Finished!");
      return 0;
  }
  </code></pre>