After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 726144 - gst_element_query_duration returns false while pipeline paused, even if MP3 has duration tag
gst_element_query_duration returns false while pipeline paused, even if MP3 h...
Status: RESOLVED NOTABUG
Product: GStreamer
Classification: Platform
Component: dont know
1.2.3
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-03-12 02:16 UTC by W. Michael Petullo
Modified: 2014-03-14 02:46 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Simple program that illustrates problem (11.34 KB, application/octet-stream)
2014-03-12 02:16 UTC, W. Michael Petullo
Details

Description W. Michael Petullo 2014-03-12 02:16:31 UTC
Created attachment 271567 [details]
Simple program that illustrates problem

I have some code in dmapd that determines the duration of an MP3, first by calling gst_element_query_duration on a paused pipeline and then calling gst_element_query_duration after having played the pipeline.

It looks like gst_element_query_duration does not identify the duration while paused, even when the MP3 contains a duration tag. Only when I call gst_element_query_duration again after playing the stream for a few seconds, does the function identify the stream's duration.

I stripped down my code (attached). When I run it, I see:

./a.out /var/db/BigDisk/Storage/Music/Dire\ Straits/Dire\ Straits\ -\ On\ The\ Night\ -\ 04\ -\ Romeo\ And\ Juliet.mp3 
found duration 604

** (a.out:20808): WARNING **: Failed to determine duration of file:///var/db/BigDisk/Storage/Music/Dire%20Straits/Dire%20Straits%20-%20On%20The%20Night%20-%2004%20-%20Romeo%20And%20Juliet.mp3 while paused; trying while playing
Comment 1 W. Michael Petullo 2014-03-12 02:26:00 UTC
I meant to also report that gst-launch also finds the duration tag in this file:

$ gst-launch -t uridecodebin uri=file:///var/db/BigDisk/Storage/Music/Dire\ Straits/Dire\ Straits\ -\ On\ The\ Night\ -\ 04\ -\ Romeo\ And\ Juliet.mp3 
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
FOUND TAG      : found by element "id3demux0".
           title: Romeo And Juliet
          artist: Dire Straits
           album: On The Night
    track number: 4
           genre: Rock
container format: ID3 tag
     track count: 10
        duration: 604000000000
Pipeline is PREROLLED ...
FOUND TAG      : found by element "mpegaudioparse0".
     audio codec: MPEG 1 Audio, Layer 3 (MP3)
 nominal bitrate: 128000
FOUND TAG      : found by element "mpegaudioparse0".
         has crc: FALSE
    channel mode: stereo
Setting pipeline to PLAYING ...
FOUND TAG      : found by element "mad0".
           layer: 3
            mode: stereo
        emphasis: none
         bitrate: 128000
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/GstURIDecodeBin:uridecodebin0/GstDecodeBin2:decodebin20/GstMpegAudioParse:mpegaudioparse0: GStreamer encountered a general stream error.
Additional debug info:
gstbaseparse.c(2890): gst_base_parse_loop (): /GstPipeline:pipeline0/GstURIDecodeBin:uridecodebin0/GstDecodeBin2:decodebin20/GstMpegAudioParse:mpegaudioparse0:
streaming stopped, reason not-linked
Execution ended after 244905 ns.
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
Comment 2 Tim-Philipp Müller 2014-03-12 07:06:40 UTC
We tend not to trust duration tags. If you want to fallback to taking the duration from the tags if querying the duration fails, or in general, that's a decision you can make in your application.

Usually querying the duration in paused state should work (this is assuming you wait for preroll, which you do), but the audio parsers will sometimes only try and estimate a duration when they've seen a couple of frames pass through, in order not to give a completely bogus duration for VBR files. That's probably why you don't get a duration here.
Comment 3 W. Michael Petullo 2014-03-12 15:33:07 UTC
I do not want to turn this bug report into a support request, but perhaps it could be an RFE. Is there a way to identify whether an MP3 stream is VBR while in the paused state? If this is the case, could the audio parser provide a duration before playing, and only require a few frames in the case of VBR? What does Ogg/Vorbis do? (I get a duration while paused from this format.)

My problem is that I want to catalog a large number of media files, so I want to assess their duration as quickly as possible (while maintaining a reasonable accuracy). I am not actually playing the files at this point, and I only do so (for some short period of time) when required to assess the duration.
Comment 4 Tim-Philipp Müller 2014-03-12 17:35:08 UTC
With Ogg you get that information because there's a container where oggdemux can get that information from the container bitstream. If you put mp3 into matroska or mp4 or whatever you also get that information reliably every time.

You might be interested in using GstDiscoverer to collect that information (although it is not immune to this of course, but it will try harder to extract it and take more time if required).

You can't know if it's VBR without reading the entire file, or at least quite a few frames.

I
Comment 5 W. Michael Petullo 2014-03-14 02:46:09 UTC
GstDiscoverer is great---thank you for bringing my attention to it.

I am going to close this bug as NOTABUG. Sorry this turned out to be a support request.