summaryrefslogtreecommitdiff
path: root/gst/rtp
diff options
context:
space:
mode:
authorLuis de Bethencourt <luis@debethencourt.com>2015-08-12 16:11:00 +0100
committerLuis de Bethencourt <luis@debethencourt.com>2015-08-12 16:34:43 +0100
commit021333a9fc38a67d4054302c55188598c325e98f (patch)
treeca1094699bec6d7681489512ea5edddc4fd985ba /gst/rtp
parentfee3129d495b4355c2716f0f5fe053f9178280a4 (diff)
downloadgstreamer-plugins-bad-021333a9fc38a67d4054302c55188598c325e98f.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.
Diffstat (limited to 'gst/rtp')
-rw-r--r--gst/rtp/gstrtph265depay.c50
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;