title: Write audio packet to file using ffmpeg
body: <p>I am trying to write audio packet to file using ffmpeg. The source device sending the packet after some interval. e.g. </p>
  
  <pre><code>First packet has a time stamp 00:00:00 
  Second packet has a time stamp 00:00:00.5000000
  Third packet has a time stamp 00:00:01
  And so on...
  </code></pre>
  
  <p>Means two packet per second.</p>
  
  <p>I want to encode those packets and write to a file.</p>
  
  <p>I am referring the Ffmpeg example from link <a href="https://www.ffmpeg.org/doxygen/3.2/muxing_8c-example.html" rel="nofollow noreferrer" title="Muxing.c">Muxing.c</a></p>
  
  <p>While encoding and writing there is no error. But output file has only 2 sec audio duration and speed is also super fast.</p>
  
  <p>The video frames are proper according the settings.</p>
  
  <p>I think the problem is related to calculation of pts, dts and duration of packet.</p>
  
  <p>How should I calculate proper values for pts, dts and duration. Or is this problem related to other thing?</p>
  
  <p>Code: </p>
  
  <pre class="lang-cpp prettyprint-override"><code>void AudioWriter::WriteAudioChunk(IntPtr chunk, int lenght, TimeSpan timestamp)
  {
      int buffer_size = av_samples_get_buffer_size(NULL, outputStream-&gt;tmp_frame-&gt;channels, outputStream-&gt;tmp_frame-&gt;nb_samples,  outputStream-&gt;AudioStream-&gt;codec-&gt;sample_fmt, 0);
  
      uint8_t *audioData = reinterpret_cast&lt;uint8_t*&gt;(static_cast&lt;void*&gt;(chunk));
      int ret = avcodec_fill_audio_frame(outputStream-&gt;tmp_frame,outputStream-&gt;Channels, outputStream-&gt;AudioStream-&gt;codec-&gt;sample_fmt, audioData, buffer_size, 1);
  
      if (!ret)
         throw gcnew System::IO::IOException("A audio file was not opened yet.");
  
      write_audio_frame(outputStream-&gt;FormatContext, outputStream, audioData);
  }
  
  
  static int write_audio_frame(AVFormatContext *oc, AudioWriterData^ ost, uint8_t *audioData)
  {
         AVCodecContext *c;
         AVPacket pkt = { 0 };
         int ret;
         int got_packet;
         int dst_nb_samples;
  
         av_init_packet(&amp;pkt);
         c = ost-&gt;AudioStream-&gt;codec;
  
         AVFrame *frame = ost-&gt;tmp_frame;
  
        if (frame)
        {
            dst_nb_samples = av_rescale_rnd(swr_get_delay(ost-&gt;swr_ctx, c-&gt;sample_rate) + frame-&gt;nb_samples, c-&gt;sample_rate, c-&gt;sample_rate, AV_ROUND_UP);
            if (dst_nb_samples != frame-&gt;nb_samples)
              throw gcnew Exception("dst_nb_samples != frame-&gt;nb_samples");
  
            ret = av_frame_make_writable(ost-&gt;AudioFrame);
            if (ret &lt; 0)
               throw gcnew Exception("Unable to make writable.");
  
            ret = swr_convert(ost-&gt;swr_ctx, ost-&gt;AudioFrame-&gt;data, dst_nb_samples, (const uint8_t **)frame-&gt;data, frame-&gt;nb_samples);
            if (ret &lt; 0) 
              throw gcnew Exception("Unable to convert to destination format.");
  
            frame = ost-&gt;AudioFrame;
  
            AVRational timebase = { 1, c-&gt;sample_rate };
            frame-&gt;pts = av_rescale_q(ost-&gt;samples_count, timebase, c-&gt;time_base);
            ost-&gt;samples_count += dst_nb_samples;
        }
  
        ret = avcodec_encode_audio2(c, &amp;pkt, frame, &amp;got_packet);
        if (ret &lt; 0) 
          throw gcnew Exception("Error encoding audio frame.");
  
        if (got_packet)
        {
          ret = write_frame(oc, &amp;c-&gt;time_base, ost-&gt;AudioStream, &amp;pkt);
          if (ret &lt; 0)
              throw gcnew Exception("Audio is not written.");
        }
        else
           throw gcnew Exception("Audio packet encode failed.");
  
        return (ost-&gt;AudioFrame || got_packet) ? 0 : 1;
  }
  
  static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
  {
      av_packet_rescale_ts(pkt, *time_base, st-&gt;time_base);
      pkt-&gt;stream_index = st-&gt;index;
      return av_interleaved_write_frame(fmt_ctx, pkt);
  }
  </code></pre>