X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Frtp%2Fgstrtpmp4apay.c;h=ab1eeb55a3545b57f43e615fd7870917d347db1f;hb=775ccdf9775bd7051929b257444b3be915e88ec6;hp=9c31fedb9ec19eacbc51ef517dec1b63391a0d58;hpb=04520cbe9a6c303f6e89c61b6dd9b060f85752a4;p=platform%2Fupstream%2Fgst-plugins-good.git diff --git a/gst/rtp/gstrtpmp4apay.c b/gst/rtp/gstrtpmp4apay.c index 9c31fed..ab1eeb5 100644 --- a/gst/rtp/gstrtpmp4apay.c +++ b/gst/rtp/gstrtpmp4apay.c @@ -13,8 +13,8 @@ * * 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 @@ -24,8 +24,10 @@ #include #include +#include #include "gstrtpmp4apay.h" +#include "gstrtputils.h" GST_DEBUG_CATEGORY_STATIC (rtpmp4apay_debug); #define GST_CAT_DEFAULT (rtpmp4apay_debug) @@ -65,9 +67,10 @@ static GstFlowReturn gst_rtp_mp4a_pay_handle_buffer (GstRTPBasePayload * 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; @@ -82,12 +85,12 @@ G_DEFINE_TYPE (GstRtpMP4APay, gst_rtp_mp4a_pay, GST_TYPE_RTP_BASE_PAYLOAD) 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 "); @@ -132,13 +135,16 @@ static gboolean gst_rtp_mp4a_pay_parse_audio_config (GstRtpMP4APay * rtpmp4apay, GstBuffer * buffer) { + GstMapInfo map; guint8 *data; gsize size; guint8 objectType; guint8 samplingIdx; guint8 channelCfg; - data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ); + gst_buffer_map (buffer, &map, GST_MAP_READ); + data = map.data; + size = map.size; if (size < 2) goto too_short; @@ -182,7 +188,7 @@ gst_rtp_mp4a_pay_parse_audio_config (GstRtpMP4APay * rtpmp4apay, "objectType: %d, samplingIdx: %d (%d), channelCfg: %d", objectType, samplingIdx, rtpmp4apay->rate, channelCfg); - gst_buffer_unmap (buffer, data, -1); + gst_buffer_unmap (buffer, &map); return TRUE; @@ -193,28 +199,28 @@ too_short: (NULL), ("config string too short, expected 2 bytes, got %" G_GSIZE_FORMAT, size)); - gst_buffer_unmap (buffer, data, -1); + gst_buffer_unmap (buffer, &map); return FALSE; } invalid_object: { GST_ELEMENT_ERROR (rtpmp4apay, STREAM, FORMAT, (NULL), ("invalid object type 0")); - gst_buffer_unmap (buffer, data, -1); + gst_buffer_unmap (buffer, &map); return FALSE; } wrong_freq: { GST_ELEMENT_ERROR (rtpmp4apay, STREAM, NOT_IMPLEMENTED, (NULL), ("unsupported frequency index %d", samplingIdx)); - gst_buffer_unmap (buffer, data, -1); + gst_buffer_unmap (buffer, &map); return FALSE; } wrong_channels: { GST_ELEMENT_ERROR (rtpmp4apay, STREAM, NOT_IMPLEMENTED, (NULL), ("unsupported number of channels %d, must < 8", channelCfg)); - gst_buffer_unmap (buffer, data, -1); + gst_buffer_unmap (buffer, &map); return FALSE; } } @@ -272,10 +278,9 @@ gst_rtp_mp4a_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps) GST_LOG_OBJECT (rtpmp4apay, "got codec_data"); if (G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) { GstBuffer *buffer, *cbuffer; - guint8 *config; - guint8 *data; + GstMapInfo map; + GstMapInfo cmap; guint i; - gsize size; buffer = gst_value_get_buffer (codec_data); GST_LOG_OBJECT (rtpmp4apay, "configuring codec_data"); @@ -286,11 +291,13 @@ gst_rtp_mp4a_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps) if (!res) goto config_failed; - data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ); + gst_buffer_map (buffer, &map, GST_MAP_READ); /* make the StreamMuxConfig, we need 15 bits for the header */ - cbuffer = gst_buffer_new_and_alloc (size + 2); - config = gst_buffer_map (cbuffer, NULL, NULL, GST_MAP_WRITE); + 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: * @@ -300,17 +307,17 @@ gst_rtp_mp4a_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps) * numProgram == 0 (4 bits) * numLayer == 0 (3 bits) */ - config[0] = 0x40; - config[1] = 0x00; + cmap.data[0] = 0x40; + cmap.data[1] = 0x00; /* append the config bits, shifting them 1 bit left */ - for (i = 0; i < size; i++) { - config[i + 1] |= ((data[i] & 0x80) >> 7); - config[i + 2] |= ((data[i] & 0x7f) << 1); + for (i = 0; i < map.size; i++) { + cmap.data[i + 1] |= ((map.data[i] & 0x80) >> 7); + cmap.data[i + 2] |= ((map.data[i] & 0x7f) << 1); } - gst_buffer_unmap (cbuffer, config, -1); - gst_buffer_unmap (buffer, data, -1); + gst_buffer_unmap (cbuffer, &cmap); + gst_buffer_unmap (buffer, &map); /* now we can configure the buffer */ if (rtpmp4apay->config) @@ -338,6 +345,8 @@ config_failed: } } +#define RTP_HEADER_LEN 12 + /* we expect buffers as exactly one complete AU */ static GstFlowReturn @@ -346,10 +355,10 @@ gst_rtp_mp4a_pay_handle_buffer (GstRTPBasePayload * basepayload, { GstRtpMP4APay *rtpmp4apay; GstFlowReturn ret; - GstBuffer *outbuf; - guint count, mtu; + GstBufferList *list; + guint mtu; + guint offset; gsize size; - guint8 *data, *bdata; gboolean fragmented; GstClockTime timestamp; @@ -357,80 +366,92 @@ gst_rtp_mp4a_pay_handle_buffer (GstRTPBasePayload * basepayload, rtpmp4apay = GST_RTP_MP4A_PAY (basepayload); - data = bdata = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ); - timestamp = GST_BUFFER_TIMESTAMP (buffer); + offset = 0; + size = gst_buffer_get_size (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, bdata, -1); + ret = + gst_rtp_base_payload_push_list (GST_RTP_BASE_PAYLOAD (rtpmp4apay), list); + gst_buffer_unref (buffer); return ret;