mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
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.
This commit is contained in:
parent
0b2e6f1c90
commit
89ae9b40f9
5 changed files with 168 additions and 54 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2007-06-01 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2007-05-31 Wim Taymans <wim@fluendo.com>
|
2007-05-31 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/rtsp/rtspextwms.c: (rtsp_ext_wms_configure_stream):
|
* gst/rtsp/rtspextwms.c: (rtsp_ext_wms_configure_stream):
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
static const GstElementDetails gst_rtp_amrdepay_details =
|
static const GstElementDetails gst_rtp_amrdepay_details =
|
||||||
GST_ELEMENT_DETAILS ("RTP packet depayloader",
|
GST_ELEMENT_DETAILS ("RTP packet depayloader",
|
||||||
"Codec/Depayloader/Network",
|
"Codec/Depayloader/Network",
|
||||||
"Extracts AMR audio from RTP packets (RFC 3267)",
|
"Extracts AMR or AMR-WB audio from RTP packets (RFC 3267)",
|
||||||
"Wim Taymans <wim@fluendo.com>");
|
"Wim Taymans <wim@fluendo.com>");
|
||||||
|
|
||||||
/* RtpAMRDepay signals and args */
|
/* RtpAMRDepay signals and args */
|
||||||
|
@ -71,6 +71,25 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
* GstCaps mapping. */
|
* GstCaps mapping. */
|
||||||
"octet-align = (string) \"1\", "
|
"octet-align = (string) \"1\", "
|
||||||
"crc = (string) { \"0\", \"1\" }, "
|
"crc = (string) { \"0\", \"1\" }, "
|
||||||
|
"robust-sorting = (string) \"0\", " "interleaving = (string) \"0\";"
|
||||||
|
/* following options are not needed for a decoder
|
||||||
|
*
|
||||||
|
"mode-set = (int) [ 0, 7 ], "
|
||||||
|
"mode-change-period = (int) [ 1, MAX ], "
|
||||||
|
"mode-change-neighbor = (boolean) { TRUE, FALSE }, "
|
||||||
|
"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\", "
|
||||||
|
/* NOTE that all values must be strings in orde to be able to do SDP <->
|
||||||
|
* GstCaps mapping. */
|
||||||
|
"octet-align = (string) \"1\", "
|
||||||
|
"crc = (string) { \"0\", \"1\" }, "
|
||||||
"robust-sorting = (string) \"0\", " "interleaving = (string) \"0\""
|
"robust-sorting = (string) \"0\", " "interleaving = (string) \"0\""
|
||||||
/* following options are not needed for a decoder
|
/* following options are not needed for a decoder
|
||||||
*
|
*
|
||||||
|
@ -87,7 +106,8 @@ static GstStaticPadTemplate gst_rtp_amr_depay_src_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
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 gboolean gst_rtp_amr_depay_setcaps (GstBaseRTPDepayload * depayload,
|
static gboolean gst_rtp_amr_depay_setcaps (GstBaseRTPDepayload * depayload,
|
||||||
|
@ -146,13 +166,28 @@ gst_rtp_amr_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||||
GstCaps *srccaps;
|
GstCaps *srccaps;
|
||||||
GstRtpAMRDepay *rtpamrdepay;
|
GstRtpAMRDepay *rtpamrdepay;
|
||||||
const gchar *params;
|
const gchar *params;
|
||||||
const gchar *str;
|
const gchar *str, *type;
|
||||||
gint clock_rate = 8000; /* default */
|
gint clock_rate, need_clock_rate;
|
||||||
|
|
||||||
rtpamrdepay = GST_RTP_AMR_DEPAY (depayload);
|
rtpamrdepay = GST_RTP_AMR_DEPAY (depayload);
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
|
/* figure out the mode first and set the clock rates */
|
||||||
|
if ((str = gst_structure_get_string (structure, "encoding-name"))) {
|
||||||
|
if (strcmp (str, "AMR") == 0) {
|
||||||
|
rtpamrdepay->mode = GST_RTP_AMR_DP_MODE_NB;
|
||||||
|
clock_rate = need_clock_rate = 8000;
|
||||||
|
type = "audio/AMR";
|
||||||
|
} else if (strcmp (str, "AMR-WB") == 0) {
|
||||||
|
rtpamrdepay->mode = GST_RTP_AMR_DP_MODE_WB;
|
||||||
|
clock_rate = need_clock_rate = 16000;
|
||||||
|
type = "audio/AMR-WB";
|
||||||
|
} else
|
||||||
|
goto invalid_mode;
|
||||||
|
} else
|
||||||
|
goto invalid_mode;
|
||||||
|
|
||||||
if (!(str = gst_structure_get_string (structure, "octet-align")))
|
if (!(str = gst_structure_get_string (structure, "octet-align")))
|
||||||
rtpamrdepay->octet_align = FALSE;
|
rtpamrdepay->octet_align = FALSE;
|
||||||
else
|
else
|
||||||
|
@ -201,7 +236,7 @@ gst_rtp_amr_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||||
* no robust sorting, no interleaving for now */
|
* no robust sorting, no interleaving for now */
|
||||||
if (rtpamrdepay->channels != 1)
|
if (rtpamrdepay->channels != 1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (clock_rate != 8000)
|
if (clock_rate != need_clock_rate)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (rtpamrdepay->octet_align != TRUE)
|
if (rtpamrdepay->octet_align != TRUE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -210,22 +245,34 @@ gst_rtp_amr_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||||
if (rtpamrdepay->interleaving != FALSE)
|
if (rtpamrdepay->interleaving != FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
srccaps = gst_caps_new_simple ("audio/AMR",
|
srccaps = gst_caps_new_simple (type,
|
||||||
"channels", G_TYPE_INT, rtpamrdepay->channels,
|
"channels", G_TYPE_INT, rtpamrdepay->channels,
|
||||||
"rate", G_TYPE_INT, clock_rate, NULL);
|
"rate", G_TYPE_INT, clock_rate, NULL);
|
||||||
|
|
||||||
gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), srccaps);
|
gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), srccaps);
|
||||||
gst_caps_unref (srccaps);
|
gst_caps_unref (srccaps);
|
||||||
|
|
||||||
rtpamrdepay->negotiated = TRUE;
|
rtpamrdepay->negotiated = TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
invalid_mode:
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (rtpamrdepay, "invalid encoding-name");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -1 is invalid */
|
/* -1 is invalid */
|
||||||
static gint frame_size[16] = {
|
static gint nb_frame_size[16] = {
|
||||||
12, 13, 15, 17, 19, 20, 26, 31,
|
12, 13, 15, 17, 19, 20, 26, 31,
|
||||||
5, -1, -1, -1, -1, -1, -1, 0
|
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 GstBuffer *
|
static GstBuffer *
|
||||||
gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||||
|
@ -233,6 +280,7 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||||
GstRtpAMRDepay *rtpamrdepay;
|
GstRtpAMRDepay *rtpamrdepay;
|
||||||
GstBuffer *outbuf = NULL;
|
GstBuffer *outbuf = NULL;
|
||||||
gint payload_len;
|
gint payload_len;
|
||||||
|
gint *frame_size;
|
||||||
|
|
||||||
rtpamrdepay = GST_RTP_AMR_DEPAY (depayload);
|
rtpamrdepay = GST_RTP_AMR_DEPAY (depayload);
|
||||||
|
|
||||||
|
@ -242,7 +290,13 @@ gst_rtp_amr_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||||
if (!gst_rtp_buffer_validate (buf))
|
if (!gst_rtp_buffer_validate (buf))
|
||||||
goto invalid_packet;
|
goto invalid_packet;
|
||||||
|
|
||||||
/* when we get here, 1 channel, 8000 Hz, octet aligned, no CRC,
|
/* setup frame size pointer */
|
||||||
|
if (rtpamrdepay->mode == GST_RTP_AMR_DP_MODE_NB)
|
||||||
|
frame_size = nb_frame_size;
|
||||||
|
else
|
||||||
|
frame_size = wb_frame_size;
|
||||||
|
|
||||||
|
/* when we get here, 1 channel, 8000/16000 Hz, octet aligned, no CRC,
|
||||||
* no robust sorting, no interleaving data is to be depayloaded */
|
* no robust sorting, no interleaving data is to be depayloaded */
|
||||||
{
|
{
|
||||||
guint8 *payload, *p, *dp;
|
guint8 *payload, *p, *dp;
|
||||||
|
|
|
@ -39,11 +39,18 @@ G_BEGIN_DECLS
|
||||||
typedef struct _GstRtpAMRDepay GstRtpAMRDepay;
|
typedef struct _GstRtpAMRDepay GstRtpAMRDepay;
|
||||||
typedef struct _GstRtpAMRDepayClass GstRtpAMRDepayClass;
|
typedef struct _GstRtpAMRDepayClass GstRtpAMRDepayClass;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GST_RTP_AMR_DP_MODE_INVALID = 0,
|
||||||
|
GST_RTP_AMR_DP_MODE_NB = 1,
|
||||||
|
GST_RTP_AMR_DP_MODE_WB = 2
|
||||||
|
} GstRtpAMRDepayMode;
|
||||||
|
|
||||||
struct _GstRtpAMRDepay
|
struct _GstRtpAMRDepay
|
||||||
{
|
{
|
||||||
GstBaseRTPDepayload depayload;
|
GstBaseRTPDepayload depayload;
|
||||||
|
|
||||||
gboolean negotiated;
|
gboolean negotiated;
|
||||||
|
GstRtpAMRDepayMode mode;
|
||||||
|
|
||||||
gboolean octet_align;
|
gboolean octet_align;
|
||||||
guint8 mode_set;
|
guint8 mode_set;
|
||||||
|
|
|
@ -35,20 +35,27 @@ GST_DEBUG_CATEGORY_STATIC (rtpamrpay_debug);
|
||||||
* RFC 3267 - Real-Time Transport Protocol (RTP) Payload Format and File
|
* RFC 3267 - Real-Time Transport Protocol (RTP) Payload Format and File
|
||||||
* Storage Format for the Adaptive Multi-Rate (AMR) and Adaptive
|
* Storage Format for the Adaptive Multi-Rate (AMR) and Adaptive
|
||||||
* Multi-Rate Wideband (AMR-WB) Audio Codecs.
|
* 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 */
|
/* elementfactory information */
|
||||||
static const GstElementDetails gst_rtp_amrpay_details =
|
static const GstElementDetails gst_rtp_amrpay_details =
|
||||||
GST_ELEMENT_DETAILS ("RTP packet payloader",
|
GST_ELEMENT_DETAILS ("RTP packet payloader",
|
||||||
"Codec/Payloader/Network",
|
"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>");
|
"Wim Taymans <wim@fluendo.com>");
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_rtp_amr_pay_sink_template =
|
static GstStaticPadTemplate gst_rtp_amr_pay_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
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 =
|
static GstStaticPadTemplate gst_rtp_amr_pay_src_template =
|
||||||
|
@ -57,7 +64,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("application/x-rtp, "
|
GST_STATIC_CAPS ("application/x-rtp, "
|
||||||
"media = (string) \"audio\", "
|
"media = (string) \"audio\", "
|
||||||
"payload = (int) [ 96, 127 ], "
|
"payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
|
||||||
"clock-rate = (int) 8000, "
|
"clock-rate = (int) 8000, "
|
||||||
"encoding-name = (string) \"AMR\", "
|
"encoding-name = (string) \"AMR\", "
|
||||||
"encoding-params = (string) \"1\", "
|
"encoding-params = (string) \"1\", "
|
||||||
|
@ -68,47 +75,33 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
"mode-set = (int) [ 0, 7 ], "
|
"mode-set = (int) [ 0, 7 ], "
|
||||||
"mode-change-period = (int) [ 1, MAX ], "
|
"mode-change-period = (int) [ 1, MAX ], "
|
||||||
"mode-change-neighbor = (string) { \"0\", \"1\" }, "
|
"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 ]")
|
"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,
|
static gboolean gst_rtp_amr_pay_setcaps (GstBaseRTPPayload * basepayload,
|
||||||
GstCaps * caps);
|
GstCaps * caps);
|
||||||
static GstFlowReturn gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * pad,
|
static GstFlowReturn gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * pad,
|
||||||
GstBuffer * buffer);
|
GstBuffer * buffer);
|
||||||
|
|
||||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
GST_BOILERPLATE (GstRtpAMRPay, gst_rtp_amr_pay, GstBaseRTPPayload,
|
||||||
|
GST_TYPE_BASE_RTP_PAYLOAD);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
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);
|
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;
|
gstbasertppayload_class->handle_buffer = gst_rtp_amr_pay_handle_buffer;
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (rtpamrpay_debug, "rtpamrpay", 0,
|
GST_DEBUG_CATEGORY_INIT (rtpamrpay_debug, "rtpamrpay", 0,
|
||||||
"AMR RTP Payloader");
|
"AMR/AMR-WB RTP Payloader");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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)
|
gst_rtp_amr_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstRtpAMRPay *rtpamrpay;
|
GstRtpAMRPay *rtpamrpay;
|
||||||
|
const GstStructure *s;
|
||||||
|
const gchar *str;
|
||||||
|
|
||||||
rtpamrpay = GST_RTP_AMR_PAY (basepayload);
|
rtpamrpay = GST_RTP_AMR_PAY (basepayload);
|
||||||
|
|
||||||
|
/* 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);
|
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,
|
gst_basertppayload_set_outcaps (basepayload,
|
||||||
"encoding-params", G_TYPE_STRING, "1", "octet-align", G_TYPE_STRING, "1",
|
"encoding-params", G_TYPE_STRING, "1", "octet-align", G_TYPE_STRING, "1",
|
||||||
/* don't set the defaults
|
/* don't set the defaults
|
||||||
|
@ -165,13 +176,25 @@ gst_rtp_amr_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
wrong_type:
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (rtpamrpay, "unsupported media type '%s'",
|
||||||
|
GST_STR_NULL (str));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -1 is invalid */
|
/* -1 is invalid */
|
||||||
static gint frame_size[16] = {
|
static gint nb_frame_size[16] = {
|
||||||
12, 13, 15, 17, 19, 20, 26, 31,
|
12, 13, 15, 17, 19, 20, 26, 31,
|
||||||
5, -1, -1, -1, -1, -1, -1, 0
|
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
|
static GstFlowReturn
|
||||||
gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
|
@ -186,6 +209,7 @@ gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
guint packet_len, mtu;
|
guint packet_len, mtu;
|
||||||
gint i, num_packets, num_nonempty_packets;
|
gint i, num_packets, num_nonempty_packets;
|
||||||
gint amr_len;
|
gint amr_len;
|
||||||
|
gint *frame_size;
|
||||||
|
|
||||||
rtpamrpay = GST_RTP_AMR_PAY (basepayload);
|
rtpamrpay = GST_RTP_AMR_PAY (basepayload);
|
||||||
mtu = GST_BASE_RTP_PAYLOAD_MTU (rtpamrpay);
|
mtu = GST_BASE_RTP_PAYLOAD_MTU (rtpamrpay);
|
||||||
|
@ -194,12 +218,19 @@ gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||||
data = GST_BUFFER_DATA (buffer);
|
data = GST_BUFFER_DATA (buffer);
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
|
|
||||||
/* FIXME, only
|
/* setup frame size pointer */
|
||||||
* octet aligned, no interleaving, single channel, no CRC,
|
if (rtpamrpay->mode == GST_RTP_AMR_P_MODE_NB)
|
||||||
* no robust-sorting. */
|
frame_size = nb_frame_size;
|
||||||
|
else
|
||||||
|
frame_size = wb_frame_size;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (basepayload, "got %d bytes", 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 */
|
/* first count number of packets and total amr frame size */
|
||||||
amr_len = num_packets = num_nonempty_packets = 0;
|
amr_len = num_packets = num_nonempty_packets = 0;
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
|
|
|
@ -40,9 +40,17 @@ G_BEGIN_DECLS
|
||||||
typedef struct _GstRtpAMRPay GstRtpAMRPay;
|
typedef struct _GstRtpAMRPay GstRtpAMRPay;
|
||||||
typedef struct _GstRtpAMRPayClass GstRtpAMRPayClass;
|
typedef struct _GstRtpAMRPayClass GstRtpAMRPayClass;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GST_RTP_AMR_P_MODE_INVALID = 0,
|
||||||
|
GST_RTP_AMR_P_MODE_NB = 1,
|
||||||
|
GST_RTP_AMR_P_MODE_WB = 2
|
||||||
|
} GstRtpAMRPayMode;
|
||||||
|
|
||||||
struct _GstRtpAMRPay
|
struct _GstRtpAMRPay
|
||||||
{
|
{
|
||||||
GstBaseRTPPayload payload;
|
GstBaseRTPPayload payload;
|
||||||
|
|
||||||
|
GstRtpAMRPayMode mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstRtpAMRPayClass
|
struct _GstRtpAMRPayClass
|
||||||
|
|
Loading…
Reference in a new issue