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
This commit is contained in:
Luis de Bethencourt 2016-01-15 15:56:59 +00:00
parent 31a7ad77b6
commit 6f8f82164a

View file

@ -162,7 +162,8 @@ gst_rtp_h265_pay_class_init (GstRtpH265PayClass * klass)
g_param_spec_int ("config-interval", g_param_spec_int ("config-interval",
"VPS SPS PPS Send Interval", "VPS SPS PPS Send Interval",
"Send VPS, SPS and PPS Insertion Interval in seconds (sprop parameter sets " "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, -1, 3600, DEFAULT_CONFIG_INTERVAL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
); );
@ -946,7 +947,7 @@ gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload,
send_vps_sps_pps = FALSE; send_vps_sps_pps = FALSE;
/* check if we need to emit an VPS/SPS/PPS now */ /* check if we need to emit an VPS/SPS/PPS now */
if (((nalType == GST_H265_NAL_SLICE_TRAIL_N) if ((nalType == GST_H265_NAL_SLICE_TRAIL_N)
|| (nalType == GST_H265_NAL_SLICE_TRAIL_R) || (nalType == GST_H265_NAL_SLICE_TRAIL_R)
|| (nalType == GST_H265_NAL_SLICE_TSA_N) || (nalType == GST_H265_NAL_SLICE_TSA_N)
|| (nalType == GST_H265_NAL_SLICE_TSA_R) || (nalType == GST_H265_NAL_SLICE_TSA_R)
@ -959,9 +960,8 @@ gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload,
|| (nalType == GST_H265_NAL_SLICE_BLA_N_LP) || (nalType == GST_H265_NAL_SLICE_BLA_N_LP)
|| (nalType == GST_H265_NAL_SLICE_IDR_W_RADL) || (nalType == GST_H265_NAL_SLICE_IDR_W_RADL)
|| (nalType == GST_H265_NAL_SLICE_IDR_N_LP) || (nalType == GST_H265_NAL_SLICE_IDR_N_LP)
|| (nalType == GST_H265_NAL_SLICE_CRA_NUT)) || (nalType == GST_H265_NAL_SLICE_CRA_NUT)) {
&& rtph265pay->vps_sps_pps_interval > 0) { if (rtph265pay->vps_sps_pps_interval > 0) {
if (rtph265pay->last_vps_sps_pps != -1) { if (rtph265pay->last_vps_sps_pps != -1) {
guint64 diff; guint64 diff;
@ -989,6 +989,12 @@ gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload,
GST_DEBUG_OBJECT (rtph265pay, "no previous VPS/SPS/PPS time, send now"); GST_DEBUG_OBJECT (rtph265pay, "no previous VPS/SPS/PPS time, send now");
send_vps_sps_pps = TRUE; send_vps_sps_pps = TRUE;
} }
} 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;
}
} }
if (send_vps_sps_pps || rtph265pay->send_vps_sps_pps) { if (send_vps_sps_pps || rtph265pay->send_vps_sps_pps) {