tsparse leaked input buffers quite badly:
GST_TRACERS=leaks GST_DEBUG=GST_TRACER:9 gst-launch-1.0 audiotestsrc num-buffers=3 ! avenc_aac ! mpegtsmux ! tsparse ! fakesink
The input_done vfunc was passed the input buffer, which it had to
consume. For this reason, the base class takes a reference on the buffer
if and only if input_done is not NULL.
Before 34af8ed66a, input_done was used in
tsparse to pass on the input buffer on the "src" pad. That commit
changed the code to packetize for that pad as well and removed the use
of input_done.
Afterwards, 0d2e908523 set input_done
again in order to handle automatic alignment of the output buffers to
the input buffers. However, it ignored the provided buffer and did not
even unref it, causing a leak.
Since no code makes use of the buffer provided with input_done, just
remove the argument in order to simplify things a bit.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1274>
Some mpeg-ts (HLS, DVB, ...) streams out there have completely broken
PCR streams on which we can't reliably recover correct timestamps.
For those, provide a property that will ignore the program PCR stream
(by faking that it's not present (0x1fff)).
This was a regression.
We only have a upstream-id via STREAM_START if we were in push-mode.
In pull-mode we need to create one.
Note: It would be good to eventually have that method (copied from
gst_pad_get_stream_id_internal()) public in the future
For each MpegTSBaseStream, we have a GstStream object which
subclasses can extend with information.
For each program a GstStreamCollection is created with all
GstStream from each stream.
When dealing with TIME-based input, the incoming stream could have
potentially changed completely.
In order to check whether it did or not, we need to re-check all sections
(PAT, PMT...). If it didn't, we will keep using the existing streams/pad,
and if it did we will act as if there was a program switch.
Fixes HLS streaming with decodebin3/playbin3
When the sub-class is delaying deactivation of the old program,
but it has the same program number as the new program, don't
overwrite the old program in the hash table and then steal
the new program back out of it. Instead, add the new program to
the hash table after handling removal of the old one.
When the sub-class claims a program for later freeing, make
sure it's not left in the hash table, or it can cause crashes on shutdown.
Make sure tsdemux frees any program it has kept around at shutdown
if it wasn't freed already.
https://bugzilla.gnome.org/show_bug.cgi?id=763503
tsdemux is not able to handle negative playback rates.
But in mpegtsbase, the same check is not being done.
added a check to not handle negative rate while seeking unless
the same is handled upstream.
https://bugzilla.gnome.org/show_bug.cgi?id=758516
When changing programs, the order of events needs to be the following:
* add pads from new program
* send EOS on old pads
* remove old pads
* emit 'no-more-pads'
Previously tsdemux was not doing that, and was first deactivating and
removing old pads before adding new ones.
We fix this by allowing subclasses of mpegtsbase to be able to handle
themselves the deactivation of programs. In this case tsdemux will
properly deactivate it once it has activated the new program.
https://bugzilla.gnome.org/show_bug.cgi?id=750402
We only want to do a hard reset of the observations if we're working
with TIME segments in push mode. For BYTE segment we want to keep
the observations (in order to do seeks in push-mode).
When in push mode, we want to discard all previous observations from the
mpegtspacketizer when we get a DISCONT buffer.
This avoids trying to calculate bogus timestamps (estimating them using old
PCR observations).
We only do a hard reset in push-mode. In pull-mode we still need the observations
(in order to seek properly)
A new program object is created to replace an existing one
in the programs hash table, so its refcount needs to match.
With the default of 0 refcount on creation, the next PAT
change will cause that refcount to be both incremented and
decremented (assuming the new PAT references that stream too),
which will cause the program to be destroyed.
https://bugzilla.gnome.org/show_bug.cgi?id=748412
Such seeks are used to change playback rate and we do not want
to alter the position in that case, so we bypass the flush/seek
logic, and set things up so a new segment is scheduled to be
regenerated.
https://bugzilla.gnome.org/show_bug.cgi?id=735100
When dealing with random-access content (such as files), we initially
search for the last PCR in order to figure out duration and to handle
other position estimation such as those used in seeking.
Previously, the code looking for that last PCR would search in the last
640kB of the file going forward, and stop at the first PCR encountered.
The problem with that was two-fold:
* It wouldn't really be the last PCR (it would be the first one within
those last 640kB. In case of VBR files, this would put off duration
and seek code slightly.
* It would fail on files with bitrates higher than 52Mbit/s (not common)
Instead this patch modifies that code by:
* Scanning over the last 2048kB (allows to cope with streams up to 160Mbit/s)
* Starts by the end of the file, going over chunks of 300 MPEG-TS packets
* Doesn't stop at the first PCR detected in a chunk, but instead records all
of them, and only stop searching if there was "at least" one PCR within
that chunk
This should improve duration reporting and seeking operations on VBR files
https://bugzilla.gnome.org/show_bug.cgi?id=708532
As a consequence, tsdemux won't remove its pads anymore on EOS.
Fixes the case when mpegtsbase is not able to process new packets
after EOS as the corresponding pids aren't known anymore because
the programs were removed and the pes/psi were kept, preventing the
PAT to be parsed again.
https://bugzilla.gnome.org/show_bug.cgi?id=738695
When the set-timestamps property is set, use PCRs on the provided
(or autodetected) pcr-pid to apply (or replace) timestamps on the
output buffers, using piece-wise linear interpolation.
This allows tsparse to be used to stream an arbitrary mpeg-ts file,
or to smooth jittery reception timestamps from a network stream.
The reported latency is increased to match the smoothing latency if
necessary.
It was previously a mix and match of both variants, introducing just too much
confusion.
The prefix are from now on:
* GstMpegts for structures and type names (and not GstMpegTs)
* gst_mpegts_ for functions (and not gst_mpeg_ts_)
* GST_MPEGTS_ for enums/flags (and not GST_MPEG_TS_)
* GST_TYPE_MPEGTS_ for types (and not GST_TYPE_MPEG_TS_)
The rationale for chosing that is:
* the namespace is shorter/direct (it's mpegts, not mpeg_ts nor mpeg-ts)
* the namespace is one word under Gst
* it's shorter (yah)
When we receive sticky events from upstream, always return TRUE.
Fixes the issue where we receive custom sticky events (such as "uri")
and no pads are created yet.
Doing a hard flush on the packetizer will drop all observations, which
will eventually break push-based seeking (with BYTES segment) since
we won't know where to seek to anymore (new data would always be
considered as the beginning of the stream).
The PAT is related to the stream, we therefore want it cleared along
with anything stream related.
This commented section was from the (old) mpegtsparse and *might* have
been related to speeding up DVB start-up. But we have another plan for that.
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=724716
This allows:
* Better duration estimation
* More accurate PCR location
* Overall more accurate running-time location and calculation
Location and values of PCR are recorded in groups (PCROffsetGroup)
with notable PCR/Offset observations in them (when bitrate changed
for example). PCR and offset are stored as 32bit values to
reduce memory usage (they are differences against that group's
first_{pcr|offset}.
Those groups each contain a global PCR offset (pcr_offset) which
indicates how far in the stream that group is.
Whenever new PCR values are observed, we store them in a sliding
window estimator (PCROffsetGroupCurrent).
When a reset/wrapover/gap is detected, we close the current group with
current values and start a new one (the pcr_offset of that new group
is also calculated).
When a notable change in bitrate is observed (+/- 10%), we record
new values in the current group. This is a compromise between
storing all PCR/offset observations and none, while at the same time
providing better information for running-time<=>offset calculation
in VBR streams.
Whenever a new non-contiguous group is start (due to seeking for example)
we re-evaluate the pcr_offset of each groups. This allows detecting as
quickly as possible PCR wrapover/reset.
When wanting to find the offset of a certain running-time, one can
iterate the groups by looking at the pcr_offset (which in essence *is*
the running-time of that group in the overall stream).
Once a group (or neighbouring groups if the running-time is between two
groups) is found, once can use the recorded values to find the most
accurate offset.
Right now this code is only used in pull-mode , but could also
be activated later on for any seekable stream, like live timeshift
with queue2.
Future improvements:
* some heuristics to "compress" the stored values in groups so as to keep
the memory usage down while still keeping a decent amount of notable
points.
* After a seek compare expected and obtained PCR/Offset and if the
difference is too big, re-calculate position with newly observed
values and seek to that more accurate position.
Note that this code will *not* provide keyframe-accurate seeking, but
will allow a much more accurate PCR/running-time/offset location on
any random stream.
For past (observed) values it will be as accurate as can be.
For future values it will be better than the current situation.
Finally the more you seek, the more accurate your positioning will be.