From 264bcf7d6f3fab8219479ae9b062842856b0e255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Wed, 8 Aug 2012 17:25:36 -0700 Subject: [PATCH] rtph264pay: Make it actually work after cleanups --- gst/rtp/gstrtph264pay.c | 49 +++++++++++++++++---------- tests/check/elements/rtp-payloading.c | 15 ++++---- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/gst/rtp/gstrtph264pay.c b/gst/rtp/gstrtph264pay.c index 0e8bf9709f..0db6555a37 100644 --- a/gst/rtp/gstrtph264pay.c +++ b/gst/rtp/gstrtph264pay.c @@ -432,7 +432,7 @@ gst_rtp_h264_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps) if (stream_format) { if (g_str_equal (stream_format, "avc")) rtph264pay->stream_format = GST_H264_STREAM_FORMAT_AVC; - if (g_str_equal (stream_format, "bytestream")) + if (g_str_equal (stream_format, "byte-stream")) rtph264pay->stream_format = GST_H264_STREAM_FORMAT_BYTESTREAM; } @@ -920,8 +920,8 @@ gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload, /* insert payload memory block */ gst_buffer_append_memory (outbuf, - gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, (guint8*) data, - size, 0, size, NULL, NULL)); + gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, (guint8 *) data, + size, 0, size, NULL, NULL)); list = gst_buffer_list_new (); @@ -988,8 +988,8 @@ gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload, /* insert payload memory block */ gst_buffer_append_memory (outbuf, - gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, (guint8 *) data + pos, - limitedSize, 0, limitedSize, NULL, NULL)); + gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, + (guint8 *) data + pos, limitedSize, 0, limitedSize, NULL, NULL)); /* add the buffer to the buffer list */ gst_buffer_list_add (list, outbuf); @@ -1026,9 +1026,12 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, /* the input buffer contains one or more NAL units */ - avc = rtph264pay->stream_format = GST_H264_STREAM_FORMAT_AVC; + avc = rtph264pay->stream_format == GST_H264_STREAM_FORMAT_AVC; if (avc) { + /* In AVC mode, there is no adapter, so nothign to flush */ + if (buffer == NULL) + return GST_FLOW_OK; gst_buffer_map (buffer, &map, GST_MAP_READ); data = map.data; size = map.size; @@ -1038,17 +1041,20 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, } else { dts = gst_adapter_prev_dts (rtph264pay->adapter, NULL); pts = gst_adapter_prev_pts (rtph264pay->adapter, NULL); - gst_adapter_push (rtph264pay->adapter, buffer); + if (buffer) + gst_adapter_push (rtph264pay->adapter, buffer); size = gst_adapter_available (rtph264pay->adapter); data = gst_adapter_map (rtph264pay->adapter, size); GST_DEBUG_OBJECT (basepayload, "got %" G_GSIZE_FORMAT " bytes (%" G_GSIZE_FORMAT ")", size, gst_buffer_get_size (buffer)); - if (!GST_CLOCK_TIME_IS_VALID (dts)) - dts = GST_BUFFER_DTS (buffer); - if (!GST_CLOCK_TIME_IS_VALID (pts)) - pts = GST_BUFFER_PTS (buffer); + if (buffer) { + if (!GST_CLOCK_TIME_IS_VALID (dts)) + dts = GST_BUFFER_DTS (buffer); + if (!GST_CLOCK_TIME_IS_VALID (pts)) + pts = GST_BUFFER_PTS (buffer); + } } ret = GST_FLOW_OK; @@ -1135,8 +1141,9 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, */ next = next_start_code (data, size); - if (next == size) { - /* Didn't find the start of next NAL, handle it next time */ + if (next == size && buffer != NULL) { + /* Didn't find the start of next NAL and it's not EOS, + * handle it next time */ break; } @@ -1194,12 +1201,12 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, /* skip start code */ data += 3; - /* Trim the end unless we're the last NAL in the buffer. + /* Trim the end unless we're the last NAL in the stream. * In case we're not at the end of the buffer we know the next block * starts with 0x000001 so all the 0x00 bytes at the end of this one are * trailing 0x0 that can be discarded */ size = nal_len; - if (i + 1 != nal_queue->len) + if (i + 1 != nal_queue->len || buffer != NULL) for (; size > 1 && data[size - 1] == 0x0; size--) /* skip */ ; @@ -1210,10 +1217,11 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, * 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->alignment == GST_H264_ALIGNMENT_AU && + if ((rtph264pay->alignment == GST_H264_ALIGNMENT_AU || buffer == NULL) && 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, dts, pts, @@ -1224,7 +1232,6 @@ gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload, /* move to next NAL packet */ data += nal_len; - size -= nal_len; pushed += nal_len + 3; } g_array_set_size (nal_queue, 0); @@ -1271,6 +1278,14 @@ gst_rtp_h264_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event) rtph264pay->send_spspps = TRUE; } break; + case GST_EVENT_EOS: + { + /* call handle_buffer with NULL to flush last NAL from adapter + * in byte-stream mode + */ + gst_rtp_h264_pay_handle_buffer (payload, NULL); + break; + } default: break; } diff --git a/tests/check/elements/rtp-payloading.c b/tests/check/elements/rtp-payloading.c index 7b045022e6..70e62146cf 100644 --- a/tests/check/elements/rtp-payloading.c +++ b/tests/check/elements/rtp-payloading.c @@ -279,8 +279,7 @@ rtp_pipeline_run (rtp_pipeline * p) } /* - * Enables buffer lists. Sets the buffer-list property of the payloader - * and adds a chain_list_function to the depayloader. + * Enables buffer lists and adds a chain_list_function to the depayloader. * @param p Pointer to the RTP pipeline. */ static void @@ -288,9 +287,6 @@ rtp_pipeline_enable_lists (rtp_pipeline * p, guint mtu_size) { GstPad *pad; - /* use buffer lists */ - g_object_set (p->rtppay, "buffer-list", TRUE, NULL); - /* set mtu size if needed */ if (mtu_size) { g_object_set (p->rtppay, "mtu", mtu_size, NULL); @@ -525,7 +521,7 @@ GST_END_TEST; static const guint8 rtp_h264_list_lt_mtu_frame_data[] = /* not packetized, next NAL starts with 0001 */ { 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xad, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00 }; @@ -533,8 +529,8 @@ static int rtp_h264_list_lt_mtu_frame_data_size = 16; static int rtp_h264_list_lt_mtu_frame_count = 2; -/* NAL = 4 bytes */ -static int rtp_h264_list_lt_mtu_bytes_sent = 2 * (16 - 4); +/* NAL = 4 bytes + 12 bytes RTP header */ +static int rtp_h264_list_lt_mtu_bytes_sent = 2 * (12 + 16 - 4); static int rtp_h264_list_lt_mtu_mtu_size = 1024; @@ -564,7 +560,8 @@ static int rtp_h264_list_gt_mtu_frame_data_size = 64; static int rtp_h264_list_gt_mtu_frame_count = 1; /* NAL = 4 bytes. When data does not fit into 1 mtu, 1 byte will be skipped */ -static int rtp_h264_list_gt_mtu_bytes_sent = 1 * (64 - 4) - 1; +/* Also 12 byte RTP header + 2 byte fragment header */ +static int rtp_h264_list_gt_mtu_bytes_sent = 1 * (64 - 4) - 1 + (5 * 14); static int rtp_h264_list_gt_mtu_mty_size = 28;