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 732945 - giosink: Won't work with mp4mux
giosink: Won't work with mp4mux
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
1.2.4
Other Linux
: Normal normal
: 1.3.91
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks: 732790
 
 
Reported: 2014-07-09 11:18 UTC by Phillip Wood
Modified: 2014-07-11 08:01 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Phillip Wood 2014-07-09 11:18:38 UTC
A sound-juicer user has reported that they cannot play the m4a files it creates (bug 732790). I think this is due to a problem with encodebin which sound-juicer uses for the encoding. Attachment 280079 [details] has a debug log from sound-juicer. The debug log contains a number of warnings from qtdemux that there are errors in the stream, I'm not sure what is creating the qtdmux element though as it seems to be logging from a different thread to the encoding elements. Attachment 280218 [details] shows the pipeline used to encode the broken file. I'm using gstreamer 1.2.4

Encoding with 

gst-launch-1.0 cdda://1 ! faac ! mp4mux ! filesink location=/tmp/works.m4a

gives playable files. Trying to play the file created with sound-juicer with

gst-launch --gst-debug=*:3 playbin uri=file:///tmp/broken.m4a

gives

Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
0:00:00.906184341 31045 0x7f5b200ef8a0 WARN                 qtdemux qtdemux.c:3060:gst_qtdemux_loop_state_header:<qtdemux0> warning: Invalid atom size.
0:00:00.906372365 31045 0x7f5b200ef8a0 WARN                 qtdemux qtdemux.c:3060:gst_qtdemux_loop_state_header:<qtdemux0> warning: Header atom 'mdat' has empty length
WARNING: from element /GstPlayBin:playbin0/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstQTDemux:qtdemux0: Invalid atom size.
Additional debug info:
qtdemux.c(3060): gst_qtdemux_loop_state_header (): /GstPlayBin:playbin0/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstQTDemux:qtdemux0:
Header atom 'mdat' has empty length
0:00:00.907121823 31045 0x7f5b200ef8a0 WARN                 qtdemux qtdemux.c:573:gst_qtdemux_post_no_playable_stream_error:<qtdemux0> error: This file contains no playable streams.
0:00:00.907239922 31045 0x7f5b200ef8a0 WARN                 qtdemux qtdemux.c:573:gst_qtdemux_post_no_playable_stream_error:<qtdemux0> error: no known streams found
ERROR: from element /GstPlayBin:playbin0/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstQTDemux:qtdemux0: This file contains no playable streams.
Additional debug info:
qtdemux.c(573): gst_qtdemux_post_no_playable_stream_error (): /GstPlayBin:playbin0/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0/GstQTDemux:qtdemux0:
no known streams found
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
0:00:00.910067438 31045 0x7f5b200ef8a0 WARN                 qtdemux qtdemux.c:573:gst_qtdemux_post_no_playable_stream_error:<qtdemux0> error: This file contains no playable streams.
0:00:00.910186418 31045 0x7f5b200ef8a0 WARN                 qtdemux qtdemux.c:573:gst_qtdemux_post_no_playable_stream_error:<qtdemux0> error: no known streams found
Freeing pipeline ...

VLC and mplayer also refuse to play the file

The files created by sound-juicer and gst-launch are very similar, diffing their hexdumps gives

diff works.hex broken.hex 
3c3
< 00000020  00 00 00 08 66 72 65 65  00 17 56 d7 6d 64 61 74  |....free..V.mdat|
---
> 00000020  00 00 00 01 6d 64 61 74  00 00 00 00 00 00 00 00  |....mdat........|
95601,95602c95601,95602
< 00175700  00 98 61 6d 6f 6f 76 00  00 00 6c 6d 76 68 64 00  |..amoov...lmvhd.|
< 00175710  00 00 00 cf e1 77 b9 cf  e1 77 b9 00 00 03 e8 00  |.....w...w......|
---
> 00175700  00 99 5e 6d 6f 6f 76 00  00 00 6c 6d 76 68 64 00  |..^moov...lmvhd.|
> 00175710  00 00 00 cf e1 d7 d0 cf  e1 d7 d0 00 00 03 e8 00  |................|
95609c95609
< 00175780  6b 68 64 00 00 00 07 cf  e1 77 b9 cf e1 77 b9 00  |khd......w...w..|
---
> 00175780  6b 68 64 00 00 00 07 cf  e1 d7 d0 cf e1 d7 d0 00  |khd.............|
95615,95616c95615,95616
< 001757e0  00 00 20 6d 64 68 64 00  00 00 00 cf e1 77 b9 cf  |.. mdhd......w..|
< 001757f0  e1 77 b9 00 00 ac 44 00  4a f0 00 00 00 00 00 00  |.w....D.J.......|
---
> 001757e0  00 00 20 6d 64 68 64 00  00 00 00 cf e1 d7 d0 cf  |.. mdhd.........|
> 001757f0  e1 d7 d0 00 00 ac 44 00  4a f0 00 00 00 00 00 00  |......D.J.......|
95628,95629c95628,95629
< 001758b0  03 19 00 01 00 04 11 40  15 00 00 00 00 00 00 00  |.......@........|
< 001758c0  00 01 ad 37 05 02 12 10  06 01 02 00 00 00 18 73  |...7...........s|
---
> 001758b0  03 19 00 01 00 04 11 40  15 00 00 00 00 02 af b7  |.......@........|
> 001758c0  00 01 b1 7d 05 02 12 10  06 01 02 00 00 00 18 73  |...}...........s|
98033c98033
< 0017ef00  17 55 d8 00 00 00 5d 75  64 74 61 00 00 00 55 6d  |.U....]udta...Um|
---
> 0017ef00  17 55 d8 00 00 01 5a 75  64 74 61 00 00 01 52 6d  |.U....Zudta...Rm|
Comment 1 Sebastian Dröge (slomo) 2014-07-09 11:50:27 UTC
Use the -e parameter on gst-launch to properly shut down the pipeline. Without that the headers of the MP4 file will not be rewritten and are broken.

In your own application you would implement the same by first sending on EOS event to the pipeline, then waiting for the EOS message from the pipeline... and only then shut down the pipeline (i.e. set it to READY or NULL state).
Comment 2 Phillip Wood 2014-07-09 13:12:23 UTC
(In reply to comment #1)
> Use the -e parameter on gst-launch to properly shut down the pipeline. Without
> that the headers of the MP4 file will not be rewritten and are broken.

I'm confused by this as the file created by gst-launch was not broken and played fine.

> In your own application you would implement the same by first sending on EOS
> event to the pipeline, then waiting for the EOS message from the pipeline...
> and only then shut down the pipeline (i.e. set it to READY or NULL state).

Thanks, I'll have a look, I thought we got an EOS message at the end of each track which we listen for to shut down the pipeline but I need to check exactly what's happening there.
Comment 3 Phillip Wood 2014-07-09 14:46:45 UTC
(In reply to comment #2)
> > In your own application you would implement the same by first sending on EOS
> > event to the pipeline, then waiting for the EOS message from the pipeline...
> > and only then shut down the pipeline (i.e. set it to READY or NULL state).
> 
> Thanks, I'll have a look, I thought we got an EOS message at the end of each
> track which we listen for to shut down the pipeline but I need to check exactly
> what's happening there.

At the moment sound-juicer does
  priv->pipeline = gst_pipeline_new ("pipeline");
  bus = gst_element_get_bus (priv->pipeline);
  gst_bus_add_signal_watch (bus);
  g_signal_connect (bus, "message::eos", G_CALLBACK (eos_cb), extractor);
/* create pipeline elelments, add them to the pipeline and link them */
  state_ret = gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);

in eos_cb it does
  gst_element_set_state (priv->pipeline, GST_STATE_NULL);

So it sets the pipeline to GST_STATE_PLAYING and waits for the eos message at the end of the track and then sets the pipeline state to GST_STATE_NULL. I'm not sure what should it be doing differently as it only sets the pipeline to GST_STATE_NULL when it gets an eos message so surely the pipeline should shut down properly and the MP4 file headers written?
Comment 4 Nicolas Dufresne (ndufresne) 2014-07-09 15:07:51 UTC
Can you provide the encodebin profile. Notice this:

0:00:19.077658053 27666 0x7f8670004cf0 WARN                   qtmux gstqtmux.c:1649:gst_qt_mux_start_file:<muxer> downstream did not handle seeking query
0:00:19.077709467 27666 0x7f8670004cf0 WARN                   qtmux gstqtmux.c:1658:gst_qt_mux_start_file:<muxer> warning: Downstream is not seekable and headers can't be rewritten

Also notice that sound-juicer uses giosink, not filesink. Can you test case (need to write it in C or Python) a muxing pipeline with giosink. Might be where the problem is. I'm not familiar with seeking a sink, but I think that's what mp4mux. For mp4 we put the header and index at the start, hence we need to seek back in the file at EOS, and prepend that data. It is likely that giosink is missing this feature. But I'm pretty much guessing at the moment.
Comment 5 Phillip Wood 2014-07-09 15:40:48 UTC
(In reply to comment #4)
> Can you provide the encodebin profile.

[profile-m4a]
name = m4a
description = MPEG 4 Audio
format = video/quicktime, variant=iso
type = container

[streamprofile-m4a-1]
parent = m4a
type = audio
format = audio/mpeg, mpegversion=4, stream-format=raw
presence = 1


> Notice this:
> 
> 0:00:19.077658053 27666 0x7f8670004cf0 WARN                   qtmux
> gstqtmux.c:1649:gst_qt_mux_start_file:<muxer> downstream did not handle seeking
> query
> 0:00:19.077709467 27666 0x7f8670004cf0 WARN                   qtmux
> gstqtmux.c:1658:gst_qt_mux_start_file:<muxer> warning: Downstream is not
> seekable and headers can't be rewritten
> 
> Also notice that sound-juicer uses giosink, not filesink. Can you test case
> (need to write it in C or Python) a muxing pipeline with giosink. Might be
> where the problem is. I'm not familiar with seeking a sink, but I think that's
> what mp4mux. For mp4 we put the header and index at the start, hence we need to
> seek back in the file at EOS, and prepend that data. It is likely that giosink
> is missing this feature. But I'm pretty much guessing at the moment.

Thanks, I think you're right. I just changed the sound-juicer pipeline to use faac ! mp4mux instead of encodebin and I get the same error so it looks like giosink is the problem. For mp3 encoding xingmux manages to put the Xing header at the front of the file with giosink though.
Comment 6 Nicolas Dufresne (ndufresne) 2014-07-09 16:34:59 UTC
Note, GstGioBaseSink do support seeking, so there might be another bug.
Comment 7 Sebastian Dröge (slomo) 2014-07-09 16:42:25 UTC
This was fixed already some time ago, it also caused problems for gnome-sound-recorder. The fix will be in 1.4.

commit e8d176c20c6bbde070701bf029913a4fa930e51f
Author: Sebastian Dröge <sebastian@centricular.com>
Date:   Fri Apr 25 17:32:59 2014 +0200

    giobasesink: Implement handling of the SEEKING query
Comment 8 Nicolas Dufresne (ndufresne) 2014-07-09 17:08:59 UTC
As there is no related bug.