title: Segmentation fault while avcodec_encode_video2
body: <p>I have some problems while trying to encode a AVFrame to a packet.</p>
  
  <p>Before reading the whole code, the input stuff is working, I tested it. The output stuff is from an example <a href="https://github.com/libav/libav/blob/master/libavformat/output-example.c" rel="nofollow noreferrer">here</a>. I think there is the problem. But the segmentation fault occurs in the loop near the end.</p>
  
  <p>Here is my reduced code: 
  </p>
  
  <pre><code>void nmain() {
  
    // input stuff
    AVFormatContext *formatCtxIn=0;
    AVInputFormat *formatIn=0;
    AVCodecContext *codecCtxIn=0;
    AVCodec *codecIn;
    AVPacket *pktIn;
  
    av_register_all();
    avdevice_register_all();
    avcodec_register_all();
  
  
    formatIn = av_find_input_format("dshow");
  
    if(!formatIn)
      return;
  
  
    AVDictionary *avoption=0;
    av_dict_set(&amp;avoption, "rtbufsize", "1000000000", NULL);
  
    if(avformat_open_input(&amp;formatCtxIn, "video=Integrated Camera", formatIn, &amp;avoption)!=0)
      return;
  
    if(avformat_find_stream_info(formatCtxIn, NULL)&lt;0)
      return;
  
    codecCtxIn = formatCtxIn-&gt;streams[0]-&gt;codec;
    codecIn = avcodec_find_decoder(codecCtxIn-&gt;codec_id);
  
    if(avcodec_open2(codecCtxIn, codecIn, NULL)&lt;0)
      return;
  
  
    // end input stuff  
  //------------------------------------------------------------------------------
    // output stuff
  
    AVOutputFormat *formatOut=0;
    AVFormatContext *formatCtxOut=0;
    AVStream *streamOut=0;
    AVFrame *frame=0;
    AVCodec *codecOut=0;
    AVPacket *pktOut;
  
    const char *filename = "test.mpeg";
  
    formatOut = av_guess_format(NULL, filename, NULL);
    if(!formatOut)
      formatOut = av_guess_format("mpeg", NULL, NULL);
    if(!formatOut)
      return;
  
    formatCtxOut = avformat_alloc_context();
    if(!formatCtxOut)
      return;
  
    formatCtxOut-&gt;oformat = formatOut;
  
    sprintf(formatCtxOut-&gt;filename, "%s", filename);
  
    if(formatOut-&gt;video_codec != AV_CODEC_ID_NONE) {
      AVCodecContext *ctx;
  
      codecOut = avcodec_find_encoder(formatOut-&gt;video_codec);
      if(!codecOut)
        return;
  
      streamOut = avformat_new_stream(formatCtxOut, codecOut);
      if(!streamOut)
        return;
  
      ctx = streamOut-&gt;codec;
  
      ctx-&gt;bit_rate = 400000;
      ctx-&gt;width    = 352;
      ctx-&gt;height   = 288;
      ctx-&gt;time_base.den = 25;
      ctx-&gt;time_base.num = 1;
      ctx-&gt;gop_size      = 12;
      ctx-&gt;pix_fmt       = AV_PIX_FMT_YUV420P;
  
      if(ctx-&gt;codec_id == AV_CODEC_ID_MPEG2VIDEO)
        ctx-&gt;max_b_frames = 2;
      if(ctx-&gt;codec_id == AV_CODEC_ID_MPEG1VIDEO)
        ctx-&gt;mb_decision = 2;
  
  
      if(formatCtxOut-&gt;oformat-&gt;flags &amp; AVFMT_GLOBALHEADER)
        ctx-&gt;flags |= CODEC_FLAG_GLOBAL_HEADER;
    }
  
    if(streamOut) {
      AVCodecContext *ctx;
      ctx = streamOut-&gt;codec;
  
      if(avcodec_open2(ctx, codecOut, NULL) &lt; 0)
        return;
    }
  
    if(!(formatCtxOut-&gt;flags &amp; AVFMT_NOFILE))
      if(avio_open(&amp;formatCtxOut-&gt;pb, filename, AVIO_FLAG_WRITE) &lt; 0)
        return;
  
    avformat_write_header(formatCtxOut, NULL);
  
  
    // doit
  
    pktIn = new AVPacket;
    pktOut = new AVPacket;
    av_init_packet(pktOut);
    pktOut-&gt;data = 0;
  
    frame = avcodec_alloc_frame();
    if(!frame)
      return;
  
    for(;;) {
      if(av_read_frame(formatCtxIn, pktIn) &gt;= 0) {
        av_dup_packet(pktIn);
  
        int fff;
        if(avcodec_decode_video2(codecCtxIn, frame, &amp;fff, pktIn) &lt; 0)
          std::cout &lt;&lt; "bad frame" &lt;&lt; std::endl;
  
        if(!fff)
          return;  // ok
  
        static int counter=0;
        SaveFrame(frame, codecCtxIn-&gt;width, codecCtxIn-&gt;height, counter++);  // work fine
  
        // here a segmentation fault is occured.
        if(avcodec_encode_video2(streamOut-&gt;codec, pktOut, frame, &amp;fff) &lt; 0)
          std::cout &lt;&lt; "bad frame" &lt;&lt; std::endl;
      }
    }
  }
  
  
  // only for testing
  // add to ensure frame is valid
  void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
    FILE *pFile;
    char szFilename[32];
    int y;
  
    // Open file
    sprintf(szFilename, "frame%d.ppm", iFrame);
    pFile=fopen(szFilename, "wb");
    if(pFile==NULL)
        return;
  
    // Write header
    fprintf(pFile, "P6\n%d %d\n255\n", width, height);
  
    // Write pixel data
    for(y=0; y&lt;height; y++)
        fwrite(pFrame-&gt;data[0]+y*pFrame-&gt;linesize[0], 1, width*3, pFile);
  
    // Close file
    fclose(pFile);
  }
  </code></pre>
  
  <p>What am i doing wrong?</p>
  
  <p>While debugging i didn't found any problems with the parameters. <code>streamOut-&gt;codec</code> is filled. <code>pktOut</code> is allocated and <code>frame</code> is filled with the picture encoded before.
  I think the problem is while creating the output codec but watching the example and looking to the doxypages it seems to be correct.</p>
  
  <p><img src="https://i.stack.imgur.com/yC3B3.png" alt="test"></p>
  
  <p>The trace route is from QT using msvc11 and framework 5.</p>
  
  <p>I also tried to run with dr. memory and get this:</p>
  
  <pre><code>Error #26: UNADDRESSABLE ACCESS: reading 0x00000000-0x00000004 4 byte(s)
  # 0 replace_memcpy                      [d:\derek\drmemory\withwiki\trunk\drmemory\replace.c:203]
  # 1 avcodec-54.dll!ff_dct_quantize_c   +0xd463   (0x6a482364 &lt;avcodec-54.dll+0x3c2364&gt;)
  # 2 avcodec-54.dll!avcodec_encode_video2+0xb7     (0x6a56a5b8 &lt;avcodec-54.dll+0x4aa5b8&gt;)
  # 3 nmain                               [d:\prg\tests\recording system-qt\libav\recsys\main.cpp:610]
  # 4 main                                [d:\prg\tests\recording system-qt\libav\recsys\main.cpp:182]
  Note: @0:00:06.318 in thread 5312
  Note: instruction: mov    (%edx) -&gt; %ebx
  </code></pre>
  
  <p>It seems like the reading process while memcpy is going wrong.</p>
  
  <hr>
  
  <h2>Version:</h2>
  
  <p>I've forgot to mention the version of libav/ffmpeg i'm using:</p>
  
  <pre><code>libavutil      51. 76.100 / 51. 76.100
  libavcodec     54. 67.100 / 54. 67.100
  libavformat    54. 33.100 / 54. 33.100
  libavdevice    54.  3.100 / 54.  3.100
  libavfilter     3. 19.103 /  3. 19.103
  libswscale      2.  1.101 /  2.  1.101
  libswresample   0. 16.100 /  0. 16.100
  libpostproc    52.  1.100 / 52.  1.100
  </code></pre>
  
  <hr>
  
  <h2>Addendum:</h2>
  
  <p>Function <code>SafeFrame</code> is copied from <a href="https://github.com/phamquy/FFmpeg-tutorial-samples/blob/master/tutorial01.c" rel="nofollow noreferrer">tutorial 1</a>.</p>