Helper functions for adding new pads to filters at runtime
[ffmpeg.git] / libavfilter / avfilter.h
index 2e50467..617e512 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef FFMPEG_AVFILTER_H
 #define FFMPEG_AVFILTER_H
 
+#include <stddef.h>
 #include "avcodec.h"
 
 typedef struct AVFilterContext AVFilterContext;
@@ -53,7 +54,7 @@ typedef struct AVFilterPic
  * and dimensions are per-reference properties.  Linesize is also useful for
  * image flipping, frame to field filters, etc, and so is also per-reference.
  *
- * TODO: add pts, and anything necessary for frame reordering
+ * TODO: add anything necessary for frame reordering
  */
 typedef struct AVFilterPicRef
 {
@@ -62,6 +63,8 @@ typedef struct AVFilterPicRef
     int linesize[4];
     int w, h;
 
+    int64_t pts;                ///< presentation timestamp in milliseconds
+
     int perms;                  ///< permissions
 #define AV_PERM_READ     0x01   ///< can read from the buffer
 #define AV_PERM_WRITE    0x02   ///< can write to the buffer
@@ -72,9 +75,10 @@ typedef struct AVFilterPicRef
 /**
  * Add a new reference to a picture.
  * @param ref An existing reference to the picture
+ * @param pmask A bitmask containing the allowable permissions in the new reference
  * @return A new reference to the picture with the same properties as the old
  */
-AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref);
+AVFilterPicRef *avfilter_ref_pic(AVFilterPicRef *ref, int pmask);
 
 /**
  * Remove a reference to a picture.  If this is the last reference to the
@@ -98,6 +102,13 @@ struct AVFilterPad
     int type;
 #define AV_PAD_VIDEO 0
 
+    /**
+     * Callback to get a list of supported formats.  The returned list should
+     * be terminated by -1.  This is used for both input and output pads and
+     * is required for both.
+     */
+    int *(*query_formats)(AVFilterLink *link);
+
     /**
      * Callback called before passing the first slice of a new frame.  If
      * NULL, the filter layer will default to storing a reference to the
@@ -131,16 +142,25 @@ struct AVFilterPad
     void (*request_frame)(AVFilterLink *link);
 
     /**
-     * Callback to set properties of the link. Only for video output pads.
-     * XXX: this is not acceptable as is.  it needs reworked to allow for
-     * negotiation of colorspace, etc.
+     * Link configuration callback.  For output pads, this should set the link
+     * properties such as width/height.  NOTE: this should not set the format
+     * property - that is negotiated between filters by the filter system using
+     * the query_formats() callback.
+     *
+     * For input pads, this should check the properties of the link, and update
+     * the filter's internal state as necessary.
      */
-    int (*set_video_props)(AVFilterLink *link);
+    int (*config_props)(AVFilterLink *link);
 };
 
-/* the default implementations of start_frame() and end_frame() */
+/* the default implementations of filter entry points */
 void avfilter_default_start_frame(AVFilterLink *link, AVFilterPicRef *picref);
 void avfilter_default_end_frame(AVFilterLink *link);
+int avfilter_default_config_output_link(AVFilterLink *link);
+int avfilter_default_config_input_link (AVFilterLink *link);
+int *avfilter_default_query_output_formats(AVFilterLink *link);
+AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link,
+                                                  int perms);
 
 typedef struct
 {
@@ -152,8 +172,10 @@ typedef struct
     /**
      * Filter initialization function.  Args contains the user-supplied
      * parameters.  FIXME: maybe an AVOption-based system would be better?
+     * opaque is data provided by the code requesting creation of the filter,
+     * and is used to pass data to the filter.
      */
-    int (*init)(AVFilterContext *ctx, const char *args);
+    int (*init)(AVFilterContext *ctx, const char *args, void *opaque);
     void (*uninit)(AVFilterContext *ctx);
 
     const AVFilterPad *inputs;  /// NULL terminated list of inputs. NULL if none
@@ -166,7 +188,14 @@ struct AVFilterContext
 
     AVFilter *filter;
 
+    char *name;
+
+    unsigned input_count;
+    AVFilterPad   *input_pads;
     AVFilterLink **inputs;
+
+    unsigned output_count;
+    AVFilterPad   *output_pads;
     AVFilterLink **outputs;
 
     void *priv;
@@ -184,12 +213,16 @@ struct AVFilterLink
     enum PixelFormat format;
 
     AVFilterPicRef *cur_pic;
+    AVFilterPicRef *outpic;
 };
 
 /** Link two filters together */
 int avfilter_link(AVFilterContext *src, unsigned srcpad,
                   AVFilterContext *dst, unsigned dstpad);
 
+/** Configure the colorspace, dimensions, etc of a link */
+int avfilter_config_link(AVFilterLink *link);
+
 AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms);
 void avfilter_request_frame(AVFilterLink *link);
 void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref);
@@ -201,9 +234,43 @@ void avfilter_uninit(void);
 void avfilter_register(AVFilter *filter);
 AVFilter *avfilter_get_by_name(char *name);
 
-AVFilterContext *avfilter_create(AVFilter *filter);
-AVFilterContext *avfilter_create_by_name(char *name);
-int avfilter_init_filter(AVFilterContext *filter, const char *args);
+AVFilterContext *avfilter_create(AVFilter *filter, char *inst_name);
+AVFilterContext *avfilter_create_by_name(char *name, char *inst_name);
+int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque);
 void avfilter_destroy(AVFilterContext *filter);
 
+int *avfilter_make_format_list(int len, ...);
+
+/**
+ * Insert a new pad
+ * @param idx Insertion point.  Pad is inserted at the end if this point
+ *            is beyond the end of the list of pads.
+ * @param count Pointer to the number of pads in the list
+ * @param padidx_off Offset within an AVFilterLink structure to the element
+ *                   to increment when inserting a new pad causes link
+ *                   numbering to change
+ * @param pads Pointer to the pointer to the beginning of the list of pads
+ * @param links Pointer to the pointer to the beginning of the list of links
+ * @param newpad The new pad to add. A copy is made when adding.
+ */
+void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
+                         AVFilterPad **pads, AVFilterLink ***links,
+                         AVFilterPad *newpad);
+
+/** insert a new input pad for the filter */
+static inline void avfilter_insert_inpad(AVFilterContext *f, unsigned index,
+                                         AVFilterPad *p)
+{
+    avfilter_insert_pad(index, &f->input_count, offsetof(AVFilterLink, dstpad),
+                        &f->input_pads, &f->inputs, p);
+}
+
+/** insert a new output pad for the filter */
+static inline void avfilter_insert_outpad(AVFilterContext *f, unsigned index,
+                                          AVFilterPad *p)
+{
+    avfilter_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad),
+                        &f->output_pads, &f->outputs, p);
+}
+
 #endif  /* FFMPEG_AVFILTER_H */