gst_element_query_duration() fails for certain filetypes

Nate Bogdanowicz natezb at stanford.edu
Sun Jan 27 12:11:40 PST 2013


Hello,

I would like to use gst_element_query_duration() for determining the length
of music files for use in a larger project that I am using GStreamer for.
The problem is, it succeeds for some filetypes and succeeds for others.
I've tried with multiple sets of music files and as far as I can tell, the
query will fail solely depending on the filetype, not on the specific file
that is used. Specifically, it works for MP3 and FLAC, while it fails for
Ogg Vorbis and M4A (AAC). I have the proper codecs/plugins installed, as I
am able to *play* all of the files via GStreamer, just not query their
duration. Also, I am sure that the pipeline is properly set to
GST_STATE_PAUSED in all cases, as my code verifies this. I've written some
sample code that reproduces my problem and included it below:

#include <stdio.h>
#include <gst/gst.h>
#include <gst/app/gstappsink.h>

void on_pad_added(GstElement *dec, GstPad *pad, GstElement *element)
{
    (void) dec;
    GstPad *sinkpad;

    sinkpad = gst_element_get_static_pad(element, "sink");
    if(!gst_pad_is_linked(sinkpad)) {
        if(gst_pad_link(pad, sinkpad) != GST_PAD_LINK_OK) {
            // Failed to link pads
            fprintf(stderr, "Failed to link pads!\n");
        }
    }

    gst_object_unref(sinkpad);
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Error: format should be \"%s path_to_song\"\n",
argv[0]);
        exit(1);
    }

    GstElement *pipe, *dec, *conv, *sink;
    gst_init(NULL, NULL);

    /* Create pipeline and elements */
    pipe = gst_pipeline_new("pipeline");
    dec = gst_element_factory_make("uridecodebin", NULL);
    conv = gst_element_factory_make("audioconvert", NULL);
    sink = gst_element_factory_make("appsink", NULL);

    /* Set up capabilities filtering */
    GstCaps *caps = gst_caps_new_simple("audio/x-raw-float", "width",
G_TYPE_INT, sizeof(double)*8, NULL);
    gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
    gst_caps_unref(caps);

    /* Add everything to the pipeline and link up static pads */
    gst_bin_add_many(GST_BIN(pipe), dec, conv, sink, NULL);
    gst_element_link(conv, sink);

    /* Set up callback to link the decoder's dynamic pad tot he converter */
    g_signal_connect(dec, "pad_added", G_CALLBACK(on_pad_added), conv);

    /* Set the uridecodebin's filename */
    gst_element_set_state(pipe, GST_STATE_NULL);
    g_object_set(G_OBJECT(dec), "uri", gst_filename_to_uri(argv[1], NULL),
NULL);

    gst_element_set_state(pipe, GST_STATE_PAUSED);
    GstStateChangeReturn res = gst_element_get_state(pipe, NULL, NULL,
((GstClockTime)1e9));
    if (res != GST_STATE_CHANGE_SUCCESS) {
        fprintf(stderr, "State change failed!\n");
        exit(1);
    }

    gint64 duration;
    GstFormat format = GST_FORMAT_DEFAULT;

    if (gst_element_query_duration(GST_ELEMENT(dec), &format, &duration)) {
        printf("duration = %d\n", duration);
    } else {
        printf("The query could not be performed!\n");
    }
}


I am running Arch Linux and building this example with gstreamer-0.10.

Thanks for your help,
Nate Bogdanowicz
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20130127/ba353794/attachment.html>


More information about the gstreamer-devel mailing list