hi again,

I tried to change some of existing filters to NMS, and filter_invert
looked easy, so I started and 2h after, here's this patch. I tried to
fix all those things I didn't do in filter_mirror - again, take a deep
look and see if it's OK. No line was deleted (theoretically yes), only
rearranged and fixed one warning, and all those nitpickings Francesco
pointed out were (I hope so) changed from original.

I could change some other filter modules too, if time allows me and if
it's OK with you:/

P.S. there is one thing I didn't get it, and no NMS module uses it so
I didn't have a reference, - that thing is marked as TODO in file, so
take a look

greetings, branko kokanovic
Index: filter/filter_invert.c
===================================================================
RCS file: /cvstc/transcode/filter/filter_invert.c,v
retrieving revision 1.21
diff -u -r1.21 filter_invert.c
--- filter/filter_invert.c	14 Sep 2006 14:10:32 -0000	1.21
+++ filter/filter_invert.c	28 Jul 2007 21:58:17 -0000
@@ -1,8 +1,8 @@
 /*
- *  filter_invert
+ *  filter_invert.c -- invert filter: inverts the image
  *
  *  Copyright (C) Tilmann Bitterberg - June 2002
- *
+ *      modified 2007 by Branko Kokanovic to use NMS
  *  This file is part of transcode, a video stream processing tool
  *
  *  transcode is free software; you can redistribute it and/or modify
@@ -22,17 +22,34 @@
  */
 
 #define MOD_NAME    "filter_invert.so"
-#define MOD_VERSION "v0.1.4 (2003-10-12)"
+#define MOD_VERSION "v0.1.5 (2007-07-29)"
 #define MOD_CAP     "invert the image"
 #define MOD_AUTHOR  "Tilmann Bitterberg"
+#define MOD_FEATURES \
+    TC_MODULE_FEATURE_FILTER|TC_MODULE_FEATURE_VIDEO
+#define MOD_FLAGS \
+    TC_MODULE_FLAG_RECONFIGURABLE
+
+/* -------------------------------------------------
+ *
+ * mandatory include files
+ *
+ *-------------------------------------------------*/
 
 #include "transcode.h"
 #include "filter.h"
 #include "libtc/libtc.h"
 #include "libtc/optstr.h"
+#include "libtc/tcmodule-plugin.h"
 
 
-// basic parameter
+static const char invert_help[]=""
+    "Overview\n"
+    "   Invert an image\n"
+    "Options\n"
+    "    'range' apply filter to [start-end]/step frames [0-oo/1]\n";
+
+/*************************************************************************/
 
 typedef struct MyFilterData {
 	unsigned int start;
@@ -41,134 +58,264 @@
 	int boolstep;
 } MyFilterData;
 
-static MyFilterData *mfd = NULL;
+/*************************************************************************/
 
-/* should probably honor the other flags too */
+/* Module interface routines and data. */
 
-/*-------------------------------------------------
- *
- * single function interface
- *
- *-------------------------------------------------*/
+/*************************************************************************/
 
-static void help_optstr(void)
-{
-    tc_log_info(MOD_NAME, "(%s) help\n"
-"* Overview\n"
-"    Invert an image\n"
-"* Options\n"
-"    'range' apply filter to [start-end]/step frames [0-oo/1]\n"
-		, MOD_CAP);
-}
+/**
+ * invert_init:  Initialize this instance of the module.  See
+ * tcmodule-data.h for function details.
+ */
 
-int tc_filter(frame_list_t *ptr_, char *options)
+static int invert_init(TCModuleInstance *self, uint32_t features)
 {
-  vframe_list_t *ptr = (vframe_list_t *)ptr_;
-  static vob_t *vob=NULL;
+    MyFilterData *mfd = NULL;
+
+    TC_MODULE_SELF_CHECK(self, "init");
+    TC_MODULE_INIT_CHECK(self, MOD_FEATURES, features);
+
+    mfd = tc_malloc(sizeof(MyFilterData));
+    if (!mfd) {
+        tc_log_error(MOD_NAME, "init: out of memory!");
+        return TC_ERROR;
+    }
+    self->userdata = mfd;
+
+    /* initialize data */
+    mfd->start=0;
+    mfd->end=(unsigned int)-1;
+    mfd->step=1;
 
-  int w;
+    if (verbose) {
+        tc_log_info (MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP);
+    }
+    return TC_OK;
+}
 
-  if(ptr->tag & TC_FILTER_GET_CONFIG) {
-      char buf[128];
-      optstr_filter_desc (options, MOD_NAME, MOD_CAP, MOD_VERSION, MOD_AUTHOR, "VRY4O", "1");
+/*************************************************************************/
 
-      tc_snprintf(buf, 128, "%u-%u/%d", mfd->start, mfd->end, mfd->step);
-      optstr_param (options, "range", "apply filter to [start-end]/step frames",
-	      "%u-%u/%d", buf, "0", "oo", "0", "oo", "1", "oo");
+/**
+ * invert_fini:  Clean up after this instance of the module.  See
+ * tcmodule-data.h for function details.
+ */
 
-      return 0;
-  }
+static int invert_fini(TCModuleInstance *self)
+{
+    TC_MODULE_SELF_CHECK(self, "fini");
 
-  //----------------------------------
-  //
-  // filter init
-  //
-  //----------------------------------
+    /* free data allocated in _init */
+    tc_free(self->userdata);
+    self->userdata = NULL;
+    return TC_OK;
+}
+
+/*************************************************************************/
 
+/**
+ * invert_configure:  Configure this instance of the module.  See
+ * tcmodule-data.h for function details.
+ */
 
-  if(ptr->tag & TC_FILTER_INIT) {
+static int invert_configure(TCModuleInstance *self,
+                          const char *options, vob_t *vob)
+{
+    MyFilterData *mfd = NULL;
 
-    if((vob = tc_get_vob())==NULL) return(-1);
+    TC_MODULE_SELF_CHECK(self, "configure");
 
-    mfd = tc_malloc (sizeof(MyFilterData));
-    if(mfd == NULL)
-        return (-1);
+    mfd = self->userdata;
 
+    if (vob == NULL){
+        return TC_ERROR;
+    }
 
+    /* setup defaults */
     mfd->start=0;
     mfd->end=(unsigned int)-1;
     mfd->step=1;
 
     if (options != NULL) {
+        if(verbose >= TC_STATS){
+            tc_log_info(MOD_NAME, "options=%s", options);
+        }
 
-	if(verbose) tc_log_info(MOD_NAME, "options=%s", options);
-
-	optstr_get (options, "range",  "%u-%u/%d",    &mfd->start, &mfd->end, &mfd->step);
+	    optstr_get (options, "range",  "%u-%u/%d",    &mfd->start, &mfd->end, &mfd->step);
     }
 
-
-    if (verbose > 1) {
-	tc_log_info (MOD_NAME, " Invert Image Settings:");
-	tc_log_info (MOD_NAME, "             range = %u-%u", mfd->start, mfd->end);
-	tc_log_info (MOD_NAME, "              step = %u", mfd->step);
+    if (verbose > TC_INFO) {
+	    tc_log_info (MOD_NAME, " Invert Image Settings:");
+	    tc_log_info (MOD_NAME, "             range = %u-%u", mfd->start, mfd->end);
+	    tc_log_info (MOD_NAME, "              step = %u", mfd->step);
     }
 
-    if (options)
-	if (optstr_lookup (options, "help")) {
-	    help_optstr();
-	}
-
     if (mfd->start % mfd->step == 0)
       mfd->boolstep = 0;
     else
       mfd->boolstep = 1;
 
-    // filter init ok.
-    if (verbose) tc_log_info (MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP);
+    return TC_OK;
+}
 
+/*************************************************************************/
 
-    return(0);
-  }
+/**
+ * invert_stop:  Reset this instance of the module.  See tcmodule-data.h
+ * for function details.
+ */
 
-  //----------------------------------
-  //
-  // filter close
-  //
-  //----------------------------------
+static int invert_stop(TCModuleInstance *self)
+{
+    TC_MODULE_SELF_CHECK(self, "stop");
+    return TC_OK;
+}
 
+/*************************************************************************/
 
-  if(ptr->tag & TC_FILTER_CLOSE) {
+/**
+ * invert_inspect:  Return the value of an option in this instance of
+ * the module.  See tcmodule-data.h for function details.
+ */
 
-    if (mfd) {
-	free(mfd);
-    }
-    mfd=NULL;
+static int invert_inspect(TCModuleInstance *self,
+                        const char *param, const char **value)
+{
+    MyFilterData *mfd = NULL;
 
-    return(0);
+    TC_MODULE_SELF_CHECK(self, "inspect");
+    TC_MODULE_SELF_CHECK(param, "inspect");
+    TC_MODULE_SELF_CHECK(value, "inspect");
 
-  } /* filter close */
+    mfd = self->userdata;
 
-  //----------------------------------
-  //
-  // filter frame routine
-  //
-  //----------------------------------
+    if (optstr_lookup(param, "help")) {
+        *value = invert_help; 
+    }
+    /* TODO: does it need optstr_lookup() for range too and how? */
 
+    return TC_OK;
+}
 
-  // tag variable indicates, if we are called before
-  // transcodes internal video/audo frame processing routines
-  // or after and determines video/audio context
+/*************************************************************************/
 
-  if((ptr->tag & TC_POST_M_PROCESS) && (ptr->tag & TC_VIDEO) && !(ptr->attributes & TC_FRAME_IS_SKIPPED))  {
-    char *p = ptr->video_buf;
+/**
+ * invert_filter_video:  show something on given frame of the video
+ * stream.  See tcmodule-data.h for function details.
+ */
 
-    if (mfd->start <= ptr->id && ptr->id <= mfd->end && ptr->id%mfd->step == mfd->boolstep) {
+static int invert_filter_video(TCModuleInstance *self, vframe_list_t *frame)
+{
+    MyFilterData *mfd = NULL;
+    int post = 0,w;
+
+    TC_MODULE_SELF_CHECK(self, "filer_video");
+    TC_MODULE_SELF_CHECK(frame, "filer_video");
 
-      for (w = 0; w < ptr->video_size; w++, p++)
-	     *p = 255 - *p;
+    mfd = self->userdata;
+    post = (frame->tag & TC_POST_M_PROCESS);
+
+    if(post && !(frame->attributes & TC_FRAME_IS_SKIPPED))  {
+        uint8_t *p = frame->video_buf;
+
+        if (mfd->start <= frame->id && frame->id <= mfd->end && frame->id%mfd->step == mfd->boolstep) {
+            for (w = 0; w < frame->video_size; w++, p++)
+                *p = 255 - *p;
+        }
     }
-  }
 
-  return(0);
+    return TC_OK;
+}
+
+/*************************************************************************/
+
+static const TCCodecID invert_codecs_in[] = { 
+    TC_CODEC_ANY, TC_CODEC_ERROR
+};
+static const TCCodecID invert_codecs_out[] = {
+    TC_CODEC_ANY, TC_CODEC_ERROR
+};
+static const TCFormatID invert_formats[] = {
+    TC_FORMAT_ERROR
+};
+
+static const TCModuleInfo invert_info = {
+    .features    = MOD_FEATURES,
+    .flags       = MOD_FLAGS,
+    .name        = MOD_NAME,
+    .version     = MOD_VERSION,
+    .description = MOD_CAP,
+    .codecs_in   = invert_codecs_in,
+    .codecs_out  = invert_codecs_out,
+    .formats_in  = invert_formats,
+    .formats_out = invert_formats
+};
+
+static const TCModuleClass invert_class = {
+    .info         = &invert_info,
+
+    .init         = invert_init,
+    .fini         = invert_fini,
+    .configure    = invert_configure,
+    .stop         = invert_stop,
+    .inspect      = invert_inspect,
+
+    .filter_video = invert_filter_video
+};
+
+extern const TCModuleClass *tc_plugin_setup(void)
+{
+    return &invert_class;
 }
 
+/*************************************************************************/
+
+static int invert_get_config(TCModuleInstance *self, char *options)
+{
+    MyFilterData *mfd = NULL;
+    char buf[TC_BUF_MIN];
+
+    TC_MODULE_SELF_CHECK(self, "get_config");
+
+    mfd = self->userdata;
+
+    optstr_filter_desc(options, MOD_NAME, MOD_CAP, MOD_VERSION, MOD_AUTHOR, "VRY4O", "1");
+
+    optstr_param (options, "help", "Inverts the image", "", "0");
+
+    tc_snprintf(buf, 128, "%u-%u/%d", mfd->start, mfd->end, mfd->step);
+    optstr_param (options, "range", "apply filter to [start-end]/step frames",
+        "%u-%u/%d", buf, "0", "oo", "0", "oo", "1", "oo");
+
+    return TC_OK;
+}
+
+static int invert_process(TCModuleInstance *self, 
+                            frame_list_t *frame)
+{
+    TC_MODULE_SELF_CHECK(self, "process");
+
+    /* choose what to do by frame->tag */
+    if (frame->tag & TC_VIDEO) {
+        return invert_filter_video(self, (vframe_list_t*)frame);
+    }
+    return TC_OK;
+}
+
+/*************************************************************************/
+
+/* Old-fashioned module interface. */
+
+TC_FILTER_OLDINTERFACE(invert)
+
+/*************************************************************************/
+
+/*
+ * Local variables:
+ *   c-file-style: "stroustrup"
+ *   c-file-offsets: ((case-label . *) (statement-case-intro . *))
+ *   indent-tabs-mode: nil
+ * End:
+ *
+ * vim: expandtab shiftwidth=4:
+ */

Reply via email to