title: ffmpeg filter dev get_video_buffer function usage
body: <p>I'm writing a mosaic ffmpeg filter.
  copy code from vf_vflip.c, I register a callback function get_video_buffer
  and implement it as follows:</p>
  
  <pre><code>static AVFrame *get_video_buffer(AVFilterLink *link, int w, int h)
  {
      MosaicContext *s = link-&gt;dst-&gt;priv;
      AVFrame *frame;
      int i;
      int j,k;
  
      frame = ff_get_video_buffer(link-&gt;dst-&gt;outputs[0], w, h);
      if (!frame)
          return NULL;
  
      if (s-&gt;w == 0 || s-&gt;h == 0)
          return frame;
  
      for (i = 0; i &lt; 3; i ++) {
          // some trick code
      }
  
      return frame;
  }
  
  static const AVFilterPad avfilter_vf_mosaic_inputs[] = {
      {
          .name             = "default",
          .type             = AVMEDIA_TYPE_VIDEO,
          //.get_video_buffer = get_video_buffer,
          .filter_frame     = filter_frame,
          .config_props     = config_input,
      },
      { NULL }
  };
  </code></pre>
  
  <p>But after read some filter dev guide, I found that only a few filter implement get_video_buffer funcition.The default function is f_default_get_video_buffer()
  I make some log find that ffmpeg call function like</p>
  
  <pre><code>get_video_buffer
  filter_frame
  get_video_buffer
  filter_frame
  get_video_buffer
  filter_frame
  ...
  </code></pre>
  
  <p>I'm confused about get_video_buffer do what job.
  Only know that some filter will hold frame cache.
  Can I juse comment out the get_video_buffer hook?</p>
  
  <p>I see flip job both in get_video_buffer() and filter_frame() in vf_vflip.c
  Is it a waste of time?</p>
  
  <pre><code>static AVFrame *get_video_buffer(AVFilterLink *link, int w, int h)
  {
      FlipContext *flip = link-&gt;dst-&gt;priv;
      AVFrame *frame;
      int i;
  
      frame = ff_get_video_buffer(link-&gt;dst-&gt;outputs[0], w, h);
      if (!frame)
          return NULL;
  
      for (i = 0; i &lt; 4; i ++) {
          int vsub = i == 1 || i == 2 ? flip-&gt;vsub : 0;
          int height = AV_CEIL_RSHIFT(h, vsub);
  
          if (frame-&gt;data[i]) {
              frame-&gt;data[i] += (height - 1) * frame-&gt;linesize[i];
              frame-&gt;linesize[i] = -frame-&gt;linesize[i];
          }
      }
  
      return frame;
  }
  
  static int filter_frame(AVFilterLink *link, AVFrame *frame)
  {
      FlipContext *flip = link-&gt;dst-&gt;priv;
      int i;
  
      for (i = 0; i &lt; 4; i ++) {
          int vsub = i == 1 || i == 2 ? flip-&gt;vsub : 0;
          int height = AV_CEIL_RSHIFT(link-&gt;h, vsub);
  
          if (frame-&gt;data[i]) {
              frame-&gt;data[i] += (height - 1) * frame-&gt;linesize[i];
              frame-&gt;linesize[i] = -frame-&gt;linesize[i];
          }
      }
  
      return ff_filter_frame(link-&gt;dst-&gt;outputs[0], frame);
  }
  </code></pre>