Re: GStreamermm: Gst::Taglist can not get Gst::TAG_DURATION?



2011-12-08 11:50, Ian Martin skrev:
On 08/12/11 08:53, Phong Cao wrote:

I went through the Gst::TagList reference and it is said that Gst::TagList::get_value(Gst::TAG_DURATION, Glib::ValueBase& value) required the variable "value" to be unsigned 64 bit integer (http://developer.gnome.org/gstreamermm/0.10/namespaceGst.html#ad14290dfbf163092d7a5c64b1cd76aee). So this is part of what I tried:

--
Phong V. Cao


Hi Phong,
I don't know the gstreamer library at all, but I've had to play with GValues.
GValue is used as a type for any unknown data type in Gtk.  The tag list is an enum of labels which can be associated with any data type; they don't play nicely with the usual wrapping procedure.  For example, a  GST_TAG_ARTIST will be a string type; GST_TAG_TRACK_NUMBER is likely an int.  The GValue is a nice trick to work around that, but it appears to be a pain to wrap, and the C++ compiler doesn't like the absence of type safety.

If you're desperate, you could try modifying the gstreamermm source to fix it.  I've had to do this with another library, and managed to get it working with a template ( I am getting out of my depth here and can't guarantee this doesn't fall into the "ugly hack" namespace).
The taglist.h file in gstreamermm source declares 3 versions of get_value:
    bool get_value(Tag tag, Glib::ValueBase& dest) const;
    bool get_value(const Glib::ustring& tag, Glib::ValueBase& dest) const;
     bool get_value(const Glib::ustring& tag, guint index, Glib::ValueBase& dest) const;

To make them work, you could try something like this ( for the first type) in taglist.cc:

template <class ValueType> bool TagList::get_value(Tag tag, ValueType& v)
{
    bool valid_result = get_value(_tag_strings[tag], v);

    if(valid_result) return true;
    return false;
}

appropriately declared in the .h file.

Ian.
Yes, Glib::Value<> is a strange beast.
The default constructor leaves the underlying GValue object uninitialized (the type is unspecified). And that's what Gst::TagList::get_value() requires. So far so good.
Now, if Gst::TagList::get_value() returns false, the GValue object is still uninitialized after the call to get_value(). (See gst_tag_list_copy_value().)

Glib::Value<>'s destructor requires the GValue object to be initialized! Otherwise it prints
   GLib-GObject-CRITICAL **: g_value_unset: assertion `G_IS_VALUE (value)' failed

Thus, if the call
   d_taglist.get_value(Gst::TAG_DURATION, temp_duration)
returns false, you will get the critical message, regardless of the type you've specified for temp_duration. To avoid that, add a line in Dingo::TagReader::getDuration().

unsigned long long Dingo::TagReader::getDuration() {
  Glib::Value<unsigned long long> temp_duration;
 
  if (d_taglist.get_value(Gst::TAG_DURATION, temp_duration)) {
    return temp_duration.get();
  }
  else {
    temp_duration.init(temp_duration.value_type()); // added line
    return 0;
  }
}

Of course none of what I've said explains why d_taglist.get_value(Gst::TAG_DURATION, temp_duration) fails to find the duration. Since I'm not familiar with gstreamer and gstreamermm, I can't explain that. There are some gstreamer bugs talking about duration. I don't know if any of these are relevant:
https://bugzilla.gnome.org/show_bug.cgi?id=550634
https://bugzilla.gnome.org/show_bug.cgi?id=638749

Kjell



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]