efl - when evas generic loaders merged the gst loader was missed. fix
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>
Mon, 25 Jul 2016 06:21:45 +0000 (15:21 +0900)
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>
Mon, 25 Jul 2016 06:21:45 +0000 (15:21 +0900)
this fixes the missing gst loader from generic loaders.

configure.ac
src/Makefile_Evas.am
src/generic/.gitignore
src/generic/evas/gst/main.c [new file with mode: 0644]
src/generic/evas/gst/main_0_10.c [new file with mode: 0644]

index bf41481..4e26919 100644 (file)
@@ -1729,7 +1729,10 @@ fi
 if test "${want_gstreamer}" = "yes"; then
   PKG_CHECK_MODULES([GSTREAMER], [gstreamer-0.10])
 fi
-AM_CONDITIONAL([HAVE_GSTREAMER], [test "${want_gstreamer}" = "yes" -o "${want_gstreamer1}" = "yes"])
+
+AM_CONDITIONAL([HAVE_GSTREAMER], [test "x${want_gstreamer}" = "xyes" -o "x${want_gstreamer1}" = "xyes"])
+AM_CONDITIONAL([HAVE_GSTREAMER0], [test "x${want_gstreamer}" = "xyes"])
+AM_CONDITIONAL([HAVE_GSTREAMER1], [test "x${want_gstreamer1}" = "xyes"])
 
 EFL_EVAL_PKGS([ECORE])
 
index 01310c0..1f07e7e 100644 (file)
@@ -2572,3 +2572,99 @@ mkdir -p $(DESTDIR)$(libdir)/evas/utils; \
 ln -sf evas_image_loader.xcf $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.xcf.gz;
 
 endif
+
+
+EXTRA_DIST2 += \
+  generic/evas/gst/main_0_10.c \
+  generic/evas/gst/main.c
+
+if HAVE_GSTREAMER
+EFL_INSTALL_EXEC_HOOK += \
+mkdir -p $(DESTDIR)$(libdir)/evas/utils; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.264; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3g2; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3gp; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3gp2; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3gpp; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3gpp2; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.3p2; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.asf; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.avi; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.bdm; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.bdmv; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.clpi; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.cpi; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.dv; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.fla; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.flv; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.m1v; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.m2t; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.m2v; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.m4v; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mkv; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mov; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mp2; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mp2ts; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mp4; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mpe; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mpeg; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mpg; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mpl; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mpls; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mts; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.mxf; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.nut; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.nuv; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ogg; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ogm; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ogv; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.qt; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rm; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rmj; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rmm; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rms; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rmx; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rmvb; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.rv; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.swf; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.ts; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.webm; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.weba; \
+ln -sf evas_image_loader.gst $(DESTDIR)$(libdir)/evas/utils/evas_image_loader.wmv;
+endif
+
+if HAVE_GSTREAMER0
+evasgenericloaders_PROGRAMS += generic/evas/gst/evas_image_loader.gst
+generic_evas_gst_evas_image_loader_gst_SOURCES = \
+  generic/evas/gst/main_0_10.c \
+  generic/evas/common/shmfile.c \
+  generic/evas/common/timeout.c
+generic_evas_gst_evas_image_loader_gst_CFLAGS = \
+  -I$(top_srcdir)/src/lib/efl \
+  -I$(top_builddir)/src/lib/efl \
+  -I$(top_srcdir)/src/lib/eina \
+  -I$(top_builddir)/src/lib/eina \
+  -I$(top_srcdir)/src/generic/evas/common \
+  @EMOTION_MODULE_GSTREAMER_CFLAGS@
+generic_evas_gst_evas_image_loader_gst_LDADD = \
+  @USE_EINA_LIBS@ @SHM_LIBS@ -lm @EMOTION_MODULE_GSTREAMER_LIBS@
+generic_evas_gst_evas_image_loader_gst_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@
+endif
+
+if HAVE_GSTREAMER1
+evasgenericloaders_PROGRAMS += generic/evas/gst/evas_image_loader.gst
+generic_evas_gst_evas_image_loader_gst_SOURCES = \
+  generic/evas/gst/main.c \
+  generic/evas/common/shmfile.c \
+  generic/evas/common/timeout.c
+generic_evas_gst_evas_image_loader_gst_CFLAGS = \
+  -I$(top_srcdir)/src/lib/efl \
+  -I$(top_builddir)/src/lib/efl \
+  -I$(top_srcdir)/src/lib/eina \
+  -I$(top_builddir)/src/lib/eina \
+  -I$(top_srcdir)/src/generic/evas/common \
+  @EMOTION_MODULE_GSTREAMER1_CFLAGS@
+generic_evas_gst_evas_image_loader_gst_LDADD = \
+  @USE_EINA_LIBS@ @SHM_LIBS@ -lm @EMOTION_MODULE_GSTREAMER1_LIBS@
+generic_evas_gst_evas_image_loader_gst_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@
+endif
index 1989117..498f89d 100644 (file)
@@ -4,3 +4,4 @@
 /evas/raw/evas_image_loader.raw
 /evas/xcf/evas_image_loader.xcf
 /evas/svg/evas_image_loader.svg
+/evas/gst/evas_image_loader.gst
diff --git a/src/generic/evas/gst/main.c b/src/generic/evas/gst/main.c
new file mode 100644 (file)
index 0000000..d9e6fa7
--- /dev/null
@@ -0,0 +1,292 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <gst/gst.h>
+
+#include <Eina.h>
+
+#include "shmfile.h"
+#include "timeout.h"
+
+#define DATA32  unsigned int
+
+//#define GST_DBG
+
+#ifdef GST_DBG
+#define D(fmt, args...) fprintf(stderr, fmt, ## args)
+#else
+#define D(fmt, args...)
+#endif
+
+#ifdef WORDS_BIGENDIAN
+# define CAPS "video/x-raw,format=ARGB"
+#else
+# define CAPS "video/x-raw,format=BGRA"
+#endif
+
+static GstElement *pipeline = NULL;
+static GstElement *sink = NULL;
+static gint64      duration = -1;
+
+int   width = 0;
+int   height = 0;
+void *data = NULL;
+
+
+static Eina_Bool
+_gst_init(const char *filename)
+{
+   GstPad              *pad;
+   GstCaps             *caps;
+   GstStructure        *structure;
+   gchar               *descr;
+   gchar               *uri;
+   GError              *error = NULL;
+   GstFormat            format;
+   GstStateChangeReturn ret;
+//   int                  vidstr = 0;
+
+   if (!filename || !*filename)
+     return EINA_FALSE;
+
+   if (!gst_init_check(NULL, NULL, &error))
+     return EINA_FALSE;
+
+   if ((*filename == '/') || (*filename == '~'))
+     {
+        uri = g_filename_to_uri(filename, NULL, NULL);
+        if (!uri)
+          {
+             D("could not create new uri from %s", filename);
+             goto unref_pipeline;
+          }
+     }
+   else
+     uri = strdup(filename);
+
+   D("Setting file %s\n", uri);
+
+   descr = g_strdup_printf("uridecodebin uri=%s ! typefind ! videoconvert ! " 
+      " appsink name=sink caps=\"" CAPS "\"", uri);
+   pipeline = gst_parse_launch(descr, &error);
+   free(uri);
+
+   if (error != NULL)
+     {
+        D("could not construct pipeline: %s\n", error->message);
+        g_error_free (error);
+        goto gst_shutdown;
+     }
+/* needs gst 1.0+
+ * also only works on playbin objects!!! this is a uridecodebin!
+   g_object_get(G_OBJECT(pipeline),
+                "n-video", &vidstr,
+                NULL);
+   if (vidstr <= 0)
+     {
+        D("no video stream\n");
+        goto gst_shutdown;
+     }
+*/
+   sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
+
+   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
+   switch (ret)
+     {
+     case GST_STATE_CHANGE_FAILURE:
+        D("failed to play the file\n");
+        goto unref_pipeline;
+     case GST_STATE_CHANGE_NO_PREROLL:
+        D("live sources not supported yet\n");
+        goto unref_pipeline;
+     default:
+        break;
+     }
+
+   ret = gst_element_get_state((pipeline), NULL, NULL, GST_CLOCK_TIME_NONE);
+   if (ret == GST_STATE_CHANGE_FAILURE)
+     {
+        D("could not complete pause\n");
+        goto unref_pipeline;
+     }
+
+   format = GST_FORMAT_TIME;
+   gst_element_query_duration (pipeline, format, &duration);
+   if (duration == -1)
+     {
+        fprintf(stderr, "duration fetch err\n");
+        D("could not retrieve the duration, set it to 1s\n");
+        duration = 1 * GST_SECOND;
+     }
+
+   pad = gst_element_get_static_pad(sink, "sink");
+   if (!pad)
+     {
+        D("could not retrieve the sink pad\n");
+        goto unref_pipeline;
+     }
+
+   caps = gst_pad_get_current_caps(pad);
+   if (!caps)
+     goto unref_pad;
+
+   structure = gst_caps_get_structure(caps, 0);
+
+   if (!gst_structure_get_int(structure, "width", &width))
+     goto unref_caps;
+   if (!gst_structure_get_int(structure, "height", &height))
+     goto unref_caps;
+
+   gst_caps_unref(caps);
+   gst_object_unref(pad);
+
+   return EINA_TRUE;
+
+ unref_caps:
+   gst_caps_unref(caps);
+ unref_pad:
+   gst_object_unref(pad);
+ unref_pipeline:
+   gst_element_set_state (pipeline, GST_STATE_NULL);
+   gst_object_unref(pipeline);
+ gst_shutdown:
+   gst_deinit();
+
+   return EINA_FALSE;
+}
+
+static void
+_gst_shutdown()
+{
+   gst_element_set_state (pipeline, GST_STATE_NULL);
+   gst_object_unref(pipeline);
+   gst_deinit();
+}
+
+static void
+_gst_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED, double pos)
+{
+   GstBuffer *buffer;
+   GstMapInfo info;
+   GstSample *sample;
+
+   D("load image\n");
+   if (pos >= 0.0)
+     gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
+                             pos);
+   else
+     gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
+                             duration / 2);
+   g_signal_emit_by_name(sink, "pull-preroll", &sample, NULL);
+
+   shm_alloc(width * height * sizeof(DATA32));
+   if (!shm_addr) return;
+   data = shm_addr;
+
+   buffer = gst_sample_get_buffer (sample);
+   gst_buffer_map (buffer, &info, GST_MAP_READ);
+   D("load image: %p %d\n", info.data, info.size);
+
+   memcpy(data, info.data, info.size);
+
+   gst_buffer_unmap(buffer, &info);
+}
+
+int
+main(int argc, char **argv)
+{
+   char *file, *p;
+   int i, numonly;
+   int size_w = 0, size_h = 0;
+   int head_only = 0;
+   long long pos = -1.0;
+
+   if (argc < 2) return -1;
+   // file is ALWAYS first arg, other options come after
+   file = argv[1];
+   for (i = 2; i < argc; i++)
+     {
+        if      (!strcmp(argv[i], "-head"))
+           // asked to only load header, not body/data
+           head_only = 1;
+        else if (!strcmp(argv[i], "-key"))
+          {
+             i++;
+             numonly = 1;
+             for (p = argv[i]; *p; p++)
+               {
+                  if ((*p < '0') || (*p > '9'))
+                    {
+                       numonly = 0;
+                       break;
+                    }
+               }
+             if (numonly) pos = atoll(argv[i]) * 1000000;
+             i++;
+          }
+        else if (!strcmp(argv[i], "-opt-scale-down-by"))
+          { // not used by ps loader
+             i++;
+             // int scale_down = atoi(argv[i]);
+          }
+        else if (!strcmp(argv[i], "-opt-dpi"))
+          {
+             i++;
+          }
+        else if (!strcmp(argv[i], "-opt-size"))
+          { // not used by ps loader
+             i++;
+             size_w = atoi(argv[i]);
+             i++;
+             size_h = atoi(argv[i]);
+          }
+     }
+
+   timeout_init(10);
+
+   D("_gst_init_file\n");
+
+   if (!_gst_init(file))
+     return -1;
+   D("_gst_init done\n");
+
+   if ((pos >= 0) && (pos > duration)) return -1;
+
+   if (!head_only)
+     {
+        _gst_load_image(size_w, size_h, pos);
+     }
+
+   D("size...: %ix%i\n", width, height);
+   D("alpha..: 0\n");
+
+   printf("size %i %i\n", width, height);
+   printf("alpha 0\n");
+
+   if (!head_only)
+     {
+        if (shm_fd >= 0)
+          {
+            printf("shmfile %s\n", shmfile);
+          }
+        else
+          {
+             // could also to "tmpfile %s\n" like shmfile but just
+             // a mmaped tmp file on the system
+             printf("data\n");
+             fwrite(data, width * height * sizeof(DATA32), 1, stdout);
+          }
+        shm_free();
+     }
+   else
+     printf("done\n");
+
+   _gst_shutdown();
+   fflush(stdout);
+   return 0;
+}
diff --git a/src/generic/evas/gst/main_0_10.c b/src/generic/evas/gst/main_0_10.c
new file mode 100644 (file)
index 0000000..3e0c02b
--- /dev/null
@@ -0,0 +1,278 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <gst/gst.h>
+
+#include <Eina.h>
+
+#include "shmfile.h"
+#include "timeout.h"
+
+#define DATA32  unsigned int
+
+//#define GST_DBG
+
+#ifdef GST_DBG
+#define D(fmt, args...) fprintf(stderr, fmt, ## args)
+#else
+#define D(fmt, args...)
+#endif
+
+#define CAPS "video/x-raw-rgb,bpp=(int)32,depth=(int)32,endianness=(int)4321,red_mask=(int)0x0000ff00, green_mask=(int)0x00ff0000, blue_mask=(int)0xff000000"
+
+static GstElement *pipeline = NULL;
+static GstElement *sink = NULL;
+static gint64      duration = -1;
+
+int   width = 0;
+int   height = 0;
+void *data = NULL;
+
+
+static Eina_Bool
+_gst_init(const char *filename)
+{
+   GstPad              *pad;
+   GstCaps             *caps;
+   GstStructure        *structure;
+   gchar               *descr;
+   gchar               *uri;
+   GError              *error = NULL;
+   GstFormat            format;
+   GstStateChangeReturn ret;
+//   int                  vidstr = 0;
+
+   if (!filename || !*filename)
+     return EINA_FALSE;
+
+   if (!gst_init_check(NULL, NULL, &error))
+     return EINA_FALSE;
+
+   if ((*filename == '/') || (*filename == '~'))
+     {
+        uri = g_filename_to_uri(filename, NULL, NULL);
+        if (!uri)
+          {
+             D("could not create new uri from %s", filename);
+             goto unref_pipeline;
+          }
+     }
+   else
+     uri = strdup(filename);
+
+   D("Setting file %s\n", uri);
+
+   descr = g_strdup_printf("uridecodebin uri=%s ! typefind ! ffmpegcolorspace ! "
+      " appsink name=sink caps=\"" CAPS "\"", uri);
+   pipeline = gst_parse_launch(descr, &error);
+   free(uri);
+
+   if (error != NULL)
+     {
+        D("could not construct pipeline: %s\n", error->message);
+        g_error_free (error);
+        goto gst_shutdown;
+     }
+/* needs gst 1.0+
+ * also only works on playbin objects!!! this is a uridecodebin!
+   g_object_get(G_OBJECT(pipeline),
+                "n-video", &vidstr,
+                NULL);
+   if (vidstr <= 0)
+     {
+        D("no video stream\n");
+        goto gst_shutdown;
+     }
+*/
+   sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
+
+   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
+   switch (ret)
+     {
+     case GST_STATE_CHANGE_FAILURE:
+        D("failed to play the file\n");
+        goto unref_pipeline;
+     case GST_STATE_CHANGE_NO_PREROLL:
+        D("live sources not supported yet\n");
+        goto unref_pipeline;
+     default:
+        break;
+     }
+
+   ret = gst_element_get_state((pipeline), NULL, NULL, GST_CLOCK_TIME_NONE);
+   if (ret == GST_STATE_CHANGE_FAILURE)
+     {
+       D("could not complete pause\n");
+        goto unref_pipeline;
+     }
+
+   format = GST_FORMAT_TIME;
+   gst_element_query_duration (pipeline, &format, &duration);
+   if (duration == -1)
+     {
+       D("could not retrieve the duration, set it to 1s\n");
+        duration = 1 * GST_SECOND;
+     }
+
+   pad = gst_element_get_static_pad(sink, "sink");
+   if (!pad)
+     {
+       D("could not retrieve the sink pad\n");
+        goto unref_pipeline;
+     }
+
+   caps = gst_pad_get_negotiated_caps(pad);
+   if (!caps)
+     goto unref_pad;
+
+   structure = gst_caps_get_structure(caps, 0);
+
+   if (!gst_structure_get_int(structure, "width", &width))
+     goto unref_caps;
+   if (!gst_structure_get_int(structure, "height", &height))
+     goto unref_caps;
+
+   gst_caps_unref(caps);
+   gst_object_unref(pad);
+
+   return EINA_TRUE;
+
+ unref_caps:
+   gst_caps_unref(caps);
+ unref_pad:
+   gst_object_unref(pad);
+ unref_pipeline:
+   gst_element_set_state (pipeline, GST_STATE_NULL);
+   gst_object_unref(pipeline);
+ gst_shutdown:
+   gst_deinit();
+
+   return EINA_FALSE;
+}
+
+static void
+_gst_shutdown()
+{
+   gst_element_set_state (pipeline, GST_STATE_NULL);
+   gst_object_unref(pipeline);
+   gst_deinit();
+}
+
+static void
+_gst_load_image(int size_w EINA_UNUSED, int size_h EINA_UNUSED, double pos)
+{
+   GstBuffer *buffer;
+
+   D("load image\n");
+   if (pos >= 0.0)
+     gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
+                             pos * 1000000000.0);
+   else
+     gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
+                             duration / 2);
+   g_signal_emit_by_name(sink, "pull-preroll", &buffer, NULL);
+   D("load image : %p %d\n", GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer));
+
+   shm_alloc(width * height * sizeof(DATA32));
+   if (!shm_addr) return;
+   data = shm_addr;
+
+   memcpy(data, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer));
+}
+
+int
+main(int argc, char **argv)
+{
+   char *file, *p;
+   int i, numonly;
+   int size_w = 0, size_h = 0;
+   int head_only = 0;
+   long long pos = -1.0;
+
+   if (argc < 2) return -1;
+   // file is ALWAYS first arg, other options come after
+   file = argv[1];
+   for (i = 2; i < argc; i++)
+     {
+        if      (!strcmp(argv[i], "-head"))
+           // asked to only load header, not body/data
+           head_only = 1;
+        else if (!strcmp(argv[i], "-key"))
+          {
+             i++;
+             numonly = 1;
+             for (p = argv[i]; *p; p++)
+               {
+                  if ((!*p < '0') || (*p > 9))
+                    {
+                       numonly = 0;
+                       break;
+                    }
+               }
+             if (numonly) pos = (double)(atoll(argv[i])) / 1000.0;
+             i++;
+          }
+        else if (!strcmp(argv[i], "-opt-scale-down-by"))
+          { // not used by ps loader
+             i++;
+             // int scale_down = atoi(argv[i]);
+          }
+        else if (!strcmp(argv[i], "-opt-dpi"))
+          {
+             i++;
+          }
+        else if (!strcmp(argv[i], "-opt-size"))
+          { // not used by ps loader
+             i++;
+             size_w = atoi(argv[i]);
+             i++;
+             size_h = atoi(argv[i]);
+          }
+     }
+
+   timeout_init(10);
+   
+   D("_gst_init_file\n");
+
+   if (!_gst_init(file))
+     return -1;
+   D("_gst_init done\n");
+
+   if (!head_only)
+     {
+        _gst_load_image(size_w, size_h, pos);
+     }
+
+   D("size...: %ix%i\n", width, height);
+   D("alpha..: 0\n");
+
+   printf("size %i %i\n", width, height);
+   printf("alpha 0\n");
+
+   if (!head_only)
+     {
+        if (shm_fd >= 0)
+          {
+            printf("shmfile %s\n", shmfile);
+          }
+        else
+          {
+             // could also to "tmpfile %s\n" like shmfile but just
+             // a mmaped tmp file on the system
+             printf("data\n");
+             fwrite(data, width * height * sizeof(DATA32), 1, stdout);
+          }
+        shm_free();
+     }
+   else
+     printf("done\n");
+
+   _gst_shutdown();
+   fflush(stdout);
+   return 0;
+}