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
|