The AVC codec_data has a flaw that it can only accomodate
31 SPS headers, even though H.264 can have 32, and 255 PPS,
when there can be 256 in H.264. When streaming RTP some
clients like to cycle through SPS/PPS ids when changing
configuration and can eventually accumulate a full set.
In that case, we have no choice but to discard one (oldest)
entry, or else the count written into the codec_data is wrong
and downstream decoding failures ensue.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/775>
If we have not received a FU with a start bit set, any subsequent FU
data is not useful at all and would result in an invalid stream.
This case is constructed from multiple requirements in
RFC 3984 Section 5.8 and RFC 7798 Section 4.4.3. Following are excerpts
from RFC 3984 but RFC 7798 contains similar language.
The FU in a single FU case is forbidden:
A fragmented NAL unit MUST NOT be transmitted in one FU; i.e., the
Start bit and End bit MUST NOT both be set to one in the same FU
header.
and dropping is possible:
If a fragmentation unit is lost, the receiver SHOULD discard all
following fragmentation units in transmission order corresponding to
the same fragmented NAL unit.
The jump in seqnum case is supported by this from the specification
instead of implementing the forbidden_zero_bit mangling:
If a fragmentation unit is lost, the receiver SHOULD discard all
following fragmentation units in transmission order corresponding to
the same fragmented NAL unit.
A receiver in an endpoint or in a MANE MAY aggregate the first n-1
fragments of a NAL unit to an (incomplete) NAL unit, even if fragment
n of that NAL unit is not received. In this case, the
forbidden_zero_bit of the NAL unit MUST be set to one to indicate a
syntax violation.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/730>
There is no difference between pushing out a buffer directly
with gst_rtp_base_depayload_push() and returning it from the
process function. The base class will just call _depayload_push()
on the returned buffer as well.
So instead of marshalling buffers through three layers and back,
just push them from one place in handle_nal() and always return
NULL from the process vfunc. This simplifies the code a little.
Also rename _push_fragmentation_unit() to _finish_fragmentation_unit()
for clarity. Push sounds like it means being pushed out, whereas
it might just be pushed into an adapter.
This change has the side-effect that multiple NALs in a single STAP
(such as SPS/PPS) may no longer be pushed out as a single buffer if
we output NALs in byte-stream format (i.e. not aggregate AUs), but
that shouldn't really make any difference to anyone.
Every g_quark_from_static_string() is a hash table lookup serialised
on the global quark lock in GLib. Let's just look up the two quarks
we need once and cache them locally for future use. While we're at it,
add new utility functions for the two most commonly used tags
(audio + video). Make first argument a gpointer so we don't have to
cast and make the code ugly. These are used for logging purposes
only anyway.
Remove calls to gst_pad_has_current_caps() which then go on to call
gst_pad_get_current_caps() as the caps can go to NULL in between. Instead just
use gst_pad_get_current_caps() and check for NULL.
https://bugzilla.gnome.org/show_bug.cgi?id=759539
The payloader didn't copy anything so far, the depayloader copied every
possible meta. Let's make it consistent and just copy all metas without
tags or with only the video tag.
https://bugzilla.gnome.org/show_bug.cgi?id=751774
h264parse does the same, let's keep the behaviour consistent. As we now
include the codec_data inside the stream too here, this causes less caps
renegotiation.
The spec says:
When a picture parameter set NAL unit with a particular value of
pic_parameter_set_id is received, its content replaces the content of the
previous picture parameter set NAL unit, in decoding order, with the same
value of pic_parameter_set_id (when a previous picture parameter set NAL unit
with the same value of pic_parameter_set_id was present in the bitstream).
h264parse does the same and this fixes decoding of some streams with 32 SPS
(or 256 PPS). It is allowed to have SPS ID 0 to 31 (or PPS ID 0 to 255), but
the field in the codec_data for the number of SPS or PPS is only 5 (or 8) bit.
As such, 32 SPS (or 256 PPS) are interpreted as 0 everywhere.
This looks like a mistake in the part of the spec about the codec_data.
For more optimised RTP packet handling: means we don't
need to map the input buffer again but can just re-use
the mapping the base class has already done.
https://bugzilla.gnome.org/show_bug.cgi?id=750235
The marker bit isn't mandatory and we had in place code to guess AU
boundaries by detecting a new picture start. This guessing code
didn't work with interlaced content that has proper marker bits
to indicate the AU boundaries. It was leaking the first field buffer
and producing a corrupted output.
fixes: https://bugzilla.gnome.org/show_bug.cgi?id=728041
encoding name is required in the caps and is a better fit for autoplugging than
the pt value. Hardware manufacturers have a bad habit of skimming through RFCs
and in this case; use unassigned numbers for encoders instead of dynamic
numbers.
In essence, this patch will add support for a lot of Bosch hardware encoders
without breaking autoplugging.
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=639292
These will be picked automatically based on downstream caps now, so
if you want the depayloader to output a specific format, make sure
the element downstream advertises that preference or use a capsfilter
after the depayloader to force it.