diff options
author | Luis de Bethencourt <luisbg@osg.samsung.com> | 2016-01-15 15:56:59 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2016-02-16 00:24:41 +0000 |
commit | 4ee6c17edbac9d65cdba600b172a593b4b40849d (patch) | |
tree | 05b0344937b10f17479eb20a0f2154e65f7ed481 /gst | |
parent | 64ca3b26d97482a9303305185a86782813631b26 (diff) | |
download | gstreamer-plugins-good-4ee6c17edbac9d65cdba600b172a593b4b40849d.tar.gz |
rtph265pay: add "send VPS/SPS/PPS with every key frame" mode
It's not enough to have timeout or event based VPS/SPS/PPS information
sent in RTP packets. There are some scenarios when key frames may appear
more frequently than once a second, in which case the minimum timeout
for "config-interval" of 1 second for sending VPS/SPS/PPS isn't enough.
It might also be desirable in general to make sure the VPS/SPS/PPS is
available with every keyframe (packet loss aside), so receivers can
actually pick up decoding immediately from the first keyframe if
VPS/SPS/PPS is not signaled out of band.
This commit adds the possibility to send VPS/SPS/PPS with every key frame.
This mode can be enabled by setting "config-interval" property to -1. In
this case the payloader will add VPS, SPS and PPS before every key (IDR)
frame.
https://bugzilla.gnome.org/show_bug.cgi?id=757892
Diffstat (limited to 'gst')
-rw-r--r-- | gst/rtp/gstrtph265pay.c | 86 |
1 files changed, 46 insertions, 40 deletions
diff --git a/gst/rtp/gstrtph265pay.c b/gst/rtp/gstrtph265pay.c index d72feb0f6..db8800bc6 100644 --- a/gst/rtp/gstrtph265pay.c +++ b/gst/rtp/gstrtph265pay.c @@ -162,7 +162,8 @@ gst_rtp_h265_pay_class_init (GstRtpH265PayClass * klass) g_param_spec_int ("config-interval", "VPS SPS PPS Send Interval", "Send VPS, SPS and PPS Insertion Interval in seconds (sprop parameter sets " - "will be multiplexed in the data stream when detected.) (0 = disabled)", + "will be multiplexed in the data stream when detected.) " + "(0 = disabled, -1 = send with every IDR frame)", -1, 3600, DEFAULT_CONFIG_INTERVAL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) ); @@ -946,47 +947,52 @@ gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload, send_vps_sps_pps = FALSE; /* check if we need to emit an VPS/SPS/PPS now */ - if (((nalType == GST_H265_NAL_SLICE_TRAIL_N) - || (nalType == GST_H265_NAL_SLICE_TRAIL_R) - || (nalType == GST_H265_NAL_SLICE_TSA_N) - || (nalType == GST_H265_NAL_SLICE_TSA_R) - || (nalType == GST_H265_NAL_SLICE_STSA_N) - || (nalType == GST_H265_NAL_SLICE_STSA_R) - || (nalType == GST_H265_NAL_SLICE_RASL_N) - || (nalType == GST_H265_NAL_SLICE_RASL_R) - || (nalType == GST_H265_NAL_SLICE_BLA_W_LP) - || (nalType == GST_H265_NAL_SLICE_BLA_W_RADL) - || (nalType == GST_H265_NAL_SLICE_BLA_N_LP) - || (nalType == GST_H265_NAL_SLICE_IDR_W_RADL) - || (nalType == GST_H265_NAL_SLICE_IDR_N_LP) - || (nalType == GST_H265_NAL_SLICE_CRA_NUT)) - && rtph265pay->vps_sps_pps_interval > 0) { - - if (rtph265pay->last_vps_sps_pps != -1) { - guint64 diff; - - GST_LOG_OBJECT (rtph265pay, - "now %" GST_TIME_FORMAT ", last VPS/SPS/PPS %" GST_TIME_FORMAT, - GST_TIME_ARGS (pts), GST_TIME_ARGS (rtph265pay->last_vps_sps_pps)); - - /* calculate diff between last SPS/PPS in milliseconds */ - if (pts > rtph265pay->last_vps_sps_pps) - diff = pts - rtph265pay->last_vps_sps_pps; - else - diff = 0; - - GST_DEBUG_OBJECT (rtph265pay, - "interval since last VPS/SPS/PPS %" GST_TIME_FORMAT, - GST_TIME_ARGS (diff)); - - /* bigger than interval, queue SPS/PPS */ - if (GST_TIME_AS_SECONDS (diff) >= rtph265pay->vps_sps_pps_interval) { - GST_DEBUG_OBJECT (rtph265pay, "time to send VPS/SPS/PPS"); + if ((nalType == GST_H265_NAL_SLICE_TRAIL_N) + || (nalType == GST_H265_NAL_SLICE_TRAIL_R) + || (nalType == GST_H265_NAL_SLICE_TSA_N) + || (nalType == GST_H265_NAL_SLICE_TSA_R) + || (nalType == GST_H265_NAL_SLICE_STSA_N) + || (nalType == GST_H265_NAL_SLICE_STSA_R) + || (nalType == GST_H265_NAL_SLICE_RASL_N) + || (nalType == GST_H265_NAL_SLICE_RASL_R) + || (nalType == GST_H265_NAL_SLICE_BLA_W_LP) + || (nalType == GST_H265_NAL_SLICE_BLA_W_RADL) + || (nalType == GST_H265_NAL_SLICE_BLA_N_LP) + || (nalType == GST_H265_NAL_SLICE_IDR_W_RADL) + || (nalType == GST_H265_NAL_SLICE_IDR_N_LP) + || (nalType == GST_H265_NAL_SLICE_CRA_NUT)) { + if (rtph265pay->vps_sps_pps_interval > 0) { + if (rtph265pay->last_vps_sps_pps != -1) { + guint64 diff; + + GST_LOG_OBJECT (rtph265pay, + "now %" GST_TIME_FORMAT ", last VPS/SPS/PPS %" GST_TIME_FORMAT, + GST_TIME_ARGS (pts), GST_TIME_ARGS (rtph265pay->last_vps_sps_pps)); + + /* calculate diff between last SPS/PPS in milliseconds */ + if (pts > rtph265pay->last_vps_sps_pps) + diff = pts - rtph265pay->last_vps_sps_pps; + else + diff = 0; + + GST_DEBUG_OBJECT (rtph265pay, + "interval since last VPS/SPS/PPS %" GST_TIME_FORMAT, + GST_TIME_ARGS (diff)); + + /* bigger than interval, queue SPS/PPS */ + if (GST_TIME_AS_SECONDS (diff) >= rtph265pay->vps_sps_pps_interval) { + GST_DEBUG_OBJECT (rtph265pay, "time to send VPS/SPS/PPS"); + send_vps_sps_pps = TRUE; + } + } else { + /* no known previous SPS/PPS time, send now */ + GST_DEBUG_OBJECT (rtph265pay, "no previous VPS/SPS/PPS time, send now"); send_vps_sps_pps = TRUE; } - } else { - /* no known previous SPS/PPS time, send now */ - GST_DEBUG_OBJECT (rtph265pay, "no previous VPS/SPS/PPS time, send now"); + } else if (rtph265pay->vps_sps_pps_interval == -1) { + GST_DEBUG_OBJECT (rtph265pay, + "sending VPS/SPS/PPS before current IDR frame"); + /* send VPS/SPS/PPS before every IDR frame */ send_vps_sps_pps = TRUE; } } |