lavfi: add avfilter_get_class() and iteration callbacks
[ffmpeg.git] / libavfilter / vf_mp.c
index 1f0a311..4fa02c7 100644 (file)
  */
 
 #include "avfilter.h"
+#include "video.h"
+#include "formats.h"
+#include "internal.h"
 #include "libavutil/avassert.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/intreadwrite.h"
-#include "libavcore/imgutils.h"
+#include "libavutil/imgutils.h"
 
 #include "libmpcodecs/vf.h"
 #include "libmpcodecs/img_format.h"
@@ -41,6 +44,7 @@
 
 
 //FIXME maybe link the orig in
+//XXX: identical pix_fmt must be following with each others
 static const struct {
     int fmt;
     enum PixelFormat pix_fmt;
@@ -119,92 +123,76 @@ static const struct {
 };
 
 //copied from vf.c
-extern const vf_info_t vf_info_vo;
-extern const vf_info_t vf_info_rectangle;
+extern const vf_info_t vf_info_1bpp;
+extern const vf_info_t vf_info_ass;
 extern const vf_info_t vf_info_bmovl;
 extern const vf_info_t vf_info_crop;
-extern const vf_info_t vf_info_expand;
-extern const vf_info_t vf_info_pp;
-extern const vf_info_t vf_info_scale;
-extern const vf_info_t vf_info_format;
-extern const vf_info_t vf_info_noformat;
-extern const vf_info_t vf_info_flip;
-extern const vf_info_t vf_info_rotate;
-extern const vf_info_t vf_info_mirror;
-extern const vf_info_t vf_info_palette;
-extern const vf_info_t vf_info_lavc;
-extern const vf_info_t vf_info_zrmjpeg;
+extern const vf_info_t vf_info_decimate;
+extern const vf_info_t vf_info_denoise3d;
+extern const vf_info_t vf_info_detc;
+extern const vf_info_t vf_info_dint;
+extern const vf_info_t vf_info_divtc;
+extern const vf_info_t vf_info_down3dright;
+extern const vf_info_t vf_info_dsize;
 extern const vf_info_t vf_info_dvbscale;
-extern const vf_info_t vf_info_cropdetect;
-extern const vf_info_t vf_info_test;
-extern const vf_info_t vf_info_noise;
-extern const vf_info_t vf_info_yvu9;
-extern const vf_info_t vf_info_lavcdeint;
-extern const vf_info_t vf_info_eq;
 extern const vf_info_t vf_info_eq2;
-extern const vf_info_t vf_info_gradfun;
+extern const vf_info_t vf_info_eq;
+extern const vf_info_t vf_info_expand;
+extern const vf_info_t vf_info_field;
+extern const vf_info_t vf_info_fil;
+extern const vf_info_t vf_info_filmdint;
+extern const vf_info_t vf_info_fixpts;
+extern const vf_info_t vf_info_flip;
+extern const vf_info_t vf_info_format;
+extern const vf_info_t vf_info_framestep;
+extern const vf_info_t vf_info_fspp;
+extern const vf_info_t vf_info_geq;
 extern const vf_info_t vf_info_halfpack;
-extern const vf_info_t vf_info_dint;
-extern const vf_info_t vf_info_1bpp;
-extern const vf_info_t vf_info_2xsai;
-extern const vf_info_t vf_info_unsharp;
-extern const vf_info_t vf_info_swapuv;
+extern const vf_info_t vf_info_harddup;
+extern const vf_info_t vf_info_hqdn3d;
+extern const vf_info_t vf_info_hue;
 extern const vf_info_t vf_info_il;
-extern const vf_info_t vf_info_fil;
-extern const vf_info_t vf_info_boxblur;
+extern const vf_info_t vf_info_ilpack;
+extern const vf_info_t vf_info_ivtc;
+extern const vf_info_t vf_info_kerndeint;
+extern const vf_info_t vf_info_lavc;
+extern const vf_info_t vf_info_lavcdeint;
+extern const vf_info_t vf_info_mcdeint;
+extern const vf_info_t vf_info_noformat;
+extern const vf_info_t vf_info_noise;
+extern const vf_info_t vf_info_ow;
+extern const vf_info_t vf_info_palette;
+extern const vf_info_t vf_info_perspective;
+extern const vf_info_t vf_info_phase;
+extern const vf_info_t vf_info_pp7;
+extern const vf_info_t vf_info_pp;
+extern const vf_info_t vf_info_pullup;
+extern const vf_info_t vf_info_qp;
+extern const vf_info_t vf_info_rectangle;
+extern const vf_info_t vf_info_rotate;
 extern const vf_info_t vf_info_sab;
+extern const vf_info_t vf_info_scale;
 extern const vf_info_t vf_info_smartblur;
-extern const vf_info_t vf_info_perspective;
-extern const vf_info_t vf_info_down3dright;
-extern const vf_info_t vf_info_field;
-extern const vf_info_t vf_info_denoise3d;
-extern const vf_info_t vf_info_hqdn3d;
-extern const vf_info_t vf_info_detc;
+extern const vf_info_t vf_info_softpulldown;
+extern const vf_info_t vf_info_softskip;
+extern const vf_info_t vf_info_spp;
+extern const vf_info_t vf_info_stereo3d;
 extern const vf_info_t vf_info_telecine;
-extern const vf_info_t vf_info_tinterlace;
+extern const vf_info_t vf_info_test;
 extern const vf_info_t vf_info_tfields;
-extern const vf_info_t vf_info_ivtc;
-extern const vf_info_t vf_info_ilpack;
-extern const vf_info_t vf_info_dsize;
-extern const vf_info_t vf_info_decimate;
-extern const vf_info_t vf_info_softpulldown;
-extern const vf_info_t vf_info_pullup;
-extern const vf_info_t vf_info_filmdint;
-extern const vf_info_t vf_info_framestep;
 extern const vf_info_t vf_info_tile;
-extern const vf_info_t vf_info_delogo;
-extern const vf_info_t vf_info_remove_logo;
-extern const vf_info_t vf_info_hue;
-extern const vf_info_t vf_info_spp;
+extern const vf_info_t vf_info_tinterlace;
+extern const vf_info_t vf_info_unsharp;
 extern const vf_info_t vf_info_uspp;
-extern const vf_info_t vf_info_fspp;
-extern const vf_info_t vf_info_pp7;
-extern const vf_info_t vf_info_yuvcsp;
-extern const vf_info_t vf_info_kerndeint;
-extern const vf_info_t vf_info_rgbtest;
-extern const vf_info_t vf_info_qp;
-extern const vf_info_t vf_info_phase;
-extern const vf_info_t vf_info_divtc;
-extern const vf_info_t vf_info_harddup;
-extern const vf_info_t vf_info_softskip;
-extern const vf_info_t vf_info_screenshot;
-extern const vf_info_t vf_info_ass;
-extern const vf_info_t vf_info_mcdeint;
+extern const vf_info_t vf_info_vo;
 extern const vf_info_t vf_info_yadif;
-extern const vf_info_t vf_info_blackframe;
-extern const vf_info_t vf_info_geq;
-extern const vf_info_t vf_info_ow;
-extern const vf_info_t vf_info_fixpts;
-extern const vf_info_t vf_info_stereo3d;
+extern const vf_info_t vf_info_yuvcsp;
+extern const vf_info_t vf_info_yvu9;
+extern const vf_info_t vf_info_zrmjpeg;
 
 
 static const vf_info_t* const filters[]={
-    &vf_info_2xsai,
-    &vf_info_blackframe,
-    &vf_info_boxblur,
-    &vf_info_cropdetect,
     &vf_info_decimate,
-    &vf_info_delogo,
     &vf_info_denoise3d,
     &vf_info_detc,
     &vf_info_dint,
@@ -220,7 +208,6 @@ static const vf_info_t* const filters[]={
     &vf_info_framestep,
     &vf_info_fspp,
     &vf_info_geq,
-    &vf_info_gradfun,
     &vf_info_harddup,
     &vf_info_hqdn3d,
     &vf_info_hue,
@@ -229,28 +216,24 @@ static const vf_info_t* const filters[]={
     &vf_info_ivtc,
     &vf_info_kerndeint,
     &vf_info_mcdeint,
-    &vf_info_mirror,
     &vf_info_noise,
     &vf_info_ow,
     &vf_info_palette,
     &vf_info_perspective,
     &vf_info_phase,
+    &vf_info_pp,
     &vf_info_pp7,
     &vf_info_pullup,
     &vf_info_qp,
     &vf_info_rectangle,
-    &vf_info_remove_logo,
-    &vf_info_rgbtest,
     &vf_info_rotate,
     &vf_info_sab,
-    &vf_info_screenshot,
     &vf_info_smartblur,
     &vf_info_softpulldown,
     &vf_info_softskip,
     &vf_info_spp,
-    &vf_info_swapuv,
+    &vf_info_stereo3d,
     &vf_info_telecine,
-    &vf_info_test,
     &vf_info_tile,
     &vf_info_tinterlace,
     &vf_info_unsharp,
@@ -277,7 +260,6 @@ lavcdeint
 noformat
 pp
 scale
-stereo3d
 tfields
 vo
 yadif
@@ -287,15 +269,6 @@ zrmjpeg
 CpuCaps gCpuCaps; //FIXME initialize this so optims work
 
 
-//exact copy from vf_scale.c
-int get_sws_cpuflags(void){
-    return
-          (gCpuCaps.hasMMX   ? SWS_CPU_CAPS_MMX   : 0)
-        | (gCpuCaps.hasMMX2  ? SWS_CPU_CAPS_MMX2  : 0)
-        | (gCpuCaps.has3DNow ? SWS_CPU_CAPS_3DNOW : 0)
-        | (gCpuCaps.hasAltiVec ? SWS_CPU_CAPS_ALTIVEC : 0);
-}
-
 static void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam)
 {
         static int firstTime=1;
@@ -348,7 +321,7 @@ struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat,
         if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = PIX_FMT_PAL8;
         sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam);
 
-        return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags | get_sws_cpuflags(), srcFilterParam, dstFilterParam, NULL);
+        return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags , srcFilterParam, dstFilterParam, NULL);
 }
 
 typedef struct {
@@ -464,7 +437,7 @@ unsigned int vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned
 }
 
 mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h){
-    MPContext *m= ((uint8_t*)vf) - offsetof(MPContext, next_vf);
+    MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, next_vf));
   mp_image_t* mpi=NULL;
   int w2;
   int number = mp_imgtype >> 16;
@@ -636,7 +609,7 @@ int vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
         goto fail;
 
     picref->buf = pic;
-    picref->buf->please_use_av_free= av_free;
+    picref->buf->please_use_av_free= (void*)av_free;
     if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps))))
         goto fail;
 
@@ -663,9 +636,9 @@ int vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
     if(pts != MP_NOPTS_VALUE)
         picref->pts= pts * av_q2d(outlink->time_base);
 
-    avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
-    avfilter_draw_slice(outlink, 0, picref->video->h, 1);
-    avfilter_end_frame(outlink);
+    ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
+    ff_draw_slice(outlink, 0, picref->video->h, 1);
+    ff_end_frame(outlink);
     avfilter_unref_buffer(picref);
     m->frame_returned++;
 
@@ -726,7 +699,7 @@ static int vf_default_query_format(struct vf_instance *vf, unsigned int fmt){
 }
 
 
-static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
+static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     MPContext *m = ctx->priv;
     char name[256];
@@ -734,7 +707,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
 
     m->avfctx= ctx;
 
-    if(!args || 1!=sscanf(args, "%255[^:]", name)){
+    if(!args || 1!=sscanf(args, "%255[^:=]", name)){
         av_log(ctx, AV_LOG_ERROR, "Invalid parameter.\n");
         return AVERROR(EINVAL);
     }
@@ -750,6 +723,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
         return AVERROR(EINVAL);
     }
 
+    av_log(ctx, AV_LOG_WARNING,
+           "'%s' is a wrapped MPlayer filter (libmpcodecs). This filter may be removed\n"
+           "once it has been ported to a native libavfilter.\n", name);
+
     memset(&m->vf,0,sizeof(m->vf));
     m->vf.info= filters[i];
 
@@ -785,22 +762,43 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
     return 0;
 }
 
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    MPContext *m = ctx->priv;
+    vf_instance_t *vf = &m->vf;
+
+    while(vf){
+        vf_instance_t *next = vf->next;
+        if(vf->uninit)
+            vf->uninit(vf);
+        free_mp_image(vf->imgctx.static_images[0]);
+        free_mp_image(vf->imgctx.static_images[1]);
+        free_mp_image(vf->imgctx.temp_images[0]);
+        free_mp_image(vf->imgctx.export_images[0]);
+        vf = next;
+    }
+}
+
 static int query_formats(AVFilterContext *ctx)
 {
     AVFilterFormats *avfmts=NULL;
     MPContext *m = ctx->priv;
+    enum PixelFormat lastpixfmt = PIX_FMT_NONE;
     int i;
 
     for(i=0; conversion_map[i].fmt; i++){
         av_log(ctx, AV_LOG_DEBUG, "query: %X\n", conversion_map[i].fmt);
         if(m->vf.query_format(&m->vf, conversion_map[i].fmt)){
             av_log(ctx, AV_LOG_DEBUG, "supported,adding\n");
-            avfilter_add_format(&avfmts, conversion_map[i].pix_fmt);
+            if (conversion_map[i].pix_fmt != lastpixfmt) {
+                ff_add_format(&avfmts, conversion_map[i].pix_fmt);
+                lastpixfmt = conversion_map[i].pix_fmt;
+            }
         }
     }
 
     //We assume all allowed input formats are also allowed output formats
-    avfilter_set_common_formats(ctx, avfmts);
+    ff_set_common_formats(ctx, avfmts);
     return 0;
 }
 
@@ -841,7 +839,7 @@ static int request_frame(AVFilterLink *outlink)
     av_log(m->avfctx, AV_LOG_DEBUG, "mp request_frame\n");
 
     for(m->frame_returned=0; !m->frame_returned;){
-        ret=avfilter_request_frame(outlink->src->inputs[0]);
+        ret=ff_request_frame(outlink->src->inputs[0]);
         if(ret<0)
             break;
     }
@@ -850,19 +848,20 @@ static int request_frame(AVFilterLink *outlink)
     return ret;
 }
 
-static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
 {
+    return 0;
 }
 
-static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
+static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
 {
+    return 0;
 }
 
-static void end_frame(AVFilterLink *inlink)
+static int end_frame(AVFilterLink *inlink)
 {
     MPContext *m = inlink->dst->priv;
     AVFilterBufferRef *inpic  = inlink->cur_buf;
-    AVFilterLink *outlink = inlink->dst->outputs[0];
     int i;
     double pts= MP_NOPTS_VALUE;
     mp_image_t* mpi = new_mp_image(inpic->video->w, inpic->video->h);
@@ -886,18 +885,18 @@ static void end_frame(AVFilterLink *inlink)
         av_log(m->avfctx, AV_LOG_DEBUG, "put_image() says skip\n");
     }
     free_mp_image(mpi);
-
-//    avfilter_unref_buffer(inpic);
+    return 0;
 }
 
 AVFilter avfilter_vf_mp = {
     .name      = "mp",
-    .description = NULL_IF_CONFIG_SMALL("libmpcodecs wrapper."),
+    .description = NULL_IF_CONFIG_SMALL("Apply a libmpcodecs filter to the input video."),
     .init = init,
+    .uninit = uninit,
     .priv_size = sizeof(MPContext),
     .query_formats = query_formats,
 
-    .inputs    = (AVFilterPad[]) {{ .name            = "default",
+    .inputs    = (const AVFilterPad[]) {{ .name      = "default",
                                     .type            = AVMEDIA_TYPE_VIDEO,
                                     .start_frame     = start_frame,
                                     .draw_slice      = null_draw_slice,
@@ -905,7 +904,7 @@ AVFilter avfilter_vf_mp = {
                                     .config_props    = config_inprops,
                                     .min_perms       = AV_PERM_READ, },
                                   { .name = NULL}},
-    .outputs   = (AVFilterPad[]) {{ .name            = "default",
+    .outputs   = (const AVFilterPad[]) {{ .name      = "default",
                                     .type            = AVMEDIA_TYPE_VIDEO,
                                     .request_frame   = request_frame,
                                     .config_props    = config_outprops, },