mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
rtph264depay: Warn when max SPS/PPS are collected in AVC mode.
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>
This commit is contained in:
parent
63c7a9ae43
commit
2623404744
1 changed files with 27 additions and 5 deletions
|
@ -351,7 +351,7 @@ gst_rtp_h264_set_src_caps (GstRtpH264Depay * rtph264depay)
|
|||
guint8 *data;
|
||||
guint len;
|
||||
guint new_size;
|
||||
guint i;
|
||||
guint i, first_sps, num_sps, first_pps, num_pps;
|
||||
guchar level = 0;
|
||||
guchar profile_compat = G_MAXUINT8;
|
||||
|
||||
|
@ -392,11 +392,22 @@ gst_rtp_h264_set_src_caps (GstRtpH264Depay * rtph264depay)
|
|||
|
||||
/* 6 bits reserved | 2 bits lengthSizeMinusOn */
|
||||
*data++ = 0xff;
|
||||
|
||||
if (rtph264depay->sps->len > 31) {
|
||||
GST_WARNING_OBJECT (rtph264depay,
|
||||
"Too many SPS to put in codec_data. Sending the most recent 31");
|
||||
num_sps = 31;
|
||||
first_sps = rtph264depay->sps->len - 31;
|
||||
} else {
|
||||
num_sps = rtph264depay->sps->len;
|
||||
first_sps = 0;
|
||||
}
|
||||
|
||||
/* 3 bits reserved | 5 bits numOfSequenceParameterSets */
|
||||
*data++ = 0xe0 | (rtph264depay->sps->len & 0x1f);
|
||||
*data++ = 0xe0 | (num_sps & 0x1f);
|
||||
|
||||
/* copy all SPS */
|
||||
for (i = 0; i < rtph264depay->sps->len; i++) {
|
||||
for (i = first_sps; i < rtph264depay->sps->len; i++) {
|
||||
gst_buffer_map (g_ptr_array_index (rtph264depay->sps, i), &nalmap,
|
||||
GST_MAP_READ);
|
||||
|
||||
|
@ -409,10 +420,21 @@ gst_rtp_h264_set_src_caps (GstRtpH264Depay * rtph264depay)
|
|||
gst_buffer_unmap (g_ptr_array_index (rtph264depay->sps, i), &nalmap);
|
||||
}
|
||||
|
||||
if (rtph264depay->pps->len > 255) {
|
||||
GST_WARNING_OBJECT (rtph264depay,
|
||||
"Too many PPS to put in codec_data. Sending the most recent 255");
|
||||
num_pps = 255;
|
||||
first_pps = rtph264depay->pps->len - 255;
|
||||
} else {
|
||||
num_pps = rtph264depay->pps->len;
|
||||
first_pps = 0;
|
||||
}
|
||||
|
||||
/* 8 bits numOfPictureParameterSets */
|
||||
*data++ = rtph264depay->pps->len;
|
||||
*data++ = num_pps;
|
||||
|
||||
/* copy all PPS */
|
||||
for (i = 0; i < rtph264depay->pps->len; i++) {
|
||||
for (i = first_pps; i < rtph264depay->pps->len; i++) {
|
||||
gst_buffer_map (g_ptr_array_index (rtph264depay->pps, i), &nalmap,
|
||||
GST_MAP_READ);
|
||||
|
||||
|
|
Loading…
Reference in a new issue