<div dir="ltr"><div><div><div>Thanks,<br>I'm using Ubuntu 13.04 amd64 with ppa with gstreamer 1.0.8, using the ppa to avoid bugs.<br><br></div>I gave up on the bus solution since it only over-complicates things and I can achieve the same thing with get_state() which apparently blocks if the previous set_state() returned an async result.<br>
</div>This is the best I came up with, but it still randomly displays wrong duration about a few (mp3) files and I don't know why.<br><br></div>//SOURCE CODE START, the relevant part<br><br><div>for (int i=0; i<vec_size; i++) {<br>
        mtl::io::QtFile *file = (*vec)[i];<br>        <br>        if (file->IsDir()) { // not a sound file<br>            delete file;<br>            continue;<br>        }<br>        <br>        QString uri = "file://" + file->full_path();<br>
        QByteArray arr = uri.toLocal8Bit();<br>        const char *c_uri = arr.data();<br><br>        if (gst_element_set_state(ref, GST_STATE_NULL) != 1) {<br>            MTL_WARN("set_state() failed");<br>            break;<br>
        }<br><br>        g_object_set(G_OBJECT(ref), "uri", c_uri, NULL);<br></div><div>//EXTRA PREPARATION START<br></div><div>        state = gst_element_set_state(ref, GST_STATE_PLAYING);<br>        if (state != GST_STATE_CHANGE_ASYNC) {<br>
            MTL_WARN("Not a GST_STATE_CHANGE_ASYNC");<br>            break;<br>        }<br>        <br>        // wait for set_state to finish<br>        state = gst_element_get_state(ref, &ret1, &ret2, GST_CLOCK_TIME_NONE);<br>
        if (state != GST_STATE_CHANGE_SUCCESS) {<br>            MTL_WARN("get_state() failed");<br>            break;<br>        }<br>        <br>        state = gst_element_set_state(ref, GST_STATE_PAUSED);<br>
        // wait for set_state to finish<br>        if (state == GST_STATE_CHANGE_ASYNC) {<br>            state = gst_element_get_state(ref, &ret1, &ret2, GST_CLOCK_TIME_NONE);<br>            if (state != GST_STATE_CHANGE_SUCCESS) {<br>
                MTL_WARN("get_state() failed");<br>                break;<br>            }<br>        }<br>//EXTRA PREPARATION END<br>        gst_element_query_duration(ref, GST_FORMAT_TIME, &duration);<br>        file->duration_set(duration);<br>
        song_tree->AddSong(file);<br>    }<br></div><div>//SOURCE CODE END<br><br></div><div>What frustrates me is that apparently I have to know about these "extra preparation" steps for such a simple task as querying for duration, worse yet,<br>
if you don't do them gstreamer reports arbitrary durations.<br><br></div><div>As one can see I set two states: to "playing", then to "paused" because if "playing" is skipped I get even more arbitrary duration results.<br>
<br></div><div>What am I doing wrong, can't the API be more intuitive?<br></div><div><div><div><br><br></div></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, Aug 17, 2013 at 8:40 PM, Tim-Philipp Müller <span dir="ltr"><<a href="mailto:t.i.m@zen.co.uk" target="_blank">t.i.m@zen.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Sat, 2013-08-17 at 04:52 +0300, Jiergir Ogoerg wrote:<br>
<br>
Hi,<br>
<br>
> I wanna query a lot of sound files duration in a loop efficiently, so<br>
> instead of waiting in a sub-loop with a sleep method until the query<br>
> succeeds for each given file - I wanna go for the second approach by<br>
> processing the GST_MESSAGE_ASYNC_DONE message on the bus, thus<br>
> bypassing the potential need to do (several) sleep(s) for each sound<br>
> file.<br>
><br>
><br>
> How do I do it properly?<br>
><br>
> The only thing I can think about is launching the files query loop in<br>
> a different thread, from there for each file block on a condition<br>
> variable until I get the async event on the bus on the main thread<br>
> which would fire pthread_cond_signal() to unblock the querying thread<br>
> to query the corresponding file and move on to the next sound file in<br>
> the loop.<br>
><br>
><br>
> Is there a better way to implement this non-sleep approach?<br>
<br>
</div>If you're happy to block, you could simply do:<br>
<br>
 msg = gst_bus_timed_pop_filtered (bus, -1,<br>
     GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);<br>
<br>
which will block until you get an error message or async_done.<br>
<div class="im"><br>
<br>
> How do I know that GST_MESSAGE_ASYNC_DONE isn't fired by some other<br>
> source since gstreamer is multi-threaded and can work with many sound<br>
> sources in parallel so the events on the bus might be rather random,<br>
> right?<br>
<br>
</div>Not sure if I understand this question right. What's your setup exactly?<br>
Do you have multiple pipelines? Or are you trying to process multiple<br>
files in parallel within the same pipeline?<br>
<br>
ASYNC_DONE is part of the preroll mechanism in GStreamer. It is usually<br>
posted by sinks, and aggregated by bins/the pipeline to only be<br>
forwarded once all sinks/children are finished prerolling.<br>
<br>
Cheers<br>
 -Tim<br>
<br>
<br>
_______________________________________________<br>
gstreamer-devel mailing list<br>
<a href="mailto:gstreamer-devel@lists.freedesktop.org">gstreamer-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel</a><br>
</blockquote></div><br></div>