diff options
author | Daniel Charles <dcharles@ti.com> | 2007-06-01 11:16:17 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2007-06-01 11:16:17 +0000 |
commit | 89ae9b40f9c32d3e8aac4c7c9aafb83d64fa2497 (patch) | |
tree | 38e5008eb73a5214a4a81e33f334b2d23bdbfbd4 /gst/rtp/gstrtpamrpay.c | |
parent | 0b2e6f1c901d105c53141cd9973e3c206c8086ec (diff) |
gst/rtp/: Add support for AMR-WB.
Original commit message from CVS:
Based on Patch by: Daniel Charles <dcharles at ti dot com>
* gst/rtp/gstrtpamrdepay.c: (gst_rtp_amr_depay_setcaps),
(gst_rtp_amr_depay_process):
* gst/rtp/gstrtpamrdepay.h:
* gst/rtp/gstrtpamrpay.c: (gst_rtp_amr_pay_base_init),
(gst_rtp_amr_pay_class_init), (gst_rtp_amr_pay_init),
(gst_rtp_amr_pay_setcaps), (gst_rtp_amr_pay_handle_buffer):
* gst/rtp/gstrtpamrpay.h:
Add support for AMR-WB.
Small cleanups such as using BOILERPLATE.
Diffstat (limited to 'gst/rtp/gstrtpamrpay.c')
-rw-r--r-- | gst/rtp/gstrtpamrpay.c | 119 |
1 files changed, 75 insertions, 44 deletions
diff --git a/gst/rtp/gstrtpamrpay.c b/gst/rtp/gstrtpamrpay.c index 9fac30bd..e32b11f3 100644 --- a/gst/rtp/gstrtpamrpay.c +++ b/gst/rtp/gstrtpamrpay.c @@ -35,29 +35,36 @@ GST_DEBUG_CATEGORY_STATIC (rtpamrpay_debug); * RFC 3267 - Real-Time Transport Protocol (RTP) Payload Format and File * Storage Format for the Adaptive Multi-Rate (AMR) and Adaptive * Multi-Rate Wideband (AMR-WB) Audio Codecs. + * + * ETSI TS 126 201 V6.0.0 (2004-12) - Digital cellular telecommunications system (Phase 2+); + * Universal Mobile Telecommunications System (UMTS); + * AMR speech codec, wideband; + * Frame structure + * (3GPP TS 26.201 version 6.0.0 Release 6) */ /* elementfactory information */ static const GstElementDetails gst_rtp_amrpay_details = GST_ELEMENT_DETAILS ("RTP packet payloader", "Codec/Payloader/Network", - "Payload-encode AMR audio into RTP packets (RFC 3267)", + "Payload-encode AMR or AMR-WB audio into RTP packets (RFC 3267)", "Wim Taymans <wim@fluendo.com>"); static GstStaticPadTemplate gst_rtp_amr_pay_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", + GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("audio/AMR, channels=(int)1, rate=(int)8000") + GST_STATIC_CAPS ("audio/AMR, channels=(int)1, rate=(int)8000; " + "audio/AMR-WB, channels=(int)1, rate=(int)16000") ); static GstStaticPadTemplate gst_rtp_amr_pay_src_template = -GST_STATIC_PAD_TEMPLATE ("src", + GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS ("application/x-rtp, " "media = (string) \"audio\", " - "payload = (int) [ 96, 127 ], " + "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", " "clock-rate = (int) 8000, " "encoding-name = (string) \"AMR\", " "encoding-params = (string) \"1\", " @@ -68,47 +75,33 @@ GST_STATIC_PAD_TEMPLATE ("src", "mode-set = (int) [ 0, 7 ], " "mode-change-period = (int) [ 1, MAX ], " "mode-change-neighbor = (string) { \"0\", \"1\" }, " + "maxptime = (int) [ 20, MAX ], " "ptime = (int) [ 20, MAX ];" + "application/x-rtp, " + "media = (string) \"audio\", " + "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", " + "clock-rate = (int) 16000, " + "encoding-name = (string) \"AMR-WB\", " + "encoding-params = (string) \"1\", " + "octet-align = (string) \"1\", " + "crc = (string) \"0\", " + "robust-sorting = (string) \"0\", " + "interleaving = (string) \"0\", " + "mode-set = (int) [ 0, 7 ], " + "mode-change-period = (int) [ 1, MAX ], " + "mode-change-neighbor = (string) { \"0\", \"1\" }, " "maxptime = (int) [ 20, MAX ], " "ptime = (int) [ 20, MAX ]") ); -static void gst_rtp_amr_pay_class_init (GstRtpAMRPayClass * klass); -static void gst_rtp_amr_pay_base_init (GstRtpAMRPayClass * klass); -static void gst_rtp_amr_pay_init (GstRtpAMRPay * rtpamrpay); - static gboolean gst_rtp_amr_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps); static GstFlowReturn gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * pad, GstBuffer * buffer); -static GstBaseRTPPayloadClass *parent_class = NULL; - -static GType -gst_rtp_amr_pay_get_type (void) -{ - static GType rtpamrpay_type = 0; - - if (!rtpamrpay_type) { - static const GTypeInfo rtpamrpay_info = { - sizeof (GstRtpAMRPayClass), - (GBaseInitFunc) gst_rtp_amr_pay_base_init, - NULL, - (GClassInitFunc) gst_rtp_amr_pay_class_init, - NULL, - NULL, - sizeof (GstRtpAMRPay), - 0, - (GInstanceInitFunc) gst_rtp_amr_pay_init, - }; - - rtpamrpay_type = - g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpAMRPay", - &rtpamrpay_info, 0); - } - return rtpamrpay_type; -} +GST_BOILERPLATE (GstRtpAMRPay, gst_rtp_amr_pay, GstBaseRTPPayload, + GST_TYPE_BASE_RTP_PAYLOAD); static void -gst_rtp_amr_pay_base_init (GstRtpAMRPayClass * klass) +gst_rtp_amr_pay_base_init (gpointer klass) { GstElementClass *element_class = GST_ELEMENT_CLASS (klass); @@ -137,12 +130,11 @@ gst_rtp_amr_pay_class_init (GstRtpAMRPayClass * klass) gstbasertppayload_class->handle_buffer = gst_rtp_amr_pay_handle_buffer; GST_DEBUG_CATEGORY_INIT (rtpamrpay_debug, "rtpamrpay", 0, - "AMR RTP Payloader"); - + "AMR/AMR-WB RTP Payloader"); } static void -gst_rtp_amr_pay_init (GstRtpAMRPay * rtpamrpay) +gst_rtp_amr_pay_init (GstRtpAMRPay * rtpamrpay, GstRtpAMRPayClass * klass) { } @@ -150,10 +142,29 @@ static gboolean gst_rtp_amr_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps) { GstRtpAMRPay *rtpamrpay; + const GstStructure *s; + const gchar *str; rtpamrpay = GST_RTP_AMR_PAY (basepayload); - gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR", 8000); + /* figure out the mode Narrow or Wideband */ + s = gst_caps_get_structure (caps, 0); + if ((str = gst_structure_get_name (s))) { + if (strcmp (str, "audio/AMR") == 0) + rtpamrpay->mode = GST_RTP_AMR_P_MODE_NB; + else if (strcmp (str, "audio/AMR-WB") == 0) + rtpamrpay->mode = GST_RTP_AMR_P_MODE_WB; + else + goto wrong_type; + } else + goto wrong_type; + + if (rtpamrpay->mode == GST_RTP_AMR_P_MODE_NB) + gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR", 8000); + else + gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR-WB", + 16000); + gst_basertppayload_set_outcaps (basepayload, "encoding-params", G_TYPE_STRING, "1", "octet-align", G_TYPE_STRING, "1", /* don't set the defaults @@ -165,13 +176,25 @@ gst_rtp_amr_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps) NULL); return TRUE; + + /* ERRORS */ +wrong_type: + { + GST_ERROR_OBJECT (rtpamrpay, "unsupported media type '%s'", + GST_STR_NULL (str)); + return FALSE; + } } /* -1 is invalid */ -static gint frame_size[16] = { +static gint nb_frame_size[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, -1, -1, -1, -1, -1, -1, 0 }; +static gint wb_frame_size[16] = { + 17, 23, 32, 36, 40, 46, 50, 58, + 60, -1, -1, -1, -1, -1, -1, 0 +}; static GstFlowReturn gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * basepayload, @@ -186,6 +209,7 @@ gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * basepayload, guint packet_len, mtu; gint i, num_packets, num_nonempty_packets; gint amr_len; + gint *frame_size; rtpamrpay = GST_RTP_AMR_PAY (basepayload); mtu = GST_BASE_RTP_PAYLOAD_MTU (rtpamrpay); @@ -194,12 +218,19 @@ gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * basepayload, data = GST_BUFFER_DATA (buffer); timestamp = GST_BUFFER_TIMESTAMP (buffer); - /* FIXME, only - * octet aligned, no interleaving, single channel, no CRC, - * no robust-sorting. */ + /* setup frame size pointer */ + if (rtpamrpay->mode == GST_RTP_AMR_P_MODE_NB) + frame_size = nb_frame_size; + else + frame_size = wb_frame_size; GST_DEBUG_OBJECT (basepayload, "got %d bytes", size); + /* FIXME, only + * octet aligned, no interleaving, single channel, no CRC, + * no robust-sorting. To fix this you need to implement the downstream + * negotiation function. */ + /* first count number of packets and total amr frame size */ amr_len = num_packets = num_nonempty_packets = 0; for (i = 0; i < size; i++) { |