<div dir="ltr"><div><div>Thanks, the GstDiscoverer seems just what I need, after like 20 minutes of searching the repos, googling etc<br></div><div>I can't figure out where it's stored and how to install it, looks like Ubuntu doesn't support it.<br>
</div> Do you know what's the package (dev) name I have to install?<br><br></div>In particular, I got libgstreamer1-dev installed, there are no other "-dev" packages related to gstreamer1.0 in Ubuntu.<br><br>
apt-cache search pbutils - yields nothing.<br><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Aug 20, 2013 at 1:23 AM, 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 Mon, 2013-08-19 at 22:25 +0300, Jiergir Ogoerg wrote:<br>
<br>
> I gave up on the bus solution since it only over-complicates things<br>
> and I can achieve the same thing with get_state() which apparently<br>
> blocks if the previous set_state() returned an async result.<br>
<br>
</div>True, that should work as well.<br>
<br>
Btw, you can also use the GstDiscoverer API from GstPbutils in<br>
gst-plugins-base to figure out metadata of files.<br>
<div class="im"><br>
<br>
> This is the best I came up with, but it still randomly displays wrong<br>
> duration about a few (mp3) files and I don't know why.<br>
<br>
</div>Likely because files have a variable bitrate (VBR). Often files are<br>
silent or slow at the beginning (low bitrate) and get more involved<br>
later (higher bitrate). If the parser estimates the duration only based<br>
on the first few frames, you will get a wrong estimate.<br>
<div class="im"><br>
<br>
> //EXTRA PREPARATION START<br>
><br>
>         state = gst_element_set_state(ref, GST_STATE_PLAYING);<br>
<br>
</div>If you don't want to play, PAUSED should be sufficient.<br>
<div class="im"><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,<br>
> 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>
<br>
</div>Might just as well set it to PAUSED from the beginning then and only<br>
wait for that.<br>
<div class="im"><br>
>         // wait for set_state to finish<br>
>         if (state == GST_STATE_CHANGE_ASYNC) {<br>
>             state = gst_element_get_state(ref, &ret1, &ret2,<br>
> 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>
><br>
> //SOURCE CODE END<br>
><br>
><br>
> What frustrates me is that apparently I have to know about these<br>
> "extra preparation" steps for such a simple task as querying for<br>
> duration<br>
<br>
</div>Well, you're using the lowest-level API available, in that case you have<br>
to understand some low-level details of how things work. We generally<br>
try to avoid blocking operations in the application thread, which is<br>
often a GUI thread, that's why things work like they work. However, I<br>
would have expected the gst_element_query_duration() API docs to at<br>
least mention these things (I'm sure I've fixed that up before<br>
somewhere).<br>
<div class="im"><br>
> , worse yet,<br>
> if you don't do them gstreamer reports arbitrary durations.<br>
<br>
</div>I don't think that's true. If you of course fail to initialise the<br>
duration variable, then do a duration query, and then ignore the return<br>
value of that which indicates whether the query succeeded or not, then<br>
you may end up with random values in the duration variable, yes. (I<br>
don't know if that's what's happening in your case, just saying.)<br>
<br>
The issue with unreliable estimates in case of some VBR files is always<br>
a problem and not really related to these "preparation steps" or not. If<br>
you don't do these "preparation steps", it's potluck if the streaming<br>
threads have already done their bit by the time the duration query<br>
executes or not.<br>
<div class="im"><br>
<br>
> As one can see I set two states: to "playing", then to "paused"<br>
> because if "playing" is skipped I get even more arbitrary duration<br>
> results.<br>
<br>
</div>This is just a slightly convoluted way to wait a bit longer and let the<br>
streaming thread process some more data.<br>
<div class="im"><br>
> can't the API be more intuitive?<br>
<br>
</div>You may find the GstDiscoverer API more intuitive.<br>
<div class="HOEnZb"><div class="h5"><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>
</div></div></blockquote></div><br></div>