[totem] Bug 581249 – Display embedded cover images in audio streams
- From: Philip Withnall <pwithnall src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [totem] Bug 581249 – Display embedded cover images in audio streams
- Date: Sat, 8 Aug 2009 18:35:18 +0000 (UTC)
commit 45f656a13c4c3f0a404724279a63ee520d551b50
Author: Robert Ancell <robert ancell gmail com>
Date: Sat Aug 8 19:28:59 2009 +0100
Bug 581249 â?? Display embedded cover images in audio streams
Display cover images when available. Currently doesn't display cover images
instead of visualisations. Helps: bgo#581249
src/backend/bacon-video-widget-gst-0.10.c | 83 ++++++++++++++++++++++------
1 files changed, 65 insertions(+), 18 deletions(-)
---
diff --git a/src/backend/bacon-video-widget-gst-0.10.c b/src/backend/bacon-video-widget-gst-0.10.c
index 0a9d740..642b269 100644
--- a/src/backend/bacon-video-widget-gst-0.10.c
+++ b/src/backend/bacon-video-widget-gst-0.10.c
@@ -156,6 +156,7 @@ struct BaconVideoWidgetPrivate
guint update_id;
GdkPixbuf *logo_pixbuf;
+ GdkPixbuf *cover_pixbuf; /* stream-specific image */
gboolean media_has_video;
gboolean media_has_audio;
@@ -256,6 +257,8 @@ static void size_changed_cb (GdkScreen *screen, BaconVideoWidget *bvw);
static void bvw_process_pending_tag_messages (BaconVideoWidget * bvw);
static void bvw_stop_play_pipeline (BaconVideoWidget * bvw);
static GError* bvw_error_from_gst_error (BaconVideoWidget *bvw, GstMessage *m);
+static gboolean bvw_check_for_cover_pixbuf (BaconVideoWidget * bvw);
+static const GdkPixbuf * bvw_get_logo_pixbuf (BaconVideoWidget * bvw);
static GtkWidgetClass *parent_class = NULL;
@@ -368,9 +371,12 @@ static void
get_media_size (BaconVideoWidget *bvw, gint *width, gint *height)
{
if (bvw->priv->logo_mode) {
- if (bvw->priv->logo_pixbuf) {
- *width = gdk_pixbuf_get_width (bvw->priv->logo_pixbuf);
- *height = gdk_pixbuf_get_height (bvw->priv->logo_pixbuf);
+ const GdkPixbuf *pixbuf;
+
+ pixbuf = bvw_get_logo_pixbuf (bvw);
+ if (pixbuf) {
+ *width = gdk_pixbuf_get_width (pixbuf);
+ *height = gdk_pixbuf_get_height (pixbuf);
} else {
*width = 0;
*height = 0;
@@ -682,7 +688,10 @@ bacon_video_widget_expose_event (GtkWidget *widget, GdkEventExpose *event)
!bvw->priv->media_has_video && !bvw->priv->show_vfx;
if (bvw->priv->logo_mode || draw_logo) {
- if (bvw->priv->logo_pixbuf != NULL) {
+ const GdkPixbuf *pixbuf;
+
+ pixbuf = bvw_get_logo_pixbuf (bvw);
+ if (pixbuf != NULL) {
/* draw logo here */
GdkPixbuf *logo = NULL;
gint s_width, s_height, w_width, w_height;
@@ -703,8 +712,8 @@ bacon_video_widget_expose_event (GtkWidget *widget, GdkEventExpose *event)
widget->allocation.width,
widget->allocation.height);
- s_width = gdk_pixbuf_get_width (bvw->priv->logo_pixbuf);
- s_height = gdk_pixbuf_get_height (bvw->priv->logo_pixbuf);
+ s_width = gdk_pixbuf_get_width (pixbuf);
+ s_height = gdk_pixbuf_get_height (pixbuf);
w_width = widget->allocation.width;
w_height = widget->allocation.height;
@@ -724,7 +733,7 @@ bacon_video_widget_expose_event (GtkWidget *widget, GdkEventExpose *event)
return TRUE;
}
- logo = gdk_pixbuf_scale_simple (bvw->priv->logo_pixbuf,
+ logo = gdk_pixbuf_scale_simple (pixbuf,
s_width, s_height, GDK_INTERP_BILINEAR);
gdk_draw_pixbuf (win, gtk_widget_get_style (widget)->fg_gc[0], logo,
@@ -1637,6 +1646,9 @@ bvw_update_tags (BaconVideoWidget * bvw, GstTagList *tag_list, const gchar *type
/* clean up */
gst_tag_list_free (tag_list);
+ if (bvw->priv->use_type != BVW_USE_TYPE_METADATA)
+ bvw_check_for_cover_pixbuf (bvw);
+
/* if we're not interactive, we want to announce metadata
* only later when we can be sure we got it all */
if (bvw->priv->use_type == BVW_USE_TYPE_VIDEO ||
@@ -3473,6 +3485,10 @@ bvw_stop_play_pipeline (BaconVideoWidget * bvw)
bvw->priv->buffering = FALSE;
bvw->priv->plugin_install_in_progress = FALSE;
bvw->priv->ignore_messages_mask = 0;
+ if (bvw->priv->cover_pixbuf) {
+ g_object_unref (bvw->priv->cover_pixbuf);
+ bvw->priv->cover_pixbuf = NULL;
+ }
GST_DEBUG ("stopped");
}
@@ -3737,6 +3753,37 @@ bacon_video_widget_get_logo_mode (BaconVideoWidget * bvw)
return bvw->priv->logo_mode;
}
+static gboolean
+bvw_check_for_cover_pixbuf (BaconVideoWidget * bvw)
+{
+ GValue value = { 0, };
+
+ /* for efficiency reasons (decoding of encoded image into pixbuf) we assume
+ * that all potential images come in the same taglist, so once we've
+ * determined the best image/cover, we assume that's really the best one
+ * for this stream, even if more tag messages come in later (this should
+ * not be a problem in practice) */
+ if (bvw->priv->cover_pixbuf)
+ return TRUE;
+
+ bacon_video_widget_get_metadata (bvw, BVW_INFO_COVER, &value);
+ if (G_VALUE_HOLDS_OBJECT (&value)) {
+ bvw->priv->cover_pixbuf = g_value_dup_object (&value);
+ g_value_unset (&value);
+ }
+
+ return (bvw->priv->cover_pixbuf != NULL);
+}
+
+static const GdkPixbuf *
+bvw_get_logo_pixbuf (BaconVideoWidget * bvw)
+{
+ if (bvw_check_for_cover_pixbuf (bvw))
+ return bvw->priv->cover_pixbuf;
+ else
+ return bvw->priv->logo_pixbuf;
+}
+
/**
* bacon_video_widget_pause:
* @bvw: a #BaconVideoWidget
@@ -5441,21 +5488,21 @@ bacon_video_widget_get_metadata_pixbuf (BaconVideoWidget * bvw,
GstBuffer *buffer)
{
GdkPixbufLoader *loader;
- GdkPixbuf *pixbuf;
+ GdkPixbuf *pixbuf = NULL;
+ GError *err = NULL;
loader = gdk_pixbuf_loader_new ();
- if (!gdk_pixbuf_loader_write (loader, buffer->data, buffer->size, NULL)) {
- g_object_unref (loader);
- return NULL;
- }
- if (!gdk_pixbuf_loader_close (loader, NULL)) {
- g_object_unref (loader);
- return NULL;
+
+ if (gdk_pixbuf_loader_write (loader, buffer->data, buffer->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);
}
- pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
- if (pixbuf)
- g_object_ref (pixbuf);
g_object_unref (loader);
return pixbuf;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]