mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
rtph264pay: Only set the marker bit on the last NALU of a multi-NALU access unit
An access unit could contain multiple NAL units, in that case, only the last RTP packet of the last NALU should have its marker bit set. https://bugzilla.gnome.org/show_bug.cgi?id=654850
This commit is contained in:
parent
216dc602c3
commit
118a7cc36a
2 changed files with 37 additions and 8 deletions
|
@ -420,6 +420,7 @@ gst_rtp_h264_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
|
|||
const GValue *value;
|
||||
guint8 *data;
|
||||
guint size;
|
||||
const gchar *alignment;
|
||||
|
||||
rtph264pay = GST_RTP_H264_PAY (basepayload);
|
||||
|
||||
|
@ -429,6 +430,12 @@ gst_rtp_h264_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
|
|||
* NALs */
|
||||
gst_basertppayload_set_options (basepayload, "video", TRUE, "H264", 90000);
|
||||
|
||||
alignment = gst_structure_get_string (str, "alignment");
|
||||
if (alignment && !strcmp (alignment, "au"))
|
||||
rtph264pay->au_alignment = TRUE;
|
||||
else
|
||||
rtph264pay->au_alignment = FALSE;
|
||||
|
||||
/* packetized AVC video has a codec_data */
|
||||
if ((value = gst_structure_get_value (str, "codec_data"))) {
|
||||
GstBuffer *buffer;
|
||||
|
@ -763,7 +770,7 @@ gst_rtp_h264_pay_decode_nal (GstRtpH264Pay * payloader,
|
|||
static GstFlowReturn
|
||||
gst_rtp_h264_pay_payload_nal (GstBaseRTPPayload * basepayload,
|
||||
const guint8 * data, guint size, GstClockTime timestamp,
|
||||
GstBuffer * buffer_orig);
|
||||
GstBuffer * buffer_orig, gboolean end_of_au);
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtp_h264_pay_send_sps_pps (GstBaseRTPPayload * basepayload,
|
||||
|
@ -779,7 +786,7 @@ gst_rtp_h264_pay_send_sps_pps (GstBaseRTPPayload * basepayload,
|
|||
/* resend SPS */
|
||||
ret = gst_rtp_h264_pay_payload_nal (basepayload,
|
||||
GST_BUFFER_DATA (sps_buf), GST_BUFFER_SIZE (sps_buf), timestamp,
|
||||
sps_buf);
|
||||
sps_buf, FALSE);
|
||||
/* Not critical here; but throw a warning */
|
||||
if (ret != GST_FLOW_OK)
|
||||
GST_WARNING ("Problem pushing SPS");
|
||||
|
@ -791,7 +798,7 @@ gst_rtp_h264_pay_send_sps_pps (GstBaseRTPPayload * basepayload,
|
|||
/* resend PPS */
|
||||
ret = gst_rtp_h264_pay_payload_nal (basepayload,
|
||||
GST_BUFFER_DATA (pps_buf), GST_BUFFER_SIZE (pps_buf), timestamp,
|
||||
pps_buf);
|
||||
pps_buf, FALSE);
|
||||
/* Not critical here; but throw a warning */
|
||||
if (ret != GST_FLOW_OK)
|
||||
GST_WARNING ("Problem pushing PPS");
|
||||
|
@ -806,7 +813,7 @@ gst_rtp_h264_pay_send_sps_pps (GstBaseRTPPayload * basepayload,
|
|||
static GstFlowReturn
|
||||
gst_rtp_h264_pay_payload_nal (GstBaseRTPPayload * basepayload,
|
||||
const guint8 * data, guint size, GstClockTime timestamp,
|
||||
GstBuffer * buffer_orig)
|
||||
GstBuffer * buffer_orig, gboolean end_of_au)
|
||||
{
|
||||
GstRtpH264Pay *rtph264pay;
|
||||
GstFlowReturn ret;
|
||||
|
@ -885,7 +892,7 @@ gst_rtp_h264_pay_payload_nal (GstBaseRTPPayload * basepayload,
|
|||
}
|
||||
|
||||
/* only set the marker bit on packets containing access units */
|
||||
if (IS_ACCESS_UNIT (nalType)) {
|
||||
if (IS_ACCESS_UNIT (nalType) && end_of_au) {
|
||||
gst_rtp_buffer_set_marker (outbuf, 1);
|
||||
}
|
||||
|
||||
|
@ -975,7 +982,7 @@ gst_rtp_h264_pay_payload_nal (GstBaseRTPPayload * basepayload,
|
|||
end = 1;
|
||||
}
|
||||
if (IS_ACCESS_UNIT (nalType)) {
|
||||
gst_rtp_buffer_set_marker (outbuf, end);
|
||||
gst_rtp_buffer_set_marker (outbuf, end && end_of_au);
|
||||
}
|
||||
|
||||
/* FU indicator */
|
||||
|
@ -1075,6 +1082,7 @@ gst_rtp_h264_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
|
||||
while (size > nal_length_size) {
|
||||
gint i;
|
||||
gboolean end_of_au = FALSE;
|
||||
|
||||
nal_len = 0;
|
||||
for (i = 0; i < nal_length_size; i++) {
|
||||
|
@ -1093,9 +1101,16 @@ gst_rtp_h264_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
nal_len);
|
||||
}
|
||||
|
||||
/* If we're at the end of the buffer, then we're at the end of the
|
||||
* access unit
|
||||
*/
|
||||
if (rtph264pay->au_alignment && size - nal_len <= nal_length_size) {
|
||||
end_of_au = TRUE;
|
||||
}
|
||||
|
||||
ret =
|
||||
gst_rtp_h264_pay_payload_nal (basepayload, data, nal_len, timestamp,
|
||||
buffer);
|
||||
buffer, end_of_au);
|
||||
if (ret != GST_FLOW_OK)
|
||||
break;
|
||||
|
||||
|
@ -1197,6 +1212,7 @@ gst_rtp_h264_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
|
||||
for (i = 0; i < nal_queue->len; i++) {
|
||||
guint size;
|
||||
gboolean end_of_au = FALSE;
|
||||
|
||||
nal_len = g_array_index (nal_queue, guint, i);
|
||||
/* skip start code */
|
||||
|
@ -1212,10 +1228,22 @@ gst_rtp_h264_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
for (; size > 1 && data[size - 1] == 0x0; size--)
|
||||
/* skip */ ;
|
||||
|
||||
/* If it's the last nal unit we have in non-bytestream mode, we can
|
||||
* assume it's the end of an access-unit
|
||||
*
|
||||
* FIXME: We need to wait until the next packet or EOS to
|
||||
* actually payload the NAL so we can know if the current NAL is
|
||||
* the last one of an access unit or not if we are in bytestream mode
|
||||
*/
|
||||
if (rtph264pay->au_alignment &&
|
||||
rtph264pay->scan_mode != GST_H264_SCAN_MODE_BYTESTREAM &&
|
||||
i == nal_queue->len - 1)
|
||||
end_of_au = TRUE;
|
||||
|
||||
/* put the data in one or more RTP packets */
|
||||
ret =
|
||||
gst_rtp_h264_pay_payload_nal (basepayload, data, size, timestamp,
|
||||
buffer);
|
||||
buffer, end_of_au);
|
||||
if (ret != GST_FLOW_OK) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ struct _GstRtpH264Pay
|
|||
GList *sps, *pps;
|
||||
|
||||
gboolean packetized;
|
||||
gboolean au_alignment;
|
||||
guint nal_length_size;
|
||||
GArray *queue;
|
||||
|
||||
|
|
Loading…
Reference in a new issue