mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 00:06:36 +00:00
Always add PPS to the sprop-parameters-set
Rework the parsing code that under certain circumstances dropped the PPS from the sprop-parameters-set. Fixes #572854.
This commit is contained in:
parent
b9adb5846b
commit
aeee52be05
1 changed files with 52 additions and 70 deletions
|
@ -467,89 +467,71 @@ gst_rtp_h264_pay_decode_nal (GstRtpH264Pay * payloader,
|
||||||
{
|
{
|
||||||
guint8 *sps = NULL, *pps = NULL;
|
guint8 *sps = NULL, *pps = NULL;
|
||||||
guint sps_len = 0, pps_len = 0;
|
guint sps_len = 0, pps_len = 0;
|
||||||
|
guint8 header, type;
|
||||||
|
guint len;
|
||||||
|
|
||||||
/* default is no update */
|
/* default is no update */
|
||||||
*updated = FALSE;
|
*updated = FALSE;
|
||||||
|
|
||||||
if (size <= 3) {
|
GST_DEBUG ("NAL payload len=%u", size);
|
||||||
GST_WARNING ("Encoded buffer len %u <= 3", size);
|
|
||||||
|
len = size;
|
||||||
|
header = data[0];
|
||||||
|
type = header & 0x1f;
|
||||||
|
|
||||||
|
/* keep sps & pps separately so that we can update either one
|
||||||
|
* independently */
|
||||||
|
if (SPS_TYPE_ID == type) {
|
||||||
|
/* encode the entire SPS NAL in base64 */
|
||||||
|
GST_DEBUG ("Found SPS %x %x %x Len=%u", (header >> 7),
|
||||||
|
(header >> 5) & 3, type, len);
|
||||||
|
|
||||||
|
sps = data;
|
||||||
|
sps_len = len;
|
||||||
|
} else if (PPS_TYPE_ID == type) {
|
||||||
|
/* encoder the entire PPS NAL in base64 */
|
||||||
|
GST_DEBUG ("Found PPS %x %x %x Len = %u",
|
||||||
|
(header >> 7), (header >> 5) & 3, type, len);
|
||||||
|
|
||||||
|
pps = data;
|
||||||
|
pps_len = len;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("NAL payload len=%u", size);
|
GST_DEBUG ("NAL: %x %x %x Len = %u", (header >> 7),
|
||||||
|
(header >> 5) & 3, type, len);
|
||||||
|
}
|
||||||
|
|
||||||
/* loop through all NAL units and save the locations of any
|
|
||||||
* SPS / PPS for later processing. Only the last seen SPS
|
|
||||||
* or PPS will be considered */
|
|
||||||
while (size > 5) {
|
|
||||||
guint8 header, type;
|
|
||||||
guint len;
|
|
||||||
|
|
||||||
len = next_start_code (data, size);
|
/* If we encountered an SPS and/or a PPS, check if it's the
|
||||||
header = data[0];
|
* same as the one we have. If not, update our version and
|
||||||
type = header & 0x1f;
|
* set *updated to TRUE
|
||||||
|
*/
|
||||||
|
if (sps_len > 0) {
|
||||||
|
if ((payloader->sps_len != sps_len)
|
||||||
|
|| !is_nal_equal (payloader->sps, sps, sps_len)) {
|
||||||
|
payloader->profile = (sps[1] << 16) + (sps[2] << 8) + sps[3];
|
||||||
|
|
||||||
/* keep sps & pps separately so that we can update either one
|
GST_DEBUG ("Profile level IDC = %06x", payloader->profile);
|
||||||
* independently */
|
|
||||||
if (SPS_TYPE_ID == type) {
|
|
||||||
/* encode the entire SPS NAL in base64 */
|
|
||||||
GST_DEBUG ("Found SPS %x %x %x Len=%u", (header >> 7),
|
|
||||||
(header >> 5) & 3, type, len);
|
|
||||||
|
|
||||||
sps = data;
|
if (payloader->sps_len)
|
||||||
sps_len = len;
|
g_free (payloader->sps);
|
||||||
} else if (PPS_TYPE_ID == type) {
|
|
||||||
/* encoder the entire PPS NAL in base64 */
|
|
||||||
GST_DEBUG ("Found PPS %x %x %x Len = %u",
|
|
||||||
(header >> 7), (header >> 5) & 3, type, len);
|
|
||||||
|
|
||||||
pps = data;
|
payloader->sps = sps_len ? g_new (guint8, sps_len) : NULL;
|
||||||
pps_len = len;
|
memcpy (payloader->sps, sps, sps_len);
|
||||||
} else {
|
payloader->sps_len = sps_len;
|
||||||
GST_DEBUG ("NAL: %x %x %x Len = %u", (header >> 7),
|
*updated = TRUE;
|
||||||
(header >> 5) & 3, type, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end of loop */
|
|
||||||
if (len >= size - 4) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* next NAL start */
|
|
||||||
data += len + 4;
|
|
||||||
size -= len + 4;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If we encountered an SPS and/or a PPS, check if it's the
|
if (pps_len > 0) {
|
||||||
* same as the one we have. If not, update our version and
|
if ((payloader->pps_len != pps_len)
|
||||||
* set *updated to TRUE
|
|| !is_nal_equal (payloader->pps, pps, pps_len)) {
|
||||||
*/
|
if (payloader->pps_len)
|
||||||
if (sps_len > 0) {
|
g_free (payloader->pps);
|
||||||
if ((payloader->sps_len != sps_len)
|
|
||||||
|| !is_nal_equal (payloader->sps, sps, sps_len)) {
|
|
||||||
payloader->profile = (sps[1] << 16) + (sps[2] << 8) + sps[3];
|
|
||||||
|
|
||||||
GST_DEBUG ("Profile level IDC = %06x", payloader->profile);
|
payloader->pps = pps_len ? g_new (guint8, pps_len) : NULL;
|
||||||
|
memcpy (payloader->pps, pps, pps_len);
|
||||||
if (payloader->sps_len)
|
payloader->pps_len = pps_len;
|
||||||
g_free (payloader->sps);
|
*updated = TRUE;
|
||||||
|
|
||||||
payloader->sps = sps_len ? g_new (guint8, sps_len) : NULL;
|
|
||||||
memcpy (payloader->sps, sps, sps_len);
|
|
||||||
payloader->sps_len = sps_len;
|
|
||||||
*updated = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pps_len > 0) {
|
|
||||||
if ((payloader->pps_len != pps_len)
|
|
||||||
|| !is_nal_equal (payloader->pps, pps, pps_len)) {
|
|
||||||
if (payloader->pps_len)
|
|
||||||
g_free (payloader->pps);
|
|
||||||
|
|
||||||
payloader->pps = pps_len ? g_new (guint8, pps_len) : NULL;
|
|
||||||
memcpy (payloader->pps, pps, pps_len);
|
|
||||||
payloader->pps_len = pps_len;
|
|
||||||
*updated = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue