summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2005-09-15 13:57:56 +0000
committerWim Taymans <wim.taymans@gmail.com>2005-09-15 13:57:56 +0000
commitfc158bc3c2739eabfb092f7a45f6656ac8c96e25 (patch)
tree199f9ea3d2fddfcbc8315e95d6fe17c2e9936cd5 /gst
parentc7468729e9e05fa3cbcf6ee1fbbd578c516e2200 (diff)
Updates to payloader/depayloaders, make payloaders use the base classes.
Original commit message from CVS: Updates to payloader/depayloaders, make payloaders use the base classes. Updated README with suggested RTP caps and how to convert to/from SDP. Added config descriptor in mp4v payloader.
Diffstat (limited to 'gst')
-rw-r--r--gst/rtp/Makefile.am2
-rw-r--r--gst/rtp/README67
-rw-r--r--gst/rtp/gstrtp.c8
-rw-r--r--gst/rtp/gstrtpamrdec.c39
-rw-r--r--gst/rtp/gstrtpamrdepay.c39
-rw-r--r--gst/rtp/gstrtpamrenc.c200
-rw-r--r--gst/rtp/gstrtpamrenc.h14
-rw-r--r--gst/rtp/gstrtpamrpay.c200
-rw-r--r--gst/rtp/gstrtpamrpay.h14
-rw-r--r--gst/rtp/gstrtpgsmdepay.c139
-rw-r--r--gst/rtp/gstrtpgsmdepay.h42
-rw-r--r--gst/rtp/gstrtpgsmenc.c242
-rw-r--r--gst/rtp/gstrtpgsmenc.h52
-rw-r--r--gst/rtp/gstrtpgsmparse.c139
-rw-r--r--gst/rtp/gstrtpgsmparse.h42
-rw-r--r--gst/rtp/gstrtpgsmpay.c242
-rw-r--r--gst/rtp/gstrtpgsmpay.h52
-rw-r--r--gst/rtp/gstrtph263pdec.c24
-rw-r--r--gst/rtp/gstrtph263pdepay.c24
-rw-r--r--gst/rtp/gstrtph263penc.c192
-rw-r--r--gst/rtp/gstrtph263penc.h14
-rw-r--r--gst/rtp/gstrtph263ppay.c192
-rw-r--r--gst/rtp/gstrtph263ppay.h14
-rw-r--r--gst/rtp/gstrtpmp4vdec.c9
-rw-r--r--gst/rtp/gstrtpmp4vdepay.c9
-rw-r--r--gst/rtp/gstrtpmp4venc.c313
-rw-r--r--gst/rtp/gstrtpmp4venc.h14
-rw-r--r--gst/rtp/gstrtpmp4vpay.c313
-rw-r--r--gst/rtp/gstrtpmp4vpay.h14
-rw-r--r--gst/rtp/gstrtpmpadec.c5
-rw-r--r--gst/rtp/gstrtpmpadepay.c5
-rw-r--r--gst/rtp/gstrtpmpaenc.c171
-rw-r--r--gst/rtp/gstrtpmpaenc.h11
-rw-r--r--gst/rtp/gstrtpmpapay.c171
-rw-r--r--gst/rtp/gstrtpmpapay.h11
35 files changed, 1021 insertions, 2018 deletions
diff --git a/gst/rtp/Makefile.am b/gst/rtp/Makefile.am
index 073e1145..151b3ef1 100644
--- a/gst/rtp/Makefile.am
+++ b/gst/rtp/Makefile.am
@@ -4,6 +4,8 @@ libgstrtp_la_SOURCES = gstrtp.c \
gstrtpdec.c \
gstrtpmpadec.c \
gstrtpmpaenc.c \
+ gstrtpgsmenc.c \
+ gstrtpgsmparse.c \
gstrtpamrdec.c \
gstrtpamrenc.c \
gstrtph263pdec.c \
diff --git a/gst/rtp/README b/gst/rtp/README
index 6a9b01bd..b809df8a 100644
--- a/gst/rtp/README
+++ b/gst/rtp/README
@@ -1,3 +1,70 @@
+The application/x-rtp mime type
+-------------------------------
+
+For valid RTP packets encapsulated in GstBuffers, we use the caps with
+mime type application/x-rtp.
+
+The following fields can or must (*) be specified in the structure:
+
+ * media: (String) [ "audio", "video", "application", "data", "control" ]
+ Defined in RFC 2327 in the SDP media announcement field.
+
+ * payload: (int) [0, 255]
+ For audio and video, these will normally be a media payload type as
+ defined in the RTP Audio/Video Profile. For dynamicaly allocated
+ payload types, this value will be >= 96 and the encoding_name must be
+ set.
+
+ * clock_rate: (int) [0 - MAXINT]
+ the RTP clock rate
+
+ ssrc: (uint) [0 - MAXINT]
+ The ssrc value currently in use.
+
+ clock_base: (uint) [0 - MAXINT]
+ The RTP time representing time 0
+
+ seqnum_base:
+ The RTP sequence number representing the first rtp packet
+
+ encoding_name: (String) ANY
+ typically second part of the mime type. ex. MP4V-ES. only required if
+ payload type >= 96
+
+ encoding_params: (String) ANY
+ extra encoding parameters (as in the SDP a=rtpmap: field). only required
+ if different from the default of the encoding_name.
+
+ Optional parameters as key/value pairs, media type specific.
+
+ Example:
+
+ "application/x-rtp",
+ "media", G_TYPE_STRING, "audio", -]
+ "payload", G_TYPE_INT, 96, ] - required
+ "clock_rate", G_TYPE_INT, 8000, -]
+ "encoding_name", G_TYPE_STRING, "AMR", -] - required since payload >= 96
+ "encoding_params", G_TYPE_STRING, "1", -] - optional param for AMR
+ "octet-align", G_TYPE_BOOLEAN, TRUE, -]
+ "crc", G_TYPE_BOOLEAN, FALSE, ]
+ "robust-sorting", G_TYPE_BOOLEAN, FALSE, ] AMR specific params.
+ "interleaving", G_TYPE_BOOLEAN, FALSE, -]
+
+ Mapping of caps to and from SDP fields:
+
+ m=<media> <udp port> RTP/AVP <payload> -] media and payload from caps
+ a=rtpmap:<payload> <encoding_name>/<clock_rate>[/<encoding_params>]
+ -> when <payload> >= 96
+ a=fmtp:<payload> <param>=<value>;...
+
+ For above caps:
+
+ m=audio <udp port> RTP/AVP 96
+ a=rtpmap:96 AMR/8000/1
+ a=fmtp:96 octet-align=1;crc=0;robust-sorting=0;interleaving=0
+
+ in RTSP, the SSRC is also sent.
+
TODO
----
diff --git a/gst/rtp/gstrtp.c b/gst/rtp/gstrtp.c
index d571b119..6c6523cc 100644
--- a/gst/rtp/gstrtp.c
+++ b/gst/rtp/gstrtp.c
@@ -22,6 +22,8 @@
#endif
#include "gstrtpdec.h"
+#include "gstrtpgsmenc.h"
+#include "gstrtpgsmparse.h"
#include "gstrtpamrenc.h"
#include "gstrtpamrdec.h"
#include "gstrtpmpaenc.h"
@@ -37,6 +39,12 @@ plugin_init (GstPlugin * plugin)
if (!gst_rtpdec_plugin_init (plugin))
return FALSE;
+ if (!gst_rtpgsmparse_plugin_init (plugin))
+ return FALSE;
+
+ if (!gst_rtpgsmenc_plugin_init (plugin))
+ return FALSE;
+
if (!gst_rtpamrdec_plugin_init (plugin))
return FALSE;
diff --git a/gst/rtp/gstrtpamrdec.c b/gst/rtp/gstrtpamrdec.c
index c242a79c..a576e6fd 100644
--- a/gst/rtp/gstrtpamrdec.c
+++ b/gst/rtp/gstrtpamrdec.c
@@ -32,7 +32,7 @@
static GstElementDetails gst_rtp_amrdec_details = {
"RTP packet parser",
"Codec/Parser/Network",
- "Extracts MPEG audio from RTP packets",
+ "Extracts AMR audio from RTP packets (RFC 3267)",
"Wim Taymans <wim@fluendo.com>"
};
@@ -58,11 +58,14 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 8000, "
+ "encoding_name = (string) \"AMR\", "
+ "encoding_params = (string) \"1\", "
"octet-align = (boolean) TRUE, "
"crc = (boolean) FALSE, "
- "robust-sorting = (boolean) FALSE, "
- "interleaving = (boolean) FALSE, "
- "channels = (int) 1, " "rate = (int) 8000"
+ "robust-sorting = (boolean) FALSE, " "interleaving = (boolean) FALSE"
/* following options are not needed for a decoder
*
"mode-set = (int) [ 0, 7 ], "
@@ -156,18 +159,10 @@ gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass)
static void
gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec)
{
- GstCaps *srccaps;
-
rtpamrdec->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get
(&gst_rtpamrdec_src_template), "src");
- /* FIXME */
- srccaps = gst_caps_new_simple ("audio/AMR",
- "channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
- gst_pad_set_caps (rtpamrdec->srcpad, srccaps);
- gst_caps_unref (srccaps);
-
gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->srcpad);
rtpamrdec->sinkpad =
@@ -184,6 +179,7 @@ gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
GstStructure *structure;
GstCaps *srccaps;
GstRtpAMRDec *rtpamrdec;
+ const gchar *params;
rtpamrdec = GST_RTP_AMR_DEC (GST_OBJECT_PARENT (pad));
@@ -193,10 +189,6 @@ gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
&rtpamrdec->octet_align))
rtpamrdec->octet_align = FALSE;
- /* FIXME, force octect align for now until all elements negotiate
- * correctly*/
- rtpamrdec->octet_align = TRUE;
-
if (!gst_structure_get_boolean (structure, "crc", &rtpamrdec->crc))
rtpamrdec->crc = FALSE;
@@ -223,9 +215,13 @@ gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
rtpamrdec->octet_align = TRUE;
}
- if (!gst_structure_get_int (structure, "channels", &rtpamrdec->channels))
+ if (!(params = gst_structure_get_string (structure, "encoding_params")))
rtpamrdec->channels = 1;
- if (!gst_structure_get_int (structure, "rate", &rtpamrdec->rate))
+ else {
+ rtpamrdec->channels = atoi (params);
+ }
+
+ if (!gst_structure_get_int (structure, "clock_rate", &rtpamrdec->rate))
rtpamrdec->rate = 8000;
/* we require 1 channel, 8000 Hz, octet aligned, no CRC,
@@ -288,7 +284,7 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
/* parse header
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+..
- * | CMR=6 |R|R|R|R|0|FT#1=5 |Q|P|P|
+ * | CMR |R|R|R|R|F| FT |Q|P|P|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+..
*/
CMR = (payload[0] & 0xf0) >> 4;
@@ -314,7 +310,7 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
outbuf = gst_buffer_new_and_alloc (payload_len);
- GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / 8000;
+ GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpamrdec->rate;
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
@@ -392,9 +388,6 @@ gst_rtpamrdec_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_NULL_TO_READY:
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
- /* FIXME, don't require negotiation until all elements
- * do */
- rtpamrdec->negotiated = TRUE;
break;
default:
break;
diff --git a/gst/rtp/gstrtpamrdepay.c b/gst/rtp/gstrtpamrdepay.c
index c242a79c..a576e6fd 100644
--- a/gst/rtp/gstrtpamrdepay.c
+++ b/gst/rtp/gstrtpamrdepay.c
@@ -32,7 +32,7 @@
static GstElementDetails gst_rtp_amrdec_details = {
"RTP packet parser",
"Codec/Parser/Network",
- "Extracts MPEG audio from RTP packets",
+ "Extracts AMR audio from RTP packets (RFC 3267)",
"Wim Taymans <wim@fluendo.com>"
};
@@ -58,11 +58,14 @@ GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 8000, "
+ "encoding_name = (string) \"AMR\", "
+ "encoding_params = (string) \"1\", "
"octet-align = (boolean) TRUE, "
"crc = (boolean) FALSE, "
- "robust-sorting = (boolean) FALSE, "
- "interleaving = (boolean) FALSE, "
- "channels = (int) 1, " "rate = (int) 8000"
+ "robust-sorting = (boolean) FALSE, " "interleaving = (boolean) FALSE"
/* following options are not needed for a decoder
*
"mode-set = (int) [ 0, 7 ], "
@@ -156,18 +159,10 @@ gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass)
static void
gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec)
{
- GstCaps *srccaps;
-
rtpamrdec->srcpad =
gst_pad_new_from_template (gst_static_pad_template_get
(&gst_rtpamrdec_src_template), "src");
- /* FIXME */
- srccaps = gst_caps_new_simple ("audio/AMR",
- "channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
- gst_pad_set_caps (rtpamrdec->srcpad, srccaps);
- gst_caps_unref (srccaps);
-
gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->srcpad);
rtpamrdec->sinkpad =
@@ -184,6 +179,7 @@ gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
GstStructure *structure;
GstCaps *srccaps;
GstRtpAMRDec *rtpamrdec;
+ const gchar *params;
rtpamrdec = GST_RTP_AMR_DEC (GST_OBJECT_PARENT (pad));
@@ -193,10 +189,6 @@ gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
&rtpamrdec->octet_align))
rtpamrdec->octet_align = FALSE;
- /* FIXME, force octect align for now until all elements negotiate
- * correctly*/
- rtpamrdec->octet_align = TRUE;
-
if (!gst_structure_get_boolean (structure, "crc", &rtpamrdec->crc))
rtpamrdec->crc = FALSE;
@@ -223,9 +215,13 @@ gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
rtpamrdec->octet_align = TRUE;
}
- if (!gst_structure_get_int (structure, "channels", &rtpamrdec->channels))
+ if (!(params = gst_structure_get_string (structure, "encoding_params")))
rtpamrdec->channels = 1;
- if (!gst_structure_get_int (structure, "rate", &rtpamrdec->rate))
+ else {
+ rtpamrdec->channels = atoi (params);
+ }
+
+ if (!gst_structure_get_int (structure, "clock_rate", &rtpamrdec->rate))
rtpamrdec->rate = 8000;
/* we require 1 channel, 8000 Hz, octet aligned, no CRC,
@@ -288,7 +284,7 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
/* parse header
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+..
- * | CMR=6 |R|R|R|R|0|FT#1=5 |Q|P|P|
+ * | CMR |R|R|R|R|F| FT |Q|P|P|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+..
*/
CMR = (payload[0] & 0xf0) >> 4;
@@ -314,7 +310,7 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
outbuf = gst_buffer_new_and_alloc (payload_len);
- GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / 8000;
+ GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpamrdec->rate;
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
@@ -392,9 +388,6 @@ gst_rtpamrdec_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_NULL_TO_READY:
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
- /* FIXME, don't require negotiation until all elements
- * do */
- rtpamrdec->negotiated = TRUE;
break;
default:
break;
diff --git a/gst/rtp/gstrtpamrenc.c b/gst/rtp/gstrtpamrenc.c
index a60648d7..9b867cfe 100644
--- a/gst/rtp/gstrtpamrenc.c
+++ b/gst/rtp/gstrtpamrenc.c
@@ -33,29 +33,10 @@
static GstElementDetails gst_rtp_amrenc_details = {
"RTP packet parser",
"Codec/Parser/Network",
- "Encode AMR audio into RTP packets",
+ "Encode AMR audio into RTP packets (RFC 3267)",
"Wim Taymans <wim@fluendo.com>"
};
-/* RtpAMREnc signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_MTU 1024
-#define DEFAULT_PT 96
-#define DEFAULT_SSRC 0
-
-enum
-{
- PROP_0,
- PROP_MTU,
- PROP_PT,
- PROP_SSRC
-};
-
static GstStaticPadTemplate gst_rtpamrenc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -68,34 +49,31 @@ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 8000, "
+ "encoding_name = (string) \"AMR\", "
+ "encoding_params = (string) \"1\", "
"octet-align = (boolean) TRUE, "
"crc = (boolean) FALSE, "
"robust-sorting = (boolean) FALSE, "
"interleaving = (boolean) FALSE, "
- "channels = (int) 1, "
- "rate = (int) 8000, "
"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 ]")
);
-
static void gst_rtpamrenc_class_init (GstRtpAMREncClass * klass);
static void gst_rtpamrenc_base_init (GstRtpAMREncClass * klass);
static void gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc);
-static GstFlowReturn gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer);
-
-static void gst_rtpamrenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtpamrenc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
+static gboolean gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload,
+ GstCaps * caps);
+static GstFlowReturn gst_rtpamrenc_handle_buffer (GstBaseRTPPayload * pad,
+ GstBuffer * buffer);
-static GstStateChangeReturn gst_rtpamrenc_change_state (GstElement * element,
- GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
+static GstBaseRTPPayloadClass *parent_class = NULL;
static GType
gst_rtpamrenc_get_type (void)
@@ -116,7 +94,7 @@ gst_rtpamrenc_get_type (void)
};
rtpamrenc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstRtpAMREnc",
+ g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpAMREnc",
&rtpamrenc_info, 0);
}
return rtpamrenc_type;
@@ -140,64 +118,44 @@ gst_rtpamrenc_class_init (GstRtpAMREncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
+
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_rtpamrenc_set_property;
- gobject_class->get_property = gst_rtpamrenc_get_property;
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
- g_param_spec_uint ("mtu", "MTU",
- "Maximum size of one packet",
- 28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PT,
- g_param_spec_uint ("pt", "payload type",
- "The payload type of the packets",
- 0, 0x80, DEFAULT_PT, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
- g_param_spec_uint ("ssrc", "SSRC",
- "The SSRC of the packets",
- 0, G_MAXUINT, DEFAULT_SSRC, G_PARAM_READWRITE));
-
- gstelement_class->change_state = gst_rtpamrenc_change_state;
+ gstbasertppayload_class->set_caps = gst_rtpamrenc_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtpamrenc_handle_buffer;
}
static void
gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc)
{
- GstCaps *caps;
+}
- rtpamrenc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpamrenc_src_template), "src");
+static gboolean
+gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
+{
+ GstRtpAMREnc *rtpamrenc;
- caps = gst_caps_new_simple ("application/x-rtp",
+ rtpamrenc = GST_RTP_AMR_ENC (basepayload);
+
+ gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR", 8000);
+ gst_basertppayload_set_outcaps (basepayload,
+ "encoding_params", G_TYPE_STRING, "1",
"octet-align", G_TYPE_BOOLEAN, TRUE,
"crc", G_TYPE_BOOLEAN, FALSE,
"robust-sorting", G_TYPE_BOOLEAN, FALSE,
- "interleaving", G_TYPE_BOOLEAN, FALSE,
- "channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
-
- gst_pad_set_caps (rtpamrenc->srcpad, caps);
- gst_caps_unref (caps);
- gst_element_add_pad (GST_ELEMENT (rtpamrenc), rtpamrenc->srcpad);
-
- rtpamrenc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpamrenc_sink_template), "sink");
- gst_pad_set_chain_function (rtpamrenc->sinkpad, gst_rtpamrenc_chain);
- gst_element_add_pad (GST_ELEMENT (rtpamrenc), rtpamrenc->sinkpad);
-
- rtpamrenc->mtu = DEFAULT_MTU;
- rtpamrenc->pt = DEFAULT_PT;
- rtpamrenc->ssrc = DEFAULT_SSRC;
+ "interleaving", G_TYPE_BOOLEAN, FALSE, NULL);
+
+ return TRUE;
}
static GstFlowReturn
-gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer)
+gst_rtpamrenc_handle_buffer (GstBaseRTPPayload * basepayload,
+ GstBuffer * buffer)
{
GstRtpAMREnc *rtpamrenc;
GstFlowReturn ret;
@@ -206,7 +164,7 @@ gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer)
guint8 *payload, *data;
GstClockTime timestamp;
- rtpamrenc = GST_RTP_AMR_ENC (gst_pad_get_parent (pad));
+ rtpamrenc = GST_RTP_AMR_ENC (basepayload);
size = GST_BUFFER_SIZE (buffer);
timestamp = GST_BUFFER_TIMESTAMP (buffer);
@@ -221,12 +179,7 @@ gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer)
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
/* FIXME, assert for now */
- g_assert (GST_BUFFER_SIZE (outbuf) < rtpamrenc->mtu);
-
- gst_rtpbuffer_set_payload_type (outbuf, rtpamrenc->pt);
- gst_rtpbuffer_set_ssrc (outbuf, rtpamrenc->ssrc);
- gst_rtpbuffer_set_seq (outbuf, rtpamrenc->seqnum++);
- gst_rtpbuffer_set_timestamp (outbuf, timestamp * 8000 / GST_SECOND);
+ g_assert (GST_BUFFER_SIZE (outbuf) < GST_BASE_RTP_PAYLOAD_MTU (rtpamrenc));
/* copy timestamp */
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
@@ -256,89 +209,8 @@ gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer)
gst_buffer_unref (buffer);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpamrenc->srcpad));
-
- ret = gst_pad_push (rtpamrenc->srcpad, outbuf);
-
- gst_object_unref (rtpamrenc);
-
- return ret;
-}
-
-static void
-gst_rtpamrenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpAMREnc *rtpamrenc;
+ ret = gst_basertppayload_push (basepayload, outbuf);
- rtpamrenc = GST_RTP_AMR_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- rtpamrenc->mtu = g_value_get_uint (value);
- break;
- case PROP_PT:
- rtpamrenc->pt = g_value_get_uint (value);
- break;
- case PROP_SSRC:
- rtpamrenc->ssrc = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtpamrenc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRtpAMREnc *rtpamrenc;
-
- rtpamrenc = GST_RTP_AMR_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- g_value_set_uint (value, rtpamrenc->mtu);
- break;
- case PROP_PT:
- g_value_set_uint (value, rtpamrenc->pt);
- break;
- case PROP_SSRC:
- g_value_set_uint (value, rtpamrenc->ssrc);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_rtpamrenc_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpAMREnc *rtpamrenc;
- GstStateChangeReturn ret;
-
- rtpamrenc = GST_RTP_AMR_ENC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- rtpamrenc->seqnum = 0;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
return ret;
}
diff --git a/gst/rtp/gstrtpamrenc.h b/gst/rtp/gstrtpamrenc.h
index 7d9e06fe..719cffa3 100644
--- a/gst/rtp/gstrtpamrenc.h
+++ b/gst/rtp/gstrtpamrenc.h
@@ -21,6 +21,7 @@
#define __GST_RTP_AMR_ENC_H__
#include <gst/gst.h>
+#include <gst/rtp/gstbasertppayload.h>
#include <gst/base/gstadapter.h>
G_BEGIN_DECLS
@@ -41,21 +42,12 @@ typedef struct _GstRtpAMREncClass GstRtpAMREncClass;
struct _GstRtpAMREnc
{
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
-
- guint16 seqnum;
- guint pt;
- guint ssrc;
-
- guint mtu;
+ GstBaseRTPPayload payload;
};
struct _GstRtpAMREncClass
{
- GstElementClass parent_class;
+ GstBaseRTPPayloadClass parent_class;
};
gboolean gst_rtpamrenc_plugin_init (GstPlugin * plugin);
diff --git a/gst/rtp/gstrtpamrpay.c b/gst/rtp/gstrtpamrpay.c
index a60648d7..9b867cfe 100644
--- a/gst/rtp/gstrtpamrpay.c
+++ b/gst/rtp/gstrtpamrpay.c
@@ -33,29 +33,10 @@
static GstElementDetails gst_rtp_amrenc_details = {
"RTP packet parser",
"Codec/Parser/Network",
- "Encode AMR audio into RTP packets",
+ "Encode AMR audio into RTP packets (RFC 3267)",
"Wim Taymans <wim@fluendo.com>"
};
-/* RtpAMREnc signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_MTU 1024
-#define DEFAULT_PT 96
-#define DEFAULT_SSRC 0
-
-enum
-{
- PROP_0,
- PROP_MTU,
- PROP_PT,
- PROP_SSRC
-};
-
static GstStaticPadTemplate gst_rtpamrenc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -68,34 +49,31 @@ GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 8000, "
+ "encoding_name = (string) \"AMR\", "
+ "encoding_params = (string) \"1\", "
"octet-align = (boolean) TRUE, "
"crc = (boolean) FALSE, "
"robust-sorting = (boolean) FALSE, "
"interleaving = (boolean) FALSE, "
- "channels = (int) 1, "
- "rate = (int) 8000, "
"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 ]")
);
-
static void gst_rtpamrenc_class_init (GstRtpAMREncClass * klass);
static void gst_rtpamrenc_base_init (GstRtpAMREncClass * klass);
static void gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc);
-static GstFlowReturn gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer);
-
-static void gst_rtpamrenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtpamrenc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
+static gboolean gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload,
+ GstCaps * caps);
+static GstFlowReturn gst_rtpamrenc_handle_buffer (GstBaseRTPPayload * pad,
+ GstBuffer * buffer);
-static GstStateChangeReturn gst_rtpamrenc_change_state (GstElement * element,
- GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
+static GstBaseRTPPayloadClass *parent_class = NULL;
static GType
gst_rtpamrenc_get_type (void)
@@ -116,7 +94,7 @@ gst_rtpamrenc_get_type (void)
};
rtpamrenc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstRtpAMREnc",
+ g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpAMREnc",
&rtpamrenc_info, 0);
}
return rtpamrenc_type;
@@ -140,64 +118,44 @@ gst_rtpamrenc_class_init (GstRtpAMREncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
+
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_rtpamrenc_set_property;
- gobject_class->get_property = gst_rtpamrenc_get_property;
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
- g_param_spec_uint ("mtu", "MTU",
- "Maximum size of one packet",
- 28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PT,
- g_param_spec_uint ("pt", "payload type",
- "The payload type of the packets",
- 0, 0x80, DEFAULT_PT, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
- g_param_spec_uint ("ssrc", "SSRC",
- "The SSRC of the packets",
- 0, G_MAXUINT, DEFAULT_SSRC, G_PARAM_READWRITE));
-
- gstelement_class->change_state = gst_rtpamrenc_change_state;
+ gstbasertppayload_class->set_caps = gst_rtpamrenc_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtpamrenc_handle_buffer;
}
static void
gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc)
{
- GstCaps *caps;
+}
- rtpamrenc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpamrenc_src_template), "src");
+static gboolean
+gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
+{
+ GstRtpAMREnc *rtpamrenc;
- caps = gst_caps_new_simple ("application/x-rtp",
+ rtpamrenc = GST_RTP_AMR_ENC (basepayload);
+
+ gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR", 8000);
+ gst_basertppayload_set_outcaps (basepayload,
+ "encoding_params", G_TYPE_STRING, "1",
"octet-align", G_TYPE_BOOLEAN, TRUE,
"crc", G_TYPE_BOOLEAN, FALSE,
"robust-sorting", G_TYPE_BOOLEAN, FALSE,
- "interleaving", G_TYPE_BOOLEAN, FALSE,
- "channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
-
- gst_pad_set_caps (rtpamrenc->srcpad, caps);
- gst_caps_unref (caps);
- gst_element_add_pad (GST_ELEMENT (rtpamrenc), rtpamrenc->srcpad);
-
- rtpamrenc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpamrenc_sink_template), "sink");
- gst_pad_set_chain_function (rtpamrenc->sinkpad, gst_rtpamrenc_chain);
- gst_element_add_pad (GST_ELEMENT (rtpamrenc), rtpamrenc->sinkpad);
-
- rtpamrenc->mtu = DEFAULT_MTU;
- rtpamrenc->pt = DEFAULT_PT;
- rtpamrenc->ssrc = DEFAULT_SSRC;
+ "interleaving", G_TYPE_BOOLEAN, FALSE, NULL);
+
+ return TRUE;
}
static GstFlowReturn
-gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer)
+gst_rtpamrenc_handle_buffer (GstBaseRTPPayload * basepayload,
+ GstBuffer * buffer)
{
GstRtpAMREnc *rtpamrenc;
GstFlowReturn ret;
@@ -206,7 +164,7 @@ gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer)
guint8 *payload, *data;
GstClockTime timestamp;
- rtpamrenc = GST_RTP_AMR_ENC (gst_pad_get_parent (pad));
+ rtpamrenc = GST_RTP_AMR_ENC (basepayload);
size = GST_BUFFER_SIZE (buffer);
timestamp = GST_BUFFER_TIMESTAMP (buffer);
@@ -221,12 +179,7 @@ gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer)
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
/* FIXME, assert for now */
- g_assert (GST_BUFFER_SIZE (outbuf) < rtpamrenc->mtu);
-
- gst_rtpbuffer_set_payload_type (outbuf, rtpamrenc->pt);
- gst_rtpbuffer_set_ssrc (outbuf, rtpamrenc->ssrc);
- gst_rtpbuffer_set_seq (outbuf, rtpamrenc->seqnum++);
- gst_rtpbuffer_set_timestamp (outbuf, timestamp * 8000 / GST_SECOND);
+ g_assert (GST_BUFFER_SIZE (outbuf) < GST_BASE_RTP_PAYLOAD_MTU (rtpamrenc));
/* copy timestamp */
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
@@ -256,89 +209,8 @@ gst_rtpamrenc_chain (GstPad * pad, GstBuffer * buffer)
gst_buffer_unref (buffer);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpamrenc->srcpad));
-
- ret = gst_pad_push (rtpamrenc->srcpad, outbuf);
-
- gst_object_unref (rtpamrenc);
-
- return ret;
-}
-
-static void
-gst_rtpamrenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpAMREnc *rtpamrenc;
+ ret = gst_basertppayload_push (basepayload, outbuf);
- rtpamrenc = GST_RTP_AMR_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- rtpamrenc->mtu = g_value_get_uint (value);
- break;
- case PROP_PT:
- rtpamrenc->pt = g_value_get_uint (value);
- break;
- case PROP_SSRC:
- rtpamrenc->ssrc = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtpamrenc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRtpAMREnc *rtpamrenc;
-
- rtpamrenc = GST_RTP_AMR_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- g_value_set_uint (value, rtpamrenc->mtu);
- break;
- case PROP_PT:
- g_value_set_uint (value, rtpamrenc->pt);
- break;
- case PROP_SSRC:
- g_value_set_uint (value, rtpamrenc->ssrc);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_rtpamrenc_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpAMREnc *rtpamrenc;
- GstStateChangeReturn ret;
-
- rtpamrenc = GST_RTP_AMR_ENC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- rtpamrenc->seqnum = 0;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
return ret;
}
diff --git a/gst/rtp/gstrtpamrpay.h b/gst/rtp/gstrtpamrpay.h
index 7d9e06fe..719cffa3 100644
--- a/gst/rtp/gstrtpamrpay.h
+++ b/gst/rtp/gstrtpamrpay.h
@@ -21,6 +21,7 @@
#define __GST_RTP_AMR_ENC_H__
#include <gst/gst.h>
+#include <gst/rtp/gstbasertppayload.h>
#include <gst/base/gstadapter.h>
G_BEGIN_DECLS
@@ -41,21 +42,12 @@ typedef struct _GstRtpAMREncClass GstRtpAMREncClass;
struct _GstRtpAMREnc
{
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
-
- guint16 seqnum;
- guint pt;
- guint ssrc;
-
- guint mtu;
+ GstBaseRTPPayload payload;
};
struct _GstRtpAMREncClass
{
- GstElementClass parent_class;
+ GstBaseRTPPayloadClass parent_class;
};
gboolean gst_rtpamrenc_plugin_init (GstPlugin * plugin);
diff --git a/gst/rtp/gstrtpgsmdepay.c b/gst/rtp/gstrtpgsmdepay.c
index 78171cbf..97b43420 100644
--- a/gst/rtp/gstrtpgsmdepay.c
+++ b/gst/rtp/gstrtpgsmdepay.c
@@ -17,8 +17,8 @@
#endif
#include <string.h>
+#include <gst/rtp/gstrtpbuffer.h>
#include "gstrtpgsmparse.h"
-#include "gstrtp-common.h"
/* elementfactory information */
static GstElementDetails gst_rtp_gsmparse_details = {
@@ -60,13 +60,15 @@ static void gst_rtpgsmparse_class_init (GstRtpGSMParseClass * klass);
static void gst_rtpgsmparse_base_init (GstRtpGSMParseClass * klass);
static void gst_rtpgsmparse_init (GstRtpGSMParse * rtpgsmparse);
-static void gst_rtpgsmparse_chain (GstPad * pad, GstData * _data);
+static GstFlowReturn gst_rtpgsmparse_chain (GstPad * pad, GstBuffer * buffer);
static void gst_rtpgsmparse_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_rtpgsmparse_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-static GstStateChangeReturn gst_rtpgsmparse_change_state (GstElement * element);
+
+static GstStateChangeReturn gst_rtpgsmparse_change_state (GstElement * element,
+ GstStateChange transition);
static GstElementClass *parent_class = NULL;
@@ -118,13 +120,13 @@ gst_rtpgsmparse_class_init (GstRtpGSMParseClass * klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+ gobject_class->set_property = gst_rtpgsmparse_set_property;
+ gobject_class->get_property = gst_rtpgsmparse_get_property;
+
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREQUENCY,
g_param_spec_int ("frequency", "frequency", "frequency",
G_MININT, G_MAXINT, 8000, G_PARAM_READWRITE));
- gobject_class->set_property = gst_rtpgsmparse_set_property;
- gobject_class->get_property = gst_rtpgsmparse_get_property;
-
gstelement_class->change_state = gst_rtpgsmparse_change_state;
}
@@ -144,21 +146,7 @@ gst_rtpgsmparse_init (GstRtpGSMParse * rtpgsmparse)
rtpgsmparse->frequency = 8000;
}
-void
-gst_rtpgsmparse_ntohs (GstBuffer * buf)
-{
- gint16 *i, *len;
-
- /* FIXME: is this code correct or even sane at all? */
- i = (gint16 *) GST_BUFFER_DATA (buf);
- len = i + GST_BUFFER_SIZE (buf) / sizeof (gint16 *);
-
- for (; i < len; i++) {
- *i = g_ntohs (*i);
- }
-}
-
-void
+static void
gst_rtpgsm_caps_nego (GstRtpGSMParse * rtpgsmparse)
{
GstCaps *caps;
@@ -166,72 +154,67 @@ gst_rtpgsm_caps_nego (GstRtpGSMParse * rtpgsmparse)
caps = gst_caps_new_simple ("audio/x-gsm",
"rate", G_TYPE_INT, rtpgsmparse->frequency, NULL);
- gst_pad_try_set_caps (rtpgsmparse->srcpad, caps);
+ gst_pad_set_caps (rtpgsmparse->srcpad, caps);
+ gst_caps_unref (caps);
}
-static void
-gst_rtpgsmparse_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_rtpgsmparse_chain (GstPad * pad, GstBuffer * buf)
{
- GstBuffer *buf = GST_BUFFER (_data);
GstRtpGSMParse *rtpgsmparse;
GstBuffer *outbuf;
- Rtp_Packet packet;
- rtp_payload_t pt;
-
- g_return_if_fail (pad != NULL);
- g_return_if_fail (GST_IS_PAD (pad));
- g_return_if_fail (buf != NULL);
+ GstFlowReturn ret;
+ guint8 pt;
- rtpgsmparse = GST_RTP_GSM_PARSE (GST_OBJECT_PARENT (pad));
+ rtpgsmparse = GST_RTP_GSM_PARSE (gst_pad_get_parent (pad));
- g_return_if_fail (rtpgsmparse != NULL);
- g_return_if_fail (GST_IS_RTP_GSM_PARSE (rtpgsmparse));
+ if (GST_PAD_CAPS (rtpgsmparse->srcpad) == NULL) {
+ gst_rtpgsm_caps_nego (rtpgsmparse);
+ }
- if (GST_IS_EVENT (buf)) {
- GstEvent *event = GST_EVENT (buf);
+ if (!gst_rtpbuffer_validate (buf))
+ goto bad_packet;
- gst_pad_event_default (pad, event);
+ if ((pt = gst_rtpbuffer_get_payload_type (buf)) != GST_RTP_PAYLOAD_GSM)
+ goto bad_payload;
- return;
- }
+ {
+ gint payload_len;
+ guint8 *payload;
+ guint32 timestamp;
- if (GST_PAD_CAPS (rtpgsmparse->srcpad) == NULL) {
- gst_rtpgsm_caps_nego (rtpgsmparse);
- }
+ payload_len = gst_rtpbuffer_get_payload_len (buf);
+ payload = gst_rtpbuffer_get_payload (buf);
- packet =
- rtp_packet_new_copy_data (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ timestamp = gst_rtpbuffer_get_timestamp (buf);
- pt = rtp_packet_get_payload_type (packet);
+ outbuf = gst_buffer_new_and_alloc (payload_len);
- if (pt != PAYLOAD_GSM) {
- g_warning ("Unexpected paload type %u\n", pt);
- rtp_packet_free (packet);
- gst_buffer_unref (buf);
- return;
- }
+ GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / 8000;
- outbuf = gst_buffer_new ();
- GST_BUFFER_SIZE (outbuf) = rtp_packet_get_payload_len (packet);
- GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf));
- GST_BUFFER_TIMESTAMP (outbuf) =
- g_ntohl (rtp_packet_get_timestamp (packet)) * GST_SECOND;
+ memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
- memcpy (GST_BUFFER_DATA (outbuf), rtp_packet_get_payload (packet),
- GST_BUFFER_SIZE (outbuf));
+ GST_DEBUG ("pushing buffer of size %d", GST_BUFFER_SIZE (outbuf));
- GST_DEBUG ("gst_rtpgsmparse_chain: pushing buffer of size %d",
- GST_BUFFER_SIZE (outbuf));
+ gst_buffer_unref (buf);
-/* FIXME: According to RFC 1890, this is required, right? */
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- gst_rtpgsmparse_ntohs (outbuf);
-#endif
+ ret = gst_pad_push (rtpgsmparse->srcpad, outbuf);
+ }
- gst_pad_push (rtpgsmparse->srcpad, GST_DATA (outbuf));
+ return ret;
- rtp_packet_free (packet);
- gst_buffer_unref (buf);
+bad_packet:
+ {
+ GST_DEBUG ("Packet did not validate");
+ gst_buffer_unref (buf);
+ return GST_FLOW_ERROR;
+ }
+bad_payload:
+ {
+ GST_DEBUG ("Unexpected payload type %u", pt);
+ gst_buffer_unref (buf);
+ return GST_FLOW_ERROR;
+ }
}
static void
@@ -240,7 +223,6 @@ gst_rtpgsmparse_set_property (GObject * object, guint prop_id,
{
GstRtpGSMParse *rtpgsmparse;
- g_return_if_fail (GST_IS_RTP_GSM_PARSE (object));
rtpgsmparse = GST_RTP_GSM_PARSE (object);
switch (prop_id) {
@@ -258,7 +240,6 @@ gst_rtpgsmparse_get_property (GObject * object, guint prop_id, GValue * value,
{
GstRtpGSMParse *rtpgsmparse;
- g_return_if_fail (GST_IS_RTP_GSM_PARSE (object));
rtpgsmparse = GST_RTP_GSM_PARSE (object);
switch (prop_id) {
@@ -275,28 +256,26 @@ static GstStateChangeReturn
gst_rtpgsmparse_change_state (GstElement * element, GstStateChange transition)
{
GstRtpGSMParse *rtpgsmparse;
-
- g_return_val_if_fail (GST_IS_RTP_GSM_PARSE (element),
- GST_STATE_CHANGE_FAILURE);
+ GstStateChangeReturn ret;
rtpgsmparse = GST_RTP_GSM_PARSE (element);
- GST_DEBUG ("state pending %d\n", GST_STATE_PENDING (element));
-
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
default:
break;
}
- /* if we haven't failed already, give the parent class a chance to ;-) */
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- return GST_STATE_CHANGE_SUCCESS;
+ switch (transition) {
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ break;
+ default:
+ break;
+ }
+ return ret;
}
gboolean
diff --git a/gst/rtp/gstrtpgsmdepay.h b/gst/rtp/gstrtpgsmdepay.h
index 0a006e70..19bd5b28 100644
--- a/gst/rtp/gstrtpgsmdepay.h
+++ b/gst/rtp/gstrtpgsmdepay.h
@@ -21,16 +21,23 @@
#define __GST_RTP_GSM_PARSE_H__
#include <gst/gst.h>
-#include "rtp-packet.h"
-#include "gstrtp-common.h"
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
+G_BEGIN_DECLS
-/* Definition of structure storing data for this element. */
typedef struct _GstRtpGSMParse GstRtpGSMParse;
+typedef struct _GstRtpGSMParseClass GstRtpGSMParseClass;
+
+#define GST_TYPE_RTP_GSM_PARSE \
+ (gst_rtpgsmparse_get_type())
+#define GST_RTP_GSM_PARSE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_GSM_PARSE,GstRtpGSMParse))
+#define GST_RTP_GSM_PARSE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_GSM_PARSE,GstRtpGSMParse))
+#define GST_IS_RTP_GSM_PARSE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_GSM_PARSE))
+#define GST_IS_RTP_GSM_PARSE_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_GSM_PARSE))
+
struct _GstRtpGSMParse
{
GstElement element;
@@ -41,30 +48,13 @@ struct _GstRtpGSMParse
guint frequency;
};
-/* Standard definition defining a class for this element. */
-typedef struct _GstRtpGSMParseClass GstRtpGSMParseClass;
struct _GstRtpGSMParseClass
{
GstElementClass parent_class;
};
-/* Standard macros for defining types for this element. */
-#define GST_TYPE_RTP_GSM_PARSE \
- (gst_rtpgsmparse_get_type())
-#define GST_RTP_GSM_PARSE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_GSM_PARSE,GstRtpGSMParse))
-#define GST_RTP_GSM_PARSE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_GSM_PARSE,GstRtpGSMParse))
-#define GST_IS_RTP_GSM_PARSE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_GSM_PARSE))
-#define GST_IS_RTP_GSM_PARSE_CLASS(obj) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_GSM_PARSE))
-
gboolean gst_rtpgsmparse_plugin_init (GstPlugin * plugin);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
+G_END_DECLS
-#endif /* __GST_RTP_GSM_PARSE_H__ */
+#endif /* __GST_RTP_GSM_PARSE_H__ */
diff --git a/gst/rtp/gstrtpgsmenc.c b/gst/rtp/gstrtpgsmenc.c
index 47daa430..19930ac3 100644
--- a/gst/rtp/gstrtpgsmenc.c
+++ b/gst/rtp/gstrtpgsmenc.c
@@ -23,6 +23,8 @@
#include <stdlib.h>
#include <string.h>
+#include <gst/rtp/gstrtpbuffer.h>
+
#include "gstrtpgsmenc.h"
/* elementfactory information */
@@ -33,19 +35,6 @@ static GstElementDetails gst_rtpgsmenc_details = {
"Zeeshan Ali <zak147@yahoo.com>"
};
-/* RtpGSMEnc signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- /* FILL ME */
- ARG_0
-};
-
static GstStaticPadTemplate gst_rtpgsmenc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -57,24 +46,23 @@ static GstStaticPadTemplate gst_rtpgsmenc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp")
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 8000, " "encoding_name = (string) \"GSM\"")
);
static void gst_rtpgsmenc_class_init (GstRtpGSMEncClass * klass);
static void gst_rtpgsmenc_base_init (GstRtpGSMEncClass * klass);
static void gst_rtpgsmenc_init (GstRtpGSMEnc * rtpgsmenc);
-static void gst_rtpgsmenc_chain (GstPad * pad, GstData * _data);
-static void gst_rtpgsmenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtpgsmenc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static GstPadLinkReturn gst_rtpgsmenc_sinkconnect (GstPad * pad,
- const GstCaps * caps);
-static GstStateChangeReturn gst_rtpgsmenc_change_state (GstElement * element,
- GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
+
+static gboolean gst_rtpgsmenc_setcaps (GstBaseRTPPayload * payload,
+ GstCaps * caps);
+static GstFlowReturn gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * payload,
+ GstBuffer * buffer);
+
+static GstBaseRTPPayloadClass *parent_class = NULL;
static GType
gst_rtpgsmenc_get_type (void)
@@ -95,7 +83,7 @@ gst_rtpgsmenc_get_type (void)
};
rtpgsmenc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstRtpGSMEnc",
+ g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpGSMEnc",
&rtpgsmenc_info, 0);
}
return rtpgsmenc_type;
@@ -118,209 +106,91 @@ gst_rtpgsmenc_class_init (GstRtpGSMEncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_rtpgsmenc_set_property;
- gobject_class->get_property = gst_rtpgsmenc_get_property;
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
- gstelement_class->change_state = gst_rtpgsmenc_change_state;
+ gstbasertppayload_class->set_caps = gst_rtpgsmenc_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtpgsmenc_handle_buffer;
}
static void
gst_rtpgsmenc_init (GstRtpGSMEnc * rtpgsmenc)
{
- rtpgsmenc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpgsmenc_sink_template), "sink");
- rtpgsmenc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpgsmenc_src_template), "src");
- gst_element_add_pad (GST_ELEMENT (rtpgsmenc), rtpgsmenc->sinkpad);
- gst_element_add_pad (GST_ELEMENT (rtpgsmenc), rtpgsmenc->srcpad);
- gst_pad_set_chain_function (rtpgsmenc->sinkpad, gst_rtpgsmenc_chain);
- gst_pad_set_link_function (rtpgsmenc->sinkpad, gst_rtpgsmenc_sinkconnect);
-
rtpgsmenc->frequency = 8000;
-
- rtpgsmenc->next_time = 0;
- rtpgsmenc->time_interval = 0;
-
- rtpgsmenc->seq = 0;
- rtpgsmenc->ssrc = random ();
}
-static GstPadLinkReturn
-gst_rtpgsmenc_sinkconnect (GstPad * pad, const GstCaps * caps)
+static gboolean
+gst_rtpgsmenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
GstRtpGSMEnc *rtpgsmenc;
GstStructure *structure;
gboolean ret;
+ GstCaps *srccaps;
- rtpgsmenc = GST_RTP_GSM_ENC (gst_pad_get_parent (pad));
+ rtpgsmenc = GST_RTP_GSM_ENC (payload);
structure = gst_caps_get_structure (caps, 0);
ret = gst_structure_get_int (structure, "rate", &rtpgsmenc->frequency);
if (!ret)
- return GST_PAD_LINK_REFUSED;
+ return FALSE;
- /* Pre-calculate what we can */
- rtpgsmenc->time_interval = GST_SECOND / (2 * rtpgsmenc->frequency);
+ srccaps = gst_caps_new_simple ("application/x-rtp", NULL);
+ gst_pad_set_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (rtpgsmenc), srccaps);
+ gst_caps_unref (srccaps);
- return GST_PAD_LINK_OK;
+ return TRUE;
}
-
-void
-gst_rtpgsmenc_htons (GstBuffer * buf)
-{
- gint16 *i, *len;
-
- /* FIXME: is this code correct or even sane at all? */
- i = (gint16 *) GST_BUFFER_DATA (buf);
- len = i + GST_BUFFER_SIZE (buf) / sizeof (gint16 *);
-
- for (; i < len; i++) {
- *i = g_htons (*i);
- }
-}
-
-static void
-gst_rtpgsmenc_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * basepayload,
+ GstBuffer * buffer)
{
- GstBuffer *buf = GST_BUFFER (_data);
GstRtpGSMEnc *rtpgsmenc;
+ guint size, payload_len;
GstBuffer *outbuf;
- Rtp_Packet packet;
-
- g_return_if_fail (pad != NULL);
- g_return_if_fail (GST_IS_PAD (pad));
- g_return_if_fail (buf != NULL);
-
- rtpgsmenc = GST_RTP_GSM_ENC (GST_OBJECT_PARENT (pad));
-
- g_return_if_fail (rtpgsmenc != NULL);
- g_return_if_fail (GST_IS_RTP_GSM_ENC (rtpgsmenc));
-
- if (GST_IS_EVENT (buf)) {
- GstEvent *event = GST_EVENT (buf);
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_DISCONTINUOUS:
- GST_DEBUG ("discont");
- rtpgsmenc->next_time = 0;
- gst_pad_event_default (pad, event);
- return;
- default:
- gst_pad_event_default (pad, event);
- return;
- }
- }
+ guint8 *payload, *data;
+ GstClockTime timestamp;
+ GstFlowReturn ret;
- /* We only need the header */
- packet = rtp_packet_new_allocate (0, 0, 0);
-
- rtp_packet_set_csrc_count (packet, 0);
- rtp_packet_set_extension (packet, 0);
- rtp_packet_set_padding (packet, 0);
- rtp_packet_set_version (packet, RTP_VERSION);
- rtp_packet_set_marker (packet, 0);
- rtp_packet_set_ssrc (packet, g_htonl (rtpgsmenc->ssrc));
- rtp_packet_set_seq (packet, g_htons (rtpgsmenc->seq));
- rtp_packet_set_timestamp (packet,
- g_htonl ((guint32) rtpgsmenc->next_time / GST_SECOND));
- rtp_packet_set_payload_type (packet, (guint8) PAYLOAD_GSM);
-
- /* FIXME: According to RFC 1890, this is required, right? */
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- gst_rtpgsmenc_htons (buf);
-#endif
+ rtpgsmenc = GST_RTP_GSM_ENC (basepayload);
- outbuf = gst_buffer_new ();
- GST_BUFFER_SIZE (outbuf) =
- rtp_packet_get_packet_len (packet) + GST_BUFFER_SIZE (buf);
- GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf));
- GST_BUFFER_TIMESTAMP (outbuf) = rtpgsmenc->next_time;
+ size = GST_BUFFER_SIZE (buffer);
+ timestamp = GST_BUFFER_TIMESTAMP (buffer);
- memcpy (GST_BUFFER_DATA (outbuf), packet->data,
- rtp_packet_get_packet_len (packet));
- memcpy (GST_BUFFER_DATA (outbuf) + rtp_packet_get_packet_len (packet),
- GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ /* FIXME, only one GSM frame per RTP packet for now */
+ payload_len = size;
- GST_DEBUG ("gst_rtpgsmenc_chain: pushing buffer of size %d",
- GST_BUFFER_SIZE (outbuf));
- gst_pad_push (rtpgsmenc->srcpad, GST_DATA (outbuf));
+ outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
+ /* FIXME, assert for now */
+ g_assert (GST_BUFFER_SIZE (outbuf) < GST_BASE_RTP_PAYLOAD_MTU (rtpgsmenc));
- ++rtpgsmenc->seq;
- rtpgsmenc->next_time += rtpgsmenc->time_interval * GST_BUFFER_SIZE (buf);
+ gst_rtpbuffer_set_timestamp (outbuf, timestamp * 8000 / GST_SECOND);
- rtp_packet_free (packet);
- gst_buffer_unref (buf);
-}
-
-static void
-gst_rtpgsmenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpGSMEnc *rtpgsmenc;
-
- g_return_if_fail (GST_IS_RTP_GSM_ENC (object));
- rtpgsmenc = GST_RTP_GSM_ENC (object);
-
- switch (prop_id) {
- default:
- break;
- }
-}
-
-static void
-gst_rtpgsmenc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRtpGSMEnc *rtpgsmenc;
-
- g_return_if_fail (GST_IS_RTP_GSM_ENC (object));
- rtpgsmenc = GST_RTP_GSM_ENC (object);
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_rtpgsmenc_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpGSMEnc *rtpgsmenc;
-
- g_return_val_if_fail (GST_IS_RTP_GSM_ENC (element), GST_STATE_CHANGE_FAILURE);
+ /* copy timestamp */
+ GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
- rtpgsmenc = GST_RTP_GSM_ENC (element);
+ /* get payload */
+ payload = gst_rtpbuffer_get_payload (outbuf);
- GST_DEBUG ("state pending %d\n", GST_STATE_PENDING (element));
+ data = GST_BUFFER_DATA (buffer);
- /* if going down into NULL state, close the file if it's open */
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
+ /* copy data in payload */
+ memcpy (&payload[0], data, size);
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
+ gst_buffer_unref (buffer);
- default:
- break;
- }
+ GST_DEBUG ("gst_rtpgsmenc_chain: pushing buffer of size %d",
+ GST_BUFFER_SIZE (outbuf));
- /* if we haven't failed already, give the parent class a chance to ;-) */
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+ ret = gst_basertppayload_push (basepayload, outbuf);
- return GST_STATE_CHANGE_SUCCESS;
+ return ret;
}
gboolean
diff --git a/gst/rtp/gstrtpgsmenc.h b/gst/rtp/gstrtpgsmenc.h
index 1220d402..46fab46a 100644
--- a/gst/rtp/gstrtpgsmenc.h
+++ b/gst/rtp/gstrtpgsmenc.h
@@ -22,42 +22,13 @@
#define __GST_RTP_GSM_ENC_H__
#include <gst/gst.h>
-#include "rtp-packet.h"
-#include "gstrtp-common.h"
+#include <gst/rtp/gstbasertppayload.h>
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
+G_BEGIN_DECLS
-/* Definition of structure storing data for this element. */
typedef struct _GstRtpGSMEnc GstRtpGSMEnc;
-struct _GstRtpGSMEnc
-{
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
-
- guint frequency;
-
- /* the timestamp of the next frame */
- guint64 next_time;
- /* the interval between frames */
- guint64 time_interval;
-
- guint32 ssrc;
- guint16 seq;
-};
-
-/* Standard definition defining a class for this element. */
typedef struct _GstRtpGSMEncClass GstRtpGSMEncClass;
-struct _GstRtpGSMEncClass
-{
- GstElementClass parent_class;
-};
-/* Standard macros for defining types for this element. */
#define GST_TYPE_RTP_GSM_ENC \
(gst_rtpgsmenc_get_type())
#define GST_RTP_GSM_ENC(obj) \
@@ -69,11 +40,20 @@ struct _GstRtpGSMEncClass
#define GST_IS_RTP_GSM_ENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_GSM_ENC))
-gboolean gst_rtpgsmenc_plugin_init (GstPlugin * plugin);
+struct _GstRtpGSMEnc
+{
+ GstBaseRTPPayload payload;
+
+ gint frequency;
+};
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+struct _GstRtpGSMEncClass
+{
+ GstBaseRTPPayloadClass parent_class;
+};
+
+gboolean gst_rtpgsmenc_plugin_init (GstPlugin * plugin);
+G_END_DECLS
-#endif /* __GST_RTP_GSM_ENC_H__ */
+#endif /* __GST_RTP_GSM_ENC_H__ */
diff --git a/gst/rtp/gstrtpgsmparse.c b/gst/rtp/gstrtpgsmparse.c
index 78171cbf..97b43420 100644
--- a/gst/rtp/gstrtpgsmparse.c
+++ b/gst/rtp/gstrtpgsmparse.c
@@ -17,8 +17,8 @@
#endif
#include <string.h>
+#include <gst/rtp/gstrtpbuffer.h>
#include "gstrtpgsmparse.h"
-#include "gstrtp-common.h"
/* elementfactory information */
static GstElementDetails gst_rtp_gsmparse_details = {
@@ -60,13 +60,15 @@ static void gst_rtpgsmparse_class_init (GstRtpGSMParseClass * klass);
static void gst_rtpgsmparse_base_init (GstRtpGSMParseClass * klass);
static void gst_rtpgsmparse_init (GstRtpGSMParse * rtpgsmparse);
-static void gst_rtpgsmparse_chain (GstPad * pad, GstData * _data);
+static GstFlowReturn gst_rtpgsmparse_chain (GstPad * pad, GstBuffer * buffer);
static void gst_rtpgsmparse_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_rtpgsmparse_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-static GstStateChangeReturn gst_rtpgsmparse_change_state (GstElement * element);
+
+static GstStateChangeReturn gst_rtpgsmparse_change_state (GstElement * element,
+ GstStateChange transition);
static GstElementClass *parent_class = NULL;
@@ -118,13 +120,13 @@ gst_rtpgsmparse_class_init (GstRtpGSMParseClass * klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+ gobject_class->set_property = gst_rtpgsmparse_set_property;
+ gobject_class->get_property = gst_rtpgsmparse_get_property;
+
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FREQUENCY,
g_param_spec_int ("frequency", "frequency", "frequency",
G_MININT, G_MAXINT, 8000, G_PARAM_READWRITE));
- gobject_class->set_property = gst_rtpgsmparse_set_property;
- gobject_class->get_property = gst_rtpgsmparse_get_property;
-
gstelement_class->change_state = gst_rtpgsmparse_change_state;
}
@@ -144,21 +146,7 @@ gst_rtpgsmparse_init (GstRtpGSMParse * rtpgsmparse)
rtpgsmparse->frequency = 8000;
}
-void
-gst_rtpgsmparse_ntohs (GstBuffer * buf)
-{
- gint16 *i, *len;
-
- /* FIXME: is this code correct or even sane at all? */
- i = (gint16 *) GST_BUFFER_DATA (buf);
- len = i + GST_BUFFER_SIZE (buf) / sizeof (gint16 *);
-
- for (; i < len; i++) {
- *i = g_ntohs (*i);
- }
-}
-
-void
+static void
gst_rtpgsm_caps_nego (GstRtpGSMParse * rtpgsmparse)
{
GstCaps *caps;
@@ -166,72 +154,67 @@ gst_rtpgsm_caps_nego (GstRtpGSMParse * rtpgsmparse)
caps = gst_caps_new_simple ("audio/x-gsm",
"rate", G_TYPE_INT, rtpgsmparse->frequency, NULL);
- gst_pad_try_set_caps (rtpgsmparse->srcpad, caps);
+ gst_pad_set_caps (rtpgsmparse->srcpad, caps);
+ gst_caps_unref (caps);
}
-static void
-gst_rtpgsmparse_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_rtpgsmparse_chain (GstPad * pad, GstBuffer * buf)
{
- GstBuffer *buf = GST_BUFFER (_data);
GstRtpGSMParse *rtpgsmparse;
GstBuffer *outbuf;
- Rtp_Packet packet;
- rtp_payload_t pt;
-
- g_return_if_fail (pad != NULL);
- g_return_if_fail (GST_IS_PAD (pad));
- g_return_if_fail (buf != NULL);
+ GstFlowReturn ret;
+ guint8 pt;
- rtpgsmparse = GST_RTP_GSM_PARSE (GST_OBJECT_PARENT (pad));
+ rtpgsmparse = GST_RTP_GSM_PARSE (gst_pad_get_parent (pad));
- g_return_if_fail (rtpgsmparse != NULL);
- g_return_if_fail (GST_IS_RTP_GSM_PARSE (rtpgsmparse));
+ if (GST_PAD_CAPS (rtpgsmparse->srcpad) == NULL) {
+ gst_rtpgsm_caps_nego (rtpgsmparse);
+ }
- if (GST_IS_EVENT (buf)) {
- GstEvent *event = GST_EVENT (buf);
+ if (!gst_rtpbuffer_validate (buf))
+ goto bad_packet;
- gst_pad_event_default (pad, event);
+ if ((pt = gst_rtpbuffer_get_payload_type (buf)) != GST_RTP_PAYLOAD_GSM)
+ goto bad_payload;
- return;
- }
+ {
+ gint payload_len;
+ guint8 *payload;
+ guint32 timestamp;
- if (GST_PAD_CAPS (rtpgsmparse->srcpad) == NULL) {
- gst_rtpgsm_caps_nego (rtpgsmparse);
- }
+ payload_len = gst_rtpbuffer_get_payload_len (buf);
+ payload = gst_rtpbuffer_get_payload (buf);
- packet =
- rtp_packet_new_copy_data (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ timestamp = gst_rtpbuffer_get_timestamp (buf);
- pt = rtp_packet_get_payload_type (packet);
+ outbuf = gst_buffer_new_and_alloc (payload_len);
- if (pt != PAYLOAD_GSM) {
- g_warning ("Unexpected paload type %u\n", pt);
- rtp_packet_free (packet);
- gst_buffer_unref (buf);
- return;
- }
+ GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / 8000;
- outbuf = gst_buffer_new ();
- GST_BUFFER_SIZE (outbuf) = rtp_packet_get_payload_len (packet);
- GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf));
- GST_BUFFER_TIMESTAMP (outbuf) =
- g_ntohl (rtp_packet_get_timestamp (packet)) * GST_SECOND;
+ memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
- memcpy (GST_BUFFER_DATA (outbuf), rtp_packet_get_payload (packet),
- GST_BUFFER_SIZE (outbuf));
+ GST_DEBUG ("pushing buffer of size %d", GST_BUFFER_SIZE (outbuf));
- GST_DEBUG ("gst_rtpgsmparse_chain: pushing buffer of size %d",
- GST_BUFFER_SIZE (outbuf));
+ gst_buffer_unref (buf);
-/* FIXME: According to RFC 1890, this is required, right? */
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- gst_rtpgsmparse_ntohs (outbuf);
-#endif
+ ret = gst_pad_push (rtpgsmparse->srcpad, outbuf);
+ }
- gst_pad_push (rtpgsmparse->srcpad, GST_DATA (outbuf));
+ return ret;
- rtp_packet_free (packet);
- gst_buffer_unref (buf);
+bad_packet:
+ {
+ GST_DEBUG ("Packet did not validate");
+ gst_buffer_unref (buf);
+ return GST_FLOW_ERROR;
+ }
+bad_payload:
+ {
+ GST_DEBUG ("Unexpected payload type %u", pt);
+ gst_buffer_unref (buf);
+ return GST_FLOW_ERROR;
+ }
}
static void
@@ -240,7 +223,6 @@ gst_rtpgsmparse_set_property (GObject * object, guint prop_id,
{
GstRtpGSMParse *rtpgsmparse;
- g_return_if_fail (GST_IS_RTP_GSM_PARSE (object));
rtpgsmparse = GST_RTP_GSM_PARSE (object);
switch (prop_id) {
@@ -258,7 +240,6 @@ gst_rtpgsmparse_get_property (GObject * object, guint prop_id, GValue * value,
{
GstRtpGSMParse *rtpgsmparse;
- g_return_if_fail (GST_IS_RTP_GSM_PARSE (object));
rtpgsmparse = GST_RTP_GSM_PARSE (object);
switch (prop_id) {
@@ -275,28 +256,26 @@ static GstStateChangeReturn
gst_rtpgsmparse_change_state (GstElement * element, GstStateChange transition)
{
GstRtpGSMParse *rtpgsmparse;
-
- g_return_val_if_fail (GST_IS_RTP_GSM_PARSE (element),
- GST_STATE_CHANGE_FAILURE);
+ GstStateChangeReturn ret;
rtpgsmparse = GST_RTP_GSM_PARSE (element);
- GST_DEBUG ("state pending %d\n", GST_STATE_PENDING (element));
-
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
default:
break;
}
- /* if we haven't failed already, give the parent class a chance to ;-) */
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
- return GST_STATE_CHANGE_SUCCESS;
+ switch (transition) {
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ break;
+ default:
+ break;
+ }
+ return ret;
}
gboolean
diff --git a/gst/rtp/gstrtpgsmparse.h b/gst/rtp/gstrtpgsmparse.h
index 0a006e70..19bd5b28 100644
--- a/gst/rtp/gstrtpgsmparse.h
+++ b/gst/rtp/gstrtpgsmparse.h
@@ -21,16 +21,23 @@
#define __GST_RTP_GSM_PARSE_H__
#include <gst/gst.h>
-#include "rtp-packet.h"
-#include "gstrtp-common.h"
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
+G_BEGIN_DECLS
-/* Definition of structure storing data for this element. */
typedef struct _GstRtpGSMParse GstRtpGSMParse;
+typedef struct _GstRtpGSMParseClass GstRtpGSMParseClass;
+
+#define GST_TYPE_RTP_GSM_PARSE \
+ (gst_rtpgsmparse_get_type())
+#define GST_RTP_GSM_PARSE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_GSM_PARSE,GstRtpGSMParse))
+#define GST_RTP_GSM_PARSE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_GSM_PARSE,GstRtpGSMParse))
+#define GST_IS_RTP_GSM_PARSE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_GSM_PARSE))
+#define GST_IS_RTP_GSM_PARSE_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_GSM_PARSE))
+
struct _GstRtpGSMParse
{
GstElement element;
@@ -41,30 +48,13 @@ struct _GstRtpGSMParse
guint frequency;
};
-/* Standard definition defining a class for this element. */
-typedef struct _GstRtpGSMParseClass GstRtpGSMParseClass;
struct _GstRtpGSMParseClass
{
GstElementClass parent_class;
};
-/* Standard macros for defining types for this element. */
-#define GST_TYPE_RTP_GSM_PARSE \
- (gst_rtpgsmparse_get_type())
-#define GST_RTP_GSM_PARSE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_GSM_PARSE,GstRtpGSMParse))
-#define GST_RTP_GSM_PARSE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_GSM_PARSE,GstRtpGSMParse))
-#define GST_IS_RTP_GSM_PARSE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_GSM_PARSE))
-#define GST_IS_RTP_GSM_PARSE_CLASS(obj) \
- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_GSM_PARSE))
-
gboolean gst_rtpgsmparse_plugin_init (GstPlugin * plugin);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
+G_END_DECLS
-#endif /* __GST_RTP_GSM_PARSE_H__ */
+#endif /* __GST_RTP_GSM_PARSE_H__ */
diff --git a/gst/rtp/gstrtpgsmpay.c b/gst/rtp/gstrtpgsmpay.c
index 47daa430..19930ac3 100644
--- a/gst/rtp/gstrtpgsmpay.c
+++ b/gst/rtp/gstrtpgsmpay.c
@@ -23,6 +23,8 @@
#include <stdlib.h>
#include <string.h>
+#include <gst/rtp/gstrtpbuffer.h>
+
#include "gstrtpgsmenc.h"
/* elementfactory information */
@@ -33,19 +35,6 @@ static GstElementDetails gst_rtpgsmenc_details = {
"Zeeshan Ali <zak147@yahoo.com>"
};
-/* RtpGSMEnc signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
-{
- /* FILL ME */
- ARG_0
-};
-
static GstStaticPadTemplate gst_rtpgsmenc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -57,24 +46,23 @@ static GstStaticPadTemplate gst_rtpgsmenc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp")
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 8000, " "encoding_name = (string) \"GSM\"")
);
static void gst_rtpgsmenc_class_init (GstRtpGSMEncClass * klass);
static void gst_rtpgsmenc_base_init (GstRtpGSMEncClass * klass);
static void gst_rtpgsmenc_init (GstRtpGSMEnc * rtpgsmenc);
-static void gst_rtpgsmenc_chain (GstPad * pad, GstData * _data);
-static void gst_rtpgsmenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtpgsmenc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-static GstPadLinkReturn gst_rtpgsmenc_sinkconnect (GstPad * pad,
- const GstCaps * caps);
-static GstStateChangeReturn gst_rtpgsmenc_change_state (GstElement * element,
- GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
+
+static gboolean gst_rtpgsmenc_setcaps (GstBaseRTPPayload * payload,
+ GstCaps * caps);
+static GstFlowReturn gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * payload,
+ GstBuffer * buffer);
+
+static GstBaseRTPPayloadClass *parent_class = NULL;
static GType
gst_rtpgsmenc_get_type (void)
@@ -95,7 +83,7 @@ gst_rtpgsmenc_get_type (void)
};
rtpgsmenc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstRtpGSMEnc",
+ g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpGSMEnc",
&rtpgsmenc_info, 0);
}
return rtpgsmenc_type;
@@ -118,209 +106,91 @@ gst_rtpgsmenc_class_init (GstRtpGSMEncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_rtpgsmenc_set_property;
- gobject_class->get_property = gst_rtpgsmenc_get_property;
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
- gstelement_class->change_state = gst_rtpgsmenc_change_state;
+ gstbasertppayload_class->set_caps = gst_rtpgsmenc_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtpgsmenc_handle_buffer;
}
static void
gst_rtpgsmenc_init (GstRtpGSMEnc * rtpgsmenc)
{
- rtpgsmenc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpgsmenc_sink_template), "sink");
- rtpgsmenc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpgsmenc_src_template), "src");
- gst_element_add_pad (GST_ELEMENT (rtpgsmenc), rtpgsmenc->sinkpad);
- gst_element_add_pad (GST_ELEMENT (rtpgsmenc), rtpgsmenc->srcpad);
- gst_pad_set_chain_function (rtpgsmenc->sinkpad, gst_rtpgsmenc_chain);
- gst_pad_set_link_function (rtpgsmenc->sinkpad, gst_rtpgsmenc_sinkconnect);
-
rtpgsmenc->frequency = 8000;
-
- rtpgsmenc->next_time = 0;
- rtpgsmenc->time_interval = 0;
-
- rtpgsmenc->seq = 0;
- rtpgsmenc->ssrc = random ();
}
-static GstPadLinkReturn
-gst_rtpgsmenc_sinkconnect (GstPad * pad, const GstCaps * caps)
+static gboolean
+gst_rtpgsmenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
GstRtpGSMEnc *rtpgsmenc;
GstStructure *structure;
gboolean ret;
+ GstCaps *srccaps;
- rtpgsmenc = GST_RTP_GSM_ENC (gst_pad_get_parent (pad));
+ rtpgsmenc = GST_RTP_GSM_ENC (payload);
structure = gst_caps_get_structure (caps, 0);
ret = gst_structure_get_int (structure, "rate", &rtpgsmenc->frequency);
if (!ret)
- return GST_PAD_LINK_REFUSED;
+ return FALSE;
- /* Pre-calculate what we can */
- rtpgsmenc->time_interval = GST_SECOND / (2 * rtpgsmenc->frequency);
+ srccaps = gst_caps_new_simple ("application/x-rtp", NULL);
+ gst_pad_set_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (rtpgsmenc), srccaps);
+ gst_caps_unref (srccaps);
- return GST_PAD_LINK_OK;
+ return TRUE;
}
-
-void
-gst_rtpgsmenc_htons (GstBuffer * buf)
-{
- gint16 *i, *len;
-
- /* FIXME: is this code correct or even sane at all? */
- i = (gint16 *) GST_BUFFER_DATA (buf);
- len = i + GST_BUFFER_SIZE (buf) / sizeof (gint16 *);
-
- for (; i < len; i++) {
- *i = g_htons (*i);
- }
-}
-
-static void
-gst_rtpgsmenc_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * basepayload,
+ GstBuffer * buffer)
{
- GstBuffer *buf = GST_BUFFER (_data);
GstRtpGSMEnc *rtpgsmenc;
+ guint size, payload_len;
GstBuffer *outbuf;
- Rtp_Packet packet;
-
- g_return_if_fail (pad != NULL);
- g_return_if_fail (GST_IS_PAD (pad));
- g_return_if_fail (buf != NULL);
-
- rtpgsmenc = GST_RTP_GSM_ENC (GST_OBJECT_PARENT (pad));
-
- g_return_if_fail (rtpgsmenc != NULL);
- g_return_if_fail (GST_IS_RTP_GSM_ENC (rtpgsmenc));
-
- if (GST_IS_EVENT (buf)) {
- GstEvent *event = GST_EVENT (buf);
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_DISCONTINUOUS:
- GST_DEBUG ("discont");
- rtpgsmenc->next_time = 0;
- gst_pad_event_default (pad, event);
- return;
- default:
- gst_pad_event_default (pad, event);
- return;
- }
- }
+ guint8 *payload, *data;
+ GstClockTime timestamp;
+ GstFlowReturn ret;
- /* We only need the header */
- packet = rtp_packet_new_allocate (0, 0, 0);
-
- rtp_packet_set_csrc_count (packet, 0);
- rtp_packet_set_extension (packet, 0);
- rtp_packet_set_padding (packet, 0);
- rtp_packet_set_version (packet, RTP_VERSION);
- rtp_packet_set_marker (packet, 0);
- rtp_packet_set_ssrc (packet, g_htonl (rtpgsmenc->ssrc));
- rtp_packet_set_seq (packet, g_htons (rtpgsmenc->seq));
- rtp_packet_set_timestamp (packet,
- g_htonl ((guint32) rtpgsmenc->next_time / GST_SECOND));
- rtp_packet_set_payload_type (packet, (guint8) PAYLOAD_GSM);
-
- /* FIXME: According to RFC 1890, this is required, right? */
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- gst_rtpgsmenc_htons (buf);
-#endif
+ rtpgsmenc = GST_RTP_GSM_ENC (basepayload);
- outbuf = gst_buffer_new ();
- GST_BUFFER_SIZE (outbuf) =
- rtp_packet_get_packet_len (packet) + GST_BUFFER_SIZE (buf);
- GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf));
- GST_BUFFER_TIMESTAMP (outbuf) = rtpgsmenc->next_time;
+ size = GST_BUFFER_SIZE (buffer);
+ timestamp = GST_BUFFER_TIMESTAMP (buffer);
- memcpy (GST_BUFFER_DATA (outbuf), packet->data,
- rtp_packet_get_packet_len (packet));
- memcpy (GST_BUFFER_DATA (outbuf) + rtp_packet_get_packet_len (packet),
- GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ /* FIXME, only one GSM frame per RTP packet for now */
+ payload_len = size;
- GST_DEBUG ("gst_rtpgsmenc_chain: pushing buffer of size %d",
- GST_BUFFER_SIZE (outbuf));
- gst_pad_push (rtpgsmenc->srcpad, GST_DATA (outbuf));
+ outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
+ /* FIXME, assert for now */
+ g_assert (GST_BUFFER_SIZE (outbuf) < GST_BASE_RTP_PAYLOAD_MTU (rtpgsmenc));
- ++rtpgsmenc->seq;
- rtpgsmenc->next_time += rtpgsmenc->time_interval * GST_BUFFER_SIZE (buf);
+ gst_rtpbuffer_set_timestamp (outbuf, timestamp * 8000 / GST_SECOND);
- rtp_packet_free (packet);
- gst_buffer_unref (buf);
-}
-
-static void
-gst_rtpgsmenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpGSMEnc *rtpgsmenc;
-
- g_return_if_fail (GST_IS_RTP_GSM_ENC (object));
- rtpgsmenc = GST_RTP_GSM_ENC (object);
-
- switch (prop_id) {
- default:
- break;
- }
-}
-
-static void
-gst_rtpgsmenc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRtpGSMEnc *rtpgsmenc;
-
- g_return_if_fail (GST_IS_RTP_GSM_ENC (object));
- rtpgsmenc = GST_RTP_GSM_ENC (object);
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_rtpgsmenc_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpGSMEnc *rtpgsmenc;
-
- g_return_val_if_fail (GST_IS_RTP_GSM_ENC (element), GST_STATE_CHANGE_FAILURE);
+ /* copy timestamp */
+ GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
- rtpgsmenc = GST_RTP_GSM_ENC (element);
+ /* get payload */
+ payload = gst_rtpbuffer_get_payload (outbuf);
- GST_DEBUG ("state pending %d\n", GST_STATE_PENDING (element));
+ data = GST_BUFFER_DATA (buffer);
- /* if going down into NULL state, close the file if it's open */
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
+ /* copy data in payload */
+ memcpy (&payload[0], data, size);
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
+ gst_buffer_unref (buffer);
- default:
- break;
- }
+ GST_DEBUG ("gst_rtpgsmenc_chain: pushing buffer of size %d",
+ GST_BUFFER_SIZE (outbuf));
- /* if we haven't failed already, give the parent class a chance to ;-) */
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+ ret = gst_basertppayload_push (basepayload, outbuf);
- return GST_STATE_CHANGE_SUCCESS;
+ return ret;
}
gboolean
diff --git a/gst/rtp/gstrtpgsmpay.h b/gst/rtp/gstrtpgsmpay.h
index 1220d402..46fab46a 100644
--- a/gst/rtp/gstrtpgsmpay.h
+++ b/gst/rtp/gstrtpgsmpay.h
@@ -22,42 +22,13 @@
#define __GST_RTP_GSM_ENC_H__
#include <gst/gst.h>
-#include "rtp-packet.h"
-#include "gstrtp-common.h"
+#include <gst/rtp/gstbasertppayload.h>
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
+G_BEGIN_DECLS
-/* Definition of structure storing data for this element. */
typedef struct _GstRtpGSMEnc GstRtpGSMEnc;
-struct _GstRtpGSMEnc
-{
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
-
- guint frequency;
-
- /* the timestamp of the next frame */
- guint64 next_time;
- /* the interval between frames */
- guint64 time_interval;
-
- guint32 ssrc;
- guint16 seq;
-};
-
-/* Standard definition defining a class for this element. */
typedef struct _GstRtpGSMEncClass GstRtpGSMEncClass;
-struct _GstRtpGSMEncClass
-{
- GstElementClass parent_class;
-};
-/* Standard macros for defining types for this element. */
#define GST_TYPE_RTP_GSM_ENC \
(gst_rtpgsmenc_get_type())
#define GST_RTP_GSM_ENC(obj) \
@@ -69,11 +40,20 @@ struct _GstRtpGSMEncClass
#define GST_IS_RTP_GSM_ENC_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_GSM_ENC))
-gboolean gst_rtpgsmenc_plugin_init (GstPlugin * plugin);
+struct _GstRtpGSMEnc
+{
+ GstBaseRTPPayload payload;
+
+ gint frequency;
+};
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+struct _GstRtpGSMEncClass
+{
+ GstBaseRTPPayloadClass parent_class;
+};
+
+gboolean gst_rtpgsmenc_plugin_init (GstPlugin * plugin);
+G_END_DECLS
-#endif /* __GST_RTP_GSM_ENC_H__ */
+#endif /* __GST_RTP_GSM_ENC_H__ */
diff --git a/gst/rtp/gstrtph263pdec.c b/gst/rtp/gstrtph263pdec.c
index 62c2d61c..16fd8be5 100644
--- a/gst/rtp/gstrtph263pdec.c
+++ b/gst/rtp/gstrtph263pdec.c
@@ -53,13 +53,17 @@ static GstStaticPadTemplate gst_rtph263pdec_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp")
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"video\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 90000, " "encoding_name = (string) \"H263-1998\"")
);
static void gst_rtph263pdec_class_init (GstRtpH263PDecClass * klass);
static void gst_rtph263pdec_base_init (GstRtpH263PDecClass * klass);
static void gst_rtph263pdec_init (GstRtpH263PDec * rtph263pdec);
+static void gst_rtph263pdec_finalize (GObject * object);
static GstFlowReturn gst_rtph263pdec_chain (GstPad * pad, GstBuffer * buffer);
@@ -122,6 +126,8 @@ gst_rtph263pdec_class_init (GstRtpH263PDecClass * klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+ gobject_class->finalize = gst_rtph263pdec_finalize;
+
gobject_class->set_property = gst_rtph263pdec_set_property;
gobject_class->get_property = gst_rtph263pdec_get_property;
@@ -145,6 +151,19 @@ gst_rtph263pdec_init (GstRtpH263PDec * rtph263pdec)
rtph263pdec->adapter = gst_adapter_new ();
}
+static void
+gst_rtph263pdec_finalize (GObject * object)
+{
+ GstRtpH263PDec *rtph263pdec;
+
+ rtph263pdec = GST_RTP_H263P_DEC (object);
+
+ g_object_unref (rtph263pdec->adapter);
+ rtph263pdec->adapter = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
static GstFlowReturn
gst_rtph263pdec_chain (GstPad * pad, GstBuffer * buf)
{
@@ -292,6 +311,9 @@ gst_rtph263pdec_change_state (GstElement * element, GstStateChange transition)
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
break;
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ gst_adapter_clear (rtph263pdec->adapter);
+ break;
default:
break;
}
diff --git a/gst/rtp/gstrtph263pdepay.c b/gst/rtp/gstrtph263pdepay.c
index 62c2d61c..16fd8be5 100644
--- a/gst/rtp/gstrtph263pdepay.c
+++ b/gst/rtp/gstrtph263pdepay.c
@@ -53,13 +53,17 @@ static GstStaticPadTemplate gst_rtph263pdec_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp")
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"video\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 90000, " "encoding_name = (string) \"H263-1998\"")
);
static void gst_rtph263pdec_class_init (GstRtpH263PDecClass * klass);
static void gst_rtph263pdec_base_init (GstRtpH263PDecClass * klass);
static void gst_rtph263pdec_init (GstRtpH263PDec * rtph263pdec);
+static void gst_rtph263pdec_finalize (GObject * object);
static GstFlowReturn gst_rtph263pdec_chain (GstPad * pad, GstBuffer * buffer);
@@ -122,6 +126,8 @@ gst_rtph263pdec_class_init (GstRtpH263PDecClass * klass)
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+ gobject_class->finalize = gst_rtph263pdec_finalize;
+
gobject_class->set_property = gst_rtph263pdec_set_property;
gobject_class->get_property = gst_rtph263pdec_get_property;
@@ -145,6 +151,19 @@ gst_rtph263pdec_init (GstRtpH263PDec * rtph263pdec)
rtph263pdec->adapter = gst_adapter_new ();
}
+static void
+gst_rtph263pdec_finalize (GObject * object)
+{
+ GstRtpH263PDec *rtph263pdec;
+
+ rtph263pdec = GST_RTP_H263P_DEC (object);
+
+ g_object_unref (rtph263pdec->adapter);
+ rtph263pdec->adapter = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
static GstFlowReturn
gst_rtph263pdec_chain (GstPad * pad, GstBuffer * buf)
{
@@ -292,6 +311,9 @@ gst_rtph263pdec_change_state (GstElement * element, GstStateChange transition)
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
break;
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ gst_adapter_clear (rtph263pdec->adapter);
+ break;
default:
break;
}
diff --git a/gst/rtp/gstrtph263penc.c b/gst/rtp/gstrtph263penc.c
index 192466d5..c1fb93fa 100644
--- a/gst/rtp/gstrtph263penc.c
+++ b/gst/rtp/gstrtph263penc.c
@@ -26,29 +26,10 @@
static GstElementDetails gst_rtp_h263penc_details = {
"RTP packet parser",
"Codec/Parser/Network",
- "Extracts H263+ video from RTP packets",
+ "Encodes H263+ video in RTP packets (RFC 2429)",
"Wim Taymans <wim@fluendo.com>"
};
-/* RtpH263PEnc signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_MTU 1024
-#define DEFAULT_PT 96
-#define DEFAULT_SSRC 0
-
-enum
-{
- PROP_0,
- PROP_MTU,
- PROP_PT,
- PROP_SSRC
-};
-
static GstStaticPadTemplate gst_rtph263penc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -60,25 +41,23 @@ static GstStaticPadTemplate gst_rtph263penc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp")
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"video\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 90000, " "encoding_name = (string) \"H263-1998\"")
);
-
static void gst_rtph263penc_class_init (GstRtpH263PEncClass * klass);
static void gst_rtph263penc_base_init (GstRtpH263PEncClass * klass);
static void gst_rtph263penc_init (GstRtpH263PEnc * rtph263penc);
+static void gst_rtph263penc_finalize (GObject * object);
-static GstFlowReturn gst_rtph263penc_chain (GstPad * pad, GstBuffer * buffer);
-
-static void gst_rtph263penc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtph263penc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
+static gboolean gst_rtph263penc_setcaps (GstBaseRTPPayload * payload,
+ GstCaps * caps);
+static GstFlowReturn gst_rtph263penc_handle_buffer (GstBaseRTPPayload * payload,
+ GstBuffer * buffer);
-static GstStateChangeReturn gst_rtph263penc_change_state (GstElement *
- element, GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
+static GstBaseRTPPayloadClass *parent_class = NULL;
static GType
gst_rtph263penc_get_type (void)
@@ -99,7 +78,7 @@ gst_rtph263penc_get_type (void)
};
rtph263penc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstRtpH263PEnc",
+ g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpH263PEnc",
&rtph263penc_info, 0);
}
return rtph263penc_type;
@@ -123,49 +102,49 @@ gst_rtph263penc_class_init (GstRtpH263PEncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
+
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_rtph263penc_set_property;
- gobject_class->get_property = gst_rtph263penc_get_property;
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
- g_param_spec_uint ("mtu", "MTU",
- "Maximum size of one packet",
- 28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PT,
- g_param_spec_uint ("pt", "payload type",
- "The payload type of the packets",
- 0, 0x80, DEFAULT_PT, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
- g_param_spec_uint ("ssrc", "SSRC",
- "The SSRC of the packets",
- 0, G_MAXUINT, DEFAULT_SSRC, G_PARAM_READWRITE));
-
- gstelement_class->change_state = gst_rtph263penc_change_state;
+ gobject_class->finalize = gst_rtph263penc_finalize;
+
+ gstbasertppayload_class->set_caps = gst_rtph263penc_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtph263penc_handle_buffer;
}
static void
gst_rtph263penc_init (GstRtpH263PEnc * rtph263penc)
{
- rtph263penc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtph263penc_src_template), "src");
- gst_element_add_pad (GST_ELEMENT (rtph263penc), rtph263penc->srcpad);
+ rtph263penc->adapter = gst_adapter_new ();
+}
+
+static void
+gst_rtph263penc_finalize (GObject * object)
+{
+ GstRtpH263PEnc *rtph263penc;
- rtph263penc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtph263penc_sink_template), "sink");
- gst_pad_set_chain_function (rtph263penc->sinkpad, gst_rtph263penc_chain);
- gst_element_add_pad (GST_ELEMENT (rtph263penc), rtph263penc->sinkpad);
+ rtph263penc = GST_RTP_H263P_ENC (object);
- rtph263penc->adapter = gst_adapter_new ();
- rtph263penc->mtu = DEFAULT_MTU;
+ g_object_unref (rtph263penc->adapter);
+ rtph263penc->adapter = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
+static gboolean
+gst_rtph263penc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
+{
+ gst_basertppayload_set_options (payload, "video", TRUE, "H263-1998", 90000);
+ gst_basertppayload_set_outcaps (payload, NULL);
+
+ return TRUE;
+}
+
+
static GstFlowReturn
gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
{
@@ -189,7 +168,7 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
/* FIXME, do better mtu packing, header len etc should be
* included in this calculation. */
- towrite = MIN (avail, rtph263penc->mtu);
+ towrite = MIN (avail, GST_BASE_RTP_PAYLOAD_MTU (rtph263penc));
/* for fragmented frames we need 2 bytes header, for other
* frames we must reuse the first 2 bytes of the data as the
* header */
@@ -197,11 +176,6 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
payload_len = header_len + towrite;
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
- gst_rtpbuffer_set_timestamp (outbuf,
- rtph263penc->first_ts * 90000 / GST_SECOND);
- gst_rtpbuffer_set_payload_type (outbuf, rtph263penc->pt);
- gst_rtpbuffer_set_ssrc (outbuf, rtph263penc->ssrc);
- gst_rtpbuffer_set_seq (outbuf, rtph263penc->seqnum++);
/* last fragment gets the marker bit set */
gst_rtpbuffer_set_marker (outbuf, avail > towrite ? 0 : 1);
@@ -222,7 +196,7 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
GST_BUFFER_TIMESTAMP (outbuf) = rtph263penc->first_ts;
gst_adapter_flush (rtph263penc->adapter, towrite);
- ret = gst_pad_push (rtph263penc->srcpad, outbuf);
+ ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtph263penc), outbuf);
avail -= towrite;
fragmented = TRUE;
@@ -232,13 +206,13 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
}
static GstFlowReturn
-gst_rtph263penc_chain (GstPad * pad, GstBuffer * buffer)
+gst_rtph263penc_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer)
{
GstRtpH263PEnc *rtph263penc;
GstFlowReturn ret;
guint size;
- rtph263penc = GST_RTP_H263P_ENC (GST_OBJECT_PARENT (pad));
+ rtph263penc = GST_RTP_H263P_ENC (payload);
size = GST_BUFFER_SIZE (buffer);
rtph263penc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
@@ -250,80 +224,6 @@ gst_rtph263penc_chain (GstPad * pad, GstBuffer * buffer)
return ret;
}
-static void
-gst_rtph263penc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpH263PEnc *rtph263penc;
-
- rtph263penc = GST_RTP_H263P_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- rtph263penc->mtu = g_value_get_uint (value);
- break;
- case PROP_PT:
- rtph263penc->pt = g_value_get_uint (value);
- break;
- case PROP_SSRC:
- rtph263penc->ssrc = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtph263penc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRtpH263PEnc *rtph263penc;
-
- rtph263penc = GST_RTP_H263P_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- g_value_set_uint (value, rtph263penc->mtu);
- break;
- case PROP_PT:
- g_value_set_uint (value, rtph263penc->pt);
- break;
- case PROP_SSRC:
- g_value_set_uint (value, rtph263penc->ssrc);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_rtph263penc_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpH263PEnc *rtph263penc;
- GstStateChangeReturn ret;
-
- rtph263penc = GST_RTP_H263P_ENC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
- return ret;
-}
-
gboolean
gst_rtph263penc_plugin_init (GstPlugin * plugin)
{
diff --git a/gst/rtp/gstrtph263penc.h b/gst/rtp/gstrtph263penc.h
index 316ae037..409e2ebd 100644
--- a/gst/rtp/gstrtph263penc.h
+++ b/gst/rtp/gstrtph263penc.h
@@ -21,6 +21,7 @@
#define __GST_RTP_H263P_ENC_H__
#include <gst/gst.h>
+#include <gst/rtp/gstbasertppayload.h>
#include <gst/base/gstadapter.h>
G_BEGIN_DECLS
@@ -41,24 +42,15 @@ typedef struct _GstRtpH263PEncClass GstRtpH263PEncClass;
struct _GstRtpH263PEnc
{
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
+ GstBaseRTPPayload payload;
GstAdapter *adapter;
GstClockTime first_ts;
-
- guint16 seqnum;
- guint pt;
- guint ssrc;
-
- guint mtu;
};
struct _GstRtpH263PEncClass
{
- GstElementClass parent_class;
+ GstBaseRTPPayloadClass parent_class;
};
gboolean gst_rtph263penc_plugin_init (GstPlugin * plugin);
diff --git a/gst/rtp/gstrtph263ppay.c b/gst/rtp/gstrtph263ppay.c
index 192466d5..c1fb93fa 100644
--- a/gst/rtp/gstrtph263ppay.c
+++ b/gst/rtp/gstrtph263ppay.c
@@ -26,29 +26,10 @@
static GstElementDetails gst_rtp_h263penc_details = {
"RTP packet parser",
"Codec/Parser/Network",
- "Extracts H263+ video from RTP packets",
+ "Encodes H263+ video in RTP packets (RFC 2429)",
"Wim Taymans <wim@fluendo.com>"
};
-/* RtpH263PEnc signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_MTU 1024
-#define DEFAULT_PT 96
-#define DEFAULT_SSRC 0
-
-enum
-{
- PROP_0,
- PROP_MTU,
- PROP_PT,
- PROP_SSRC
-};
-
static GstStaticPadTemplate gst_rtph263penc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -60,25 +41,23 @@ static GstStaticPadTemplate gst_rtph263penc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp")
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"video\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 90000, " "encoding_name = (string) \"H263-1998\"")
);
-
static void gst_rtph263penc_class_init (GstRtpH263PEncClass * klass);
static void gst_rtph263penc_base_init (GstRtpH263PEncClass * klass);
static void gst_rtph263penc_init (GstRtpH263PEnc * rtph263penc);
+static void gst_rtph263penc_finalize (GObject * object);
-static GstFlowReturn gst_rtph263penc_chain (GstPad * pad, GstBuffer * buffer);
-
-static void gst_rtph263penc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtph263penc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
+static gboolean gst_rtph263penc_setcaps (GstBaseRTPPayload * payload,
+ GstCaps * caps);
+static GstFlowReturn gst_rtph263penc_handle_buffer (GstBaseRTPPayload * payload,
+ GstBuffer * buffer);
-static GstStateChangeReturn gst_rtph263penc_change_state (GstElement *
- element, GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
+static GstBaseRTPPayloadClass *parent_class = NULL;
static GType
gst_rtph263penc_get_type (void)
@@ -99,7 +78,7 @@ gst_rtph263penc_get_type (void)
};
rtph263penc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstRtpH263PEnc",
+ g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpH263PEnc",
&rtph263penc_info, 0);
}
return rtph263penc_type;
@@ -123,49 +102,49 @@ gst_rtph263penc_class_init (GstRtpH263PEncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
+
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_rtph263penc_set_property;
- gobject_class->get_property = gst_rtph263penc_get_property;
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
- g_param_spec_uint ("mtu", "MTU",
- "Maximum size of one packet",
- 28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PT,
- g_param_spec_uint ("pt", "payload type",
- "The payload type of the packets",
- 0, 0x80, DEFAULT_PT, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
- g_param_spec_uint ("ssrc", "SSRC",
- "The SSRC of the packets",
- 0, G_MAXUINT, DEFAULT_SSRC, G_PARAM_READWRITE));
-
- gstelement_class->change_state = gst_rtph263penc_change_state;
+ gobject_class->finalize = gst_rtph263penc_finalize;
+
+ gstbasertppayload_class->set_caps = gst_rtph263penc_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtph263penc_handle_buffer;
}
static void
gst_rtph263penc_init (GstRtpH263PEnc * rtph263penc)
{
- rtph263penc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtph263penc_src_template), "src");
- gst_element_add_pad (GST_ELEMENT (rtph263penc), rtph263penc->srcpad);
+ rtph263penc->adapter = gst_adapter_new ();
+}
+
+static void
+gst_rtph263penc_finalize (GObject * object)
+{
+ GstRtpH263PEnc *rtph263penc;
- rtph263penc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtph263penc_sink_template), "sink");
- gst_pad_set_chain_function (rtph263penc->sinkpad, gst_rtph263penc_chain);
- gst_element_add_pad (GST_ELEMENT (rtph263penc), rtph263penc->sinkpad);
+ rtph263penc = GST_RTP_H263P_ENC (object);
- rtph263penc->adapter = gst_adapter_new ();
- rtph263penc->mtu = DEFAULT_MTU;
+ g_object_unref (rtph263penc->adapter);
+ rtph263penc->adapter = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
+static gboolean
+gst_rtph263penc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
+{
+ gst_basertppayload_set_options (payload, "video", TRUE, "H263-1998", 90000);
+ gst_basertppayload_set_outcaps (payload, NULL);
+
+ return TRUE;
+}
+
+
static GstFlowReturn
gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
{
@@ -189,7 +168,7 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
/* FIXME, do better mtu packing, header len etc should be
* included in this calculation. */
- towrite = MIN (avail, rtph263penc->mtu);
+ towrite = MIN (avail, GST_BASE_RTP_PAYLOAD_MTU (rtph263penc));
/* for fragmented frames we need 2 bytes header, for other
* frames we must reuse the first 2 bytes of the data as the
* header */
@@ -197,11 +176,6 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
payload_len = header_len + towrite;
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
- gst_rtpbuffer_set_timestamp (outbuf,
- rtph263penc->first_ts * 90000 / GST_SECOND);
- gst_rtpbuffer_set_payload_type (outbuf, rtph263penc->pt);
- gst_rtpbuffer_set_ssrc (outbuf, rtph263penc->ssrc);
- gst_rtpbuffer_set_seq (outbuf, rtph263penc->seqnum++);
/* last fragment gets the marker bit set */
gst_rtpbuffer_set_marker (outbuf, avail > towrite ? 0 : 1);
@@ -222,7 +196,7 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
GST_BUFFER_TIMESTAMP (outbuf) = rtph263penc->first_ts;
gst_adapter_flush (rtph263penc->adapter, towrite);
- ret = gst_pad_push (rtph263penc->srcpad, outbuf);
+ ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtph263penc), outbuf);
avail -= towrite;
fragmented = TRUE;
@@ -232,13 +206,13 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
}
static GstFlowReturn
-gst_rtph263penc_chain (GstPad * pad, GstBuffer * buffer)
+gst_rtph263penc_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer)
{
GstRtpH263PEnc *rtph263penc;
GstFlowReturn ret;
guint size;
- rtph263penc = GST_RTP_H263P_ENC (GST_OBJECT_PARENT (pad));
+ rtph263penc = GST_RTP_H263P_ENC (payload);
size = GST_BUFFER_SIZE (buffer);
rtph263penc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
@@ -250,80 +224,6 @@ gst_rtph263penc_chain (GstPad * pad, GstBuffer * buffer)
return ret;
}
-static void
-gst_rtph263penc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpH263PEnc *rtph263penc;
-
- rtph263penc = GST_RTP_H263P_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- rtph263penc->mtu = g_value_get_uint (value);
- break;
- case PROP_PT:
- rtph263penc->pt = g_value_get_uint (value);
- break;
- case PROP_SSRC:
- rtph263penc->ssrc = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtph263penc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRtpH263PEnc *rtph263penc;
-
- rtph263penc = GST_RTP_H263P_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- g_value_set_uint (value, rtph263penc->mtu);
- break;
- case PROP_PT:
- g_value_set_uint (value, rtph263penc->pt);
- break;
- case PROP_SSRC:
- g_value_set_uint (value, rtph263penc->ssrc);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_rtph263penc_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpH263PEnc *rtph263penc;
- GstStateChangeReturn ret;
-
- rtph263penc = GST_RTP_H263P_ENC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
- return ret;
-}
-
gboolean
gst_rtph263penc_plugin_init (GstPlugin * plugin)
{
diff --git a/gst/rtp/gstrtph263ppay.h b/gst/rtp/gstrtph263ppay.h
index 316ae037..409e2ebd 100644
--- a/gst/rtp/gstrtph263ppay.h
+++ b/gst/rtp/gstrtph263ppay.h
@@ -21,6 +21,7 @@
#define __GST_RTP_H263P_ENC_H__
#include <gst/gst.h>
+#include <gst/rtp/gstbasertppayload.h>
#include <gst/base/gstadapter.h>
G_BEGIN_DECLS
@@ -41,24 +42,15 @@ typedef struct _GstRtpH263PEncClass GstRtpH263PEncClass;
struct _GstRtpH263PEnc
{
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
+ GstBaseRTPPayload payload;
GstAdapter *adapter;
GstClockTime first_ts;
-
- guint16 seqnum;
- guint pt;
- guint ssrc;
-
- guint mtu;
};
struct _GstRtpH263PEncClass
{
- GstElementClass parent_class;
+ GstBaseRTPPayloadClass parent_class;
};
gboolean gst_rtph263penc_plugin_init (GstPlugin * plugin);
diff --git a/gst/rtp/gstrtpmp4vdec.c b/gst/rtp/gstrtpmp4vdec.c
index 39ab5df9..4250e77b 100644
--- a/gst/rtp/gstrtpmp4vdec.c
+++ b/gst/rtp/gstrtpmp4vdec.c
@@ -54,10 +54,12 @@ static GstStaticPadTemplate gst_rtpmp4vdec_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp"
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"video\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) [1, MAX ], " "encoding_name = (string) \"MP4V-ES\""
/* All optional parameters
*
- * "rate=(int) [1, MAX],"
* "profile-level-id=[1,MAX]"
* "config="
*/
@@ -164,7 +166,7 @@ gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps)
structure = gst_caps_get_structure (caps, 0);
- if (!gst_structure_get_int (structure, "rate", &rtpmp4vdec->rate))
+ if (!gst_structure_get_int (structure, "clock_rate", &rtpmp4vdec->rate))
rtpmp4vdec->rate = 90000;
srccaps = gst_caps_new_simple ("video/mpeg",
@@ -282,7 +284,6 @@ gst_rtpmp4vdec_change_state (GstElement * element, GstStateChange transition)
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
gst_adapter_clear (rtpmp4vdec->adapter);
- rtpmp4vdec->rate = 90000;
break;
default:
break;
diff --git a/gst/rtp/gstrtpmp4vdepay.c b/gst/rtp/gstrtpmp4vdepay.c
index 39ab5df9..4250e77b 100644
--- a/gst/rtp/gstrtpmp4vdepay.c
+++ b/gst/rtp/gstrtpmp4vdepay.c
@@ -54,10 +54,12 @@ static GstStaticPadTemplate gst_rtpmp4vdec_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp"
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"video\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) [1, MAX ], " "encoding_name = (string) \"MP4V-ES\""
/* All optional parameters
*
- * "rate=(int) [1, MAX],"
* "profile-level-id=[1,MAX]"
* "config="
*/
@@ -164,7 +166,7 @@ gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps)
structure = gst_caps_get_structure (caps, 0);
- if (!gst_structure_get_int (structure, "rate", &rtpmp4vdec->rate))
+ if (!gst_structure_get_int (structure, "clock_rate", &rtpmp4vdec->rate))
rtpmp4vdec->rate = 90000;
srccaps = gst_caps_new_simple ("video/mpeg",
@@ -282,7 +284,6 @@ gst_rtpmp4vdec_change_state (GstElement * element, GstStateChange transition)
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
gst_adapter_clear (rtpmp4vdec->adapter);
- rtpmp4vdec->rate = 90000;
break;
default:
break;
diff --git a/gst/rtp/gstrtpmp4venc.c b/gst/rtp/gstrtpmp4venc.c
index 13b1e33d..bba139a0 100644
--- a/gst/rtp/gstrtpmp4venc.c
+++ b/gst/rtp/gstrtpmp4venc.c
@@ -30,25 +30,6 @@ static GstElementDetails gst_rtp_mp4venc_details = {
"Wim Taymans <wim@fluendo.com>"
};
-/* RtpMP4VEnc signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_MTU 1024
-#define DEFAULT_PT 96
-#define DEFAULT_SSRC 0
-
-enum
-{
- PROP_0,
- PROP_MTU,
- PROP_PT,
- PROP_SSRC
-};
-
static GstStaticPadTemplate gst_rtpmp4venc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -61,9 +42,15 @@ static GstStaticPadTemplate gst_rtpmp4venc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp,"
- "rate=(int) [1, MAX]," "profile-level-id=[1,MAX]"
- /* "config=" */
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"video\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) [1, MAX ], "
+ "encoding_name = (string) \"MP4V-ES\", " "profile-level-id=[1,MAX]"
+ /* All optional parameters
+ *
+ * "config="
+ */
)
);
@@ -71,19 +58,14 @@ GST_STATIC_PAD_TEMPLATE ("src",
static void gst_rtpmp4venc_class_init (GstRtpMP4VEncClass * klass);
static void gst_rtpmp4venc_base_init (GstRtpMP4VEncClass * klass);
static void gst_rtpmp4venc_init (GstRtpMP4VEnc * rtpmp4venc);
+static void gst_rtpmp4venc_finalize (GObject * object);
-static gboolean gst_rtpmp4venc_setcaps (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_rtpmp4venc_chain (GstPad * pad, GstBuffer * buffer);
-
-static void gst_rtpmp4venc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtpmp4venc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static GstStateChangeReturn gst_rtpmp4venc_change_state (GstElement * element,
- GstStateChange transition);
+static gboolean gst_rtpmp4venc_setcaps (GstBaseRTPPayload * payload,
+ GstCaps * caps);
+static GstFlowReturn gst_rtpmp4venc_handle_buffer (GstBaseRTPPayload * payload,
+ GstBuffer * buffer);
-static GstElementClass *parent_class = NULL;
+static GstBaseRTPPayloadClass *parent_class = NULL;
static GType
gst_rtpmp4venc_get_type (void)
@@ -104,7 +86,7 @@ gst_rtpmp4venc_get_type (void)
};
rtpmp4venc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMP4VEnc",
+ g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpMP4VEnc",
&rtpmp4venc_info, 0);
}
return rtpmp4venc_type;
@@ -128,69 +110,58 @@ gst_rtpmp4venc_class_init (GstRtpMP4VEncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_rtpmp4venc_set_property;
- gobject_class->get_property = gst_rtpmp4venc_get_property;
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
- g_param_spec_uint ("mtu", "MTU",
- "Maximum size of one packet",
- 28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PT,
- g_param_spec_uint ("pt", "payload type",
- "The payload type of the packets",
- 0, 0x80, DEFAULT_PT, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
- g_param_spec_uint ("ssrc", "SSRC",
- "The SSRC of the packets",
- 0, G_MAXUINT, DEFAULT_SSRC, G_PARAM_READWRITE));
-
- gstelement_class->change_state = gst_rtpmp4venc_change_state;
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
+
+ gobject_class->finalize = gst_rtpmp4venc_finalize;
+
+ gstbasertppayload_class->set_caps = gst_rtpmp4venc_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtpmp4venc_handle_buffer;
}
static void
gst_rtpmp4venc_init (GstRtpMP4VEnc * rtpmp4venc)
{
- rtpmp4venc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpmp4venc_src_template), "src");
- gst_element_add_pad (GST_ELEMENT (rtpmp4venc), rtpmp4venc->srcpad);
-
- rtpmp4venc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpmp4venc_sink_template), "sink");
- gst_pad_set_setcaps_function (rtpmp4venc->sinkpad, gst_rtpmp4venc_setcaps);
- gst_pad_set_chain_function (rtpmp4venc->sinkpad, gst_rtpmp4venc_chain);
- gst_element_add_pad (GST_ELEMENT (rtpmp4venc), rtpmp4venc->sinkpad);
-
rtpmp4venc->adapter = gst_adapter_new ();
- rtpmp4venc->mtu = DEFAULT_MTU;
- rtpmp4venc->pt = DEFAULT_PT;
- rtpmp4venc->ssrc = DEFAULT_SSRC;
rtpmp4venc->rate = 90000;
rtpmp4venc->profile = 1;
}
-static gboolean
-gst_rtpmp4venc_setcaps (GstPad * pad, GstCaps * caps)
+static void
+gst_rtpmp4venc_finalize (GObject * object)
{
GstRtpMP4VEnc *rtpmp4venc;
- GstCaps *srccaps;
- rtpmp4venc = GST_RTP_MP4V_ENC (gst_pad_get_parent (pad));
+ rtpmp4venc = GST_RTP_MP4V_ENC (object);
- srccaps = gst_caps_new_simple ("application/x-rtp",
- "rate", G_TYPE_INT, rtpmp4venc->rate,
- "profile-level-id", G_TYPE_INT, rtpmp4venc->profile, NULL);
- gst_pad_set_caps (rtpmp4venc->srcpad, srccaps);
- gst_caps_unref (srccaps);
+ g_object_unref (rtpmp4venc->adapter);
+ rtpmp4venc->adapter = NULL;
- gst_object_unref (rtpmp4venc);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_rtpmp4venc_new_caps (GstRtpMP4VEnc * rtpmp4venc)
+{
+ gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4venc),
+ "profile-level-id", G_TYPE_INT, rtpmp4venc->profile,
+ "config", GST_TYPE_BUFFER, rtpmp4venc->config, NULL);
+}
+
+static gboolean
+gst_rtpmp4venc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
+{
+ GstRtpMP4VEnc *rtpmp4venc;
+
+ rtpmp4venc = GST_RTP_MP4V_ENC (payload);
+
+ gst_basertppayload_set_options (payload, "video", TRUE, "MP4V-ES",
+ rtpmp4venc->rate);
return TRUE;
}
@@ -201,7 +172,6 @@ gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
guint avail;
GstBuffer *outbuf;
GstFlowReturn ret;
- guint16 frag_offset;
/* the data available in the adapter is either smaller
* than the MTU or bigger. In the case it is smaller, the complete
@@ -212,7 +182,6 @@ gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
ret = GST_FLOW_OK;
- frag_offset = 0;
while (avail > 0) {
guint towrite;
guint8 *payload;
@@ -224,159 +193,149 @@ gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
packet_len = gst_rtpbuffer_calc_packet_len (avail, 0, 0);
/* fill one MTU or all available bytes */
- towrite = MIN (packet_len, rtpmp4venc->mtu);
+ towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpmp4venc));
/* this is the payload length */
payload_len = gst_rtpbuffer_calc_payload_len (towrite, 0, 0);
/* create buffer to hold the payload */
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpmp4venc->srcpad));
-
- /* set timestamp */
- if (GST_CLOCK_TIME_IS_VALID (rtpmp4venc->first_ts)) {
- gst_rtpbuffer_set_timestamp (outbuf,
- rtpmp4venc->first_ts * 90000 / GST_SECOND);
- }
- gst_rtpbuffer_set_payload_type (outbuf, rtpmp4venc->pt);
- gst_rtpbuffer_set_seq (outbuf, rtpmp4venc->seqnum++);
+ /* copy payload */
payload = gst_rtpbuffer_get_payload (outbuf);
-
data = (guint8 *) gst_adapter_peek (rtpmp4venc->adapter, payload_len);
memcpy (payload, data, payload_len);
+
gst_adapter_flush (rtpmp4venc->adapter, payload_len);
avail -= payload_len;
- frag_offset += payload_len;
gst_rtpbuffer_set_marker (outbuf, avail == 0);
GST_BUFFER_TIMESTAMP (outbuf) = rtpmp4venc->first_ts;
- ret = gst_pad_push (rtpmp4venc->srcpad, outbuf);
+ ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmp4venc), outbuf);
}
return ret;
}
+#define VOS_STARTCODE 0x000001B0
+#define VOS_ENDCODE 0x000001B1
+#define USER_DATA_STARTCODE 0x000001B2
+#define GOP_STARTCODE 0x000001B3
+#define VISUAL_OBJECT_STARTCODE 0x000001B5
+#define VOP_STARTCODE 0x000001B6
+
+static gboolean
+gst_rtpmp4venc_parse_data (GstRtpMP4VEnc * enc, guint8 * data, guint size)
+{
+ guint32 code;
+ gboolean result;
+
+ if (size < 5)
+ return FALSE;
+
+ code = GST_READ_UINT32_BE (data);
+
+ switch (code) {
+ case VOS_STARTCODE:
+ {
+ gint i;
+ guint8 profile;
+ gboolean newprofile = FALSE;
+ gboolean equal;
+
+ /* profile_and_level_indication */
+ profile = data[4];
+
+ if (profile != enc->profile) {
+ newprofile = TRUE;
+ enc->profile = profile;
+ }
+
+ /* up to the next GOP_STARTCODE or VOP_STARTCODE is
+ * the config information */
+ code = 0xffffffff;
+ for (i = 5; i < size - 4; i++) {
+ code = (code << 8) | data[i];
+ if (code == GOP_STARTCODE || code == VOP_STARTCODE)
+ break;
+ }
+ i -= 3;
+ /* see if config changed */
+ equal = FALSE;
+ if (enc->config) {
+ if (GST_BUFFER_SIZE (enc->config) == i) {
+ equal = memcmp (GST_BUFFER_DATA (enc->config), data, i) == 0;
+ }
+ }
+ /* if config string changed or new profile, make new caps */
+ if (!equal || newprofile) {
+ if (enc->config)
+ gst_buffer_unref (enc->config);
+ enc->config = gst_buffer_new_and_alloc (i);
+ memcpy (GST_BUFFER_DATA (enc->config), data, i);
+ gst_rtpmp4venc_new_caps (enc);
+ }
+ result = TRUE;
+ break;
+ }
+ case VOP_STARTCODE:
+ result = FALSE;
+ break;
+ default:
+ result = TRUE;
+ break;
+ }
+ return result;
+}
+
/* we expect buffers starting on startcodes.
- *
- * FIXME, need to flush the adapter if we receive non VOP
- * packets.
*/
static GstFlowReturn
-gst_rtpmp4venc_chain (GstPad * pad, GstBuffer * buffer)
+gst_rtpmp4venc_handle_buffer (GstBaseRTPPayload * basepayload,
+ GstBuffer * buffer)
{
GstRtpMP4VEnc *rtpmp4venc;
GstFlowReturn ret;
guint size, avail;
guint packet_len;
+ guint8 *data;
+ gboolean flush;
- rtpmp4venc = GST_RTP_MP4V_ENC (gst_pad_get_parent (pad));
+ rtpmp4venc = GST_RTP_MP4V_ENC (basepayload);
size = GST_BUFFER_SIZE (buffer);
+ data = GST_BUFFER_DATA (buffer);
avail = gst_adapter_available (rtpmp4venc->adapter);
+ /* parse incomming data and see if we need to start a new RTP
+ * packet */
+ flush = gst_rtpmp4venc_parse_data (rtpmp4venc, data, size);
+
/* get packet length of previous data and this new data */
packet_len = gst_rtpbuffer_calc_packet_len (avail + size, 0, 0);
/* if this buffer is going to overflow the packet, flush what we
* have. */
- if (packet_len > rtpmp4venc->mtu) {
+ if (flush || packet_len > GST_BASE_RTP_PAYLOAD_MTU (rtpmp4venc)) {
ret = gst_rtpmp4venc_flush (rtpmp4venc);
avail = 0;
}
gst_adapter_push (rtpmp4venc->adapter, buffer);
+
if (avail == 0) {
rtpmp4venc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
}
- gst_object_unref (rtpmp4venc);
ret = GST_FLOW_OK;
return ret;
}
-static void
-gst_rtpmp4venc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpMP4VEnc *rtpmp4venc;
-
- rtpmp4venc = GST_RTP_MP4V_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- rtpmp4venc->mtu = g_value_get_uint (value);
- break;
- case PROP_PT:
- rtpmp4venc->pt = g_value_get_uint (value);
- break;
- case PROP_SSRC:
- rtpmp4venc->ssrc = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtpmp4venc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRtpMP4VEnc *rtpmp4venc;
-
- rtpmp4venc = GST_RTP_MP4V_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- g_value_set_uint (value, rtpmp4venc->mtu);
- break;
- case PROP_PT:
- g_value_set_uint (value, rtpmp4venc->pt);
- break;
- case PROP_SSRC:
- g_value_set_uint (value, rtpmp4venc->ssrc);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_rtpmp4venc_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpMP4VEnc *rtpmp4venc;
- GstStateChangeReturn ret;
-
- rtpmp4venc = GST_RTP_MP4V_ENC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- rtpmp4venc->seqnum = 0;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
- return ret;
-}
-
gboolean
gst_rtpmp4venc_plugin_init (GstPlugin * plugin)
{
diff --git a/gst/rtp/gstrtpmp4venc.h b/gst/rtp/gstrtpmp4venc.h
index b6949039..2edd0171 100644
--- a/gst/rtp/gstrtpmp4venc.h
+++ b/gst/rtp/gstrtpmp4venc.h
@@ -21,6 +21,7 @@
#define __GST_RTP_MP4V_ENC_H__
#include <gst/gst.h>
+#include <gst/rtp/gstbasertppayload.h>
#include <gst/base/gstadapter.h>
G_BEGIN_DECLS
@@ -41,26 +42,19 @@ typedef struct _GstRtpMP4VEncClass GstRtpMP4VEncClass;
struct _GstRtpMP4VEnc
{
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
+ GstBaseRTPPayload payload;
GstAdapter *adapter;
GstClockTime first_ts;
- guint16 seqnum;
gint rate;
gint profile;
-
- guint mtu;
- guint pt;
- guint ssrc;
+ GstBuffer *config;
};
struct _GstRtpMP4VEncClass
{
- GstElementClass parent_class;
+ GstBaseRTPPayloadClass parent_class;
};
gboolean gst_rtpmp4venc_plugin_init (GstPlugin * plugin);
diff --git a/gst/rtp/gstrtpmp4vpay.c b/gst/rtp/gstrtpmp4vpay.c
index 13b1e33d..bba139a0 100644
--- a/gst/rtp/gstrtpmp4vpay.c
+++ b/gst/rtp/gstrtpmp4vpay.c
@@ -30,25 +30,6 @@ static GstElementDetails gst_rtp_mp4venc_details = {
"Wim Taymans <wim@fluendo.com>"
};
-/* RtpMP4VEnc signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_MTU 1024
-#define DEFAULT_PT 96
-#define DEFAULT_SSRC 0
-
-enum
-{
- PROP_0,
- PROP_MTU,
- PROP_PT,
- PROP_SSRC
-};
-
static GstStaticPadTemplate gst_rtpmp4venc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -61,9 +42,15 @@ static GstStaticPadTemplate gst_rtpmp4venc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp,"
- "rate=(int) [1, MAX]," "profile-level-id=[1,MAX]"
- /* "config=" */
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"video\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) [1, MAX ], "
+ "encoding_name = (string) \"MP4V-ES\", " "profile-level-id=[1,MAX]"
+ /* All optional parameters
+ *
+ * "config="
+ */
)
);
@@ -71,19 +58,14 @@ GST_STATIC_PAD_TEMPLATE ("src",
static void gst_rtpmp4venc_class_init (GstRtpMP4VEncClass * klass);
static void gst_rtpmp4venc_base_init (GstRtpMP4VEncClass * klass);
static void gst_rtpmp4venc_init (GstRtpMP4VEnc * rtpmp4venc);
+static void gst_rtpmp4venc_finalize (GObject * object);
-static gboolean gst_rtpmp4venc_setcaps (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_rtpmp4venc_chain (GstPad * pad, GstBuffer * buffer);
-
-static void gst_rtpmp4venc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtpmp4venc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static GstStateChangeReturn gst_rtpmp4venc_change_state (GstElement * element,
- GstStateChange transition);
+static gboolean gst_rtpmp4venc_setcaps (GstBaseRTPPayload * payload,
+ GstCaps * caps);
+static GstFlowReturn gst_rtpmp4venc_handle_buffer (GstBaseRTPPayload * payload,
+ GstBuffer * buffer);
-static GstElementClass *parent_class = NULL;
+static GstBaseRTPPayloadClass *parent_class = NULL;
static GType
gst_rtpmp4venc_get_type (void)
@@ -104,7 +86,7 @@ gst_rtpmp4venc_get_type (void)
};
rtpmp4venc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMP4VEnc",
+ g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpMP4VEnc",
&rtpmp4venc_info, 0);
}
return rtpmp4venc_type;
@@ -128,69 +110,58 @@ gst_rtpmp4venc_class_init (GstRtpMP4VEncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_rtpmp4venc_set_property;
- gobject_class->get_property = gst_rtpmp4venc_get_property;
-
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
- g_param_spec_uint ("mtu", "MTU",
- "Maximum size of one packet",
- 28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PT,
- g_param_spec_uint ("pt", "payload type",
- "The payload type of the packets",
- 0, 0x80, DEFAULT_PT, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
- g_param_spec_uint ("ssrc", "SSRC",
- "The SSRC of the packets",
- 0, G_MAXUINT, DEFAULT_SSRC, G_PARAM_READWRITE));
-
- gstelement_class->change_state = gst_rtpmp4venc_change_state;
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
+
+ gobject_class->finalize = gst_rtpmp4venc_finalize;
+
+ gstbasertppayload_class->set_caps = gst_rtpmp4venc_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtpmp4venc_handle_buffer;
}
static void
gst_rtpmp4venc_init (GstRtpMP4VEnc * rtpmp4venc)
{
- rtpmp4venc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpmp4venc_src_template), "src");
- gst_element_add_pad (GST_ELEMENT (rtpmp4venc), rtpmp4venc->srcpad);
-
- rtpmp4venc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpmp4venc_sink_template), "sink");
- gst_pad_set_setcaps_function (rtpmp4venc->sinkpad, gst_rtpmp4venc_setcaps);
- gst_pad_set_chain_function (rtpmp4venc->sinkpad, gst_rtpmp4venc_chain);
- gst_element_add_pad (GST_ELEMENT (rtpmp4venc), rtpmp4venc->sinkpad);
-
rtpmp4venc->adapter = gst_adapter_new ();
- rtpmp4venc->mtu = DEFAULT_MTU;
- rtpmp4venc->pt = DEFAULT_PT;
- rtpmp4venc->ssrc = DEFAULT_SSRC;
rtpmp4venc->rate = 90000;
rtpmp4venc->profile = 1;
}
-static gboolean
-gst_rtpmp4venc_setcaps (GstPad * pad, GstCaps * caps)
+static void
+gst_rtpmp4venc_finalize (GObject * object)
{
GstRtpMP4VEnc *rtpmp4venc;
- GstCaps *srccaps;
- rtpmp4venc = GST_RTP_MP4V_ENC (gst_pad_get_parent (pad));
+ rtpmp4venc = GST_RTP_MP4V_ENC (object);
- srccaps = gst_caps_new_simple ("application/x-rtp",
- "rate", G_TYPE_INT, rtpmp4venc->rate,
- "profile-level-id", G_TYPE_INT, rtpmp4venc->profile, NULL);
- gst_pad_set_caps (rtpmp4venc->srcpad, srccaps);
- gst_caps_unref (srccaps);
+ g_object_unref (rtpmp4venc->adapter);
+ rtpmp4venc->adapter = NULL;
- gst_object_unref (rtpmp4venc);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_rtpmp4venc_new_caps (GstRtpMP4VEnc * rtpmp4venc)
+{
+ gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4venc),
+ "profile-level-id", G_TYPE_INT, rtpmp4venc->profile,
+ "config", GST_TYPE_BUFFER, rtpmp4venc->config, NULL);
+}
+
+static gboolean
+gst_rtpmp4venc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
+{
+ GstRtpMP4VEnc *rtpmp4venc;
+
+ rtpmp4venc = GST_RTP_MP4V_ENC (payload);
+
+ gst_basertppayload_set_options (payload, "video", TRUE, "MP4V-ES",
+ rtpmp4venc->rate);
return TRUE;
}
@@ -201,7 +172,6 @@ gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
guint avail;
GstBuffer *outbuf;
GstFlowReturn ret;
- guint16 frag_offset;
/* the data available in the adapter is either smaller
* than the MTU or bigger. In the case it is smaller, the complete
@@ -212,7 +182,6 @@ gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
ret = GST_FLOW_OK;
- frag_offset = 0;
while (avail > 0) {
guint towrite;
guint8 *payload;
@@ -224,159 +193,149 @@ gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
packet_len = gst_rtpbuffer_calc_packet_len (avail, 0, 0);
/* fill one MTU or all available bytes */
- towrite = MIN (packet_len, rtpmp4venc->mtu);
+ towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpmp4venc));
/* this is the payload length */
payload_len = gst_rtpbuffer_calc_payload_len (towrite, 0, 0);
/* create buffer to hold the payload */
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpmp4venc->srcpad));
-
- /* set timestamp */
- if (GST_CLOCK_TIME_IS_VALID (rtpmp4venc->first_ts)) {
- gst_rtpbuffer_set_timestamp (outbuf,
- rtpmp4venc->first_ts * 90000 / GST_SECOND);
- }
- gst_rtpbuffer_set_payload_type (outbuf, rtpmp4venc->pt);
- gst_rtpbuffer_set_seq (outbuf, rtpmp4venc->seqnum++);
+ /* copy payload */
payload = gst_rtpbuffer_get_payload (outbuf);
-
data = (guint8 *) gst_adapter_peek (rtpmp4venc->adapter, payload_len);
memcpy (payload, data, payload_len);
+
gst_adapter_flush (rtpmp4venc->adapter, payload_len);
avail -= payload_len;
- frag_offset += payload_len;
gst_rtpbuffer_set_marker (outbuf, avail == 0);
GST_BUFFER_TIMESTAMP (outbuf) = rtpmp4venc->first_ts;
- ret = gst_pad_push (rtpmp4venc->srcpad, outbuf);
+ ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmp4venc), outbuf);
}
return ret;
}
+#define VOS_STARTCODE 0x000001B0
+#define VOS_ENDCODE 0x000001B1
+#define USER_DATA_STARTCODE 0x000001B2
+#define GOP_STARTCODE 0x000001B3
+#define VISUAL_OBJECT_STARTCODE 0x000001B5
+#define VOP_STARTCODE 0x000001B6
+
+static gboolean
+gst_rtpmp4venc_parse_data (GstRtpMP4VEnc * enc, guint8 * data, guint size)
+{
+ guint32 code;
+ gboolean result;
+
+ if (size < 5)
+ return FALSE;
+
+ code = GST_READ_UINT32_BE (data);
+
+ switch (code) {
+ case VOS_STARTCODE:
+ {
+ gint i;
+ guint8 profile;
+ gboolean newprofile = FALSE;
+ gboolean equal;
+
+ /* profile_and_level_indication */
+ profile = data[4];
+
+ if (profile != enc->profile) {
+ newprofile = TRUE;
+ enc->profile = profile;
+ }
+
+ /* up to the next GOP_STARTCODE or VOP_STARTCODE is
+ * the config information */
+ code = 0xffffffff;
+ for (i = 5; i < size - 4; i++) {
+ code = (code << 8) | data[i];
+ if (code == GOP_STARTCODE || code == VOP_STARTCODE)
+ break;
+ }
+ i -= 3;
+ /* see if config changed */
+ equal = FALSE;
+ if (enc->config) {
+ if (GST_BUFFER_SIZE (enc->config) == i) {
+ equal = memcmp (GST_BUFFER_DATA (enc->config), data, i) == 0;
+ }
+ }
+ /* if config string changed or new profile, make new caps */
+ if (!equal || newprofile) {
+ if (enc->config)
+ gst_buffer_unref (enc->config);
+ enc->config = gst_buffer_new_and_alloc (i);
+ memcpy (GST_BUFFER_DATA (enc->config), data, i);
+ gst_rtpmp4venc_new_caps (enc);
+ }
+ result = TRUE;
+ break;
+ }
+ case VOP_STARTCODE:
+ result = FALSE;
+ break;
+ default:
+ result = TRUE;
+ break;
+ }
+ return result;
+}
+
/* we expect buffers starting on startcodes.
- *
- * FIXME, need to flush the adapter if we receive non VOP
- * packets.
*/
static GstFlowReturn
-gst_rtpmp4venc_chain (GstPad * pad, GstBuffer * buffer)
+gst_rtpmp4venc_handle_buffer (GstBaseRTPPayload * basepayload,
+ GstBuffer * buffer)
{
GstRtpMP4VEnc *rtpmp4venc;
GstFlowReturn ret;
guint size, avail;
guint packet_len;
+ guint8 *data;
+ gboolean flush;
- rtpmp4venc = GST_RTP_MP4V_ENC (gst_pad_get_parent (pad));
+ rtpmp4venc = GST_RTP_MP4V_ENC (basepayload);
size = GST_BUFFER_SIZE (buffer);
+ data = GST_BUFFER_DATA (buffer);
avail = gst_adapter_available (rtpmp4venc->adapter);
+ /* parse incomming data and see if we need to start a new RTP
+ * packet */
+ flush = gst_rtpmp4venc_parse_data (rtpmp4venc, data, size);
+
/* get packet length of previous data and this new data */
packet_len = gst_rtpbuffer_calc_packet_len (avail + size, 0, 0);
/* if this buffer is going to overflow the packet, flush what we
* have. */
- if (packet_len > rtpmp4venc->mtu) {
+ if (flush || packet_len > GST_BASE_RTP_PAYLOAD_MTU (rtpmp4venc)) {
ret = gst_rtpmp4venc_flush (rtpmp4venc);
avail = 0;
}
gst_adapter_push (rtpmp4venc->adapter, buffer);
+
if (avail == 0) {
rtpmp4venc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
}
- gst_object_unref (rtpmp4venc);
ret = GST_FLOW_OK;
return ret;
}
-static void
-gst_rtpmp4venc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpMP4VEnc *rtpmp4venc;
-
- rtpmp4venc = GST_RTP_MP4V_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- rtpmp4venc->mtu = g_value_get_uint (value);
- break;
- case PROP_PT:
- rtpmp4venc->pt = g_value_get_uint (value);
- break;
- case PROP_SSRC:
- rtpmp4venc->ssrc = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtpmp4venc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRtpMP4VEnc *rtpmp4venc;
-
- rtpmp4venc = GST_RTP_MP4V_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- g_value_set_uint (value, rtpmp4venc->mtu);
- break;
- case PROP_PT:
- g_value_set_uint (value, rtpmp4venc->pt);
- break;
- case PROP_SSRC:
- g_value_set_uint (value, rtpmp4venc->ssrc);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_rtpmp4venc_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpMP4VEnc *rtpmp4venc;
- GstStateChangeReturn ret;
-
- rtpmp4venc = GST_RTP_MP4V_ENC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- rtpmp4venc->seqnum = 0;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
- return ret;
-}
-
gboolean
gst_rtpmp4venc_plugin_init (GstPlugin * plugin)
{
diff --git a/gst/rtp/gstrtpmp4vpay.h b/gst/rtp/gstrtpmp4vpay.h
index b6949039..2edd0171 100644
--- a/gst/rtp/gstrtpmp4vpay.h
+++ b/gst/rtp/gstrtpmp4vpay.h
@@ -21,6 +21,7 @@
#define __GST_RTP_MP4V_ENC_H__
#include <gst/gst.h>
+#include <gst/rtp/gstbasertppayload.h>
#include <gst/base/gstadapter.h>
G_BEGIN_DECLS
@@ -41,26 +42,19 @@ typedef struct _GstRtpMP4VEncClass GstRtpMP4VEncClass;
struct _GstRtpMP4VEnc
{
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
+ GstBaseRTPPayload payload;
GstAdapter *adapter;
GstClockTime first_ts;
- guint16 seqnum;
gint rate;
gint profile;
-
- guint mtu;
- guint pt;
- guint ssrc;
+ GstBuffer *config;
};
struct _GstRtpMP4VEncClass
{
- GstElementClass parent_class;
+ GstBaseRTPPayloadClass parent_class;
};
gboolean gst_rtpmp4venc_plugin_init (GstPlugin * plugin);
diff --git a/gst/rtp/gstrtpmpadec.c b/gst/rtp/gstrtpmpadec.c
index 50576a3b..f2adc4ba 100644
--- a/gst/rtp/gstrtpmpadec.c
+++ b/gst/rtp/gstrtpmpadec.c
@@ -53,7 +53,10 @@ static GstStaticPadTemplate gst_rtpmpadec_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp")
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 90000, " "encoding_name = (string) \"MPA\"")
);
diff --git a/gst/rtp/gstrtpmpadepay.c b/gst/rtp/gstrtpmpadepay.c
index 50576a3b..f2adc4ba 100644
--- a/gst/rtp/gstrtpmpadepay.c
+++ b/gst/rtp/gstrtpmpadepay.c
@@ -53,7 +53,10 @@ static GstStaticPadTemplate gst_rtpmpadec_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp")
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 90000, " "encoding_name = (string) \"MPA\"")
);
diff --git a/gst/rtp/gstrtpmpaenc.c b/gst/rtp/gstrtpmpaenc.c
index 6ad805c4..691e556a 100644
--- a/gst/rtp/gstrtpmpaenc.c
+++ b/gst/rtp/gstrtpmpaenc.c
@@ -30,21 +30,6 @@ static GstElementDetails gst_rtp_mpaenc_details = {
"Wim Taymans <wim@fluendo.com>"
};
-/* RtpMPAEnc signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_MTU 1024
-
-enum
-{
- PROP_0,
- PROP_MTU
-};
-
static GstStaticPadTemplate gst_rtpmpaenc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -56,25 +41,23 @@ static GstStaticPadTemplate gst_rtpmpaenc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp")
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 90000, " "encoding_name = (string) \"MPA\"")
);
-
static void gst_rtpmpaenc_class_init (GstRtpMPAEncClass * klass);
static void gst_rtpmpaenc_base_init (GstRtpMPAEncClass * klass);
static void gst_rtpmpaenc_init (GstRtpMPAEnc * rtpmpaenc);
+static void gst_rtpmpaenc_finalize (GObject * object);
-static GstFlowReturn gst_rtpmpaenc_chain (GstPad * pad, GstBuffer * buffer);
-
-static void gst_rtpmpaenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtpmpaenc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
+static gboolean gst_rtpmpaenc_setcaps (GstBaseRTPPayload * payload,
+ GstCaps * caps);
+static GstFlowReturn gst_rtpmpaenc_handle_buffer (GstBaseRTPPayload * payload,
+ GstBuffer * buffer);
-static GstStateChangeReturn gst_rtpmpaenc_change_state (GstElement * element,
- GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
+static GstBaseRTPPayloadClass *parent_class = NULL;
static GType
gst_rtpmpaenc_get_type (void)
@@ -95,7 +78,7 @@ gst_rtpmpaenc_get_type (void)
};
rtpmpaenc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMPAEnc",
+ g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpMPAEnc",
&rtpmpaenc_info, 0);
}
return rtpmpaenc_type;
@@ -119,39 +102,46 @@ gst_rtpmpaenc_class_init (GstRtpMPAEncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_rtpmpaenc_set_property;
- gobject_class->get_property = gst_rtpmpaenc_get_property;
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
- g_param_spec_uint ("mtu", "MTU",
- "Maximum size of one packet",
- 28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
+ gobject_class->finalize = gst_rtpmpaenc_finalize;
- gstelement_class->change_state = gst_rtpmpaenc_change_state;
+ gstbasertppayload_class->set_caps = gst_rtpmpaenc_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtpmpaenc_handle_buffer;
}
static void
gst_rtpmpaenc_init (GstRtpMPAEnc * rtpmpaenc)
{
- rtpmpaenc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpmpaenc_src_template), "src");
- gst_element_add_pad (GST_ELEMENT (rtpmpaenc), rtpmpaenc->srcpad);
+ rtpmpaenc->adapter = gst_adapter_new ();
+}
- rtpmpaenc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpmpaenc_sink_template), "sink");
- gst_pad_set_chain_function (rtpmpaenc->sinkpad, gst_rtpmpaenc_chain);
- gst_element_add_pad (GST_ELEMENT (rtpmpaenc), rtpmpaenc->sinkpad);
+static void
+gst_rtpmpaenc_finalize (GObject * object)
+{
+ GstRtpMPAEnc *rtpmpaenc;
- rtpmpaenc->adapter = gst_adapter_new ();
- rtpmpaenc->mtu = DEFAULT_MTU;
+ rtpmpaenc = GST_RTP_MPA_ENC (object);
+
+ g_object_unref (rtpmpaenc->adapter);
+ rtpmpaenc->adapter = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gboolean
+gst_rtpmpaenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
+{
+ gst_basertppayload_set_options (payload, "audio", TRUE, "MPA", 90000);
+ gst_basertppayload_set_outcaps (payload, NULL);
+
+ return TRUE;
}
static GstFlowReturn
@@ -184,7 +174,7 @@ gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
packet_len = gst_rtpbuffer_calc_packet_len (4 + avail, 0, 0);
/* fill one MTU or all available bytes */
- towrite = MIN (packet_len, rtpmpaenc->mtu);
+ towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpmpaenc));
/* this is the payload length */
payload_len = gst_rtpbuffer_calc_payload_len (towrite, 0, 0);
@@ -194,11 +184,7 @@ gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
payload_len -= 4;
- /* set timestamp */
- gst_rtpbuffer_set_timestamp (outbuf,
- rtpmpaenc->first_ts * 90000 / GST_SECOND);
gst_rtpbuffer_set_payload_type (outbuf, GST_RTP_PAYLOAD_MPA);
- gst_rtpbuffer_set_seq (outbuf, rtpmpaenc->seqnum++);
/*
* 0 1 2 3
@@ -225,21 +211,22 @@ gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
GST_BUFFER_TIMESTAMP (outbuf) = rtpmpaenc->first_ts;
- ret = gst_pad_push (rtpmpaenc->srcpad, outbuf);
+ ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmpaenc), outbuf);
}
return ret;
}
static GstFlowReturn
-gst_rtpmpaenc_chain (GstPad * pad, GstBuffer * buffer)
+gst_rtpmpaenc_handle_buffer (GstBaseRTPPayload * basepayload,
+ GstBuffer * buffer)
{
GstRtpMPAEnc *rtpmpaenc;
GstFlowReturn ret;
guint size, avail;
guint packet_len;
- rtpmpaenc = GST_RTP_MPA_ENC (gst_pad_get_parent (pad));
+ rtpmpaenc = GST_RTP_MPA_ENC (basepayload);
size = GST_BUFFER_SIZE (buffer);
avail = gst_adapter_available (rtpmpaenc->adapter);
@@ -250,9 +237,11 @@ gst_rtpmpaenc_chain (GstPad * pad, GstBuffer * buffer)
/* if this buffer is going to overflow the packet, flush what we
* have. */
- if (packet_len > rtpmpaenc->mtu) {
+ if (packet_len > GST_BASE_RTP_PAYLOAD_MTU (rtpmpaenc)) {
ret = gst_rtpmpaenc_flush (rtpmpaenc);
avail = 0;
+ } else {
+ ret = GST_FLOW_OK;
}
gst_adapter_push (rtpmpaenc->adapter, buffer);
@@ -260,75 +249,7 @@ gst_rtpmpaenc_chain (GstPad * pad, GstBuffer * buffer)
if (avail == 0) {
rtpmpaenc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
}
- gst_object_unref (rtpmpaenc);
- ret = GST_FLOW_OK;
-
- return ret;
-}
-
-static void
-gst_rtpmpaenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpMPAEnc *rtpmpaenc;
-
- rtpmpaenc = GST_RTP_MPA_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- rtpmpaenc->mtu = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtpmpaenc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRtpMPAEnc *rtpmpaenc;
-
- rtpmpaenc = GST_RTP_MPA_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- g_value_set_uint (value, rtpmpaenc->mtu);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_rtpmpaenc_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpMPAEnc *rtpmpaenc;
- GstStateChangeReturn ret;
-
- rtpmpaenc = GST_RTP_MPA_ENC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- rtpmpaenc->seqnum = 0;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
return ret;
}
diff --git a/gst/rtp/gstrtpmpaenc.h b/gst/rtp/gstrtpmpaenc.h
index 5a03c7cb..6079f83e 100644
--- a/gst/rtp/gstrtpmpaenc.h
+++ b/gst/rtp/gstrtpmpaenc.h
@@ -21,6 +21,7 @@
#define __GST_RTP_MPA_ENC_H__
#include <gst/gst.h>
+#include <gst/rtp/gstbasertppayload.h>
#include <gst/base/gstadapter.h>
G_BEGIN_DECLS
@@ -41,21 +42,15 @@ typedef struct _GstRtpMPAEncClass GstRtpMPAEncClass;
struct _GstRtpMPAEnc
{
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
+ GstBaseRTPPayload payload;
GstAdapter *adapter;
GstClockTime first_ts;
- guint16 seqnum;
-
- guint mtu;
};
struct _GstRtpMPAEncClass
{
- GstElementClass parent_class;
+ GstBaseRTPPayloadClass parent_class;
};
gboolean gst_rtpmpaenc_plugin_init (GstPlugin * plugin);
diff --git a/gst/rtp/gstrtpmpapay.c b/gst/rtp/gstrtpmpapay.c
index 6ad805c4..691e556a 100644
--- a/gst/rtp/gstrtpmpapay.c
+++ b/gst/rtp/gstrtpmpapay.c
@@ -30,21 +30,6 @@ static GstElementDetails gst_rtp_mpaenc_details = {
"Wim Taymans <wim@fluendo.com>"
};
-/* RtpMPAEnc signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-#define DEFAULT_MTU 1024
-
-enum
-{
- PROP_0,
- PROP_MTU
-};
-
static GstStaticPadTemplate gst_rtpmpaenc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@@ -56,25 +41,23 @@ static GstStaticPadTemplate gst_rtpmpaenc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("application/x-rtp")
+ GST_STATIC_CAPS ("application/x-rtp, "
+ "media = (string) \"audio\", "
+ "payload = (int) [ 96, 255 ], "
+ "clock_rate = (int) 90000, " "encoding_name = (string) \"MPA\"")
);
-
static void gst_rtpmpaenc_class_init (GstRtpMPAEncClass * klass);
static void gst_rtpmpaenc_base_init (GstRtpMPAEncClass * klass);
static void gst_rtpmpaenc_init (GstRtpMPAEnc * rtpmpaenc);
+static void gst_rtpmpaenc_finalize (GObject * object);
-static GstFlowReturn gst_rtpmpaenc_chain (GstPad * pad, GstBuffer * buffer);
-
-static void gst_rtpmpaenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_rtpmpaenc_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
+static gboolean gst_rtpmpaenc_setcaps (GstBaseRTPPayload * payload,
+ GstCaps * caps);
+static GstFlowReturn gst_rtpmpaenc_handle_buffer (GstBaseRTPPayload * payload,
+ GstBuffer * buffer);
-static GstStateChangeReturn gst_rtpmpaenc_change_state (GstElement * element,
- GstStateChange transition);
-
-static GstElementClass *parent_class = NULL;
+static GstBaseRTPPayloadClass *parent_class = NULL;
static GType
gst_rtpmpaenc_get_type (void)
@@ -95,7 +78,7 @@ gst_rtpmpaenc_get_type (void)
};
rtpmpaenc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMPAEnc",
+ g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpMPAEnc",
&rtpmpaenc_info, 0);
}
return rtpmpaenc_type;
@@ -119,39 +102,46 @@ gst_rtpmpaenc_class_init (GstRtpMPAEncClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ GstBaseRTPPayloadClass *gstbasertppayload_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
+ gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
-
- gobject_class->set_property = gst_rtpmpaenc_set_property;
- gobject_class->get_property = gst_rtpmpaenc_get_property;
+ parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
- g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
- g_param_spec_uint ("mtu", "MTU",
- "Maximum size of one packet",
- 28, G_MAXUINT, DEFAULT_MTU, G_PARAM_READWRITE));
+ gobject_class->finalize = gst_rtpmpaenc_finalize;
- gstelement_class->change_state = gst_rtpmpaenc_change_state;
+ gstbasertppayload_class->set_caps = gst_rtpmpaenc_setcaps;
+ gstbasertppayload_class->handle_buffer = gst_rtpmpaenc_handle_buffer;
}
static void
gst_rtpmpaenc_init (GstRtpMPAEnc * rtpmpaenc)
{
- rtpmpaenc->srcpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpmpaenc_src_template), "src");
- gst_element_add_pad (GST_ELEMENT (rtpmpaenc), rtpmpaenc->srcpad);
+ rtpmpaenc->adapter = gst_adapter_new ();
+}
- rtpmpaenc->sinkpad =
- gst_pad_new_from_template (gst_static_pad_template_get
- (&gst_rtpmpaenc_sink_template), "sink");
- gst_pad_set_chain_function (rtpmpaenc->sinkpad, gst_rtpmpaenc_chain);
- gst_element_add_pad (GST_ELEMENT (rtpmpaenc), rtpmpaenc->sinkpad);
+static void
+gst_rtpmpaenc_finalize (GObject * object)
+{
+ GstRtpMPAEnc *rtpmpaenc;
- rtpmpaenc->adapter = gst_adapter_new ();
- rtpmpaenc->mtu = DEFAULT_MTU;
+ rtpmpaenc = GST_RTP_MPA_ENC (object);
+
+ g_object_unref (rtpmpaenc->adapter);
+ rtpmpaenc->adapter = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gboolean
+gst_rtpmpaenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
+{
+ gst_basertppayload_set_options (payload, "audio", TRUE, "MPA", 90000);
+ gst_basertppayload_set_outcaps (payload, NULL);
+
+ return TRUE;
}
static GstFlowReturn
@@ -184,7 +174,7 @@ gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
packet_len = gst_rtpbuffer_calc_packet_len (4 + avail, 0, 0);
/* fill one MTU or all available bytes */
- towrite = MIN (packet_len, rtpmpaenc->mtu);
+ towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpmpaenc));
/* this is the payload length */
payload_len = gst_rtpbuffer_calc_payload_len (towrite, 0, 0);
@@ -194,11 +184,7 @@ gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
payload_len -= 4;
- /* set timestamp */
- gst_rtpbuffer_set_timestamp (outbuf,
- rtpmpaenc->first_ts * 90000 / GST_SECOND);
gst_rtpbuffer_set_payload_type (outbuf, GST_RTP_PAYLOAD_MPA);
- gst_rtpbuffer_set_seq (outbuf, rtpmpaenc->seqnum++);
/*
* 0 1 2 3
@@ -225,21 +211,22 @@ gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
GST_BUFFER_TIMESTAMP (outbuf) = rtpmpaenc->first_ts;
- ret = gst_pad_push (rtpmpaenc->srcpad, outbuf);
+ ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmpaenc), outbuf);
}
return ret;
}
static GstFlowReturn
-gst_rtpmpaenc_chain (GstPad * pad, GstBuffer * buffer)
+gst_rtpmpaenc_handle_buffer (GstBaseRTPPayload * basepayload,
+ GstBuffer * buffer)
{
GstRtpMPAEnc *rtpmpaenc;
GstFlowReturn ret;
guint size, avail;
guint packet_len;
- rtpmpaenc = GST_RTP_MPA_ENC (gst_pad_get_parent (pad));
+ rtpmpaenc = GST_RTP_MPA_ENC (basepayload);
size = GST_BUFFER_SIZE (buffer);
avail = gst_adapter_available (rtpmpaenc->adapter);
@@ -250,9 +237,11 @@ gst_rtpmpaenc_chain (GstPad * pad, GstBuffer * buffer)
/* if this buffer is going to overflow the packet, flush what we
* have. */
- if (packet_len > rtpmpaenc->mtu) {
+ if (packet_len > GST_BASE_RTP_PAYLOAD_MTU (rtpmpaenc)) {
ret = gst_rtpmpaenc_flush (rtpmpaenc);
avail = 0;
+ } else {
+ ret = GST_FLOW_OK;
}
gst_adapter_push (rtpmpaenc->adapter, buffer);
@@ -260,75 +249,7 @@ gst_rtpmpaenc_chain (GstPad * pad, GstBuffer * buffer)
if (avail == 0) {
rtpmpaenc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
}
- gst_object_unref (rtpmpaenc);
- ret = GST_FLOW_OK;
-
- return ret;
-}
-
-static void
-gst_rtpmpaenc_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- GstRtpMPAEnc *rtpmpaenc;
-
- rtpmpaenc = GST_RTP_MPA_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- rtpmpaenc->mtu = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gst_rtpmpaenc_get_property (GObject * object, guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- GstRtpMPAEnc *rtpmpaenc;
-
- rtpmpaenc = GST_RTP_MPA_ENC (object);
-
- switch (prop_id) {
- case PROP_MTU:
- g_value_set_uint (value, rtpmpaenc->mtu);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GstStateChangeReturn
-gst_rtpmpaenc_change_state (GstElement * element, GstStateChange transition)
-{
- GstRtpMPAEnc *rtpmpaenc;
- GstStateChangeReturn ret;
-
- rtpmpaenc = GST_RTP_MPA_ENC (element);
-
- switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_PAUSED:
- rtpmpaenc->seqnum = 0;
- break;
- default:
- break;
- }
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
- switch (transition) {
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
- default:
- break;
- }
return ret;
}
diff --git a/gst/rtp/gstrtpmpapay.h b/gst/rtp/gstrtpmpapay.h
index 5a03c7cb..6079f83e 100644
--- a/gst/rtp/gstrtpmpapay.h
+++ b/gst/rtp/gstrtpmpapay.h
@@ -21,6 +21,7 @@
#define __GST_RTP_MPA_ENC_H__
#include <gst/gst.h>
+#include <gst/rtp/gstbasertppayload.h>
#include <gst/base/gstadapter.h>
G_BEGIN_DECLS
@@ -41,21 +42,15 @@ typedef struct _GstRtpMPAEncClass GstRtpMPAEncClass;
struct _GstRtpMPAEnc
{
- GstElement element;
-
- GstPad *sinkpad;
- GstPad *srcpad;
+ GstBaseRTPPayload payload;
GstAdapter *adapter;
GstClockTime first_ts;
- guint16 seqnum;
-
- guint mtu;
};
struct _GstRtpMPAEncClass
{
- GstElementClass parent_class;
+ GstBaseRTPPayloadClass parent_class;
};
gboolean gst_rtpmpaenc_plugin_init (GstPlugin * plugin);