*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include <string.h>
#include <gst/rtp/gstrtpbuffer.h>
+#include <gst/audio/audio.h>
#include "gstrtpmp4apay.h"
+#include "gstrtputils.h"
GST_DEBUG_CATEGORY_STATIC (rtpmp4apay_debug);
#define GST_CAT_DEFAULT (rtpmp4apay_debug)
payload, GstBuffer * buffer);
#define gst_rtp_mp4a_pay_parent_class parent_class
-G_DEFINE_TYPE (GstRtpMP4APay, gst_rtp_mp4a_pay, GST_TYPE_RTP_BASE_PAYLOAD)
+G_DEFINE_TYPE (GstRtpMP4APay, gst_rtp_mp4a_pay, GST_TYPE_RTP_BASE_PAYLOAD);
- static void gst_rtp_mp4a_pay_class_init (GstRtpMP4APayClass * klass)
+static void
+gst_rtp_mp4a_pay_class_init (GstRtpMP4APayClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gstrtpbasepayload_class->set_caps = gst_rtp_mp4a_pay_setcaps;
gstrtpbasepayload_class->handle_buffer = gst_rtp_mp4a_pay_handle_buffer;
- gst_element_class_add_pad_template (gstelement_class,
- gst_static_pad_template_get (&gst_rtp_mp4a_pay_src_template));
- gst_element_class_add_pad_template (gstelement_class,
- gst_static_pad_template_get (&gst_rtp_mp4a_pay_sink_template));
+ gst_element_class_add_static_pad_template (gstelement_class,
+ &gst_rtp_mp4a_pay_src_template);
+ gst_element_class_add_static_pad_template (gstelement_class,
+ &gst_rtp_mp4a_pay_sink_template);
- gst_element_class_set_details_simple (gstelement_class,
+ gst_element_class_set_static_metadata (gstelement_class,
"RTP MPEG4 audio payloader", "Codec/Payloader/Network/RTP",
"Payload MPEG4 audio as RTP packets (RFC 3016)",
"Wim Taymans <wim.taymans@gmail.com>");
cbuffer = gst_buffer_new_and_alloc (map.size + 2);
gst_buffer_map (cbuffer, &cmap, GST_MAP_WRITE);
+ memset (cmap.data, 0, map.size + 2);
+
/* Create StreamMuxConfig according to ISO/IEC 14496-3:
*
* audioMuxVersion == 0 (1 bit)
}
}
+#define RTP_HEADER_LEN 12
+
/* we expect buffers as exactly one complete AU
*/
static GstFlowReturn
{
GstRtpMP4APay *rtpmp4apay;
GstFlowReturn ret;
- GstBuffer *outbuf;
- guint count, mtu;
- GstMapInfo map;
+ GstBufferList *list;
+ guint mtu;
+ guint offset;
gsize size;
- guint8 *data;
gboolean fragmented;
GstClockTime timestamp;
rtpmp4apay = GST_RTP_MP4A_PAY (basepayload);
- gst_buffer_map (buffer, &map, GST_MAP_READ);
- size = map.size;
- data = map.data;
+ offset = 0;
+ size = gst_buffer_get_size (buffer);
- timestamp = GST_BUFFER_TIMESTAMP (buffer);
+ timestamp = GST_BUFFER_PTS (buffer);
fragmented = FALSE;
mtu = GST_RTP_BASE_PAYLOAD_MTU (rtpmp4apay);
+ list = gst_buffer_list_new_sized (size / (mtu - RTP_HEADER_LEN) + 1);
+
while (size > 0) {
guint towrite;
- guint8 *payload;
+ GstBuffer *outbuf;
guint payload_len;
guint packet_len;
+ guint header_len;
+ GstBuffer *paybuf;
GstRTPBuffer rtp = { NULL };
- /* this will be the total lenght of the packet */
- packet_len = gst_rtp_buffer_calc_packet_len (size, 0, 0);
-
+ header_len = 0;
if (!fragmented) {
+ guint count;
/* first packet calculate space for the packet including the header */
count = size;
while (count >= 0xff) {
- packet_len++;
+ header_len++;
count -= 0xff;
}
- packet_len++;
+ header_len++;
}
- /* fill one MTU or all available bytes */
+ packet_len = gst_rtp_buffer_calc_packet_len (header_len + size, 0, 0);
towrite = MIN (packet_len, mtu);
-
- /* this is the payload length */
payload_len = gst_rtp_buffer_calc_payload_len (towrite, 0, 0);
+ payload_len -= header_len;
GST_DEBUG_OBJECT (rtpmp4apay,
- "avail %" G_GSIZE_FORMAT ", towrite %d, packet_len %d, payload_len %d",
- size, towrite, packet_len, payload_len);
+ "avail %" G_GSIZE_FORMAT
+ ", header_len %d, packet_len %d, payload_len %d", size, header_len,
+ packet_len, payload_len);
/* create buffer to hold the payload. */
- outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
+ outbuf = gst_rtp_base_payload_allocate_output_buffer (basepayload,
+ header_len, 0, 0);
/* copy payload */
gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
- payload = gst_rtp_buffer_get_payload (&rtp);
if (!fragmented) {
+ guint8 *payload = gst_rtp_buffer_get_payload (&rtp);
+ guint count;
+
/* first packet write the header */
count = size;
while (count >= 0xff) {
*payload++ = 0xff;
- payload_len--;
count -= 0xff;
}
*payload++ = count;
- payload_len--;
}
- /* copy data to payload */
- memcpy (payload, data, payload_len);
- data += payload_len;
- size -= payload_len;
-
/* marker only if the packet is complete */
- gst_rtp_buffer_set_marker (&rtp, size == 0);
+ gst_rtp_buffer_set_marker (&rtp, size == payload_len);
gst_rtp_buffer_unmap (&rtp);
- /* copy incomming timestamp (if any) to outgoing buffers */
- GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
+ /* create a new buf to hold the payload */
+ paybuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL,
+ offset, payload_len);
- ret = gst_rtp_base_payload_push (GST_RTP_BASE_PAYLOAD (rtpmp4apay), outbuf);
+ /* join memory parts */
+ gst_rtp_copy_audio_meta (rtpmp4apay, outbuf, paybuf);
+ outbuf = gst_buffer_append (outbuf, paybuf);
+ gst_buffer_list_add (list, outbuf);
+ offset += payload_len;
+ size -= payload_len;
+
+ /* copy incoming timestamp (if any) to outgoing buffers */
+ GST_BUFFER_PTS (outbuf) = timestamp;
fragmented = TRUE;
}
- gst_buffer_unmap (buffer, &map);
+ ret =
+ gst_rtp_base_payload_push_list (GST_RTP_BASE_PAYLOAD (rtpmp4apay), list);
+
gst_buffer_unref (buffer);
return ret;