Commit graph

112 commits

Author SHA1 Message Date
Aurélien Zanelli
d87177b69b mpegtspacketizer: handle early PTS conversion when a group has been found
In some cases, the PTS might be smaller than the first observed PCR
value which causes element to apply wraparound leading to bogus
timestamp. To solve this, we only apply it if the PTS-PCR difference is
greater that 1 second to be sure that it's a real wraparound.

Moreover, using unsigned 32 bits values to handle wrapover could end up
with bogus value, so it use pts value to handle it.

Also, convert pcr time to gst time before comparing it to pts.
Since refpcr is expressed in PCR time base while pts is expressed in GStreamer
time.

https://bugzilla.gnome.org/show_bug.cgi?id=743259
2016-03-03 00:50:15 +11:00
Reynaldo H. Verdejo Pinochet
86ec812429 Remove unnecessary NULL checks before g_free()
g_free() is NULL-safe
2015-11-18 16:05:42 -08:00
Nicolas Huet
d65d8657e6 mpegtsdemux: fix section_data leak
If packet->payload_unit_start_indicator is true and pointer 0, there is no
discontinuity check. Therefore there could be a previous section not complete
that need to be cleared.

https://bugzilla.gnome.org/show_bug.cgi?id=758010
2015-11-13 09:37:53 +01:00
Jimmy Ohn
365375a1de mpegtspacketizer: fix find_subtable() return value
find_subtable() returns a pointer, so return NULL and
not FALSE when nothing is found.

https://bugzilla.gnome.org/show_bug.cgi?id=748527
2015-04-28 14:48:22 +01:00
Edward Hervey
ed27244c03 mpegtspacketizer: Unify debug statements
Use 0x%04x for PIDs
2015-04-17 16:21:28 +02:00
Ramprakash Jelari
f9e50eee58 mpegtspacketizer: Fix format string compiler warning 2014-11-24 13:34:21 +01:00
Jan Schmidt
068cba5df6 tsparse: Handle backward and discont timestamps better.
Assume that small backward PCR jumps are just from upstream packet
mis-ordering and don't reset timestamp tracking state - assuming that
things will be OK again shortly.

Make the threshold for detecting discont between sequential buffers
configurable and match the smoothing-latency setting on tsparse
to better cope with data bursts.
2014-10-29 23:02:50 +11:00
Edward Hervey
b59a9262c0 tsdemux: GAP detection
All pads of a stream are now added at the beginning. In order to cope with
streams that don't get any data (forever or for a long time) we detect gaps
and push out GAP events when needed.

Cleanups and commenting by Jan Schmidt <jan@centricular.com>

https://bugzilla.gnome.org/show_bug.cgi?id=734040
2014-10-20 12:32:10 +02:00
Jesper Larsen
ff444dbf6d tsdemux: clear mutex resources in dispose
https://bugzilla.gnome.org/show_bug.cgi?id=736390
2014-09-10 18:53:47 +01:00
Sebastian Dröge
54c61efe44 mpegtspacketizer: Store PCR time/byte offsets in 64 bit integers
32 bit integers are going to overflow, especially the PCR offset to
the first PCR will overflow after about 159 seconds. This makes playback
of streams stop at 159 seconds as suddenly the timestamps are starting
again from 0. Now we have a few more years time until it happens again
and 64 bits are too small.
2014-08-05 11:45:55 +02:00
Sebastian Dröge
cb293af93d Revert "mpegtspacketizer: Convert PCR times to GStreamer times before comparing them against 500 * GST_MSECOND"
This reverts commit 9f186c6ab3.

That commit was actually completely wrong, nevermind.
2014-08-05 10:42:28 +02:00
Sebastian Dröge
9f186c6ab3 mpegtspacketizer: Convert PCR times to GStreamer times before comparing them against 500 * GST_MSECOND
Otherwise it will believe to detect PCR gaps already when there's a very small
gap of a few milliseconds, breaking playback of some files.
2014-08-05 10:37:41 +02:00
Thiago Santos
1685c45465 mpegtspacketizer: avoid timestamp overflows
Cause timing to break in the pipeline that can lead to a stall

https://bugzilla.gnome.org/show_bug.cgi?id=733837
2014-08-01 10:37:15 -03:00
Sebastian Dröge
aa6ee77297 mpegtspacketizer: Don't dereference NULL if we have no PCR yet
Can happen sometimes if the duration is requested before we
received enough data with a PCR.
2014-07-03 14:15:36 +02:00
Jan Schmidt
c103f7134b tsdemux: Add locking around mpegtspacketiser groups.
Otherwise occasionally DURATION queries can crash, if they happen at
the wrong moment.
2014-07-03 21:46:28 +10:00
Edward Hervey
22dfd9aef3 mpegts: Unify API : GstMpegts / gst_mpegts_ / GST_*_MPEGTS_
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)
2014-06-25 14:50:05 +02:00
Edward Hervey
97b3382c80 mpegtspacketizer: live: handle pcr/dts discrepancies some more
When wrapover/reset occur, we end up with a small window of time where
the PTS/DTS will still be using the previous/next time-range.

In order not to return bogus values, return GST_CLOCK_TIME_NONE if the
PTS/DTS value to convert differs by more than 15s against the last seen
PCR

https://bugzilla.gnome.org/show_bug.cgi?id=674536
2014-06-13 11:52:15 +02:00
Edward Hervey
fdf9bdf929 mpegtspacketizer: Fix wraparound detection issue
Using 32bit unsigned values for corrected pcr/offset meant that we
potentially ended up in bogus values

Furthermore, refpcr - refpcroffset could end up being negative, which
PCRTIME_TO_GSTTIME() can't handle (and returned a massive positive value)
2014-06-13 11:48:39 +02:00
Edward Hervey
6be887783e mpegtspacketizer: Use first group for handling reference pcr
If _set_current_pcr_offset gets called after a flushing seek, we ended
up using the current group for delta calculation ... whereas we should
be using the first group to calculate shifts.

Also add an early exit if there are no changes to apply
2014-06-11 09:41:50 +02:00
Edward Hervey
6043f7a578 mpegtspacketizer: Fix debug statement 2014-06-10 14:27:53 +02:00
Edward Hervey
8e28f335f4 mpegtspacketizer: Fix duration evaluation in push mode
When working in push mode, we need to be able to evaluate the duration
based on a single group of observations.

To do that we use the current group values
2014-06-10 14:27:01 +02:00
Edward Hervey
a822517ca9 mpegtspacketizer: Handle early PTS conversion
When handling the PTS/DTS conversion in new groups, there's a possibility
that the PTS might be smaller than the first PCR value observed, due to
re-ordering.

When using the current group, only apply the wraparound correction when we
are certain it is one (i.e. differs by more than a second) and not when it's
just a small difference (like out-of-order PTS).

https://bugzilla.gnome.org/show_bug.cgi?id=731088
2014-06-10 13:29:28 +02:00
Jan Schmidt
a86b3d032c mpegtspacketiser: Always initialise packet AFC flags and PCR fields
Also fix a slight typo in a comment about the smoothing algorithm
2014-06-04 21:56:00 +10:00
Sebastian Dröge
516597d5fa mpegtspacketizer: Remove dead code and simplify if statement
CID 1204274
2014-04-22 12:56:54 +02:00
Edward Hervey
f062b78051 mpegtspacketizer: Improve ts_to_offset code
* Search in current pending values first. For CBR streams we can very
  easily end up having just one initial observations and then nothing
  else (since the bitrate doesn't change).
* Use one group whether we are in that group *OR* if there is only
  one group.
* If the group to use isn't closed (points are being accumulated in the
  PCROffsetCurrent), use the latest data available for calculation
* If in the unlikelyness that all of this *still* didn't produce more
  than one data point, just return the initial offset
2014-04-18 16:23:43 +02:00
Vincent Penquerc'h
f255422ec2 mpegtsdemux: catch prev-not-found when inserting in the group list
While this probably should never happen if callers are well behaved,
this avoids a crash if it does. With a warning about it. Unsure if
it'd be better to not add at all, but it should not happen...

Coverity 1139713
2014-04-09 14:13:46 +01:00
Sebastian Dröge
7b2cfa6303 mpegtspacketizer: Fix typo in debug output 2014-03-29 10:33:45 +01:00
Jan Schmidt
bfe2994101 tsdemux: Fix mpegts_packetizer_set_current_pcr_offset()
When adjusting the PCR offset of groups, adjust the correct group
entry from the list - not the current group repeatedly.
2014-03-25 21:40:11 +11:00
Edward Hervey
c229a87ac3 mpegtspacketizer: Fix ts_to_offset beyond last observed PCR
The requested TS might be beyond the last observed PCR. In order to calculate
a coherent offset, we need to use the last and previous-to-last groups.

https://bugzilla.gnome.org/show_bug.cgi?id=721035
2014-02-20 21:52:16 +01:00
Edward Hervey
3e6c1967c9 mpegtspacketizer: Remove or move variable assignments
To where they're needed
2014-02-07 11:54:07 +01:00
Andrey Utkin
0caa4cdfd8 tsdemux: Fix leak of PCROffsetGroup
https://bugzilla.gnome.org/show_bug.cgi?id=722462
2014-01-17 23:08:49 -03:00
Andrey Utkin
4d957e53e4 tsdemux: fix memleak of PCROffsetCurrent
https://bugzilla.gnome.org/show_bug.cgi?id=722145
2014-01-14 10:33:44 +01:00
Matthieu Bouron
84fbc08c25 mpegtsdemux: fix uninitialized variable warning
https://bugzilla.gnome.org/show_bug.cgi?id=710759
2013-10-25 12:26:23 +01:00
Edward Hervey
70d83b323b mpegtspacketizer: Skip packets with corrupted length
This is similar to what we do for packets with payload
2013-10-11 10:34:17 +02:00
Edward Hervey
2762ead5ef mpegtsdemux: New PCR<=>Offset estimation code
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.
2013-09-28 13:15:43 +02:00
Edward Hervey
5017ba84a7 mpegtspacketizer: No longer use a private struct
These are not public headers, it just adds complexity for no reason
2013-09-28 13:15:43 +02:00
Arnaud Vrac
467e0151d3 mpegtspacketizer: rework TS packet sync and extraction
The previous code could enter an infinite loop because the adapter state
could get out of sync with its mapped data state after sync was lost.
The code was pretty confusing so it's been rewritten to be clearer.

The easiest way to reproduce the infinite loop is to use the breakmydata
element before tsdemux to trigger a resync.

https://bugzilla.gnome.org/show_bug.cgi?id=708161
2013-09-27 15:17:24 +02:00
Sudip Jain
27739e8bb6 mpegtspacketizer: Correct condition check for current next indicator
https://bugzilla.gnome.org/show_bug.cgi?id=708106
2013-09-16 11:00:16 +02:00
Tim-Philipp Müller
cf791f6cb0 mpegtsdemux: fix possible read beyond end of buffer when resyncing 2013-08-27 17:05:44 +01:00
Edward Hervey
3b60f88437 mpegtspacketizer: Look harder for next sync position
If ever we lose sync, we were just checking for the next 0x47 marker ...
which might actually happen within a mpeg-ts packet.

Instead check for 3 repeating 0x47 at the expected packet size interval,
which the same logic we use when we initially look for the packet size.
2013-08-02 10:41:25 +02:00
Edward Hervey
c28acaa3c5 mpegtspacketizer: Fix PCR LUT table
We were only resetting the first 512 values of the lookup table instead
of the whole 8192.
This resulted in any PCR PID over 0x0200 ... ending up taking the first PCR
table around :(
2013-08-02 10:41:25 +02:00
Edward Hervey
8c60e42070 mpegtsdemux: Add more flag debugging for PES and TS packets
Helps with debugging issues. And also remove unused variable (opcr)

This will also allow us in the future to properly detect:
* random-access location (to enable keyframe observation and
  potentially seeking
* discont location (to properly handle resets)
* splice location (to properly handle new stream changes)
2013-07-26 08:17:17 +02:00
Edward Hervey
8ca1751f00 mpegtsdemux: Avoid parsing section without enough data
This is actually a workaround (we'll be skipping the upcoming section)

This will only happen for sections where the beginning is located within
the last 8 bytes of a packet (which is the minimum we need to properly
identify any section beginning).

Later we should figure out a way to store those bytes and mark that
some analysis needs to happen. The probability of this happening is
too low for me to care right now and do that fix. There is a good chance
that section will eventually be repeated and won't end up on such border.
2013-07-09 12:25:11 +02:00
Edward Hervey
61b30175b3 mpegtsdemux: Remove unneeded variables
* packet.origts is no longer used since the PCR refactoring done ages ago
* known_packet_size is a duplicate of packet_size != 0
* caps was never used outside of the packetizer
2013-07-09 12:25:11 +02:00
Edward Hervey
f58f13e874 mpegtsdemux: Fix multiple-SI detection/parsing
We had two issues with the previous code:
1) We were badly handling PUSI-flagged packets. We were discarding the
   initial data (if pointer != 0) whereas we should have been accumulating
   it with the previous data (if there was a continuity of course).
   => First series of information loss
2) We were not checking whether there were more sections after the end
   of one (i.e. when the following byte was not a stuff byte).

This fixes those two issues.

Fixes #677443

https://bugzilla.gnome.org/show_bug.cgi?id=677443
2013-07-07 08:29:37 +02:00
Edward Hervey
b7bba5658a mpegtsdemux: Fix compilation with debugging disabling
We previously weren't using that variable ...
2013-07-05 10:57:34 +02:00
Edward Hervey
1f2bb15618 mpegtsdemux: GstMpegTS => GstMpegTs 2013-07-03 14:00:58 +02:00
Edward Hervey
92edd82c86 mpegtsdemux: Switch to MPEG-TS SI library
* Only mpeg-ts section packetization remains.
* Improve code to detect duplicated sections as early as possible
* Add FIXME for various issues that need fixing (but are not regressions)

https://bugzilla.gnome.org/show_bug.cgi?id=702724
2013-07-03 09:17:25 +02:00
Edward Hervey
f9b3b46ab5 mpegtspacketizer: Speed up section parsing
Only create subtables when needed. It was previously creating one every
single time ... to check if one was present.
And speed up code to detect whether a subtable was already present or not.

Overall makes section pushing 2 times faster.
2013-06-24 07:49:34 +02:00
Edward Hervey
9fd7f1c082 mpegtspacketizer: Speedup packet parsing
Avoid using bitshifting where not needed.

Speeds up packet parsing by 3% (this is *the* hotspot of mpeg-ts elements).
2013-06-24 07:49:34 +02:00