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:
Wai-Ming Ho 2009-02-23 15:43:51 +01:00 committed by Wim Taymans
parent b9adb5846b
commit aeee52be05

View file

@ -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;
}
} }
} }
} }