title: How can I seek to frame No. X with ffmpeg?
body: <p>I'm writing a <em>video editor</em>, and I need to seek to exact frame, knowing the <em>frame number</em>.</p>
  
  <p>Other posts on stackoverflow told me that ffmpeg may give me a few broken frames after seeking, which is not a problem for playback but a big problem for video editors.</p>
  
  <p>And I need to seek <strong>by frame number</strong>, <em>not</em> by time, which will become inaccurate when converted to frame number.</p>
  
  <p>I've read dranger's tuts (which is outdated now), and end up with:</p>
  
  <pre><code>av_seek_frame(fmt_ctx, video_stream_id, frame, AVSEEK_FLAG_ANY);
  </code></pre>
  
  <p>It always seek to frame <code>No. 0</code>, and always <code>return 0</code> which means success.
  Then I tried to read Blender's source code and found it really complex(maybe I should implement an image buffer?).</p>
  
  <p>So, is there any simple way to seek to a frame with just a simple call like <code>seek(context, frame_number)</code>(while getting a full frame, not a broken one)? Or, is there any lightweight library that simplifies this?</p>
  
  <p><strong>EDIT:</strong>
  Thanks to <strong>praks411</strong>，I found the solution:</p>
  
  <pre><code>void AV_seek(AV * av, size_t frame)
  {
      int frame_delta = frame - av-&gt;frame_id;
      if (frame_delta &lt; 0 || frame_delta &gt; 5)
          av_seek_frame(av-&gt;fmt_ctx, av-&gt;video_stream_id,
                  frame, AVSEEK_FLAG_BACKWARD);
      while (av-&gt;frame_id != frame)
          AV_read_frame(av);
  }
  
  void AV_read_frame(AV * av)
  {
      AVPacket packet;
      int frame_done;
  
      while (av_read_frame(av-&gt;fmt_ctx, &amp;packet) &gt;= 0) {
          if (packet.stream_index == av-&gt;video_stream_id) {
              avcodec_decode_video2(av-&gt;codec_ctx, av-&gt;frame, &amp;frame_done, &amp;packet);
              if (frame_done) {
                  ...
                  av-&gt;frame_id = packet.dts;
                  av_free_packet(&amp;packet);
                  return;
              }
          }
          av_free_packet(&amp;packet);
      }
  }
  </code></pre>
  
  <p><strong>EDIT2:</strong>
  Turns out there is a library for this: <a href="https://github.com/FFMS/ffms2" rel="noreferrer">FFMS2</a>.
  It is "an FFmpeg based source library [...] for easy frame accurate access", and is portable (at least across Windows and Linux).</p>