Add gstreamer generic loader

SVN revision: 59925
This commit is contained in:
Vincent Torri 2011-06-03 22:38:13 +00:00
parent 671504094c
commit c4001fcaef
4 changed files with 311 additions and 2 deletions

View File

@ -66,6 +66,18 @@ PKG_CHECK_MODULES([SPECTRE], [libspectre], [have_ps="yes"], [have_ps="no"])
PKG_CHECK_MODULES([LIBRAW], [libraw], [have_raw="yes"], [have_raw="no"])
GST_REQS=0.10.2
GSTPLUG_REQS=0.10.1
GST_MAJORMINOR=0.10
PKG_CHECK_MODULES([GSTREAMER],
[gstreamer-$GST_MAJORMINOR >= $GST_REQS
gstreamer-plugins-base-$GST_MAJORMINOR >= $GSTPLUG_REQS
],
[have_gst="yes"],
[have_gst="no"])
AM_CONDITIONAL(HAVE_GST, test "x${have_gst}" = "xyes")
AM_CONDITIONAL([HAVE_PDF], [test "x${have_poppler}" = "xyes"])
AM_CONDITIONAL([HAVE_PS], [test "x${have_ps}" = "xyes"])
AM_CONDITIONAL(HAVE_RAW, [test "x${have_raw}" = "xyes"])
@ -120,10 +132,11 @@ Makefile
src/Makefile
src/bin/Makefile
src/bin/common/Makefile
src/bin/xcf/Makefile
src/bin/raw/Makefile
src/bin/gst/Makefile
src/bin/pdf/Makefile
src/bin/ps/Makefile
src/bin/raw/Makefile
src/bin/xcf/Makefile
])
AC_OUTPUT
@ -143,6 +156,7 @@ echo "Configuration Options Summary:"
echo
echo "Loaders:"
echo " XCF..................: yes"
echo " Gstreamer............: ${have_gst}"
echo " PDF..................: ${have_poppler}"
echo " PS...................: ${have_ps}"
echo " RAW..................: ${have_raw}"

View File

@ -3,6 +3,10 @@ MAINTAINERCLEANFILES = Makefile.in
SUBDIRS = common \
xcf
if HAVE_GST
SUBDIRS += gst
endif
if HAVE_PDF
SUBDIRS += pdf
endif

View File

@ -0,0 +1,41 @@
MAINTAINERCLEANFILES = Makefile.in
AM_CPPFLAGS = \
-I$(top_srcdir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/bin \
-I$(top_srcdir)/src/bin/common \
-I$(top_srcdir)/src/bin/gst \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
@EINA_CFLAGS@ \
@GSTREAMER_CFLAGS@
bin_PROGRAMS = evas_image_loader.gst
evas_image_loader_gst_SOURCES = \
main.cpp \
$(top_srcdir)/src/bin/common/shmfile.c
evas_image_loader_gst_CFLAGS =
evas_image_loader_gst_LDADD = @GSTREAMER_LIBS@ @EINA_LIBS@ @SHM_OPEN_LIBS@
evas_image_loader_gst_LDFLAGS =
install-data-hook:
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.3g2
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.3gp
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.asf
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.avi
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.mkv
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.mov
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.mp4
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.mpg
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.mpeg
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.mxf
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.nut
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.ogg
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.ogm
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.rm
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.webm
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.weba
ln -sf evas_image_loader.gst $(DESTDIR)$(bindir)/evas_image_loader.wmv

View File

@ -0,0 +1,250 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/mman.h>
#include <fcntl.h>
#include <gst/gst.h>
#include <Eina.h>
#include "shmfile.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;
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 ! 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;
}
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, int size_h)
{
GstBuffer *buffer;
D("load image\n");
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;
int i;
int size_w = 0, size_h = 0;
int head_only = 0;
int page = 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++;
page = atoi(argv[i]);
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]);
}
}
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);
}
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();
return 0;
}