title: Decoding then re-encoding frames in reverse order with ffmpeg
body: <p>I am pretty new to ffmpeg, and now I want to decode the frames and encode it back in reverse order. I have used <a href="http://dranger.com/ffmpeg/tutorial01.html" rel="nofollow">this tutorial</a> for decoding the video and <a href="https://ffmpeg.org/doxygen/trunk/decoding_encoding_8c-example.html" rel="nofollow">this example</a> to encode it back. I can decode the frames properly, but when I re-encode it, I get a dummy image rather than clear video. How can I get the actual reversed video?</p>
  
  <pre><code>static void video_encode_example(const char *filename, int codec_id)
  {
      AVCodec *codec;
      AVCodecContext *c= NULL;
      int i, ret, x, y, got_output;
      FILE *f;
      struct SwsContext *sws_ctx = NULL;
      AVFrame *frame;
      AVFrame *frameRGB = NULL;
      AVPacket pkt;
      uint8_t endcode[] = { 0, 0, 1, 0xb7 };
  
      printf("Encode video file %s\n", filename);
  
      /* find the mpeg1 video encoder */
      codec = avcodec_find_encoder(codec_id);
      if (!codec) {
          fprintf(stderr, "Codec not found\n");
          exit(1);
      }
  
      c = avcodec_alloc_context3(codec);
      if (!c) {
          fprintf(stderr, "Could not allocate video codec context\n");
          exit(1);
      }
  
      /* put sample parameters */
      c-&gt;bit_rate = 400000;
      /* resolution must be a multiple of two */
      c-&gt;width = 352;
      c-&gt;height = 288;
      /* frames per second */
      c-&gt;time_base = (AVRational){1,25};
      /* emit one intra frame every ten frames
       * check frame pict_type before passing frame
       * to encoder, if frame-&gt;pict_type is AV_PICTURE_TYPE_I
       * then gop_size is ignored and the output of encoder
       * will always be I frame irrespective to gop_size
       */
      c-&gt;gop_size = 10;
      c-&gt;max_b_frames = 1;
      c-&gt;pix_fmt = AV_PIX_FMT_YUV420P;
  
      if (codec_id == AV_CODEC_ID_H264)
          av_opt_set(c-&gt;priv_data, "preset", "slow", 0);
  
      /* open it */
      if (avcodec_open2(c, codec, NULL) &lt; 0) {
          fprintf(stderr, "Could not open codec\n");
          exit(1);
      }
  
      f = fopen(filename, "wb");
      if (!f) {
          fprintf(stderr, "Could not open %s\n", filename);
          exit(1);
      }
  
      frame = av_frame_alloc();
      if (!frame) {
          fprintf(stderr, "Could not allocate video frame\n");
          exit(1);
      }
      frame-&gt;format = c-&gt;pix_fmt;
      frame-&gt;width  = c-&gt;width;
      frame-&gt;height = c-&gt;height;
  
      /* the image can be allocated by any means and av_image_alloc() is
       * just the most convenient way if av_malloc() is to be used */
      ret = av_image_alloc(frame-&gt;data, frame-&gt;linesize, c-&gt;width, c-&gt;height,
                           c-&gt;pix_fmt, 32);
      if (ret &lt; 0) {
          fprintf(stderr, "Could not allocate raw picture buffer\n");
          exit(1);
      }
  
      /* encode 1 second of video */
      for (i = 0; i &lt; 25; i++) {
          av_init_packet(&amp;pkt);
          pkt.data = NULL;    // packet data will be allocated by the encoder
          pkt.size = 0;
  
          fflush(stdout);
          /* prepare a dummy image */
          /* Y */
          for (y = 0; y &lt; c-&gt;height; y++) {
              for (x = 0; x &lt; c-&gt;width; x++) {
                  frame-&gt;data[0][y * frame-&gt;linesize[0] + x] = x + y + i * 3;
              }
          }
  
          /* Cb and Cr */
          for (y = 0; y &lt; c-&gt;height/2; y++) {
              for (x = 0; x &lt; c-&gt;width/2; x++) {
                  frame-&gt;data[1][y * frame-&gt;linesize[1] + x] = 128 + y + i * 2;
                  frame-&gt;data[2][y * frame-&gt;linesize[2] + x] = 64 + x + i * 5;
              }
          }
  
          frame-&gt;pts = i;
  
          /* encode the image */
          ret = avcodec_encode_video2(c, &amp;pkt, frame, &amp;got_output);
          if (ret &lt; 0) {
              fprintf(stderr, "Error encoding frame\n");
              exit(1);
          }
  
          if (got_output) {
              // Convert the image from its native format to RGB
              sws_scale
              (
                  sws_ctx,
                  (uint8_t const * const *)frame-&gt;data,
                  frame-&gt;linesize,
                  0,
                  c-&gt;height,
                  frameRGB-&gt;data,
                  frameRGB-&gt;linesize
              );
              printf("Write frame %3d (size=%5d)\n", i, pkt.size);
              fwrite(pkt.data, 1, pkt.size, f);
              av_free_packet(&amp;pkt);
          }
      }
  
      /* get the delayed frames */
      for (got_output = 1; got_output; i++) {
          fflush(stdout);
  
          ret = avcodec_encode_video2(c, &amp;pkt, NULL, &amp;got_output);
          if (ret &lt; 0) {
              fprintf(stderr, "Error encoding frame\n");
              exit(1);
          }
  
          if (got_output) {
              printf("Write frame %3d (size=%5d)\n", i, pkt.size);
              fwrite(pkt.data, 1, pkt.size, f);
              av_free_packet(&amp;pkt);
          }
      }
  
      /* add sequence end code to have a real mpeg file */
      fwrite(endcode, 1, sizeof(endcode), f);
      fclose(f);
  
      avcodec_close(c);
      av_free(c);
      av_freep(&amp;frame-&gt;data[0]);
      av_frame_free(&amp;frame);
      printf("\n");
  }
  </code></pre>