Search code examples
memorygstreamermux

Record with gstreamer h264 + aac in mp4 produces only partially playable file


I'm trying to building streaming application in gstreamer which a) capture audio and video from live source's b) encode it in h264 and aac and c) save it in file.mp4

I'm using following pipeline to record in file:

gst-launch-1.0 -e --gst-debug=**:4 videotestsrc is-live=true \
! queue ! videoconvert \
! videorate silent=false \
! videoscale \
! "video/x-raw, width=1280, height=720, framerate=25/1" \
! queue ! x264enc speed-preset=3 tune=zerolatency bitrate=3800 key-int-max=0 \
! queue ! muxer.video_0 \
audiotestsrc is-live=true \
! audioconvert ! audioresample ! audiorate ! "audio/x-raw, rate=48000, channels=2" \
! queue ! faac bitrate=128000 rate-control=2 \
! queue ! muxer.audio_0 \
mp4mux name=muxer streamable=true \
! queue ! filesink location="/home/myenc/mystream.mp4" sync=false

Q/Problem:

It seems that there are no problems with given pipeline if we run it for short session e.a. ~1-2 hour(s) or so. But when we run it a bit longer, recording file get broken somewhere around ~4GB in file (equals to physical RAM!?) For example: if we capture 360p 1Mbit then file is playable until 4 hours and if we capture in 720p 4Mbit then file is playable until 1 hour in file.

Did anyone experienced same issue or maybe somebody can reproduce it?

Is this a normal behavior of qt/mp4mux like 'ensonic' mentioned here for example?

Is there a workaround for it?

After a lot of testing I made a hypothesis that it has something to do with physical memory and how mp4mux works. However putting and/or removing extra RAM from machine did not had any affect on broken files(still only playable until 4GB)

Any suggestion, example, point to right direction would be very much appreciated.

Note:

-the only playable recording file after 4GB I was able to generate, is when we DO NOT use any muxer at all (aka byte-stream=true filename.h264)

-or we use mpegtsmux, which doesn't make use of index tables in memory

What I tried:

  • using extra queue's and putting it before/after elements

  • using leaky property in queue

  • using different audio/video sources (decklinksrc, videotestsrc, audiotestsrc)

  • capture Video only, without audio

  • using different audio codec (mp3)

  • using qtmux|mp4mux

  • mp4mux: trying streamable=true, trying faststart=true, trying segmented=2000

  • playing with tune=zerolatency property of x264enc

  • using theoraenc+oggenc+oggmux vs x264enc+faac

  • tested on two different machines with same hardware

info:

OS: Ubuntu 14.04

Gstreamer: 1.4.5 (also tested with 1.3.90)

Proc: i5-3570 @ 3.4Ghz

Ram: 4GB (also tested with 2GB, 8GB)


Solution

  • This question was originally answered by gstreamer-devel mailing list, thanks ) -> link

    Summary:
    There was a bug in gstreamer 'qtmux'(mp4mux) which generated files unplayable after 4GB. After manually applying patch in 1.4.5 my problem was resolved.

    -bug description: https://bugzilla.gnome.org/show_bug.cgi?id=741279
    -patch commit: http://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/?id=2505e343b1cb29541e60afa3418c21b08ded3981