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:
Jan Schmidt 2020-10-17 00:05:15 +11:00 committed by GStreamer Merge Bot
parent 63c7a9ae43
commit 2623404744

View file

@ -351,7 +351,7 @@ gst_rtp_h264_set_src_caps (GstRtpH264Depay * rtph264depay)
guint8 *data; guint8 *data;
guint len; guint len;
guint new_size; guint new_size;
guint i; guint i, first_sps, num_sps, first_pps, num_pps;
guchar level = 0; guchar level = 0;
guchar profile_compat = G_MAXUINT8; guchar profile_compat = G_MAXUINT8;
@ -392,11 +392,22 @@ gst_rtp_h264_set_src_caps (GstRtpH264Depay * rtph264depay)
/* 6 bits reserved | 2 bits lengthSizeMinusOn */ /* 6 bits reserved | 2 bits lengthSizeMinusOn */
*data++ = 0xff; *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 */ /* 3 bits reserved | 5 bits numOfSequenceParameterSets */
*data++ = 0xe0 | (rtph264depay->sps->len & 0x1f); *data++ = 0xe0 | (num_sps & 0x1f);
/* copy all SPS */ /* 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_buffer_map (g_ptr_array_index (rtph264depay->sps, i), &nalmap,
GST_MAP_READ); 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); 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 */ /* 8 bits numOfPictureParameterSets */
*data++ = rtph264depay->pps->len; *data++ = num_pps;
/* copy all 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_buffer_map (g_ptr_array_index (rtph264depay->pps, i), &nalmap,
GST_MAP_READ); GST_MAP_READ);