diff options
author | Luis de Bethencourt <luis@debethencourt.com> | 2015-08-12 16:11:00 +0100 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2016-02-16 00:24:40 +0000 |
commit | d10b6f1e3ac35c48ca9239d8d526e244d6b982f3 (patch) | |
tree | c6b9fb28a373d391a95f9b2ca52129f493484b0c | |
parent | 0bfa97b047c788875c9cb1f4a570c5db8c2242ce (diff) | |
download | gstreamer-plugins-good-d10b6f1e3ac35c48ca9239d8d526e244d6b982f3.tar.gz |
rtph265depay: Insert SPS/PPS NALs into the stream
rtph264depay 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 spect about the codec_data.
-rw-r--r-- | gst/rtp/gstrtph265depay.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/gst/rtp/gstrtph265depay.c b/gst/rtp/gstrtph265depay.c index 39e6c6886..de4e20292 100644 --- a/gst/rtp/gstrtph265depay.c +++ b/gst/rtp/gstrtph265depay.c @@ -534,6 +534,56 @@ gst_rtp_h265_set_src_caps (GstRtpH265Depay * rtph265depay) srccaps); gst_caps_unref (srccaps); + /* Insert SPS and PPS into the stream on next opportunity */ + { + gint i; + GstBuffer *codec_data; + GstMapInfo map; + guint8 *data; + guint len = 0; + + for (i = 0; i < rtph265depay->sps->len; i++) { + len += 4 + gst_buffer_get_size (g_ptr_array_index (rtph265depay->sps, i)); + } + + for (i = 0; i < rtph265depay->pps->len; i++) { + len += 4 + gst_buffer_get_size (g_ptr_array_index (rtph265depay->pps, i)); + } + + codec_data = gst_buffer_new_and_alloc (len); + gst_buffer_map (codec_data, &map, GST_MAP_WRITE); + data = map.data; + + for (i = 0; i < rtph265depay->sps->len; i++) { + GstBuffer *sps_buf = g_ptr_array_index (rtph265depay->sps, i); + guint sps_size = gst_buffer_get_size (sps_buf); + + if (rtph265depay->byte_stream) + memcpy (data, sync_bytes, sizeof (sync_bytes)); + else + GST_WRITE_UINT32_BE (data, sps_size); + gst_buffer_extract (sps_buf, 0, data + 4, -1); + data += 4 + sps_size; + } + + for (i = 0; i < rtph265depay->pps->len; i++) { + GstBuffer *pps_buf = g_ptr_array_index (rtph265depay->pps, i); + guint pps_size = gst_buffer_get_size (pps_buf); + + if (rtph265depay->byte_stream) + memcpy (data, sync_bytes, sizeof (sync_bytes)); + else + GST_WRITE_UINT32_BE (data, pps_size); + gst_buffer_extract (pps_buf, 0, data + 4, -1); + data += 4 + pps_size; + } + + gst_buffer_unmap (codec_data, &map); + if (rtph265depay->codec_data) + gst_buffer_unref (rtph265depay->codec_data); + rtph265depay->codec_data = codec_data; + } + if (res) rtph265depay->new_codec_data = FALSE; |