title: FFmpeg: avcodec_encode_video() and JPEG images
body: <p>I'm trying to encode a series of .jpg files into a video using the ffmpeg library, and I can't seem to get the frames to encode. (I have to use the ffmpeg library, and using ffmpeg from a command line is not an option in my case.)</p>
  
  <p>Except for the part where I'm trying to open JPG files as AVFrames, my code is more or less the same thing as found in api-example.c from the ffmpeg library. When I populate the frames as the example does, everything works as expected. In the code below, I fail to encode any frames. Obviously the trouble is related to how I'm opening the JPG files, but I can't figure out what.</p>
  
  <p>I'm opening the image like this:</p>
  
  <pre><code>AVFrame* open_image(const char* imageFileName, int width, int height, long * bufSize)
  {
      AVFormatContext *pFormatCtx;
  
      if(av_open_input_file(&amp;pFormatCtx, imageFileName, NULL, 0, NULL)!=0)
      {
          printf("Can't open image file '%s'\n", imageFileName);
          return NULL;
      }       
  
      AVCodecContext *pCodecCtx;
  
      pCodecCtx = pFormatCtx-&gt;streams[0]-&gt;codec;
      pCodecCtx-&gt;width = width;
      pCodecCtx-&gt;height = height;
      pCodecCtx-&gt;pix_fmt = PIX_FMT_YUV420P;
  
      // Find the decoder for the video stream
      AVCodec *pCodec = avcodec_find_decoder(pCodecCtx-&gt;codec_id);
      if (!pCodec)
      {
          printf("Codec not found\n");
          return NULL;
      }
  
      // Open codec
      if(avcodec_open(pCodecCtx, pCodec)&lt;0)
      {
          printf("Could not open codec\n");
          return NULL;
      }
  
      AVFrame *pFrame = avcodec_alloc_frame();
      if (!pFrame)
      {
          LOGV(TAG, "Can't allocate memory for AVFrame\n");
          return NULL;
      }
  
      int frameFinished;
      int numBytes;
  
      // Determine required buffer size and allocate buffer
      numBytes = avpicture_get_size(PIX_FMT_YUVJ420P, pCodecCtx-&gt;width, pCodecCtx-&gt;height);
  
      // ***
      *bufSize = numBytes;
      // ***
  
      uint8_t *buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
  
      avpicture_fill((AVPicture *) pFrame, buffer, PIX_FMT_YUVJ420P, pCodecCtx-&gt;width, pCodecCtx-&gt;height);
  
      // Read frame
  
      AVPacket packet;
  
      int framesNumber = 0;
      while (av_read_frame(pFormatCtx, &amp;packet) &gt;= 0)
      {
          if(packet.stream_index != 0)
              continue;
  
          int ret = avcodec_decode_video2(pCodecCtx, pFrame, &amp;frameFinished, &amp;packet);
          if (ret &gt; 0)
          {
              sprintf(buf, "Frame is decoded, size %d", ret);
              LOGV(TAG, buf);
              pFrame-&gt;quality = 4;
              return pFrame;
          }
          else {
              // printf("Error [%d] while decoding frame: %s\n", ret, strerror(AVERROR(ret)));
              sprintf(buf, "Error %d decoding frame: %s", ret, strerror(AVERROR(ret)));
              LOGV(TAG, buf);
          }
      }
  }
  </code></pre>
  
  <p>...and attempting to encode them like this:</p>
  
  <pre><code>DIR * dir = opendir(path);
  int i = 0;
  
  if (dir != NULL) {
  
      for(struct dirent *ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
          fflush(stdout);
  
          printf("%s/%s", path, ent-&gt;d_name);
          LOGV(TAG, filename);
  
          // If not a jpg file, pass it over
          const char * ext = strrchr(filename, '.');
          if((!ext) || (strcmp(ext, ".jpg"))) {
              continue;
          }
  
          /*** NOTE: Is this where I've gone wrong? Bufsize is set in open_image based on av_picture_size() */
          long bufSize = 0L;
          AVFrame * frame = open_image(filename, width, height, &amp;bufSize);
          if(frame) {
              // This is what it needs to do, and it does not work.
              // Causes:
              // Wrong format?
              // Wrong buffer size?
              uint8_t * picBuf = (uint8_t *)malloc(bufSize);
  
              out_size = avcodec_encode_video(c, picBuf, bufSize, frame);
  
              printf("encoding frame %3d (size=%5d)\n", i++, out_size);
              /** On the first image, out_size is 0. On the next, it's -1, and fails. */
  
              if(out_size &lt; 0) {
                  printf("Error encoding frame");
                  return -6;
              }
  
              fwrite(picBuf, 1, bufSize, f);
  
              free(picBuf);
              av_free(frame);
          }
          else {
              printf("Couldn't open image");
              return -5;
          }
      }
  
      closedir(dir);
  } 
  else {
      printf("Couldn't open directory %s\n", path);
      return -4;
  }
  </code></pre>
  
  <p>Could someone point me in the right direction? </p>