rtpmp4vpay: config-interval -1 send at idr

adjust/port from rtph264pay and allow sending the configuration data at
every IDR

The payloader was stripping the configuration data when the
config-interval was set to 0. The code was written in such a way !(a >
0) that it stripped the config when it was set at -1 (send config_data
as soon as possible).

This resulted in some MPEG4 streams where no GOP/VOP-I was detected to
be sent out without configuration.
This commit is contained in:
Marc Leeman 2019-08-01 14:28:04 +00:00 committed by Tim-Philipp Müller
parent 5451e4e900
commit d365c4fdf9
2 changed files with 31 additions and 21 deletions

View file

@ -107,10 +107,11 @@ gst_rtp_mp4v_pay_class_init (GstRtpMP4VPayClass * klass)
"Wim Taymans <wim.taymans@gmail.com>"); "Wim Taymans <wim.taymans@gmail.com>");
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_CONFIG_INTERVAL, g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_CONFIG_INTERVAL,
g_param_spec_uint ("config-interval", "Config Send Interval", g_param_spec_int ("config-interval", "Config Send Interval",
"Send Config Insertion Interval in seconds (configuration headers " "Send Config Insertion Interval in seconds (configuration headers "
"will be multiplexed in the data stream when detected.) (0 = disabled)", "will be multiplexed in the data stream when detected.) "
0, 3600, DEFAULT_CONFIG_INTERVAL, "(0 = disabled, -1 = send with every IDR frame)",
-1, 3600, DEFAULT_CONFIG_INTERVAL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
); );
@ -412,7 +413,7 @@ gst_rtp_mp4v_pay_depay_data (GstRtpMP4VPay * enc, guint8 * data, guint size,
return result; return result;
} }
/* we expect buffers starting on startcodes. /* we expect buffers starting on startcodes.
*/ */
static GstFlowReturn static GstFlowReturn
gst_rtp_mp4v_pay_handle_buffer (GstRTPBasePayload * basepayload, gst_rtp_mp4v_pay_handle_buffer (GstRTPBasePayload * basepayload,
@ -429,6 +430,7 @@ gst_rtp_mp4v_pay_handle_buffer (GstRTPBasePayload * basepayload,
GstClockTime timestamp, duration; GstClockTime timestamp, duration;
gboolean vopi; gboolean vopi;
gboolean send_config; gboolean send_config;
GstClockTime running_time = GST_CLOCK_TIME_NONE;
ret = GST_FLOW_OK; ret = GST_FLOW_OK;
send_config = FALSE; send_config = FALSE;
@ -457,8 +459,10 @@ gst_rtp_mp4v_pay_handle_buffer (GstRTPBasePayload * basepayload,
gst_buffer_unmap (buffer, &map); gst_buffer_unmap (buffer, &map);
if (strip) { if (strip) {
/* strip off config if requested */ /* strip off config if requested, do not strip off if the
if (!(rtpmp4vpay->config_interval > 0)) { * config_interval is set to -1 */
if (!(rtpmp4vpay->config_interval > 0)
&& !(rtpmp4vpay->config_interval == -1)) {
GstBuffer *subbuf; GstBuffer *subbuf;
GST_LOG_OBJECT (rtpmp4vpay, "stripping config at %d, size %d", strip, GST_LOG_OBJECT (rtpmp4vpay, "stripping config at %d, size %d", strip,
@ -473,7 +477,7 @@ gst_rtp_mp4v_pay_handle_buffer (GstRTPBasePayload * basepayload,
size = gst_buffer_get_size (buffer); size = gst_buffer_get_size (buffer);
} else { } else {
GstClockTime running_time = running_time =
gst_segment_to_running_time (&basepayload->segment, GST_FORMAT_TIME, gst_segment_to_running_time (&basepayload->segment, GST_FORMAT_TIME,
timestamp); timestamp);
@ -484,7 +488,7 @@ gst_rtp_mp4v_pay_handle_buffer (GstRTPBasePayload * basepayload,
/* there is a config request, see if we need to insert it */ /* there is a config request, see if we need to insert it */
if (vopi && (rtpmp4vpay->config_interval > 0) && rtpmp4vpay->config) { if (vopi && (rtpmp4vpay->config_interval > 0) && rtpmp4vpay->config) {
GstClockTime running_time = running_time =
gst_segment_to_running_time (&basepayload->segment, GST_FORMAT_TIME, gst_segment_to_running_time (&basepayload->segment, GST_FORMAT_TIME,
timestamp); timestamp);
@ -516,20 +520,26 @@ gst_rtp_mp4v_pay_handle_buffer (GstRTPBasePayload * basepayload,
GST_DEBUG_OBJECT (rtpmp4vpay, "no previous config time, send now"); GST_DEBUG_OBJECT (rtpmp4vpay, "no previous config time, send now");
send_config = TRUE; send_config = TRUE;
} }
}
if (send_config) { if (vopi && (rtpmp4vpay->config_interval == -1)) {
/* we need to send config now first */ GST_DEBUG_OBJECT (rtpmp4vpay, "sending config before current IDR frame");
GST_LOG_OBJECT (rtpmp4vpay, "inserting config in stream"); /* send config before every IDR frame */
send_config = TRUE;
}
/* insert header */ if (send_config) {
buffer = gst_buffer_append (gst_buffer_ref (rtpmp4vpay->config), buffer); /* we need to send config now first */
GST_LOG_OBJECT (rtpmp4vpay, "inserting config in stream");
GST_BUFFER_PTS (buffer) = timestamp; /* insert header */
size = gst_buffer_get_size (buffer); buffer = gst_buffer_append (gst_buffer_ref (rtpmp4vpay->config), buffer);
if (running_time != -1) { GST_BUFFER_PTS (buffer) = timestamp;
rtpmp4vpay->last_config = running_time; size = gst_buffer_get_size (buffer);
}
if (running_time != -1) {
rtpmp4vpay->last_config = running_time;
} }
} }
@ -596,7 +606,7 @@ gst_rtp_mp4v_pay_set_property (GObject * object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_CONFIG_INTERVAL: case PROP_CONFIG_INTERVAL:
rtpmp4vpay->config_interval = g_value_get_uint (value); rtpmp4vpay->config_interval = g_value_get_int (value);
break; break;
default: default:
break; break;
@ -613,7 +623,7 @@ gst_rtp_mp4v_pay_get_property (GObject * object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_CONFIG_INTERVAL: case PROP_CONFIG_INTERVAL:
g_value_set_uint (value, rtpmp4vpay->config_interval); g_value_set_int (value, rtpmp4vpay->config_interval);
break; break;
default: default:
break; break;

View file

@ -56,7 +56,7 @@ struct _GstRtpMP4VPay
/* naming might be confusing with send_config; but naming matches h264 /* naming might be confusing with send_config; but naming matches h264
* payloader */ * payloader */
guint config_interval; gint config_interval;
GstClockTime last_config; GstClockTime last_config;
}; };