Gstreamer RTSP & splitmux issues
Will McElderry
wm-gstreamer at switchd.net
Fri Apr 14 14:34:14 UTC 2023
On 12/04/2023 11:22, W McElderry via gstreamer-devel wrote:
> Hi All,
>
>
> First up: Thank you to all those who have contributed to the project
> - it's very useful and appreciated!
>
>
> I've got a complex set of issues when using gstreamer through
> pygobject and gst-launch-1.0 to capture some live RTSP camera streams
> to video files. From what I've read, that doesn't sound very novel!
>
> What I've done with a splitmuxsink/splitmuxsrc to try and mitigate the
> issue may be more interesting as I think that has revealed a bug
> somewhere in the code (though I'd like to lay it out for someone who
> knows more to comment!)
>
>
> Before I dive in: is this type of discussion or is there somewhere
> better?
>
>
> Thanks!
>
>
> Will.
>
Hi All,
I've written this while waiting for a response - and then just decided
to send it. It is large, but I've tried to make it easy to read and
address questions.
*NB:* I have discovered the following using an old gstreamer version
(*1.14.5*) - I cannot upgrade the system, but I'm running the pipeline
again now through docker with 22.04 as a base (*1.20.3*). I haven't
looked at building gstreamer from source.
Here's the story in order:
I'm trying to reliably record data from a group of security cameras
using RTSP/RTP H.264, but it's failing in some cameras/situations.
One set of cameras I'm attempting to capture from is misbehaving - I
believe it is reporting that it is changing it's framerate, even though
it has been manually configured to be 15 FPS. That causes the MP4 mux
to get upset in this pipeline:
WARNING: from element /GstPipeline:pipeline0/GstMP4Mux:mp4mux0: Can't
change input format at runtime.
Additional debug info:
gstqtmux.c(5757): gst_qt_mux_video_sink_set_caps ():
/GstPipeline:pipeline0/GstMP4Mux:mp4mux0: pad video_0 refused
renegotiation to video/x-h264, stream-format=(string)avc,
alignment=(string)au, codec_data=(buffer)<trimmed>, level=(string)3.1,
profile=(string)high, pixel-aspect-ratio=(fraction)1/1, width=(int)1280,
height=(int)720, framerate=(fraction)*7/1*,
interlace-mode=(string)progressive, chroma-format=(string)4:2:0,
bit-depth-luma=(uint)8, bit-depth-chroma=(uint)8, parsed=(boolean)true
sometimes it chooses other framerates too.
*Question 1*: Is there a mux which will handle this better and just
keep right on recording?
*Question (set) 2*: Possible workarounds?
When this happens, it seems like the pipeline halts: no more data is
written to file, the MOOV atom is not written and the process doesn't
terminate until a further sigINT is sent, where it terminates without
wring the MOOV atom.
Consequence is the recording is not useful.
I think I've seen similar issues with the python equivalent
implementation - the EOS is generated, but there is no way to terminate
gracefully anymore. Is that the case, or am I missing something? Does
that constitute a bug or a feature?
The primary work-a-round I came up with was to use --gst-fatal-warnings,
but that doesn't terminate the process whie using the -e flag too.
Perhaps that constitutes a bug, even if the MOOV atom not being written
may not be?
*Update:* since writing the above, I've discovered mp4mux settings for
reserved-duration-remaining and reserved-moov-update-period which seem
to ensure I end up with a valid file. I'm interested by
moov-recovery-file, don't know how to make it work and note it is
'experimental'. Any comments appreciated!
(Written before the update above) To minimise the impact of the issue, I
decided to use a tee and splitmuxsink so I'd have some valid data close
to the point the issue occurred, or the whole file if no issue occurred
as before:
For clarity pipeline described by:
gst-launch-1.0 --gst-fatal-warnings -e rtspsrc "location=${URI}" ! \
rtpjitterbuffer ! \
queue ! \
rtph264depay ! \
h264parse ! \
tee name=t ! \
t. ! \
splitmuxsink location=${FILE}.%05d max-size-time=$((60*1000000000)\
t. ! \
mp4mux ! \
filesink "location=${FILE}" &
#aside: I'm not sure of the impact of the rtpjitterbuffer - is this
embedded within the rtspsrc, which seems to be a bin?
I tested the system and in time I saw a similar issue and attempted to
use the split files to recover, then I discovered some situations (A,B
and C below) I didn't expect that /may/ indicate something is wrong (or
may be just my knowledge/use, but in case it's useful here we go)
A) Reassembling splits does not produce the same output as the
monolithic file:
(NB: this situation persists when running with *1.20.3*, though input
files were created with *1.14.5*)
Looking at the duration of the combined file and the original capture,
it is clear these are not the same as the duration is shorter for the
recombined file.
*Question 3:* Probably my limited understanding, but is it expected that
reassembling a large h264 stream from a set of split files would yield a
different output to storing the same h264 stream from an RTSP/RTP server
directly?
B) Splitting the monolithic file does not recreate matching split files
(NB: this situation persists when running with *1.20.3*, though
monolithic input file was created with *1.14.5*)
Taking the monolithic MP4 file instead of the rtspsrc and using the same
command to repackage the encapsulated h264 stream through a splitmuxsink
with the same parameters produces a different number of split files, so
they must have different content.
As I'm not transcoding this is a bit of a surprise: I thought the h264
stream cannot be changed during this process and the information about
splitting files would be deterministically derived from information
embedded within the h264 stream, so I cannot see how this can happen.
*Question 4:* Probably my limited understanding, but is that expected?
C) Sometimes the split files cannot be successfully recombined
(NB: this situation persists when running with *1.20.3*, though input
files were created with *1.14.5*)
Given that all split files are derived from one stream that seems to
play normally, and the individual split files seem to 'play' normally
(using splitmuxsrc location=${single_file}), I'm surprised that when
using splitmuxsrc location=${multifile_glob} they can reliably produce
errors (mp4mux: Buffer has no PTS.)
*Question 5:* Does that make sense in some way?
Any other tips to improve reliable recordings greatly appreciated!
I'll send through any more technical details I can if they're deemed
useful (though I cannot send any actual data captured - best I can do is
debug logs, carefully reviewed).
Thanks for your time!
Will.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20230414/72497b8a/attachment.htm>
More information about the gstreamer-devel
mailing list