<div dir="ltr"><div><div>I am trying to read an RTP audio stream, and encode it into a FLAC file. </div><div>However, when I am reading the stream, I get this error: </div><div><br></div><div>  Â  [libvorbis @ 028b1520] more samples than frame size (avcodec_encode_audio2)</div><div>  Â Â </div><div>During debug mode, it seems the frame_size of my input and output codec context are mismatched:</div><div><br></div><div>  Â  inCodecCtx->frame_size = 1152;</div><div>  Â  outCodecCtx->frame_size = 64;</div><div>  Â Â </div><div>I tried to write 1152 to outCodecCtx->frame_size, but it gets overwritten with 64 at `avcodec_open2()`. Why can't I set the frame_size to match the input frame_size? Should I create an additional output frame to copy the contents over in a loop?</div><div><br></div><div>I'd really appreciate it if you could help me some help or suggestions.</div><div><br></div><div>Here is my source:</div><div>  Â Â </div><div>  Â  // </div><div>  Â  // Test with this command: ffmpeg -re -f lavfi -i aevalsrc="atan(t/2)*sin(400*2*PI*t)" -ar 16000 -c:a pcm_s16be -f rtp rtp://<a href="http://127.0.0.1:8554">127.0.0.1:8554</a></div><div>  Â  // ffmpeg -f dshow -i audio="Microphone (High Definition Audio Device)" -ar 16000 -c:a pcm_s16be -ac 1 -f rtp rtp://<a href="http://127.0.0.1:8554">127.0.0.1:8554</a></div><div>  Â  // Working code</div><div><br></div><div>  Â  #include "stdafx.h"</div><div>  Â  #include <math.h></div><div>  Â  extern "C"</div><div>  Â  {</div><div>  Â  #include <libavutil/opt.h></div><div>  Â  #include <libavcodec/avcodec.h></div><div>  Â  #include <libavutil/channel_layout.h></div><div>  Â  #include <libavutil/common.h></div><div>  Â  #include <libavutil/imgutils.h></div><div>  Â  #include <libavutil/mathematics.h></div><div>  Â  #include <libavutil/samplefmt.h></div><div>  Â  #include <libavformat/avformat.h></div><div>  Â  }</div><div><br></div><div>  Â  #define AUDIO_INBUF_SIZE 20480</div><div><br></div><div>  Â  #define ERRBUFFLEN 200</div><div>  Â  char errbuf[ERRBUFFLEN];</div><div>  Â  #define av_err2str(ret) av_strerror(ret, errbuf, ERRBUFFLEN)</div><div>  Â  const int samp_rate = 16000;</div><div>  Â  int count = 0;</div><div>  Â  // Callback function</div><div>  Â  int _ffmpeg_interrupt_fcn(void* ptr)</div><div>  Â  {</div><div>  Â  Â  Â  int &r = *((int*)ptr);</div><div>  Â  Â  Â  //double &r = *((double*)ptr);</div><div>  Â  Â  Â  r += 1;</div><div>  Â  Â  Â  printf("Interrupted! %d\n", r);</div><div>  Â  Â  Â  if (r > 30) return 1;</div><div>  Â  Â  Â  return 0;</div><div>  Â  }</div><div><br></div><div>  Â  static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)</div><div>  Â  {</div><div>  Â  Â  Â  /* rescale output packet timestamp values from codec to stream timebase */</div><div>  Â  Â  Â  av_packet_rescale_ts(pkt, *time_base, st->time_base);</div><div>  Â  Â  Â  pkt->stream_index = st->index;</div><div><br></div><div>  Â  Â  Â  /* Write the compressed frame to the media file. */</div><div>  Â  #ifdef DEBUG_PACKET</div><div>  Â  Â  Â  log_packet(fmt_ctx, pkt);</div><div>  Â  #endif</div><div>  Â  Â  Â  return av_interleaved_write_frame(fmt_ctx, pkt);</div><div>  Â  }</div><div><br></div><div>  Â  /*</div><div>  Â  * Audio decoding.</div><div>  Â  */</div><div>  Â  static void audio_decode_example(const char *outfilename, const char *filename)</div><div>  Â  {</div><div>  Â  Â  Â  int len;</div><div>  Â  Â  Â  FILE *f, *outfile;</div><div>  Â  Â  Â  uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];</div><div>  Â  Â  Â  AVPacket inpkt, outpkt;</div><div>  Â  Â  Â Â </div><div>  Â  Â  Â  AVCodec *inCodec = NULL;</div><div>  Â  Â  Â  AVCodecContext *inCodecCtx = NULL;</div><div>  Â  Â  Â  AVFrame *decoded_frame = NULL;</div><div>  Â  Â  Â  AVFormatContext *inFormatCtx = NULL;</div><div><br></div><div>  Â  Â  Â  AVCodec *outCodec = NULL;</div><div>  Â  Â  Â  AVCodecContext *outCodecCtx = NULL;</div><div>  Â  Â  Â  AVFormatContext *outFormatCtx = NULL;</div><div>  Â  Â  Â  AVStream * outAudioStream = NULL;</div><div>  Â  Â  Â Â </div><div>  Â  Â  Â Â </div><div>  Â  Â  Â  int ret;</div><div><br></div><div>  Â  Â  Â  av_init_packet(&inpkt);</div><div><br></div><div>  Â  Â  Â  AVDictionary *d = NULL; Â  Â  Â  Â  Â  // "create" an empty dictionary</div><div>  Â  Â  Â  av_dict_set(&d, "protocol_whitelist", "file,udp,rtp", 0); // add an entry</div><div><br></div><div>  Â  Â  Â  // Open video file</div><div>  Â  Â  Â  ret = avformat_open_input(&inFormatCtx, filename, NULL, &d);</div><div>  Â  Â  Â  if (ret <0)</div><div>  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  printf_s("Failed: cannot open input.\n");</div><div>  Â  Â  Â  Â  Â  av_strerror(ret, errbuf, ERRBUFFLEN);</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "avformat_open_input() fail: %s\n", errbuf);</div><div>  Â  Â  Â  Â  Â  exit(1);</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  printf_s("Retrieve stream information.\n");</div><div>  Â  Â  Â  ret = avformat_find_stream_info(inFormatCtx, NULL);</div><div>  Â  Â  Â  if (ret <0)</div><div>  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  printf_s("Failed: cannot find stream.\n");</div><div>  Â  Â  Â  Â  Â  av_strerror(ret, errbuf, ERRBUFFLEN);</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "avformat_find_stream_info() fail: %s\n", errbuf);</div><div>  Â  Â  Â  Â  Â  exit(1);</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  av_dump_format(inFormatCtx, 0, filename, 0);</div><div><br></div><div>  Â  Â  Â  int stream_idx = -1;</div><div><br></div><div>  Â  Â  Â  for (int i = 0; i < inFormatCtx->nb_streams; i++)</div><div>  Â  Â  Â  Â  Â  if (inFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {</div><div>  Â  Â  Â  Â  Â  Â  Â  stream_idx = i;</div><div>  Â  Â  Â  Â  Â  Â  Â  break;</div><div>  Â  Â  Â  Â  Â  }</div><div>  Â  Â  Â  if (stream_idx == -1)</div><div>  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "Video stream not found\n");</div><div>  Â  Â  Â  Â  Â  exit(1);</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  inCodec = avcodec_find_decoder(inFormatCtx->streams[stream_idx]->codec->codec_id);</div><div>  Â  Â  Â  if (!inCodec) {</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "Codec not found\n");</div><div>  Â  Â  Â  Â  Â  exit(1);</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  inCodecCtx = avcodec_alloc_context3(inCodec);</div><div>  Â  Â  Â  if (!inCodecCtx) {</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "Could not allocate audio codec context\n");</div><div>  Â  Â  Â  Â  Â  exit(1);</div><div>  Â  Â  Â  }</div><div>  Â  Â  Â Â </div><div>  Â  Â  Â  inCodecCtx->channels = 1;</div><div><br></div><div>  Â  Â  Â  ret = avcodec_open2(inCodecCtx, inCodec, NULL);</div><div>  Â  Â  Â  if (ret < 0) {</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));</div><div>  Â  Â  Â  Â  Â  exit(1);</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  // Set output</div><div>  Â  Â  Â  ret = avformat_alloc_output_context2(&outFormatCtx, NULL, NULL, outfilename);</div><div>  Â  Â  Â  if (!outFormatCtx || ret < 0)</div><div>  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "Could not allocate output context");</div><div>  Â  Â  Â  }</div><div>  Â  Â  Â  outFormatCtx->flags |= AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS;</div><div>  Â  Â  Â  outFormatCtx->audio_codec_id = AV_CODEC_ID_FLAC;</div><div><br></div><div>  Â  Â  Â  // Find the codec.</div><div>  Â  Â  Â  outCodec = avcodec_find_encoder(outFormatCtx->oformat->audio_codec);</div><div>  Â  Â  Â  if (outCodec == NULL) {</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "Codec not found\n");</div><div>  Â  Â  Â  Â  Â  return;</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  // Add stream to pFormatCtx</div><div>  Â  Â  Â  outAudioStream = avformat_new_stream(outFormatCtx, outCodec);</div><div>  Â  Â  Â  if (!outAudioStream)</div><div>  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "Cannot add new video stream\n");</div><div>  Â  Â  Â  Â  Â  return;</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  outAudioStream->id = outFormatCtx->nb_streams - 1;</div><div>  Â  Â  Â  outCodecCtx = outAudioStream->codec;</div><div>  Â  Â  Â  outCodecCtx->sample_rate = samp_rate;</div><div>  Â  Â  Â  outCodecCtx->sample_fmt = AV_SAMPLE_FMT_FLTP;</div><div>  Â  Â  Â  outCodecCtx->channels = 1;</div><div>  Â  Â  Â  outCodecCtx->frame_size = 1152;</div><div><br></div><div>  Â  Â  Â  if (outFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)</div><div>  Â  Â  Â  Â  Â  outCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;</div><div><br></div><div>  Â  Â  Â  // Open the codec.</div><div>  Â  Â  Â  if (avcodec_open2(outCodecCtx, outCodec, NULL) < 0)</div><div>  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "Cannot open audio codec\n");</div><div>  Â  Â  Â  Â  Â  return;</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  if (avio_open2(&outFormatCtx->pb, outfilename, AVIO_FLAG_WRITE, NULL, NULL) < 0)</div><div>  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  av_strerror(ret, errbuf, ERRBUFFLEN);</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "avio_open2 fail: %s\n", errbuf);</div><div>  Â  Â  Â  Â  Â  return;</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  // Write file header.</div><div>  Â  Â  Â  ret = avformat_write_header(outFormatCtx, NULL);</div><div>  Â  Â  Â  if (ret < 0)</div><div>  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  fprintf(stderr, "error writing header");</div><div>  Â  Â  Â  Â  Â  return;</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  // Set callback</div><div>  Â  Â  Â  inFormatCtx->interrupt_callback.callback = _ffmpeg_interrupt_fcn;</div><div>  Â  Â  Â  inFormatCtx->interrupt_callback.opaque = &count;</div><div><br></div><div>  Â  Â  Â  /**************************************************************</div><div>  Â  Â  Â  * Â  Â Input Code Ctx Frame size: 1152</div><div>  Â  Â  Â  * Â  Â Output Code Ctx Frame size: 64 Â  Â  Â  Â </div><div>  Â  Â  Â  **************************************************************/</div><div>  Â  Â  Â  printf("Input Code Ctx Frame size: %d\n", inCodecCtx->frame_size);</div><div>  Â  Â  Â  printf("Output Code Ctx Frame size: %d\n", inCodecCtx->frame_size);</div><div>  Â  Â  Â Â </div><div>  Â  Â  Â  int got_packet = 0;</div><div><br></div><div>  Â  Â  Â  while (av_read_frame(inFormatCtx, &inpkt) == 0) {</div><div>  Â  Â  Â  Â  Â  int i, ch;</div><div>  Â  Â  Â  Â  Â  int got_frame = 0;</div><div><br></div><div>  Â  Â  Â  Â  Â  if (!decoded_frame) {</div><div>  Â  Â  Â  Â  Â  Â  Â  if (!(decoded_frame = av_frame_alloc())) {</div><div>  Â  Â  Â  Â  Â  Â  Â  Â  Â  fprintf(stderr, "Could not allocate audio frame\n");</div><div>  Â  Â  Â  Â  Â  Â  Â  Â  Â  exit(1);</div><div>  Â  Â  Â  Â  Â  Â  Â  }</div><div>  Â  Â  Â  Â  Â  }</div><div>  Â  Â  Â  Â  Â  len = avcodec_decode_audio4(inCodecCtx, decoded_frame, &got_frame, &inpkt);</div><div>  Â  Â  Â  Â  Â  if (len < 0) {</div><div>  Â  Â  Â  Â  Â  Â  Â  fprintf(stderr, "Error while decoding\n");</div><div>  Â  Â  Â  Â  Â  Â  Â  exit(1);</div><div>  Â  Â  Â  Â  Â  }</div><div>  Â  Â  Â  Â  Â  if (got_frame) {</div><div>  Â  Â  Â  Â  Â  Â  Â  printf("Packet size: %d\n", decoded_frame->pkt_size);</div><div>  Â  Â  Â  Â  Â  Â  Â  printf("Frame samples: %d\n", decoded_frame->nb_samples);</div><div>  Â  Â  Â  Â  Â  Â  Â  got_packet = 0;</div><div>  Â  Â  Â  Â  Â  Â  Â  av_init_packet(&outpkt);</div><div>  Â  Â  Â  Â  Â  Â  Â  int error = avcodec_encode_audio2(outCodecCtx, &outpkt, decoded_frame, &got_packet);</div><div><br></div><div>  Â  Â  Â  Â  Â  Â  Â  if (!error && got_packet > 0)</div><div>  Â  Â  Â  Â  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  Â  Â  Â  Â  // Write packet with frame.</div><div>  Â  Â  Â  Â  Â  Â  Â  Â  Â  ret = write_frame(outFormatCtx, &outCodecCtx->time_base, outAudioStream, &outpkt);</div><div><br></div><div>  Â  Â  Â  Â  Â  Â  Â  }</div><div>  Â  Â  Â  Â  Â  Â  Â  av_packet_unref(&outpkt);</div><div><br></div><div>  Â  Â  Â  Â  Â  }</div><div>  Â  Â  Â  Â  Â  count = 0;</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  // Flush remaining encoded data</div><div>  Â  Â  Â  while (1)</div><div>  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  got_packet = 0;</div><div>  Â  Â  Â  Â  Â  // Encode frame to packet.</div><div>  Â  Â  Â  Â  Â  int error = avcodec_encode_audio2(outCodecCtx, &outpkt, NULL, &got_packet);</div><div><br></div><div>  Â  Â  Â  Â  Â  if (!error && got_packet > 0)</div><div>  Â  Â  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  Â  Â  av_init_packet(&outpkt);</div><div>  Â  Â  Â  Â  Â  Â  Â  // Write packet with frame.</div><div>  Â  Â  Â  Â  Â  Â  Â  ret = write_frame(outFormatCtx, &outCodecCtx->time_base, outAudioStream, &outpkt);</div><div><br></div><div>  Â  Â  Â  Â  Â  Â  Â  av_packet_unref(&outpkt);</div><div>  Â  Â  Â  Â  Â  }</div><div>  Â  Â  Â  Â  Â  else</div><div>  Â  Â  Â  Â  Â  {</div><div>  Â  Â  Â  Â  Â  Â  Â  break;</div><div>  Â  Â  Â  Â  Â  }</div><div>  Â  Â  Â  }</div><div><br></div><div>  Â  Â  Â  av_write_trailer(outFormatCtx);</div><div>  Â  Â  Â  avcodec_close(outAudioStream->codec); // codecCtx</div><div>  Â  Â  Â  avio_close(outFormatCtx->pb);</div><div>  Â  Â  Â  avformat_free_context(outFormatCtx);</div><div><br></div><div>  Â  Â  Â  avcodec_close(inCodecCtx);</div><div>  Â  Â  Â  av_free(inCodecCtx);</div><div>  Â  Â  Â  av_frame_free(&decoded_frame);</div><div>  Â  }</div><div><br></div><div>  Â  int main(int argc, char **argv)</div><div>  Â  {</div><div>  Â  Â  Â  const char *output_type;</div><div><br></div><div>  Â  Â  Â  av_register_all();</div><div>  Â  Â  Â  avformat_network_init(); // for network streaming</div><div><br></div><div>  Â  Â  Â  audio_decode_example("test.flac", "test.sdp");</div><div><br></div><div>  Â  Â  Â  return 0;</div><div>  Â  }</div><div><span class="Apple-tab-span" style="white-space:pre">    </span></div><div>Cheers, </div><div>ytan</div></div><div><br></div></div>