diff options
author | Bastien Nocera <hadess@hadess.net> | 2012-07-13 11:52:18 +0100 |
---|---|---|
committer | Bastien Nocera <hadess@hadess.net> | 2012-07-13 13:14:32 +0100 |
commit | de7fca7706bab4a1f6c9eaf2c23b7371839a5ffa (patch) | |
tree | 4bbf43d178c2ac6a9e1aa25ae987ec466dd75cbc /src/gst/totem-gst-pixbuf-helpers.c | |
parent | 9e7f5c3e89184c4d5e71cbb5f709eee919553c64 (diff) | |
download | totem-de7fca7706bab4a1f6c9eaf2c23b7371839a5ffa.tar.gz |
build: Fix pkg-config usage
We shouldn't be concatenating outputs from pkg-config, it ends up
listing libraries twice and making a mess.
This commit also cleans up the dependencies for the thumbnailer,
audio preview and nautilus tabs, as they don't need clutter for
example.
https://bugzilla.gnome.org/show_bug.cgi?id=679461
Diffstat (limited to 'src/gst/totem-gst-pixbuf-helpers.c')
-rw-r--r-- | src/gst/totem-gst-pixbuf-helpers.c | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/src/gst/totem-gst-pixbuf-helpers.c b/src/gst/totem-gst-pixbuf-helpers.c new file mode 100644 index 000000000..54ca32522 --- /dev/null +++ b/src/gst/totem-gst-pixbuf-helpers.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2003-2007 the GStreamer project + * Julien Moutte <julien@moutte.net> + * Ronald Bultje <rbultje@ronald.bitfreak.net> + * Copyright (C) 2005-2008 Tim-Philipp Müller <tim centricular net> + * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk> + * Copyright © 2009 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * The Totem project hereby grant permission for non-gpl compatible GStreamer + * plugins to be used and distributed together with GStreamer and Totem. This + * permission is above and beyond the permissions granted by the GPL license + * Totem is covered by. + * + * Monday 7th February 2005: Christian Schaller: Add exception clause. + * See license_change file for details. + * + */ + +#include "totem-gst-pixbuf-helpers.h" + +#include <gst/tag/tag.h> +#include <gst/video/video-format.h> + +static void +destroy_pixbuf (guchar *pix, gpointer data) +{ + gst_sample_unref (GST_SAMPLE (data)); +} + +GdkPixbuf * +totem_gst_playbin_get_frame (GstElement *play) +{ + GstStructure *s; + GstSample *sample = NULL; + GdkPixbuf *pixbuf; + GstCaps *to_caps, *sample_caps; + gint outwidth = 0; + gint outheight = 0; + GstMemory *memory; + GstMapInfo info; + + g_return_val_if_fail (play != NULL, NULL); + g_return_val_if_fail (GST_IS_ELEMENT (play), NULL); + + /* our desired output format (RGB24) */ + to_caps = gst_caps_new_simple ("video/x-raw", + "format", G_TYPE_STRING, "RGB", + /* Note: we don't ask for a specific width/height here, so that + * videoscale can adjust dimensions from a non-1/1 pixel aspect + * ratio to a 1/1 pixel-aspect-ratio. We also don't ask for a + * specific framerate, because the input framerate won't + * necessarily match the output framerate if there's a deinterlacer + * in the pipeline. */ + "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, + NULL); + + /* get frame */ + g_signal_emit_by_name (play, "convert-sample", to_caps, &sample); + gst_caps_unref (to_caps); + + if (!sample) { + GST_DEBUG ("Could not take screenshot: %s", + "failed to retrieve or convert video frame"); + g_warning ("Could not take screenshot: %s", + "failed to retrieve or convert video frame"); + return NULL; + } + + sample_caps = gst_sample_get_caps (sample); + if (!sample_caps) { + GST_DEBUG ("Could not take screenshot: %s", "no caps on output buffer"); + g_warning ("Could not take screenshot: %s", "no caps on output buffer"); + return NULL; + } + + GST_DEBUG ("frame caps: %" GST_PTR_FORMAT, sample_caps); + + s = gst_caps_get_structure (sample_caps, 0); + gst_structure_get_int (s, "width", &outwidth); + gst_structure_get_int (s, "height", &outheight); + if (outwidth <= 0 || outheight <= 0) + goto done; + + memory = gst_buffer_get_memory (gst_sample_get_buffer (sample), 0); + gst_memory_map (memory, &info, GST_MAP_READ); + + /* create pixbuf from that - use our own destroy function */ + pixbuf = gdk_pixbuf_new_from_data (info.data, + GDK_COLORSPACE_RGB, FALSE, 8, outwidth, outheight, + GST_ROUND_UP_4 (outwidth * 3), destroy_pixbuf, sample); + + gst_memory_unmap (memory, &info); + +done: + if (!pixbuf) { + GST_DEBUG ("Could not take screenshot: %s", "could not create pixbuf"); + g_warning ("Could not take screenshot: %s", "could not create pixbuf"); + gst_sample_unref (sample); + } + + return pixbuf; +} + +static GdkPixbuf * +totem_gst_buffer_to_pixbuf (GstBuffer *buffer) +{ + GdkPixbufLoader *loader; + GdkPixbuf *pixbuf = NULL; + GError *err = NULL; + GstMemory *memory; + GstMapInfo info; + + memory = gst_buffer_get_memory (buffer, 0); + if (!memory) { + GST_WARNING("could not get memory for buffer"); + return NULL; + } + + if (!gst_memory_map (memory, &info, GST_MAP_READ)) { + GST_WARNING("could not map memory buffer"); + return NULL; + } + + loader = gdk_pixbuf_loader_new (); + + if (gdk_pixbuf_loader_write (loader, info.data, info.size, &err) && + gdk_pixbuf_loader_close (loader, &err)) { + pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + if (pixbuf) + g_object_ref (pixbuf); + } else { + GST_WARNING("could not convert tag image to pixbuf: %s", err->message); + g_error_free (err); + } + + g_object_unref (loader); + + gst_memory_unmap (memory, &info); + + return pixbuf; +} + +static const GValue * +totem_gst_tag_list_get_cover_real (GstTagList *tag_list) +{ + const GValue *cover_value = NULL; + guint i; + + for (i = 0; ; i++) { + const GValue *value; + GstSample *sample; + const GstStructure *caps_struct; + int type; + + value = gst_tag_list_get_value_index (tag_list, + GST_TAG_IMAGE, + i); + if (value == NULL) + break; + + + sample = gst_value_get_sample (value); + caps_struct = gst_sample_get_info (sample); + gst_structure_get_enum (caps_struct, + "image-type", + GST_TYPE_TAG_IMAGE_TYPE, + &type); + if (type == GST_TAG_IMAGE_TYPE_UNDEFINED) { + if (cover_value == NULL) + cover_value = value; + } else if (type == GST_TAG_IMAGE_TYPE_FRONT_COVER) { + cover_value = value; + break; + } + } + + return cover_value; +} + +GdkPixbuf * +totem_gst_tag_list_get_cover (GstTagList *tag_list) +{ + const GValue *cover_value; + + g_return_val_if_fail (tag_list != NULL, FALSE); + + cover_value = totem_gst_tag_list_get_cover_real (tag_list); + /* Fallback to preview */ + if (!cover_value) { + cover_value = gst_tag_list_get_value_index (tag_list, + GST_TAG_PREVIEW_IMAGE, + 0); + } + + if (cover_value) { + GstBuffer *buffer; + GstSample *sample; + GdkPixbuf *pixbuf; + + sample = gst_value_get_sample (cover_value); + buffer = gst_sample_get_buffer (sample); + pixbuf = totem_gst_buffer_to_pixbuf (buffer); + return pixbuf; + } + + return NULL; +} + +/* + * vim: sw=2 ts=8 cindent noai bs=2 + */ |