title: Decode H264 video using libavcodec, C
body: <p>I'm trying to decode a raw h264 file with ffmpeg/libavcodec, but can't get it to work properly. Output should be a raw YUV-File for now. It's possible to compile the code with GCC</p>
  
  <pre><code>gcc -o decoder decoder.c -L./lib/ -llibavcodec -llibavutil
  </code></pre>
  
  <p>avcodec.dll, avutil.dll and swresample.dll must be placed in the directory for the .exe to start. Output in the CMD looks like this (only part of it, but its always like this):</p>
  
  <pre><code>[h264 @ 00a80f20] reference picture missing during reorder
  [h264 @ 00a80f20] Missing reference picture, default is 65562
  [h264 @ 00a80f20] error while decoding MB 80 54, bytestream -10
  [h264 @ 00a80f20] concealing 1649 DC, 1649 AC, 1649 MV errors in B frame
  [h264 @ 00a80f20] reference picture missing during reorder
  [h264 @ 00a80f20] reference picture missing during reorder
  [h264 @ 00a80f20] reference picture missing during reorder
  [h264 @ 00a80f20] Missing reference picture, default is 65566
  [h264 @ 00a80f20] Missing reference picture, default is 65566
  [h264 @ 00a80f20] Missing reference picture, default is 65566
  [h264 @ 00a80f20] reference picture missing during reorder
  [h264 @ 00a80f20] Missing reference picture, default is 65568
  [h264 @ 00a80f20] reference picture missing during reorder
  [h264 @ 00a80f20] Missing reference picture, default is 65570
  [h264 @ 00a80f20] reference picture missing during reorder
  </code></pre>
  
  <p>Heres my code</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  
  #ifdef HAVE_AV_CONFIG_H
  #undef HAVE_AV_CONFIG_H
  #endif
  
  #include "libavcodec/avcodec.h"
  //#include "libavcodec/libavutil/mathematics.h"
  
  #define INBUF_SIZE 4096
  
  void video_decode(char *outfilename, char *filename)
  {
      AVCodec *codec;
      AVCodecContext *c= NULL;
      int frame, got_picture, len;
      FILE *f, *outf;
      AVFrame *picture;
      uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
      AVPacket avpkt;
      int i;
  
      av_init_packet(&amp;avpkt);
  
      memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
  
      codec = avcodec_find_decoder(AV_CODEC_ID_H264);
      if (!codec) {
          fprintf(stderr, "codec not found\n");
          exit(1);
      }
  
      c = avcodec_alloc_context3(codec);
      picture = av_frame_alloc();
  
      if((codec-&gt;capabilities)&amp;CODEC_CAP_TRUNCATED)
          (c-&gt;flags) |= CODEC_FLAG_TRUNCATED;
  
      c-&gt;height = 1080;
      c-&gt;width = 1920;
  
      if (avcodec_open2(c, codec, NULL) &lt; 0) {
          fprintf(stderr, "could not open codec\n");
          exit(1);
      }
  
      f = fopen(filename, "rb");
      if (!f) {
          fprintf(stderr, "could not open %s\n", filename);
          exit(1);
      }
  
      outf = fopen(outfilename,"w");
      if(!outf){
          fprintf(stderr, "could not open %s\n", filename);
          exit(1);
      }
      frame = 0;
      for(;;) {
          avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
          if (avpkt.size == 0)
              break;
  
          avpkt.data = inbuf;
          while (avpkt.size &gt; 0) {
  
              len = avcodec_decode_video2(c, picture, &amp;got_picture, &amp;avpkt);
  
              if (len &lt; 0) {
                  fprintf(stderr, "Error while decoding frame %d\n", frame);
                  exit(1);
              }
              if (got_picture) {
                  printf("saving frame %3d\n", frame);
                  fflush(stdout);
                  for(i=0; i&lt;c-&gt;height; i++)
                      fwrite(picture-&gt;data[0] + i * picture-&gt;linesize[0], 1, c-&gt;width, outf  );
                  for(i=0; i&lt;c-&gt;height/2; i++)
                      fwrite(picture-&gt;data[1] + i * picture-&gt;linesize[1], 1, c-&gt;width/2, outf );
                  for(i=0; i&lt;c-&gt;height/2; i++)
                      fwrite(picture-&gt;data[2] + i * picture-&gt;linesize[2], 1, c-&gt;width/2, outf );
                  frame++;
              }
              avpkt.size -= len;
              avpkt.data += len;
          }
      }
  
      avpkt.data = NULL;
      avpkt.size = 0;
      len = avcodec_decode_video2(c,picture, &amp;got_picture, &amp;avpkt);
      if(got_picture) {
          printf("saving last frame %d\n",frame);
          fflush(stdout);
          for(i=0; i&lt;c-&gt;height; i++)
              fwrite(picture-&gt;data[0] + i * picture-&gt;linesize[0], 1, c-&gt;width, outf );
          for(i=0; i&lt;c-&gt;height/2; i++)
              fwrite(picture-&gt;data[1] + i * picture-&gt;linesize[1], 1, c-&gt;width/2, outf );
          for(i=0; i&lt;c-&gt;height/2; i++)
              fwrite(picture-&gt;data[2] + i * picture-&gt;linesize[2], 1, c-&gt;width/2, outf );
          frame++;
      }
  
      fclose(f);
      fclose(outf);
  
      avcodec_close(c);
      av_free(c);
      av_frame_free(&amp;picture);
      printf("\n");
  }
  
  int main(int argc, char **argv){
      avcodec_register_all();
      video_decode("test", "trailer.264");
  
      return 0;
  }
  </code></pre>
  
  <p>I also tried different videos in different formats (of course i changed the codec in the code in this case) like MPEG1, H263, H265, but none of those was working properly either.
  I hope someone can help me with this and tell me what I'm doing wrong here. Thanks</p>