rem: if (bvw->priv->last_error_message) g_free (bvw->priv->last_error_message); bvw->priv->last_error_message = g_strdup (error_message);
add: if (!bvw->priv->last_error) { bvw->priv->last_error = g_error_copy (err); }
context: bacon_video_widget_signal_idler (BaconVideoWidget *bvw){  BVWSignal *signal = NULL;  gint queue_length;    g_return_val_if_fail (bvw != NULL, FALSE);  g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), FALSE);    signal = g_async_queue_try_pop (bvw->priv->queue);  if (!signal)    return FALSE;    switch (signal->signal_id)    {      case ASYNC_VIDEO_SIZE:        {          g_signal_emit (G_OBJECT (bvw), bvw_table_signals[SIGNAL_GOT_METADATA], 0, NULL);          if (bvw->priv->auto_resize && !bvw->priv->fullscreen_mode) {            gint w, h;            shrink_toplevel (bvw);            get_media_size (bvw, &w, &h);            totem_widget_set_preferred_size (GTK_WIDGET (bvw), w, h);          } else {            bacon_video_widget_size_allocate (GTK_WIDGET (bvw),					      &GTK_WIDGET (bvw)->allocation);	    /* Uhm, so this ugly hack here makes media loading work for	     * weird laptops with NVIDIA graphics cards... Dunno what the	     * bug is really, but hey, it works. :). */	    gdk_window_hide (GTK_WIDGET (bvw)->window);	    gdk_window_show (GTK_WIDGET (bvw)->window);            bacon_video_widget_expose_event (GTK_WIDGET (bvw), NULL);          }          break;        }      case ASYNC_ERROR:        {          char *error_message = NULL;          gboolean emit = TRUE;                    if (signal->signal_data.error.error)            error_message = signal->signal_data.error.error->message;          if (bvw->priv->last_error_message) {            /* Let's check the latest error message */            if (g_ascii_strcasecmp (error_message,                                    bvw->priv->last_error_message) == 0)              emit = FALSE;          }          if (emit) {            g_signal_emit (G_OBJECT (bvw),                           bvw_table_signals[SIGNAL_ERROR], 0,			   error_message, TRUE, FALSE);                        /* Keep a copy of the last emitted message */            if (bvw->priv->last_error_message)              g_free (bvw->priv->last_error_message);            bvw->priv->last_error_message = g_strdup (error_message);          }                    /* Cleaning the error infos */          if (signal->signal_data.error.error)            g_error_free (signal->signal_data.error.error);          if (signal->signal_data.error.debug_message)            g_free (signal->signal_data.error.debug_message);                    break;        }      case ASYNC_FOUND_TAG:        {          GstTagList *tag_list = signal->signal_data.found_tag.tag_list,		*result;          GstElementFactory *f;          result = gst_tag_list_merge (bvw->priv->tagcache, tag_list,				       GST_TAG_MERGE_APPEND);          if (bvw->priv->tagcache)            gst_tag_list_free (bvw->priv->tagcache);          bvw->priv->tagcache = result;	  if ((f = gst_element_get_factory (signal->signal_data.found_tag.source))) {            const gchar *klass = gst_element_factory_get_klass (f);	    GstTagList **cache = NULL;	    if (g_strrstr (klass, "Video")) {	      cache = &bvw->priv->videotags;	    } else if (g_strrstr (klass, "Audio")) {	      cache = &bvw->priv->audiotags;	    }	    if (cache) {	      result = gst_tag_list_merge (*cache, tag_list,					   GST_TAG_MERGE_APPEND);	      if (*cache)		gst_tag_list_free (*cache);	      *cache = result;	    }	  }          if (tag_list)            gst_tag_list_free (tag_list);          g_signal_emit (G_OBJECT (bvw),			 bvw_table_signals[SIGNAL_GOT_METADATA],			 0, NULL);          break;        }      case ASYNC_NOTIFY_STREAMINFO:        {          g_signal_emit (G_OBJECT (bvw),			 bvw_table_signals[SIGNAL_GOT_METADATA], 0, NULL);          g_signal_emit (bvw, bvw_table_signals[SIGNAL_CHANNELS_CHANGE], 0);          break;        }      case ASYNC_EOS:        {          gst_element_set_state (GST_ELEMENT (bvw->priv->play),                                 GST_STATE_READY);          g_signal_emit (G_OBJECT (bvw), bvw_table_signals[SIGNAL_EOS], 0, NULL);          break;        }      case ASYNC_BUFFERING:        {          g_signal_emit (G_OBJECT (bvw), bvw_table_signals[SIGNAL_BUFFERING],			 0, signal->signal_data.buffering.percent);          break;        }      case ASYNC_REDIRECT:	{	  g_signal_emit (G_OBJECT (bvw), bvw_table_signals[SIGNAL_REDIRECT],			 0, signal->signal_data.redirect.new_location);	  g_free (signal->signal_data.redirect.new_location);	  break;	}      default:        break;    }      g_free (signal);  queue_length = g_async_queue_length (bvw->priv->queue);  return (queue_length > 0);}