const GValue *value;
guint8 *data;
guint size;
+ const gchar *alignment;
rtph264pay = GST_RTP_H264_PAY (basepayload);
* 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;
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,
/* 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");
/* 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");
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;
}
/* 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);
}
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 */
while (size > nal_length_size) {
gint i;
+ gboolean end_of_au = FALSE;
nal_len = 0;
for (i = 0; i < nal_length_size; i++) {
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;
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 */
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;
}