mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 02:01:12 +00:00
Do burger's rename for rtp payloaders and depayloaders
Original commit message from CVS: Do burger's rename for rtp payloaders and depayloaders
This commit is contained in:
parent
0b3776c0b8
commit
7a4f8655ce
77 changed files with 1575 additions and 6938 deletions
75
ChangeLog
75
ChangeLog
|
@ -1,3 +1,78 @@
|
|||
2005-12-01 Thomas Vander Stichele <thomas (at) apestaart (dot) org>
|
||||
|
||||
* gst/rtp/Makefile.am:
|
||||
* gst/rtp/gstasteriskh263.c:
|
||||
* gst/rtp/gstrtp.c:
|
||||
* gst/rtp/gstrtpL16enc.c:
|
||||
* gst/rtp/gstrtpL16enc.h:
|
||||
* gst/rtp/gstrtpL16parse.c:
|
||||
* gst/rtp/gstrtpL16parse.h:
|
||||
* gst/rtp/gstrtpL16pay.c:
|
||||
* gst/rtp/gstrtpL16pay.h:
|
||||
* gst/rtp/gstrtpamrdec.c:
|
||||
* gst/rtp/gstrtpamrdec.h:
|
||||
* gst/rtp/gstrtpamrdepay.c:
|
||||
* gst/rtp/gstrtpamrdepay.h:
|
||||
* gst/rtp/gstrtpamrenc.c:
|
||||
* gst/rtp/gstrtpamrenc.h:
|
||||
* gst/rtp/gstrtpamrpay.c:
|
||||
* gst/rtp/gstrtpamrpay.h:
|
||||
* gst/rtp/gstrtpdec.c:
|
||||
* gst/rtp/gstrtpdec.h:
|
||||
* gst/rtp/gstrtpdepay.c:
|
||||
* gst/rtp/gstrtpdepay.h:
|
||||
* gst/rtp/gstrtpg711dec.c:
|
||||
* gst/rtp/gstrtpg711dec.h:
|
||||
* gst/rtp/gstrtpg711depay.c:
|
||||
* gst/rtp/gstrtpg711depay.h:
|
||||
* gst/rtp/gstrtpg711enc.c:
|
||||
* gst/rtp/gstrtpg711enc.h:
|
||||
* gst/rtp/gstrtpg711pay.c:
|
||||
* gst/rtp/gstrtpg711pay.h:
|
||||
* gst/rtp/gstrtpgsmenc.c:
|
||||
* gst/rtp/gstrtpgsmenc.h:
|
||||
* gst/rtp/gstrtpgsmparse.c:
|
||||
* gst/rtp/gstrtpgsmparse.h:
|
||||
* gst/rtp/gstrtpgsmpay.c:
|
||||
* gst/rtp/gstrtpgsmpay.h:
|
||||
* gst/rtp/gstrtph263enc.c:
|
||||
* gst/rtp/gstrtph263enc.h:
|
||||
* gst/rtp/gstrtph263pay.c:
|
||||
* gst/rtp/gstrtph263pay.h:
|
||||
* gst/rtp/gstrtph263pdec.c:
|
||||
* gst/rtp/gstrtph263pdec.h:
|
||||
* gst/rtp/gstrtph263pdepay.c:
|
||||
* gst/rtp/gstrtph263pdepay.h:
|
||||
* gst/rtp/gstrtph263penc.c:
|
||||
* gst/rtp/gstrtph263penc.h:
|
||||
* gst/rtp/gstrtph263ppay.c:
|
||||
* gst/rtp/gstrtph263ppay.h:
|
||||
* gst/rtp/gstrtpmp4vdec.c:
|
||||
* gst/rtp/gstrtpmp4vdec.h:
|
||||
* gst/rtp/gstrtpmp4vdepay.c:
|
||||
* gst/rtp/gstrtpmp4vdepay.h:
|
||||
* gst/rtp/gstrtpmp4venc.c:
|
||||
* gst/rtp/gstrtpmp4venc.h:
|
||||
* gst/rtp/gstrtpmp4vpay.c:
|
||||
* gst/rtp/gstrtpmp4vpay.h:
|
||||
* gst/rtp/gstrtpmpadec.c:
|
||||
* gst/rtp/gstrtpmpadec.h:
|
||||
* gst/rtp/gstrtpmpadepay.c:
|
||||
* gst/rtp/gstrtpmpadepay.h:
|
||||
* gst/rtp/gstrtpmpaenc.c:
|
||||
* gst/rtp/gstrtpmpaenc.h:
|
||||
* gst/rtp/gstrtpmpapay.c:
|
||||
* gst/rtp/gstrtpmpapay.h:
|
||||
* gst/rtp/gstrtpspeexdec.c:
|
||||
* gst/rtp/gstrtpspeexdec.h:
|
||||
* gst/rtp/gstrtpspeexdepay.c:
|
||||
* gst/rtp/gstrtpspeexdepay.h:
|
||||
* gst/rtp/gstrtpspeexenc.c:
|
||||
* gst/rtp/gstrtpspeexenc.h:
|
||||
* gst/rtp/gstrtpspeexpay.c:
|
||||
* gst/rtp/gstrtpspeexpay.h:
|
||||
Do burger's rename for rtp payloaders and depayloaders
|
||||
|
||||
2005-11-30 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* ext/dv/gstdvdec.c: (gst_dvdec_chain):
|
||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit f9f5f063728688cf455a1512d492b632c43963d7
|
||||
Subproject commit 54bb21c57bb86941d80c15590e0a121405173156
|
|
@ -2,25 +2,25 @@ plugin_LTLIBRARIES = libgstrtp.la
|
|||
|
||||
libgstrtp_la_SOURCES = \
|
||||
gstrtp.c \
|
||||
gstrtpdec.c \
|
||||
gstrtpmpadec.c \
|
||||
gstrtpmpaenc.c \
|
||||
gstrtpg711enc.c \
|
||||
gstrtpg711dec.c \
|
||||
gstrtpgsmenc.c \
|
||||
gstrtpdepay.c \
|
||||
gstrtpmpadepay.c \
|
||||
gstrtpmpapay.c \
|
||||
gstrtpg711pay.c \
|
||||
gstrtpg711depay.c \
|
||||
gstrtpgsmpay.c \
|
||||
gstrtpgsmparse.c \
|
||||
gstrtpamrdec.c \
|
||||
gstrtpamrenc.c \
|
||||
gstrtph263pdec.c \
|
||||
gstrtph263penc.c \
|
||||
gstrtph263enc.c \
|
||||
gstrtpamrdepay.c \
|
||||
gstrtpamrpay.c \
|
||||
gstrtph263pdepay.c \
|
||||
gstrtph263ppay.c \
|
||||
gstrtph263pay.c \
|
||||
gstasteriskh263.c \
|
||||
gstrtpmp4venc.c \
|
||||
gstrtpmp4vdec.c \
|
||||
gstrtpspeexenc.c \
|
||||
gstrtpspeexdec.c
|
||||
gstrtpmp4vpay.c \
|
||||
gstrtpmp4vdepay.c \
|
||||
gstrtpspeexpay.c \
|
||||
gstrtpspeexdepay.c
|
||||
|
||||
#gstrtpL16enc.c gstrtpL16parse.c gstrtpgsmenc.c gstrtpgsmparse.c
|
||||
#gstrtpL16pay.c gstrtpL16parse.c gstrtpgsmpay.c gstrtpgsmparse.c
|
||||
|
||||
if HAVE_WINSOCK2_H
|
||||
WINSOCK2_LIBS = -lws2_32
|
||||
|
@ -33,23 +33,23 @@ libgstrtp_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) \
|
|||
-lgstrtp-@GST_MAJORMINOR@ $(WINSOCK2_LIBS)
|
||||
libgstrtp_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
|
||||
noinst_HEADERS = gstrtpL16enc.h \
|
||||
noinst_HEADERS = gstrtpL16pay.h \
|
||||
gstrtpL16parse.h \
|
||||
gstrtpamrdec.h \
|
||||
gstrtpamrenc.h \
|
||||
gstrtpg711enc.h \
|
||||
gstrtpg711dec.h \
|
||||
gstrtpgsmenc.h \
|
||||
gstrtpamrdepay.h \
|
||||
gstrtpamrpay.h \
|
||||
gstrtpg711pay.h \
|
||||
gstrtpg711depay.h \
|
||||
gstrtpgsmpay.h \
|
||||
gstrtpgsmparse.h \
|
||||
gstrtpmpadec.h \
|
||||
gstrtpmpaenc.h \
|
||||
gstrtph263pdec.h \
|
||||
gstrtph263penc.h \
|
||||
gstrtph263enc.h \
|
||||
gstrtpmp4venc.h \
|
||||
gstrtpmp4vdec.h \
|
||||
gstrtpdec.h \
|
||||
gstrtph263enc.h \
|
||||
gstrtpmpadepay.h \
|
||||
gstrtpmpapay.h \
|
||||
gstrtph263pdepay.h \
|
||||
gstrtph263ppay.h \
|
||||
gstrtph263pay.h \
|
||||
gstrtpmp4vpay.h \
|
||||
gstrtpmp4vdepay.h \
|
||||
gstrtpdepay.h \
|
||||
gstrtph263pay.h \
|
||||
gstasteriskh263.h \
|
||||
gstrtpspeexenc.h \
|
||||
gstrtpspeexdec.h
|
||||
gstrtpspeexpay.h \
|
||||
gstrtpspeexdepay.h
|
||||
|
|
|
@ -41,7 +41,7 @@ typedef struct _GstAsteriskH263Header
|
|||
#define GST_ASTERISKH263_HEADER_LENGTH(buf) (((GstAsteriskH263Header *)(GST_BUFFER_DATA (buf)))->length)
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_h263pdec_details = {
|
||||
static GstElementDetails gst_rtp_h263p_depaydetails = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts H263 video from RTP and encodes in Asterisk H263 format",
|
||||
|
@ -130,7 +130,7 @@ gst_asteriskh263_base_init (GstAsteriskh263Class * klass)
|
|||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_asteriskh263_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263pdec_details);
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263p_depaydetails);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -191,7 +191,7 @@ gst_asteriskh263_chain (GstPad * pad, GstBuffer * buf)
|
|||
|
||||
asteriskh263 = GST_ASTERISK_H263 (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (!gst_rtpbuffer_validate (buf))
|
||||
if (!gst_rtp_buffer_validate (buf))
|
||||
goto bad_packet;
|
||||
|
||||
{
|
||||
|
@ -202,11 +202,11 @@ gst_asteriskh263_chain (GstPad * pad, GstBuffer * buf)
|
|||
guint32 samples;
|
||||
guint16 asterisk_len;
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
payload_len = gst_rtp_buffer_get_payload_len (buf);
|
||||
payload = gst_rtp_buffer_get_payload (buf);
|
||||
|
||||
M = gst_rtpbuffer_get_marker (buf);
|
||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||
M = gst_rtp_buffer_get_marker (buf);
|
||||
timestamp = gst_rtp_buffer_get_timestamp (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len +
|
||||
GST_ASTERISKH263_HEADER_LEN);
|
||||
|
|
|
@ -21,76 +21,76 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gstrtpdec.h"
|
||||
#include "gstrtpg711enc.h"
|
||||
#include "gstrtpg711dec.h"
|
||||
#include "gstrtpgsmenc.h"
|
||||
#include "gstrtpdepay.h"
|
||||
#include "gstrtpg711pay.h"
|
||||
#include "gstrtpg711depay.h"
|
||||
#include "gstrtpgsmpay.h"
|
||||
#include "gstrtpgsmparse.h"
|
||||
#include "gstrtpamrenc.h"
|
||||
#include "gstrtpamrdec.h"
|
||||
#include "gstrtpmpaenc.h"
|
||||
#include "gstrtpmpadec.h"
|
||||
#include "gstrtph263pdec.h"
|
||||
#include "gstrtph263penc.h"
|
||||
#include "gstrtph263enc.h"
|
||||
#include "gstrtpamrpay.h"
|
||||
#include "gstrtpamrdepay.h"
|
||||
#include "gstrtpmpapay.h"
|
||||
#include "gstrtpmpadepay.h"
|
||||
#include "gstrtph263pdepay.h"
|
||||
#include "gstrtph263ppay.h"
|
||||
#include "gstrtph263pay.h"
|
||||
#include "gstasteriskh263.h"
|
||||
#include "gstrtpmp4venc.h"
|
||||
#include "gstrtpmp4vdec.h"
|
||||
#include "gstrtpspeexenc.h"
|
||||
#include "gstrtpspeexdec.h"
|
||||
#include "gstrtpmp4vpay.h"
|
||||
#include "gstrtpmp4vdepay.h"
|
||||
#include "gstrtpspeexpay.h"
|
||||
#include "gstrtpspeexdepay.h"
|
||||
|
||||
static gboolean
|
||||
plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
if (!gst_rtpdec_plugin_init (plugin))
|
||||
if (!gst_rtp_depay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpgsmparse_plugin_init (plugin))
|
||||
if (!gst_rtp_gsm_parse_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpgsmenc_plugin_init (plugin))
|
||||
if (!gst_rtp_gsm_pay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpamrdec_plugin_init (plugin))
|
||||
if (!gst_rtp_amr_depay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpamrenc_plugin_init (plugin))
|
||||
if (!gst_rtp_amr_pay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpg711dec_plugin_init (plugin))
|
||||
if (!gst_rtp_g711_depay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpg711enc_plugin_init (plugin))
|
||||
if (!gst_rtp_g711_pay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpmpadec_plugin_init (plugin))
|
||||
if (!gst_rtp_mpa_depay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpmpaenc_plugin_init (plugin))
|
||||
if (!gst_rtp_mpa_pay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtph263penc_plugin_init (plugin))
|
||||
if (!gst_rtp_h263p_pay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtph263pdec_plugin_init (plugin))
|
||||
if (!gst_rtp_h263p_depay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtph263enc_plugin_init (plugin))
|
||||
if (!gst_rtp_h263_pay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_asteriskh263_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpmp4venc_plugin_init (plugin))
|
||||
if (!gst_rtp_mp4v_pay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpmp4vdec_plugin_init (plugin))
|
||||
if (!gst_rtp_mp4v_depay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpspeexenc_plugin_init (plugin))
|
||||
if (!gst_rtp_speex_pay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
if (!gst_rtpspeexdec_plugin_init (plugin))
|
||||
if (!gst_rtp_speex_depay_plugin_init (plugin))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -100,4 +100,4 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
|||
GST_VERSION_MINOR,
|
||||
"rtp",
|
||||
"Real-time protocol plugins",
|
||||
plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
|
||||
plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
|
||||
|
|
|
@ -41,7 +41,7 @@ enum
|
|||
ARG_PAYLOAD_TYPE
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpL16parse_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_L16parse_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -53,43 +53,44 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
|||
"rate = (int) [ 1000, 48000 ], " "channels = (int) [ 1, 2 ]")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpL16parse_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_L16parse_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp")
|
||||
);
|
||||
|
||||
static void gst_rtpL16parse_class_init (GstRtpL16ParseClass * klass);
|
||||
static void gst_rtpL16parse_base_init (GstRtpL16ParseClass * klass);
|
||||
static void gst_rtpL16parse_init (GstRtpL16Parse * rtpL16parse);
|
||||
static void gst_rtp_L16parse_class_init (GstRtpL16ParseClass * klass);
|
||||
static void gst_rtp_L16parse_base_init (GstRtpL16ParseClass * klass);
|
||||
static void gst_rtp_L16parse_init (GstRtpL16Parse * rtpL16parse);
|
||||
|
||||
static void gst_rtpL16parse_chain (GstPad * pad, GstData * _data);
|
||||
static void gst_rtp_L16parse_chain (GstPad * pad, GstData * _data);
|
||||
|
||||
static void gst_rtpL16parse_set_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_L16parse_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpL16parse_get_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_L16parse_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static GstStateChangeReturn gst_rtpL16parse_change_state (GstElement * element);
|
||||
static GstStateChangeReturn gst_rtp_L16parse_change_state (GstElement *
|
||||
element);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpL16parse_get_type (void)
|
||||
gst_rtp_L16parse_get_type (void)
|
||||
{
|
||||
static GType rtpL16parse_type = 0;
|
||||
|
||||
if (!rtpL16parse_type) {
|
||||
static const GTypeInfo rtpL16parse_info = {
|
||||
sizeof (GstRtpL16ParseClass),
|
||||
(GBaseInitFunc) gst_rtpL16parse_base_init,
|
||||
(GBaseInitFunc) gst_rtp_L16parse_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpL16parse_class_init,
|
||||
(GClassInitFunc) gst_rtp_L16parse_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpL16Parse),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpL16parse_init,
|
||||
(GInstanceInitFunc) gst_rtp_L16parse_init,
|
||||
};
|
||||
|
||||
rtpL16parse_type =
|
||||
|
@ -100,19 +101,19 @@ gst_rtpL16parse_get_type (void)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_base_init (GstRtpL16ParseClass * klass)
|
||||
gst_rtp_L16parse_base_init (GstRtpL16ParseClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpL16parse_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_L16parse_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpL16parse_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_L16parse_sink_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_L16parse_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_class_init (GstRtpL16ParseClass * klass)
|
||||
gst_rtp_L16parse_class_init (GstRtpL16ParseClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -129,24 +130,24 @@ gst_rtpL16parse_class_init (GstRtpL16ParseClass * klass)
|
|||
g_param_spec_int ("frequency", "frequency", "frequency",
|
||||
G_MININT, G_MAXINT, 44100, G_PARAM_READWRITE));
|
||||
|
||||
gobject_class->set_property = gst_rtpL16parse_set_property;
|
||||
gobject_class->get_property = gst_rtpL16parse_get_property;
|
||||
gobject_class->set_property = gst_rtp_L16parse_set_property;
|
||||
gobject_class->get_property = gst_rtp_L16parse_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtpL16parse_change_state;
|
||||
gstelement_class->change_state = gst_rtp_L16parse_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_init (GstRtpL16Parse * rtpL16parse)
|
||||
gst_rtp_L16parse_init (GstRtpL16Parse * rtpL16parse)
|
||||
{
|
||||
rtpL16parse->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpL16parse_src_template), "src");
|
||||
(&gst_rtp_L16parse_src_template), "src");
|
||||
rtpL16parse->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpL16parse_sink_template), "sink");
|
||||
(&gst_rtp_L16parse_sink_template), "sink");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpL16parse), rtpL16parse->srcpad);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpL16parse), rtpL16parse->sinkpad);
|
||||
gst_pad_set_chain_function (rtpL16parse->sinkpad, gst_rtpL16parse_chain);
|
||||
gst_pad_set_chain_function (rtpL16parse->sinkpad, gst_rtp_L16parse_chain);
|
||||
|
||||
rtpL16parse->frequency = 44100;
|
||||
rtpL16parse->channels = 2;
|
||||
|
@ -155,7 +156,7 @@ gst_rtpL16parse_init (GstRtpL16Parse * rtpL16parse)
|
|||
}
|
||||
|
||||
void
|
||||
gst_rtpL16parse_ntohs (GstBuffer * buf)
|
||||
gst_rtp_L16parse_ntohs (GstBuffer * buf)
|
||||
{
|
||||
gint16 *i, *len;
|
||||
|
||||
|
@ -169,12 +170,12 @@ gst_rtpL16parse_ntohs (GstBuffer * buf)
|
|||
}
|
||||
|
||||
void
|
||||
gst_rtpL16_caps_nego (GstRtpL16Parse * rtpL16parse)
|
||||
gst_rtp_L16_caps_nego (GstRtpL16Parse * rtpL16parse)
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
caps =
|
||||
gst_caps_copy (gst_static_caps_get (&gst_rtpL16parse_src_template.
|
||||
gst_caps_copy (gst_static_caps_get (&gst_rtp_L16parse_src_template.
|
||||
static_caps));
|
||||
|
||||
gst_caps_set_simple (caps,
|
||||
|
@ -185,7 +186,7 @@ gst_rtpL16_caps_nego (GstRtpL16Parse * rtpL16parse)
|
|||
}
|
||||
|
||||
void
|
||||
gst_rtpL16parse_payloadtype_change (GstRtpL16Parse * rtpL16parse,
|
||||
gst_rtp_L16parse_payloadtype_change (GstRtpL16Parse * rtpL16parse,
|
||||
rtp_payload_t pt)
|
||||
{
|
||||
rtpL16parse->payload_type = pt;
|
||||
|
@ -201,11 +202,11 @@ gst_rtpL16parse_payloadtype_change (GstRtpL16Parse * rtpL16parse,
|
|||
g_warning ("unknown payload_t %d\n", pt);
|
||||
}
|
||||
|
||||
gst_rtpL16_caps_nego (rtpL16parse);
|
||||
gst_rtp_L16_caps_nego (rtpL16parse);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_chain (GstPad * pad, GstData * _data)
|
||||
gst_rtp_L16parse_chain (GstPad * pad, GstData * _data)
|
||||
{
|
||||
GstBuffer *buf = GST_BUFFER (_data);
|
||||
GstRtpL16Parse *rtpL16parse;
|
||||
|
@ -231,7 +232,7 @@ gst_rtpL16parse_chain (GstPad * pad, GstData * _data)
|
|||
}
|
||||
|
||||
if (GST_PAD_CAPS (rtpL16parse->srcpad) == NULL) {
|
||||
gst_rtpL16_caps_nego (rtpL16parse);
|
||||
gst_rtp_L16_caps_nego (rtpL16parse);
|
||||
}
|
||||
|
||||
packet =
|
||||
|
@ -240,7 +241,7 @@ gst_rtpL16parse_chain (GstPad * pad, GstData * _data)
|
|||
pt = rtp_packet_get_payload_type (packet);
|
||||
|
||||
if (pt != rtpL16parse->payload_type) {
|
||||
gst_rtpL16parse_payloadtype_change (rtpL16parse, pt);
|
||||
gst_rtp_L16parse_payloadtype_change (rtpL16parse, pt);
|
||||
}
|
||||
|
||||
outbuf = gst_buffer_new ();
|
||||
|
@ -252,12 +253,12 @@ gst_rtpL16parse_chain (GstPad * pad, GstData * _data)
|
|||
memcpy (GST_BUFFER_DATA (outbuf), rtp_packet_get_payload (packet),
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
GST_DEBUG ("gst_rtpL16parse_chain: pushing buffer of size %d",
|
||||
GST_DEBUG ("gst_rtp_L16parse_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
/* FIXME: According to RFC 1890, this is required, right? */
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
gst_rtpL16parse_ntohs (outbuf);
|
||||
gst_rtp_L16parse_ntohs (outbuf);
|
||||
#endif
|
||||
|
||||
gst_pad_push (rtpL16parse->srcpad, GST_DATA (outbuf));
|
||||
|
@ -267,7 +268,7 @@ gst_rtpL16parse_chain (GstPad * pad, GstData * _data)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_set_property (GObject * object, guint prop_id,
|
||||
gst_rtp_L16parse_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpL16Parse *rtpL16parse;
|
||||
|
@ -277,7 +278,8 @@ gst_rtpL16parse_set_property (GObject * object, guint prop_id,
|
|||
|
||||
switch (prop_id) {
|
||||
case ARG_PAYLOAD_TYPE:
|
||||
gst_rtpL16parse_payloadtype_change (rtpL16parse, g_value_get_int (value));
|
||||
gst_rtp_L16parse_payloadtype_change (rtpL16parse,
|
||||
g_value_get_int (value));
|
||||
break;
|
||||
case ARG_FREQUENCY:
|
||||
rtpL16parse->frequency = g_value_get_int (value);
|
||||
|
@ -288,7 +290,7 @@ gst_rtpL16parse_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
gst_rtp_L16parse_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRtpL16Parse *rtpL16parse;
|
||||
|
@ -310,7 +312,7 @@ gst_rtpL16parse_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpL16parse_change_state (GstElement * element, GstStateChange transition)
|
||||
gst_rtp_L16parse_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstRtpL16Parse *rtpL16parse;
|
||||
|
||||
|
@ -338,7 +340,7 @@ gst_rtpL16parse_change_state (GstElement * element, GstStateChange transition)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpL16parse_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_L16parse_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpL16parse",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_L16_PARSE);
|
||||
|
|
|
@ -53,7 +53,7 @@ struct _GstRtpL16ParseClass
|
|||
|
||||
/* Standard macros for defining types for this element. */
|
||||
#define GST_TYPE_RTP_L16_PARSE \
|
||||
(gst_rtpL16parse_get_type())
|
||||
(gst_rtp_L16parse_get_type())
|
||||
#define GST_RTP_L16_PARSE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_L16_PARSE,GstRtpL16Parse))
|
||||
#define GST_RTP_L16_PARSE_CLASS(klass) \
|
||||
|
@ -63,7 +63,7 @@ struct _GstRtpL16ParseClass
|
|||
#define GST_IS_RTP_L16_PARSE_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_L16_PARSE))
|
||||
|
||||
gboolean gst_rtpL16parse_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_L16parse_plugin_init (GstPlugin * plugin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,345 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "gstrtpL16enc.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtpL16enc_details = {
|
||||
"RTP RAW Audio Encoder",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes Raw Audio into a RTP packet",
|
||||
"Zeeshan Ali <zak147@yahoo.com>"
|
||||
};
|
||||
|
||||
/* RtpL16Enc signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
ARG_0
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpL16enc_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-raw-int, "
|
||||
"endianness = (int) BYTE_ORDER, "
|
||||
"signed = (boolean) true, "
|
||||
"width = (int) 16, "
|
||||
"depth = (int) 16, "
|
||||
"rate = (int) [ 1000, 48000 ], " "channels = (int) [ 1, 2 ]")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpL16enc_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp")
|
||||
);
|
||||
|
||||
static void gst_rtpL16enc_class_init (GstRtpL16EncClass * klass);
|
||||
static void gst_rtpL16enc_base_init (GstRtpL16EncClass * klass);
|
||||
static void gst_rtpL16enc_init (GstRtpL16Enc * rtpL16enc);
|
||||
static void gst_rtpL16enc_chain (GstPad * pad, GstData * _data);
|
||||
static void gst_rtpL16enc_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpL16enc_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static GstPadLinkReturn gst_rtpL16enc_sinkconnect (GstPad * pad,
|
||||
const GstCaps * caps);
|
||||
static GstStateChangeReturn gst_rtpL16enc_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpL16enc_get_type (void)
|
||||
{
|
||||
static GType rtpL16enc_type = 0;
|
||||
|
||||
if (!rtpL16enc_type) {
|
||||
static const GTypeInfo rtpL16enc_info = {
|
||||
sizeof (GstRtpL16EncClass),
|
||||
(GBaseInitFunc) gst_rtpL16enc_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpL16enc_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpL16Enc),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpL16enc_init,
|
||||
};
|
||||
|
||||
rtpL16enc_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpL16Enc",
|
||||
&rtpL16enc_info, 0);
|
||||
}
|
||||
return rtpL16enc_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_base_init (GstRtpL16EncClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpL16enc_sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpL16enc_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtpL16enc_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_class_init (GstRtpL16EncClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_rtpL16enc_set_property;
|
||||
gobject_class->get_property = gst_rtpL16enc_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtpL16enc_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_init (GstRtpL16Enc * rtpL16enc)
|
||||
{
|
||||
rtpL16enc->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpL16enc_sink_template), "sink");
|
||||
rtpL16enc->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpL16enc_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpL16enc), rtpL16enc->sinkpad);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpL16enc), rtpL16enc->srcpad);
|
||||
gst_pad_set_chain_function (rtpL16enc->sinkpad, gst_rtpL16enc_chain);
|
||||
gst_pad_set_link_function (rtpL16enc->sinkpad, gst_rtpL16enc_sinkconnect);
|
||||
|
||||
rtpL16enc->frequency = 44100;
|
||||
rtpL16enc->channels = 2;
|
||||
|
||||
rtpL16enc->next_time = 0;
|
||||
rtpL16enc->time_interval = 0;
|
||||
|
||||
rtpL16enc->seq = 0;
|
||||
rtpL16enc->ssrc = random ();
|
||||
}
|
||||
|
||||
static GstPadLinkReturn
|
||||
gst_rtpL16enc_sinkconnect (GstPad * pad, const GstCaps * caps)
|
||||
{
|
||||
GstRtpL16Enc *rtpL16enc;
|
||||
GstStructure *structure;
|
||||
gboolean ret;
|
||||
|
||||
rtpL16enc = GST_RTP_L16_ENC (gst_pad_get_parent (pad));
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
ret = gst_structure_get_int (structure, "rate", &rtpL16enc->frequency);
|
||||
ret &= gst_structure_get_int (structure, "channels", &rtpL16enc->channels);
|
||||
|
||||
if (!ret)
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
|
||||
/* Pre-calculate what we can */
|
||||
rtpL16enc->time_interval =
|
||||
GST_SECOND / (2 * rtpL16enc->channels * rtpL16enc->frequency);
|
||||
|
||||
return GST_PAD_LINK_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gst_rtpL16enc_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_rtpL16enc_chain (GstPad * pad, GstData * _data)
|
||||
{
|
||||
GstBuffer *buf = GST_BUFFER (_data);
|
||||
GstRtpL16Enc *rtpL16enc;
|
||||
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);
|
||||
|
||||
rtpL16enc = GST_RTP_L16_ENC (GST_OBJECT_PARENT (pad));
|
||||
|
||||
g_return_if_fail (rtpL16enc != NULL);
|
||||
g_return_if_fail (GST_IS_RTP_L16_ENC (rtpL16enc));
|
||||
|
||||
if (GST_IS_EVENT (buf)) {
|
||||
GstEvent *event = GST_EVENT (buf);
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_DISCONTINUOUS:
|
||||
GST_DEBUG ("discont");
|
||||
rtpL16enc->next_time = 0;
|
||||
gst_pad_event_default (pad, event);
|
||||
return;
|
||||
default:
|
||||
gst_pad_event_default (pad, event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 (rtpL16enc->ssrc));
|
||||
rtp_packet_set_seq (packet, g_htons (rtpL16enc->seq));
|
||||
rtp_packet_set_timestamp (packet,
|
||||
g_htonl ((guint32) rtpL16enc->next_time / GST_SECOND));
|
||||
|
||||
if (rtpL16enc->channels == 1) {
|
||||
rtp_packet_set_payload_type (packet, (guint8) PAYLOAD_L16_MONO);
|
||||
}
|
||||
|
||||
else {
|
||||
rtp_packet_set_payload_type (packet, (guint8) PAYLOAD_L16_STEREO);
|
||||
}
|
||||
|
||||
/* FIXME: According to RFC 1890, this is required, right? */
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
gst_rtpL16enc_htons (buf);
|
||||
#endif
|
||||
|
||||
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) = rtpL16enc->next_time;
|
||||
|
||||
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));
|
||||
|
||||
GST_DEBUG ("gst_rtpL16enc_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
gst_pad_push (rtpL16enc->srcpad, GST_DATA (outbuf));
|
||||
|
||||
++rtpL16enc->seq;
|
||||
rtpL16enc->next_time += rtpL16enc->time_interval * GST_BUFFER_SIZE (buf);
|
||||
|
||||
rtp_packet_free (packet);
|
||||
gst_buffer_unref (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpL16Enc *rtpL16enc;
|
||||
|
||||
g_return_if_fail (GST_IS_RTP_L16_ENC (object));
|
||||
rtpL16enc = GST_RTP_L16_ENC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRtpL16Enc *rtpL16enc;
|
||||
|
||||
g_return_if_fail (GST_IS_RTP_L16_ENC (object));
|
||||
rtpL16enc = GST_RTP_L16_ENC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpL16enc_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstRtpL16Enc *rtpL16enc;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTP_L16_ENC (element), GST_STATE_CHANGE_FAILURE);
|
||||
|
||||
rtpL16enc = GST_RTP_L16_ENC (element);
|
||||
|
||||
GST_DEBUG ("state pending %d\n", GST_STATE_PENDING (element));
|
||||
|
||||
/* if going down into NULL state, close the file if it's open */
|
||||
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);
|
||||
|
||||
return GST_STATE_CHANGE_SUCCESS;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpL16enc_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpL16enc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_L16_ENC);
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GST_RTP_L16_ENC_H__
|
||||
#define __GST_RTP_L16_ENC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Definition of structure storing data for this element. */
|
||||
typedef struct _GstRtpL16Enc GstRtpL16Enc;
|
||||
struct _GstRtpL16Enc
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
guint frequency;
|
||||
guint channels;
|
||||
|
||||
/* 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 _GstRtpL16EncClass GstRtpL16EncClass;
|
||||
struct _GstRtpL16EncClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
/* Standard macros for defining types for this element. */
|
||||
#define GST_TYPE_RTP_L16_ENC \
|
||||
(gst_rtpL16enc_get_type())
|
||||
#define GST_RTP_L16_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_L16_ENC,GstRtpL16Enc))
|
||||
#define GST_RTP_L16_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_L16_ENC,GstRtpL16Enc))
|
||||
#define GST_IS_RTP_L16_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_L16_ENC))
|
||||
#define GST_IS_RTP_L16_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_L16_ENC))
|
||||
|
||||
gboolean gst_rtpL16enc_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_L16_ENC_H__ */
|
|
@ -41,7 +41,7 @@ enum
|
|||
ARG_PAYLOAD_TYPE
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpL16parse_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_L16parse_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -53,43 +53,44 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
|||
"rate = (int) [ 1000, 48000 ], " "channels = (int) [ 1, 2 ]")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpL16parse_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_L16parse_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp")
|
||||
);
|
||||
|
||||
static void gst_rtpL16parse_class_init (GstRtpL16ParseClass * klass);
|
||||
static void gst_rtpL16parse_base_init (GstRtpL16ParseClass * klass);
|
||||
static void gst_rtpL16parse_init (GstRtpL16Parse * rtpL16parse);
|
||||
static void gst_rtp_L16parse_class_init (GstRtpL16ParseClass * klass);
|
||||
static void gst_rtp_L16parse_base_init (GstRtpL16ParseClass * klass);
|
||||
static void gst_rtp_L16parse_init (GstRtpL16Parse * rtpL16parse);
|
||||
|
||||
static void gst_rtpL16parse_chain (GstPad * pad, GstData * _data);
|
||||
static void gst_rtp_L16parse_chain (GstPad * pad, GstData * _data);
|
||||
|
||||
static void gst_rtpL16parse_set_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_L16parse_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpL16parse_get_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_L16parse_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static GstStateChangeReturn gst_rtpL16parse_change_state (GstElement * element);
|
||||
static GstStateChangeReturn gst_rtp_L16parse_change_state (GstElement *
|
||||
element);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpL16parse_get_type (void)
|
||||
gst_rtp_L16parse_get_type (void)
|
||||
{
|
||||
static GType rtpL16parse_type = 0;
|
||||
|
||||
if (!rtpL16parse_type) {
|
||||
static const GTypeInfo rtpL16parse_info = {
|
||||
sizeof (GstRtpL16ParseClass),
|
||||
(GBaseInitFunc) gst_rtpL16parse_base_init,
|
||||
(GBaseInitFunc) gst_rtp_L16parse_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpL16parse_class_init,
|
||||
(GClassInitFunc) gst_rtp_L16parse_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpL16Parse),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpL16parse_init,
|
||||
(GInstanceInitFunc) gst_rtp_L16parse_init,
|
||||
};
|
||||
|
||||
rtpL16parse_type =
|
||||
|
@ -100,19 +101,19 @@ gst_rtpL16parse_get_type (void)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_base_init (GstRtpL16ParseClass * klass)
|
||||
gst_rtp_L16parse_base_init (GstRtpL16ParseClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpL16parse_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_L16parse_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpL16parse_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_L16parse_sink_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_L16parse_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_class_init (GstRtpL16ParseClass * klass)
|
||||
gst_rtp_L16parse_class_init (GstRtpL16ParseClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -129,24 +130,24 @@ gst_rtpL16parse_class_init (GstRtpL16ParseClass * klass)
|
|||
g_param_spec_int ("frequency", "frequency", "frequency",
|
||||
G_MININT, G_MAXINT, 44100, G_PARAM_READWRITE));
|
||||
|
||||
gobject_class->set_property = gst_rtpL16parse_set_property;
|
||||
gobject_class->get_property = gst_rtpL16parse_get_property;
|
||||
gobject_class->set_property = gst_rtp_L16parse_set_property;
|
||||
gobject_class->get_property = gst_rtp_L16parse_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtpL16parse_change_state;
|
||||
gstelement_class->change_state = gst_rtp_L16parse_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_init (GstRtpL16Parse * rtpL16parse)
|
||||
gst_rtp_L16parse_init (GstRtpL16Parse * rtpL16parse)
|
||||
{
|
||||
rtpL16parse->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpL16parse_src_template), "src");
|
||||
(&gst_rtp_L16parse_src_template), "src");
|
||||
rtpL16parse->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpL16parse_sink_template), "sink");
|
||||
(&gst_rtp_L16parse_sink_template), "sink");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpL16parse), rtpL16parse->srcpad);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpL16parse), rtpL16parse->sinkpad);
|
||||
gst_pad_set_chain_function (rtpL16parse->sinkpad, gst_rtpL16parse_chain);
|
||||
gst_pad_set_chain_function (rtpL16parse->sinkpad, gst_rtp_L16parse_chain);
|
||||
|
||||
rtpL16parse->frequency = 44100;
|
||||
rtpL16parse->channels = 2;
|
||||
|
@ -155,7 +156,7 @@ gst_rtpL16parse_init (GstRtpL16Parse * rtpL16parse)
|
|||
}
|
||||
|
||||
void
|
||||
gst_rtpL16parse_ntohs (GstBuffer * buf)
|
||||
gst_rtp_L16parse_ntohs (GstBuffer * buf)
|
||||
{
|
||||
gint16 *i, *len;
|
||||
|
||||
|
@ -169,12 +170,12 @@ gst_rtpL16parse_ntohs (GstBuffer * buf)
|
|||
}
|
||||
|
||||
void
|
||||
gst_rtpL16_caps_nego (GstRtpL16Parse * rtpL16parse)
|
||||
gst_rtp_L16_caps_nego (GstRtpL16Parse * rtpL16parse)
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
caps =
|
||||
gst_caps_copy (gst_static_caps_get (&gst_rtpL16parse_src_template.
|
||||
gst_caps_copy (gst_static_caps_get (&gst_rtp_L16parse_src_template.
|
||||
static_caps));
|
||||
|
||||
gst_caps_set_simple (caps,
|
||||
|
@ -185,7 +186,7 @@ gst_rtpL16_caps_nego (GstRtpL16Parse * rtpL16parse)
|
|||
}
|
||||
|
||||
void
|
||||
gst_rtpL16parse_payloadtype_change (GstRtpL16Parse * rtpL16parse,
|
||||
gst_rtp_L16parse_payloadtype_change (GstRtpL16Parse * rtpL16parse,
|
||||
rtp_payload_t pt)
|
||||
{
|
||||
rtpL16parse->payload_type = pt;
|
||||
|
@ -201,11 +202,11 @@ gst_rtpL16parse_payloadtype_change (GstRtpL16Parse * rtpL16parse,
|
|||
g_warning ("unknown payload_t %d\n", pt);
|
||||
}
|
||||
|
||||
gst_rtpL16_caps_nego (rtpL16parse);
|
||||
gst_rtp_L16_caps_nego (rtpL16parse);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_chain (GstPad * pad, GstData * _data)
|
||||
gst_rtp_L16parse_chain (GstPad * pad, GstData * _data)
|
||||
{
|
||||
GstBuffer *buf = GST_BUFFER (_data);
|
||||
GstRtpL16Parse *rtpL16parse;
|
||||
|
@ -231,7 +232,7 @@ gst_rtpL16parse_chain (GstPad * pad, GstData * _data)
|
|||
}
|
||||
|
||||
if (GST_PAD_CAPS (rtpL16parse->srcpad) == NULL) {
|
||||
gst_rtpL16_caps_nego (rtpL16parse);
|
||||
gst_rtp_L16_caps_nego (rtpL16parse);
|
||||
}
|
||||
|
||||
packet =
|
||||
|
@ -240,7 +241,7 @@ gst_rtpL16parse_chain (GstPad * pad, GstData * _data)
|
|||
pt = rtp_packet_get_payload_type (packet);
|
||||
|
||||
if (pt != rtpL16parse->payload_type) {
|
||||
gst_rtpL16parse_payloadtype_change (rtpL16parse, pt);
|
||||
gst_rtp_L16parse_payloadtype_change (rtpL16parse, pt);
|
||||
}
|
||||
|
||||
outbuf = gst_buffer_new ();
|
||||
|
@ -252,12 +253,12 @@ gst_rtpL16parse_chain (GstPad * pad, GstData * _data)
|
|||
memcpy (GST_BUFFER_DATA (outbuf), rtp_packet_get_payload (packet),
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
GST_DEBUG ("gst_rtpL16parse_chain: pushing buffer of size %d",
|
||||
GST_DEBUG ("gst_rtp_L16parse_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
/* FIXME: According to RFC 1890, this is required, right? */
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
gst_rtpL16parse_ntohs (outbuf);
|
||||
gst_rtp_L16parse_ntohs (outbuf);
|
||||
#endif
|
||||
|
||||
gst_pad_push (rtpL16parse->srcpad, GST_DATA (outbuf));
|
||||
|
@ -267,7 +268,7 @@ gst_rtpL16parse_chain (GstPad * pad, GstData * _data)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_set_property (GObject * object, guint prop_id,
|
||||
gst_rtp_L16parse_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpL16Parse *rtpL16parse;
|
||||
|
@ -277,7 +278,8 @@ gst_rtpL16parse_set_property (GObject * object, guint prop_id,
|
|||
|
||||
switch (prop_id) {
|
||||
case ARG_PAYLOAD_TYPE:
|
||||
gst_rtpL16parse_payloadtype_change (rtpL16parse, g_value_get_int (value));
|
||||
gst_rtp_L16parse_payloadtype_change (rtpL16parse,
|
||||
g_value_get_int (value));
|
||||
break;
|
||||
case ARG_FREQUENCY:
|
||||
rtpL16parse->frequency = g_value_get_int (value);
|
||||
|
@ -288,7 +290,7 @@ gst_rtpL16parse_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16parse_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
gst_rtp_L16parse_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRtpL16Parse *rtpL16parse;
|
||||
|
@ -310,7 +312,7 @@ gst_rtpL16parse_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpL16parse_change_state (GstElement * element, GstStateChange transition)
|
||||
gst_rtp_L16parse_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstRtpL16Parse *rtpL16parse;
|
||||
|
||||
|
@ -338,7 +340,7 @@ gst_rtpL16parse_change_state (GstElement * element, GstStateChange transition)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpL16parse_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_L16parse_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpL16parse",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_L16_PARSE);
|
||||
|
|
|
@ -53,7 +53,7 @@ struct _GstRtpL16ParseClass
|
|||
|
||||
/* Standard macros for defining types for this element. */
|
||||
#define GST_TYPE_RTP_L16_PARSE \
|
||||
(gst_rtpL16parse_get_type())
|
||||
(gst_rtp_L16parse_get_type())
|
||||
#define GST_RTP_L16_PARSE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_L16_PARSE,GstRtpL16Parse))
|
||||
#define GST_RTP_L16_PARSE_CLASS(klass) \
|
||||
|
@ -63,7 +63,7 @@ struct _GstRtpL16ParseClass
|
|||
#define GST_IS_RTP_L16_PARSE_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_L16_PARSE))
|
||||
|
||||
gboolean gst_rtpL16parse_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_L16parse_plugin_init (GstPlugin * plugin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -22,17 +22,17 @@
|
|||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "gstrtpL16enc.h"
|
||||
#include "gstrtpL16pay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtpL16enc_details = {
|
||||
"RTP RAW Audio Encoder",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes Raw Audio into a RTP packet",
|
||||
static GstElementDetails gst_rtpL16pay_details = {
|
||||
"RTP RAW Audio Payloader",
|
||||
"Codec/Payloader/Network",
|
||||
"Payodes Raw Audio into a RTP packet",
|
||||
"Zeeshan Ali <zak147@yahoo.com>"
|
||||
};
|
||||
|
||||
/* RtpL16Enc signals and args */
|
||||
/* RtpL16Pay signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
|
@ -45,7 +45,7 @@ enum
|
|||
ARG_0
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpL16enc_sink_template =
|
||||
static GstStaticPadTemplate gst_rtpL16pay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -57,67 +57,67 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
"rate = (int) [ 1000, 48000 ], " "channels = (int) [ 1, 2 ]")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpL16enc_src_template =
|
||||
static GstStaticPadTemplate gst_rtpL16pay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp")
|
||||
);
|
||||
|
||||
static void gst_rtpL16enc_class_init (GstRtpL16EncClass * klass);
|
||||
static void gst_rtpL16enc_base_init (GstRtpL16EncClass * klass);
|
||||
static void gst_rtpL16enc_init (GstRtpL16Enc * rtpL16enc);
|
||||
static void gst_rtpL16enc_chain (GstPad * pad, GstData * _data);
|
||||
static void gst_rtpL16enc_set_property (GObject * object, guint prop_id,
|
||||
static void gst_rtpL16pay_class_init (GstRtpL16PayClass * klass);
|
||||
static void gst_rtpL16pay_base_init (GstRtpL16PayClass * klass);
|
||||
static void gst_rtpL16pay_init (GstRtpL16Pay * rtpL16enc);
|
||||
static void gst_rtpL16pay_chain (GstPad * pad, GstData * _data);
|
||||
static void gst_rtpL16pay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpL16enc_get_property (GObject * object, guint prop_id,
|
||||
static void gst_rtpL16pay_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static GstPadLinkReturn gst_rtpL16enc_sinkconnect (GstPad * pad,
|
||||
static GstPadLinkReturn gst_rtpL16pay_sinkconnect (GstPad * pad,
|
||||
const GstCaps * caps);
|
||||
static GstStateChangeReturn gst_rtpL16enc_change_state (GstElement * element,
|
||||
static GstStateChangeReturn gst_rtpL16pay_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpL16enc_get_type (void)
|
||||
gst_rtpL16pay_get_type (void)
|
||||
{
|
||||
static GType rtpL16enc_type = 0;
|
||||
static GType rtpL16pay_type = 0;
|
||||
|
||||
if (!rtpL16enc_type) {
|
||||
static const GTypeInfo rtpL16enc_info = {
|
||||
sizeof (GstRtpL16EncClass),
|
||||
(GBaseInitFunc) gst_rtpL16enc_base_init,
|
||||
if (!rtpL16pay_type) {
|
||||
static const GTypeInfo rtpL16pay_info = {
|
||||
sizeof (GstRtpL16PayClass),
|
||||
(GBaseInitFunc) gst_rtpL16pay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpL16enc_class_init,
|
||||
(GClassInitFunc) gst_rtpL16pay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpL16Enc),
|
||||
sizeof (GstRtpL16Pay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpL16enc_init,
|
||||
(GInstanceInitFunc) gst_rtpL16pay_init,
|
||||
};
|
||||
|
||||
rtpL16enc_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpL16Enc",
|
||||
&rtpL16enc_info, 0);
|
||||
rtpL16pay_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpL16Pay",
|
||||
&rtpL16pay_info, 0);
|
||||
}
|
||||
return rtpL16enc_type;
|
||||
return rtpL16pay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_base_init (GstRtpL16EncClass * klass)
|
||||
gst_rtpL16pay_base_init (GstRtpL16PayClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpL16enc_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtpL16pay_sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpL16enc_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtpL16enc_details);
|
||||
gst_static_pad_template_get (&gst_rtpL16pay_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtpL16pay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_class_init (GstRtpL16EncClass * klass)
|
||||
gst_rtpL16pay_class_init (GstRtpL16PayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -127,25 +127,25 @@ gst_rtpL16enc_class_init (GstRtpL16EncClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_rtpL16enc_set_property;
|
||||
gobject_class->get_property = gst_rtpL16enc_get_property;
|
||||
gobject_class->set_property = gst_rtpL16pay_set_property;
|
||||
gobject_class->get_property = gst_rtpL16pay_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtpL16enc_change_state;
|
||||
gstelement_class->change_state = gst_rtpL16pay_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_init (GstRtpL16Enc * rtpL16enc)
|
||||
gst_rtpL16pay_init (GstRtpL16Pay * rtpL16enc)
|
||||
{
|
||||
rtpL16enc->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpL16enc_sink_template), "sink");
|
||||
(&gst_rtpL16pay_sink_template), "sink");
|
||||
rtpL16enc->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpL16enc_src_template), "src");
|
||||
(&gst_rtpL16pay_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpL16enc), rtpL16enc->sinkpad);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpL16enc), rtpL16enc->srcpad);
|
||||
gst_pad_set_chain_function (rtpL16enc->sinkpad, gst_rtpL16enc_chain);
|
||||
gst_pad_set_link_function (rtpL16enc->sinkpad, gst_rtpL16enc_sinkconnect);
|
||||
gst_pad_set_chain_function (rtpL16enc->sinkpad, gst_rtpL16pay_chain);
|
||||
gst_pad_set_link_function (rtpL16enc->sinkpad, gst_rtpL16pay_sinkconnect);
|
||||
|
||||
rtpL16enc->frequency = 44100;
|
||||
rtpL16enc->channels = 2;
|
||||
|
@ -158,13 +158,13 @@ gst_rtpL16enc_init (GstRtpL16Enc * rtpL16enc)
|
|||
}
|
||||
|
||||
static GstPadLinkReturn
|
||||
gst_rtpL16enc_sinkconnect (GstPad * pad, const GstCaps * caps)
|
||||
gst_rtpL16pay_sinkconnect (GstPad * pad, const GstCaps * caps)
|
||||
{
|
||||
GstRtpL16Enc *rtpL16enc;
|
||||
GstRtpL16Pay *rtpL16enc;
|
||||
GstStructure *structure;
|
||||
gboolean ret;
|
||||
|
||||
rtpL16enc = GST_RTP_L16_ENC (gst_pad_get_parent (pad));
|
||||
rtpL16enc = GST_RTP_L16_PAY (gst_pad_get_parent (pad));
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
|
@ -183,7 +183,7 @@ gst_rtpL16enc_sinkconnect (GstPad * pad, const GstCaps * caps)
|
|||
|
||||
|
||||
void
|
||||
gst_rtpL16enc_htons (GstBuffer * buf)
|
||||
gst_rtpL16pay_htons (GstBuffer * buf)
|
||||
{
|
||||
gint16 *i, *len;
|
||||
|
||||
|
@ -197,10 +197,10 @@ gst_rtpL16enc_htons (GstBuffer * buf)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_chain (GstPad * pad, GstData * _data)
|
||||
gst_rtpL16pay_chain (GstPad * pad, GstData * _data)
|
||||
{
|
||||
GstBuffer *buf = GST_BUFFER (_data);
|
||||
GstRtpL16Enc *rtpL16enc;
|
||||
GstRtpL16Pay *rtpL16enc;
|
||||
GstBuffer *outbuf;
|
||||
Rtp_Packet packet;
|
||||
|
||||
|
@ -208,10 +208,10 @@ gst_rtpL16enc_chain (GstPad * pad, GstData * _data)
|
|||
g_return_if_fail (GST_IS_PAD (pad));
|
||||
g_return_if_fail (buf != NULL);
|
||||
|
||||
rtpL16enc = GST_RTP_L16_ENC (GST_OBJECT_PARENT (pad));
|
||||
rtpL16enc = GST_RTP_L16_PAY (GST_OBJECT_PARENT (pad));
|
||||
|
||||
g_return_if_fail (rtpL16enc != NULL);
|
||||
g_return_if_fail (GST_IS_RTP_L16_ENC (rtpL16enc));
|
||||
g_return_if_fail (GST_IS_RTP_L16_PAY (rtpL16enc));
|
||||
|
||||
if (GST_IS_EVENT (buf)) {
|
||||
GstEvent *event = GST_EVENT (buf);
|
||||
|
@ -251,7 +251,7 @@ gst_rtpL16enc_chain (GstPad * pad, GstData * _data)
|
|||
|
||||
/* FIXME: According to RFC 1890, this is required, right? */
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
gst_rtpL16enc_htons (buf);
|
||||
gst_rtpL16pay_htons (buf);
|
||||
#endif
|
||||
|
||||
outbuf = gst_buffer_new ();
|
||||
|
@ -265,7 +265,7 @@ gst_rtpL16enc_chain (GstPad * pad, GstData * _data)
|
|||
memcpy (GST_BUFFER_DATA (outbuf) + rtp_packet_get_packet_len (packet),
|
||||
GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
|
||||
|
||||
GST_DEBUG ("gst_rtpL16enc_chain: pushing buffer of size %d",
|
||||
GST_DEBUG ("gst_rtpL16pay_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
gst_pad_push (rtpL16enc->srcpad, GST_DATA (outbuf));
|
||||
|
||||
|
@ -277,13 +277,13 @@ gst_rtpL16enc_chain (GstPad * pad, GstData * _data)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_set_property (GObject * object, guint prop_id,
|
||||
gst_rtpL16pay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpL16Enc *rtpL16enc;
|
||||
GstRtpL16Pay *rtpL16enc;
|
||||
|
||||
g_return_if_fail (GST_IS_RTP_L16_ENC (object));
|
||||
rtpL16enc = GST_RTP_L16_ENC (object);
|
||||
g_return_if_fail (GST_IS_RTP_L16_PAY (object));
|
||||
rtpL16enc = GST_RTP_L16_PAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -292,13 +292,13 @@ gst_rtpL16enc_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpL16enc_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
gst_rtpL16pay_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRtpL16Enc *rtpL16enc;
|
||||
GstRtpL16Pay *rtpL16enc;
|
||||
|
||||
g_return_if_fail (GST_IS_RTP_L16_ENC (object));
|
||||
rtpL16enc = GST_RTP_L16_ENC (object);
|
||||
g_return_if_fail (GST_IS_RTP_L16_PAY (object));
|
||||
rtpL16enc = GST_RTP_L16_PAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -308,13 +308,13 @@ gst_rtpL16enc_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpL16enc_change_state (GstElement * element, GstStateChange transition)
|
||||
gst_rtpL16pay_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstRtpL16Enc *rtpL16enc;
|
||||
GstRtpL16Pay *rtpL16enc;
|
||||
|
||||
g_return_val_if_fail (GST_IS_RTP_L16_ENC (element), GST_STATE_CHANGE_FAILURE);
|
||||
g_return_val_if_fail (GST_IS_RTP_L16_PAY (element), GST_STATE_CHANGE_FAILURE);
|
||||
|
||||
rtpL16enc = GST_RTP_L16_ENC (element);
|
||||
rtpL16enc = GST_RTP_L16_PAY (element);
|
||||
|
||||
GST_DEBUG ("state pending %d\n", GST_STATE_PENDING (element));
|
||||
|
||||
|
@ -338,8 +338,8 @@ gst_rtpL16enc_change_state (GstElement * element, GstStateChange transition)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpL16enc_plugin_init (GstPlugin * plugin)
|
||||
gst_rtpL16pay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpL16enc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_L16_ENC);
|
||||
GST_RANK_NONE, GST_TYPE_RTP_L16_PAY);
|
||||
}
|
||||
|
|
|
@ -18,16 +18,16 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef __GST_RTP_L16_ENC_H__
|
||||
#define __GST_RTP_L16_ENC_H__
|
||||
#ifndef __GST_RTP_L16_PAY_H__
|
||||
#define __GST_RTP_L16_PAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Definition of structure storing data for this element. */
|
||||
typedef struct _GstRtpL16Enc GstRtpL16Enc;
|
||||
struct _GstRtpL16Enc
|
||||
typedef struct _GstRtpL16Pay GstRtpL16Pay;
|
||||
struct _GstRtpL16Pay
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
|
@ -47,26 +47,26 @@ struct _GstRtpL16Enc
|
|||
};
|
||||
|
||||
/* Standard definition defining a class for this element. */
|
||||
typedef struct _GstRtpL16EncClass GstRtpL16EncClass;
|
||||
struct _GstRtpL16EncClass
|
||||
typedef struct _GstRtpL16PayClass GstRtpL16PayClass;
|
||||
struct _GstRtpL16PayClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
/* Standard macros for defining types for this element. */
|
||||
#define GST_TYPE_RTP_L16_ENC \
|
||||
(gst_rtpL16enc_get_type())
|
||||
#define GST_RTP_L16_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_L16_ENC,GstRtpL16Enc))
|
||||
#define GST_RTP_L16_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_L16_ENC,GstRtpL16Enc))
|
||||
#define GST_IS_RTP_L16_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_L16_ENC))
|
||||
#define GST_IS_RTP_L16_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_L16_ENC))
|
||||
#define GST_TYPE_RTP_L16_PAY \
|
||||
(gst_rtpL16pay_get_type())
|
||||
#define GST_RTP_L16_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_L16_PAY,GstRtpL16Pay))
|
||||
#define GST_RTP_L16_PAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_L16_PAY,GstRtpL16Pay))
|
||||
#define GST_IS_RTP_L16_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_L16_PAY))
|
||||
#define GST_IS_RTP_L16_PAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_L16_PAY))
|
||||
|
||||
gboolean gst_rtpL16enc_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtpL16pay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_L16_ENC_H__ */
|
||||
#endif /* __GST_RTP_L16_PAY_H__ */
|
||||
|
|
|
@ -1,486 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "gstrtpamrdec.h"
|
||||
|
||||
/* references:
|
||||
*
|
||||
* RFC 3267 - Real-Time Transport Protocol (RTP) Payload Format and File Storage Format
|
||||
* for the Adaptive Multi-Rate (AMR) and Adaptive Multi-Rate Wideband (AMR-WB) Audio
|
||||
* Codecs.
|
||||
*/
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_amrdec_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts AMR audio from RTP packets (RFC 3267)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
/* RtpAMRDec signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_FREQUENCY
|
||||
};
|
||||
|
||||
/* input is an RTP packet
|
||||
*
|
||||
* params see RFC 3267, section 8.1
|
||||
*/
|
||||
static GstStaticPadTemplate gst_rtpamrdec_sink_template =
|
||||
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 = (string) \"1\", "
|
||||
"crc = (string) { \"0\", \"1\" }, "
|
||||
"robust-sorting = (string) \"0\", " "interleaving = (string) \"0\""
|
||||
/* following options are not needed for a decoder
|
||||
*
|
||||
"mode-set = (int) [ 0, 7 ], "
|
||||
"mode-change-period = (int) [ 1, MAX ], "
|
||||
"mode-change-neighbor = (boolean) { TRUE, FALSE }, "
|
||||
"maxptime = (int) [ 20, MAX ], "
|
||||
"ptime = (int) [ 20, MAX ]"
|
||||
*/
|
||||
)
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpamrdec_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/AMR, " "channels = (int) 1," "rate = (int) 8000")
|
||||
);
|
||||
|
||||
static void gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass);
|
||||
static void gst_rtpamrdec_base_init (GstRtpAMRDecClass * klass);
|
||||
static void gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec);
|
||||
|
||||
static gboolean gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buffer);
|
||||
|
||||
static void gst_rtpamrdec_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpamrdec_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtpamrdec_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpamrdec_get_type (void)
|
||||
{
|
||||
static GType rtpamrdec_type = 0;
|
||||
|
||||
if (!rtpamrdec_type) {
|
||||
static const GTypeInfo rtpamrdec_info = {
|
||||
sizeof (GstRtpAMRDecClass),
|
||||
(GBaseInitFunc) gst_rtpamrdec_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpamrdec_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpAMRDec),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpamrdec_init,
|
||||
};
|
||||
|
||||
rtpamrdec_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpAMRDec",
|
||||
&rtpamrdec_info, 0);
|
||||
}
|
||||
return rtpamrdec_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrdec_base_init (GstRtpAMRDecClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpamrdec_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpamrdec_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_amrdec_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_rtpamrdec_set_property;
|
||||
gobject_class->get_property = gst_rtpamrdec_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtpamrdec_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec)
|
||||
{
|
||||
rtpamrdec->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpamrdec_src_template), "src");
|
||||
|
||||
gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->srcpad);
|
||||
|
||||
rtpamrdec->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpamrdec_sink_template), "sink");
|
||||
gst_pad_set_setcaps_function (rtpamrdec->sinkpad, gst_rtpamrdec_sink_setcaps);
|
||||
gst_pad_set_chain_function (rtpamrdec->sinkpad, gst_rtpamrdec_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->sinkpad);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
GstCaps *srccaps;
|
||||
GstRtpAMRDec *rtpamrdec;
|
||||
const gchar *params;
|
||||
const gchar *str;
|
||||
|
||||
rtpamrdec = GST_RTP_AMR_DEC (GST_OBJECT_PARENT (pad));
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
if (!(str = gst_structure_get_string (structure, "octet-align")))
|
||||
rtpamrdec->octet_align = FALSE;
|
||||
else
|
||||
rtpamrdec->octet_align = (atoi (str) == 1);
|
||||
|
||||
if (!(str = gst_structure_get_string (structure, "crc")))
|
||||
rtpamrdec->crc = FALSE;
|
||||
else
|
||||
rtpamrdec->crc = (atoi (str) == 1);
|
||||
|
||||
if (rtpamrdec->crc) {
|
||||
/* crc mode implies octet aligned mode */
|
||||
rtpamrdec->octet_align = TRUE;
|
||||
}
|
||||
|
||||
if (!(str = gst_structure_get_string (structure, "robust-sorting")))
|
||||
rtpamrdec->robust_sorting = FALSE;
|
||||
else
|
||||
rtpamrdec->robust_sorting = (atoi (str) == 1);
|
||||
|
||||
if (rtpamrdec->robust_sorting) {
|
||||
/* robust_sorting mode implies octet aligned mode */
|
||||
rtpamrdec->octet_align = TRUE;
|
||||
}
|
||||
|
||||
if (!(str = gst_structure_get_string (structure, "interleaving")))
|
||||
rtpamrdec->interleaving = FALSE;
|
||||
else
|
||||
rtpamrdec->interleaving = (atoi (str) == 1);
|
||||
|
||||
if (rtpamrdec->interleaving) {
|
||||
/* interleaving mode implies octet aligned mode */
|
||||
rtpamrdec->octet_align = TRUE;
|
||||
}
|
||||
|
||||
if (!(params = gst_structure_get_string (structure, "encoding-params")))
|
||||
rtpamrdec->channels = 1;
|
||||
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,
|
||||
* no robust sorting, no interleaving for now */
|
||||
if (rtpamrdec->channels != 1)
|
||||
return FALSE;
|
||||
if (rtpamrdec->rate != 8000)
|
||||
return FALSE;
|
||||
if (rtpamrdec->octet_align != TRUE)
|
||||
return FALSE;
|
||||
if (rtpamrdec->robust_sorting != FALSE)
|
||||
return FALSE;
|
||||
if (rtpamrdec->interleaving != FALSE)
|
||||
return FALSE;
|
||||
|
||||
srccaps = gst_caps_new_simple ("audio/AMR",
|
||||
"channels", G_TYPE_INT, rtpamrdec->channels,
|
||||
"rate", G_TYPE_INT, rtpamrdec->rate, NULL);
|
||||
gst_pad_set_caps (rtpamrdec->srcpad, srccaps);
|
||||
gst_caps_unref (srccaps);
|
||||
|
||||
rtpamrdec->negotiated = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* -1 is invalid */
|
||||
static gint frame_size[16] = {
|
||||
12, 13, 15, 17, 19, 20, 26, 31,
|
||||
5, -1, -1, -1, -1, -1, -1, 0
|
||||
};
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstRtpAMRDec *rtpamrdec;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret;
|
||||
|
||||
rtpamrdec = GST_RTP_AMR_DEC (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (!rtpamrdec->negotiated)
|
||||
goto not_negotiated;
|
||||
|
||||
if (!gst_rtpbuffer_validate (buf))
|
||||
goto bad_packet;
|
||||
|
||||
/* when we get here, 1 channel, 8000 Hz, octet aligned, no CRC,
|
||||
* no robust sorting, no interleaving data is to be parsed */
|
||||
{
|
||||
gint payload_len;
|
||||
guint8 *payload, *p, *dp;
|
||||
guint32 timestamp;
|
||||
guint8 CMR;
|
||||
gint i, num_packets, num_nonempty_packets;
|
||||
gint amr_len;
|
||||
gint ILL, ILP;
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
|
||||
/* need at least 2 bytes for the header */
|
||||
if (payload_len < 2)
|
||||
goto bad_packet;
|
||||
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
|
||||
/* parse CMR. The CMR is used by the sender to request
|
||||
* a new encoding mode.
|
||||
*
|
||||
* 0 1 2 3 4 5 6 7
|
||||
* +-+-+-+-+-+-+-+-+
|
||||
* | CMR |R|R|R|R|
|
||||
* +-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
CMR = (payload[0] & 0xf0) >> 4;
|
||||
|
||||
/* strip CMR header now, pack FT and the data for the decoder */
|
||||
payload_len -= 1;
|
||||
payload += 1;
|
||||
|
||||
if (rtpamrdec->interleaving) {
|
||||
ILL = (payload[0] & 0xf0) >> 4;
|
||||
ILP = (payload[0] & 0x0f);
|
||||
|
||||
payload_len -= 1;
|
||||
payload += 1;
|
||||
|
||||
if (ILP > ILL)
|
||||
goto bad_packet;
|
||||
}
|
||||
|
||||
/*
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
|
||||
* +-+-+-+-+-+-+-+-+..
|
||||
* |F| FT |Q|P|P| more FT..
|
||||
* +-+-+-+-+-+-+-+-+..
|
||||
*/
|
||||
/* count number of packets by counting the FTs. Also
|
||||
* count number of amr data bytes and number of non-empty
|
||||
* packets (this is also the number of CRCs if present). */
|
||||
amr_len = 0;
|
||||
num_nonempty_packets = 0;
|
||||
num_packets = 0;
|
||||
for (i = 0; i < payload_len; i++) {
|
||||
gint fr_size;
|
||||
guint8 FT;
|
||||
|
||||
FT = (payload[i] & 0x78) >> 3;
|
||||
|
||||
fr_size = frame_size[FT];
|
||||
if (fr_size == -1)
|
||||
goto bad_packet;
|
||||
|
||||
if (fr_size > 0) {
|
||||
amr_len += fr_size;
|
||||
num_nonempty_packets++;
|
||||
}
|
||||
num_packets++;
|
||||
|
||||
if ((payload[i] & 0x80) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* this is impossible */
|
||||
if (num_packets == payload_len)
|
||||
goto bad_packet;
|
||||
|
||||
if (rtpamrdec->crc) {
|
||||
/* data len + CRC len + header bytes should be smaller than payload_len */
|
||||
if (num_packets + num_nonempty_packets + amr_len > payload_len)
|
||||
goto bad_packet;
|
||||
} else {
|
||||
/* data len + header bytes should be smaller than payload_len */
|
||||
if (num_packets + amr_len > payload_len)
|
||||
goto bad_packet;
|
||||
}
|
||||
|
||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpamrdec->rate;
|
||||
|
||||
/* point to destination */
|
||||
p = GST_BUFFER_DATA (outbuf);
|
||||
/* point to first data packet */
|
||||
dp = payload + num_packets;
|
||||
if (rtpamrdec->crc) {
|
||||
/* skip CRC if present */
|
||||
dp += num_nonempty_packets;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_packets; i++) {
|
||||
gint fr_size;
|
||||
|
||||
fr_size = frame_size[(payload[i] & 0x78) >> 3];
|
||||
if (fr_size > 0) {
|
||||
/* copy FT */
|
||||
*p++ = payload[i];
|
||||
/* copy data packet, FIXME, calc CRC here. */
|
||||
memcpy (p, dp, fr_size);
|
||||
|
||||
p += fr_size;
|
||||
dp += fr_size;
|
||||
}
|
||||
}
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpamrdec->srcpad));
|
||||
|
||||
GST_DEBUG ("gst_rtpamrdec_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
ret = gst_pad_push (rtpamrdec->srcpad, outbuf);
|
||||
|
||||
gst_buffer_unref (buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
not_negotiated:
|
||||
{
|
||||
GST_ELEMENT_ERROR (rtpamrdec, STREAM, NOT_IMPLEMENTED,
|
||||
("not negotiated"), (NULL));
|
||||
gst_buffer_unref (buf);
|
||||
return GST_FLOW_NOT_NEGOTIATED;
|
||||
}
|
||||
bad_packet:
|
||||
{
|
||||
GST_ELEMENT_WARNING (rtpamrdec, STREAM, DECODE,
|
||||
("amr packet did not validate"), (NULL));
|
||||
gst_buffer_unref (buf);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrdec_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpAMRDec *rtpamrdec;
|
||||
|
||||
rtpamrdec = GST_RTP_AMR_DEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrdec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRtpAMRDec *rtpamrdec;
|
||||
|
||||
rtpamrdec = GST_RTP_AMR_DEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpamrdec_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstRtpAMRDec *rtpamrdec;
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
rtpamrdec = GST_RTP_AMR_DEC (element);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
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_rtpamrdec_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpamrdec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_AMR_DEC);
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_AMR_DEC_H__
|
||||
#define __GST_RTP_AMR_DEC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_AMR_DEC \
|
||||
(gst_rtpamrdec_get_type())
|
||||
#define GST_RTP_AMR_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_AMR_DEC,GstRtpAMRDec))
|
||||
#define GST_RTP_AMR_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_AMR_DEC,GstRtpAMRDec))
|
||||
#define GST_IS_RTP_AMR_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_AMR_DEC))
|
||||
#define GST_IS_RTP_AMR_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_AMR_DEC))
|
||||
|
||||
typedef struct _GstRtpAMRDec GstRtpAMRDec;
|
||||
typedef struct _GstRtpAMRDecClass GstRtpAMRDecClass;
|
||||
|
||||
struct _GstRtpAMRDec
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
gboolean negotiated;
|
||||
|
||||
gboolean octet_align;
|
||||
guint8 mode_set;
|
||||
gint mode_change_period;
|
||||
gboolean mode_change_neighbor;
|
||||
gint maxptime;
|
||||
gboolean crc;
|
||||
gboolean robust_sorting;
|
||||
gboolean interleaving;
|
||||
gint ptime;
|
||||
gint channels;
|
||||
gint rate;
|
||||
};
|
||||
|
||||
struct _GstRtpAMRDecClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpamrdec_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_AMR_DEC_H__ */
|
|
@ -19,7 +19,7 @@
|
|||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "gstrtpamrdec.h"
|
||||
#include "gstrtpamrdepay.h"
|
||||
|
||||
/* references:
|
||||
*
|
||||
|
@ -29,14 +29,14 @@
|
|||
*/
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_amrdec_details = {
|
||||
static GstElementDetails gst_rtp_amrdepay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts AMR audio from RTP packets (RFC 3267)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
/* RtpAMRDec signals and args */
|
||||
/* RtpAMRDepay signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
|
@ -53,7 +53,7 @@ enum
|
|||
*
|
||||
* params see RFC 3267, section 8.1
|
||||
*/
|
||||
static GstStaticPadTemplate gst_rtpamrdec_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_amr_depay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -77,70 +77,70 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
)
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpamrdec_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_amr_depay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/AMR, " "channels = (int) 1," "rate = (int) 8000")
|
||||
);
|
||||
|
||||
static void gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass);
|
||||
static void gst_rtpamrdec_base_init (GstRtpAMRDecClass * klass);
|
||||
static void gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec);
|
||||
static void gst_rtp_amr_depay_class_init (GstRtpAMRDepayClass * klass);
|
||||
static void gst_rtp_amr_depay_base_init (GstRtpAMRDepayClass * klass);
|
||||
static void gst_rtp_amr_depay_init (GstRtpAMRDepay * rtpamrdepay);
|
||||
|
||||
static gboolean gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static gboolean gst_rtp_amr_depay_sink_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static GstFlowReturn gst_rtp_amr_depay_chain (GstPad * pad, GstBuffer * buffer);
|
||||
|
||||
static void gst_rtpamrdec_set_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_amr_depay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpamrdec_get_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_amr_depay_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtpamrdec_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
static GstStateChangeReturn gst_rtp_amr_depay_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpamrdec_get_type (void)
|
||||
gst_rtp_amr_depay_get_type (void)
|
||||
{
|
||||
static GType rtpamrdec_type = 0;
|
||||
static GType rtpamrdepay_type = 0;
|
||||
|
||||
if (!rtpamrdec_type) {
|
||||
static const GTypeInfo rtpamrdec_info = {
|
||||
sizeof (GstRtpAMRDecClass),
|
||||
(GBaseInitFunc) gst_rtpamrdec_base_init,
|
||||
if (!rtpamrdepay_type) {
|
||||
static const GTypeInfo rtpamrdepay_info = {
|
||||
sizeof (GstRtpAMRDepayClass),
|
||||
(GBaseInitFunc) gst_rtp_amr_depay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpamrdec_class_init,
|
||||
(GClassInitFunc) gst_rtp_amr_depay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpAMRDec),
|
||||
sizeof (GstRtpAMRDepay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpamrdec_init,
|
||||
(GInstanceInitFunc) gst_rtp_amr_depay_init,
|
||||
};
|
||||
|
||||
rtpamrdec_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpAMRDec",
|
||||
&rtpamrdec_info, 0);
|
||||
rtpamrdepay_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpAMRDepay",
|
||||
&rtpamrdepay_info, 0);
|
||||
}
|
||||
return rtpamrdec_type;
|
||||
return rtpamrdepay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrdec_base_init (GstRtpAMRDecClass * klass)
|
||||
gst_rtp_amr_depay_base_init (GstRtpAMRDepayClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpamrdec_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_amr_depay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpamrdec_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_amr_depay_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_amrdec_details);
|
||||
gst_element_class_set_details (element_class, &gst_rtp_amrdepay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass)
|
||||
gst_rtp_amr_depay_class_init (GstRtpAMRDepayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -150,106 +150,107 @@ gst_rtpamrdec_class_init (GstRtpAMRDecClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_rtpamrdec_set_property;
|
||||
gobject_class->get_property = gst_rtpamrdec_get_property;
|
||||
gobject_class->set_property = gst_rtp_amr_depay_set_property;
|
||||
gobject_class->get_property = gst_rtp_amr_depay_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtpamrdec_change_state;
|
||||
gstelement_class->change_state = gst_rtp_amr_depay_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrdec_init (GstRtpAMRDec * rtpamrdec)
|
||||
gst_rtp_amr_depay_init (GstRtpAMRDepay * rtpamrdepay)
|
||||
{
|
||||
rtpamrdec->srcpad =
|
||||
rtpamrdepay->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpamrdec_src_template), "src");
|
||||
(&gst_rtp_amr_depay_src_template), "src");
|
||||
|
||||
gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->srcpad);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpamrdepay), rtpamrdepay->srcpad);
|
||||
|
||||
rtpamrdec->sinkpad =
|
||||
rtpamrdepay->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpamrdec_sink_template), "sink");
|
||||
gst_pad_set_setcaps_function (rtpamrdec->sinkpad, gst_rtpamrdec_sink_setcaps);
|
||||
gst_pad_set_chain_function (rtpamrdec->sinkpad, gst_rtpamrdec_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpamrdec), rtpamrdec->sinkpad);
|
||||
(&gst_rtp_amr_depay_sink_template), "sink");
|
||||
gst_pad_set_setcaps_function (rtpamrdepay->sinkpad,
|
||||
gst_rtp_amr_depay_sink_setcaps);
|
||||
gst_pad_set_chain_function (rtpamrdepay->sinkpad, gst_rtp_amr_depay_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpamrdepay), rtpamrdepay->sinkpad);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpamrdec_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||
gst_rtp_amr_depay_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
GstCaps *srccaps;
|
||||
GstRtpAMRDec *rtpamrdec;
|
||||
GstRtpAMRDepay *rtpamrdepay;
|
||||
const gchar *params;
|
||||
const gchar *str;
|
||||
|
||||
rtpamrdec = GST_RTP_AMR_DEC (GST_OBJECT_PARENT (pad));
|
||||
rtpamrdepay = GST_RTP_AMR_DEPAY (GST_OBJECT_PARENT (pad));
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
if (!(str = gst_structure_get_string (structure, "octet-align")))
|
||||
rtpamrdec->octet_align = FALSE;
|
||||
rtpamrdepay->octet_align = FALSE;
|
||||
else
|
||||
rtpamrdec->octet_align = (atoi (str) == 1);
|
||||
rtpamrdepay->octet_align = (atoi (str) == 1);
|
||||
|
||||
if (!(str = gst_structure_get_string (structure, "crc")))
|
||||
rtpamrdec->crc = FALSE;
|
||||
rtpamrdepay->crc = FALSE;
|
||||
else
|
||||
rtpamrdec->crc = (atoi (str) == 1);
|
||||
rtpamrdepay->crc = (atoi (str) == 1);
|
||||
|
||||
if (rtpamrdec->crc) {
|
||||
if (rtpamrdepay->crc) {
|
||||
/* crc mode implies octet aligned mode */
|
||||
rtpamrdec->octet_align = TRUE;
|
||||
rtpamrdepay->octet_align = TRUE;
|
||||
}
|
||||
|
||||
if (!(str = gst_structure_get_string (structure, "robust-sorting")))
|
||||
rtpamrdec->robust_sorting = FALSE;
|
||||
rtpamrdepay->robust_sorting = FALSE;
|
||||
else
|
||||
rtpamrdec->robust_sorting = (atoi (str) == 1);
|
||||
rtpamrdepay->robust_sorting = (atoi (str) == 1);
|
||||
|
||||
if (rtpamrdec->robust_sorting) {
|
||||
if (rtpamrdepay->robust_sorting) {
|
||||
/* robust_sorting mode implies octet aligned mode */
|
||||
rtpamrdec->octet_align = TRUE;
|
||||
rtpamrdepay->octet_align = TRUE;
|
||||
}
|
||||
|
||||
if (!(str = gst_structure_get_string (structure, "interleaving")))
|
||||
rtpamrdec->interleaving = FALSE;
|
||||
rtpamrdepay->interleaving = FALSE;
|
||||
else
|
||||
rtpamrdec->interleaving = (atoi (str) == 1);
|
||||
rtpamrdepay->interleaving = (atoi (str) == 1);
|
||||
|
||||
if (rtpamrdec->interleaving) {
|
||||
if (rtpamrdepay->interleaving) {
|
||||
/* interleaving mode implies octet aligned mode */
|
||||
rtpamrdec->octet_align = TRUE;
|
||||
rtpamrdepay->octet_align = TRUE;
|
||||
}
|
||||
|
||||
if (!(params = gst_structure_get_string (structure, "encoding-params")))
|
||||
rtpamrdec->channels = 1;
|
||||
rtpamrdepay->channels = 1;
|
||||
else {
|
||||
rtpamrdec->channels = atoi (params);
|
||||
rtpamrdepay->channels = atoi (params);
|
||||
}
|
||||
|
||||
if (!gst_structure_get_int (structure, "clock-rate", &rtpamrdec->rate))
|
||||
rtpamrdec->rate = 8000;
|
||||
if (!gst_structure_get_int (structure, "clock-rate", &rtpamrdepay->rate))
|
||||
rtpamrdepay->rate = 8000;
|
||||
|
||||
/* we require 1 channel, 8000 Hz, octet aligned, no CRC,
|
||||
* no robust sorting, no interleaving for now */
|
||||
if (rtpamrdec->channels != 1)
|
||||
if (rtpamrdepay->channels != 1)
|
||||
return FALSE;
|
||||
if (rtpamrdec->rate != 8000)
|
||||
if (rtpamrdepay->rate != 8000)
|
||||
return FALSE;
|
||||
if (rtpamrdec->octet_align != TRUE)
|
||||
if (rtpamrdepay->octet_align != TRUE)
|
||||
return FALSE;
|
||||
if (rtpamrdec->robust_sorting != FALSE)
|
||||
if (rtpamrdepay->robust_sorting != FALSE)
|
||||
return FALSE;
|
||||
if (rtpamrdec->interleaving != FALSE)
|
||||
if (rtpamrdepay->interleaving != FALSE)
|
||||
return FALSE;
|
||||
|
||||
srccaps = gst_caps_new_simple ("audio/AMR",
|
||||
"channels", G_TYPE_INT, rtpamrdec->channels,
|
||||
"rate", G_TYPE_INT, rtpamrdec->rate, NULL);
|
||||
gst_pad_set_caps (rtpamrdec->srcpad, srccaps);
|
||||
"channels", G_TYPE_INT, rtpamrdepay->channels,
|
||||
"rate", G_TYPE_INT, rtpamrdepay->rate, NULL);
|
||||
gst_pad_set_caps (rtpamrdepay->srcpad, srccaps);
|
||||
gst_caps_unref (srccaps);
|
||||
|
||||
rtpamrdec->negotiated = TRUE;
|
||||
rtpamrdepay->negotiated = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -261,18 +262,18 @@ static gint frame_size[16] = {
|
|||
};
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
||||
gst_rtp_amr_depay_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstRtpAMRDec *rtpamrdec;
|
||||
GstRtpAMRDepay *rtpamrdepay;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret;
|
||||
|
||||
rtpamrdec = GST_RTP_AMR_DEC (GST_OBJECT_PARENT (pad));
|
||||
rtpamrdepay = GST_RTP_AMR_DEPAY (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (!rtpamrdec->negotiated)
|
||||
if (!rtpamrdepay->negotiated)
|
||||
goto not_negotiated;
|
||||
|
||||
if (!gst_rtpbuffer_validate (buf))
|
||||
if (!gst_rtp_buffer_validate (buf))
|
||||
goto bad_packet;
|
||||
|
||||
/* when we get here, 1 channel, 8000 Hz, octet aligned, no CRC,
|
||||
|
@ -286,13 +287,13 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
gint amr_len;
|
||||
gint ILL, ILP;
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload_len = gst_rtp_buffer_get_payload_len (buf);
|
||||
|
||||
/* need at least 2 bytes for the header */
|
||||
if (payload_len < 2)
|
||||
goto bad_packet;
|
||||
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
payload = gst_rtp_buffer_get_payload (buf);
|
||||
|
||||
/* parse CMR. The CMR is used by the sender to request
|
||||
* a new encoding mode.
|
||||
|
@ -308,7 +309,7 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
payload_len -= 1;
|
||||
payload += 1;
|
||||
|
||||
if (rtpamrdec->interleaving) {
|
||||
if (rtpamrdepay->interleaving) {
|
||||
ILL = (payload[0] & 0xf0) >> 4;
|
||||
ILP = (payload[0] & 0x0f);
|
||||
|
||||
|
@ -355,7 +356,7 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
if (num_packets == payload_len)
|
||||
goto bad_packet;
|
||||
|
||||
if (rtpamrdec->crc) {
|
||||
if (rtpamrdepay->crc) {
|
||||
/* data len + CRC len + header bytes should be smaller than payload_len */
|
||||
if (num_packets + num_nonempty_packets + amr_len > payload_len)
|
||||
goto bad_packet;
|
||||
|
@ -365,16 +366,16 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
goto bad_packet;
|
||||
}
|
||||
|
||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||
timestamp = gst_rtp_buffer_get_timestamp (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpamrdec->rate;
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpamrdepay->rate;
|
||||
|
||||
/* point to destination */
|
||||
p = GST_BUFFER_DATA (outbuf);
|
||||
/* point to first data packet */
|
||||
dp = payload + num_packets;
|
||||
if (rtpamrdec->crc) {
|
||||
if (rtpamrdepay->crc) {
|
||||
/* skip CRC if present */
|
||||
dp += num_nonempty_packets;
|
||||
}
|
||||
|
@ -393,11 +394,11 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
dp += fr_size;
|
||||
}
|
||||
}
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpamrdec->srcpad));
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpamrdepay->srcpad));
|
||||
|
||||
GST_DEBUG ("gst_rtpamrdec_chain: pushing buffer of size %d",
|
||||
GST_DEBUG ("gst_rtp_amr_depay_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
ret = gst_pad_push (rtpamrdec->srcpad, outbuf);
|
||||
ret = gst_pad_push (rtpamrdepay->srcpad, outbuf);
|
||||
|
||||
gst_buffer_unref (buf);
|
||||
}
|
||||
|
@ -406,14 +407,14 @@ gst_rtpamrdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
|
||||
not_negotiated:
|
||||
{
|
||||
GST_ELEMENT_ERROR (rtpamrdec, STREAM, NOT_IMPLEMENTED,
|
||||
GST_ELEMENT_ERROR (rtpamrdepay, STREAM, NOT_IMPLEMENTED,
|
||||
("not negotiated"), (NULL));
|
||||
gst_buffer_unref (buf);
|
||||
return GST_FLOW_NOT_NEGOTIATED;
|
||||
}
|
||||
bad_packet:
|
||||
{
|
||||
GST_ELEMENT_WARNING (rtpamrdec, STREAM, DECODE,
|
||||
GST_ELEMENT_WARNING (rtpamrdepay, STREAM, DECODE,
|
||||
("amr packet did not validate"), (NULL));
|
||||
gst_buffer_unref (buf);
|
||||
return GST_FLOW_OK;
|
||||
|
@ -421,12 +422,12 @@ bad_packet:
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrdec_set_property (GObject * object, guint prop_id,
|
||||
gst_rtp_amr_depay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpAMRDec *rtpamrdec;
|
||||
GstRtpAMRDepay *rtpamrdepay;
|
||||
|
||||
rtpamrdec = GST_RTP_AMR_DEC (object);
|
||||
rtpamrdepay = GST_RTP_AMR_DEPAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -436,12 +437,12 @@ gst_rtpamrdec_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrdec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
gst_rtp_amr_depay_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRtpAMRDec *rtpamrdec;
|
||||
GstRtpAMRDepay *rtpamrdepay;
|
||||
|
||||
rtpamrdec = GST_RTP_AMR_DEC (object);
|
||||
rtpamrdepay = GST_RTP_AMR_DEPAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -451,12 +452,12 @@ gst_rtpamrdec_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpamrdec_change_state (GstElement * element, GstStateChange transition)
|
||||
gst_rtp_amr_depay_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstRtpAMRDec *rtpamrdec;
|
||||
GstRtpAMRDepay *rtpamrdepay;
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
rtpamrdec = GST_RTP_AMR_DEC (element);
|
||||
rtpamrdepay = GST_RTP_AMR_DEPAY (element);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
|
@ -479,8 +480,8 @@ gst_rtpamrdec_change_state (GstElement * element, GstStateChange transition)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpamrdec_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_amr_depay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpamrdec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_AMR_DEC);
|
||||
return gst_element_register (plugin, "rtpamrdepay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_AMR_DEPAY);
|
||||
}
|
||||
|
|
|
@ -17,28 +17,28 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_AMR_DEC_H__
|
||||
#define __GST_RTP_AMR_DEC_H__
|
||||
#ifndef __GST_RTP_AMR_DEPAY_H__
|
||||
#define __GST_RTP_AMR_DEPAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_AMR_DEC \
|
||||
(gst_rtpamrdec_get_type())
|
||||
#define GST_RTP_AMR_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_AMR_DEC,GstRtpAMRDec))
|
||||
#define GST_RTP_AMR_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_AMR_DEC,GstRtpAMRDec))
|
||||
#define GST_IS_RTP_AMR_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_AMR_DEC))
|
||||
#define GST_IS_RTP_AMR_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_AMR_DEC))
|
||||
#define GST_TYPE_RTP_AMR_DEPAY \
|
||||
(gst_rtp_amr_depay_get_type())
|
||||
#define GST_RTP_AMR_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_AMR_DEPAY,GstRtpAMRDepay))
|
||||
#define GST_RTP_AMR_DEPAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_AMR_DEPAY,GstRtpAMRDepay))
|
||||
#define GST_IS_RTP_AMR_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_AMR_DEPAY))
|
||||
#define GST_IS_RTP_AMR_DEPAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_AMR_DEPAY))
|
||||
|
||||
typedef struct _GstRtpAMRDec GstRtpAMRDec;
|
||||
typedef struct _GstRtpAMRDecClass GstRtpAMRDecClass;
|
||||
typedef struct _GstRtpAMRDepay GstRtpAMRDepay;
|
||||
typedef struct _GstRtpAMRDepayClass GstRtpAMRDepayClass;
|
||||
|
||||
struct _GstRtpAMRDec
|
||||
struct _GstRtpAMRDepay
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
|
@ -60,13 +60,13 @@ struct _GstRtpAMRDec
|
|||
gint rate;
|
||||
};
|
||||
|
||||
struct _GstRtpAMRDecClass
|
||||
struct _GstRtpAMRDepayClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpamrdec_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_amr_depay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_AMR_DEC_H__ */
|
||||
#endif /* __GST_RTP_AMR_DEPAY_H__ */
|
||||
|
|
|
@ -1,225 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpamrenc.h"
|
||||
|
||||
/* references:
|
||||
*
|
||||
* RFC 3267 - Real-Time Transport Protocol (RTP) Payload Format and File
|
||||
* Storage Format for the Adaptive Multi-Rate (AMR) and Adaptive
|
||||
* Multi-Rate Wideband (AMR-WB) Audio Codecs.
|
||||
*/
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_amrenc_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encode AMR audio into RTP packets (RFC 3267)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpamrenc_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/AMR, channels=(int)1, rate=(int)8000")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpamrenc_src_template =
|
||||
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 = (string) \"1\", "
|
||||
"crc = (string) \"0\", "
|
||||
"robust-sorting = (string) \"0\", "
|
||||
"interleaving = (string) \"0\", "
|
||||
"mode-set = (int) [ 0, 7 ], "
|
||||
"mode-change-period = (int) [ 1, MAX ], "
|
||||
"mode-change-neighbor = (string) { \"0\", \"1\" }, "
|
||||
"maxptime = (int) [ 20, MAX ], " "ptime = (int) [ 20, MAX ]")
|
||||
);
|
||||
|
||||
static void gst_rtpamrenc_class_init (GstRtpAMREncClass * klass);
|
||||
static void gst_rtpamrenc_base_init (GstRtpAMREncClass * klass);
|
||||
static void gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc);
|
||||
|
||||
static gboolean gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpamrenc_handle_buffer (GstBaseRTPPayload * pad,
|
||||
GstBuffer * buffer);
|
||||
|
||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpamrenc_get_type (void)
|
||||
{
|
||||
static GType rtpamrenc_type = 0;
|
||||
|
||||
if (!rtpamrenc_type) {
|
||||
static const GTypeInfo rtpamrenc_info = {
|
||||
sizeof (GstRtpAMREncClass),
|
||||
(GBaseInitFunc) gst_rtpamrenc_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpamrenc_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpAMREnc),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpamrenc_init,
|
||||
};
|
||||
|
||||
rtpamrenc_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpAMREnc",
|
||||
&rtpamrenc_info, 0);
|
||||
}
|
||||
return rtpamrenc_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrenc_base_init (GstRtpAMREncClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpamrenc_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpamrenc_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_amrenc_details);
|
||||
}
|
||||
|
||||
static void
|
||||
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);
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpamrenc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpamrenc_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
|
||||
{
|
||||
GstRtpAMREnc *rtpamrenc;
|
||||
|
||||
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_STRING, "1",
|
||||
/* don't set the defaults
|
||||
*
|
||||
* "crc", G_TYPE_STRING, "0",
|
||||
* "robust-sorting", G_TYPE_STRING, "0",
|
||||
* "interleaving", G_TYPE_STRING, "0",
|
||||
*/
|
||||
NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpamrenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpAMREnc *rtpamrenc;
|
||||
GstFlowReturn ret;
|
||||
guint size, payload_len;
|
||||
GstBuffer *outbuf;
|
||||
guint8 *payload, *data;
|
||||
GstClockTime timestamp;
|
||||
|
||||
rtpamrenc = GST_RTP_AMR_ENC (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
/* FIXME, only one AMR frame per RTP packet for now,
|
||||
* octet aligned, no interleaving, single channel, no CRC,
|
||||
* no robust-sorting. */
|
||||
|
||||
/* we need one extra byte for the CMR, the ToC is in the input
|
||||
* data */
|
||||
payload_len = size + 1;
|
||||
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
/* FIXME, assert for now */
|
||||
g_assert (GST_BUFFER_SIZE (outbuf) < GST_BASE_RTP_PAYLOAD_MTU (rtpamrenc));
|
||||
|
||||
/* copy timestamp */
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
||||
|
||||
/* get payload */
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
|
||||
/* 0 1 2 3 4 5 6 7
|
||||
* +-+-+-+-+-+-+-+-+
|
||||
* | CMR |R|R|R|R|
|
||||
* +-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
payload[0] = 0xF0; /* CMR, no specific mode requested */
|
||||
|
||||
data = GST_BUFFER_DATA (buffer);
|
||||
|
||||
/* copy data in payload */
|
||||
memcpy (&payload[1], data, size);
|
||||
|
||||
/* 0 1 2 3 4 5 6 7
|
||||
* +-+-+-+-+-+-+-+-+
|
||||
* |F| FT |Q|P|P|
|
||||
* +-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
/* clear F flag */
|
||||
payload[1] = payload[1] & 0x7f;
|
||||
|
||||
gst_buffer_unref (buffer);
|
||||
|
||||
ret = gst_basertppayload_push (basepayload, outbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpamrenc_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpamrenc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_AMR_ENC);
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_AMR_ENC_H__
|
||||
#define __GST_RTP_AMR_ENC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_AMR_ENC \
|
||||
(gst_rtpamrenc_get_type())
|
||||
#define GST_RTP_AMR_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_AMR_ENC,GstRtpAMREnc))
|
||||
#define GST_RTP_AMR_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_AMR_ENC,GstRtpAMREnc))
|
||||
#define GST_IS_RTP_AMR_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_AMR_ENC))
|
||||
#define GST_IS_RTP_AMR_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_AMR_ENC))
|
||||
|
||||
typedef struct _GstRtpAMREnc GstRtpAMREnc;
|
||||
typedef struct _GstRtpAMREncClass GstRtpAMREncClass;
|
||||
|
||||
struct _GstRtpAMREnc
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
};
|
||||
|
||||
struct _GstRtpAMREncClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpamrenc_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_AMR_ENC_H__ */
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpamrenc.h"
|
||||
#include "gstrtpamrpay.h"
|
||||
|
||||
/* references:
|
||||
*
|
||||
|
@ -30,21 +30,21 @@
|
|||
*/
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_amrenc_details = {
|
||||
static GstElementDetails gst_rtp_amrpay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encode AMR audio into RTP packets (RFC 3267)",
|
||||
"Codec/Payloader/Network",
|
||||
"Payode AMR audio into RTP packets (RFC 3267)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpamrenc_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_amr_pay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/AMR, channels=(int)1, rate=(int)8000")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpamrenc_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_amr_pay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -64,57 +64,57 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
|||
"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 void gst_rtp_amr_pay_class_init (GstRtpAMRPayClass * klass);
|
||||
static void gst_rtp_amr_pay_base_init (GstRtpAMRPayClass * klass);
|
||||
static void gst_rtp_amr_pay_init (GstRtpAMRPay * rtpamrpay);
|
||||
|
||||
static gboolean gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload,
|
||||
static gboolean gst_rtp_amr_pay_setcaps (GstBaseRTPPayload * basepayload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpamrenc_handle_buffer (GstBaseRTPPayload * pad,
|
||||
static GstFlowReturn gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * pad,
|
||||
GstBuffer * buffer);
|
||||
|
||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpamrenc_get_type (void)
|
||||
gst_rtp_amr_pay_get_type (void)
|
||||
{
|
||||
static GType rtpamrenc_type = 0;
|
||||
static GType rtpamrpay_type = 0;
|
||||
|
||||
if (!rtpamrenc_type) {
|
||||
static const GTypeInfo rtpamrenc_info = {
|
||||
sizeof (GstRtpAMREncClass),
|
||||
(GBaseInitFunc) gst_rtpamrenc_base_init,
|
||||
if (!rtpamrpay_type) {
|
||||
static const GTypeInfo rtpamrpay_info = {
|
||||
sizeof (GstRtpAMRPayClass),
|
||||
(GBaseInitFunc) gst_rtp_amr_pay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpamrenc_class_init,
|
||||
(GClassInitFunc) gst_rtp_amr_pay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpAMREnc),
|
||||
sizeof (GstRtpAMRPay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpamrenc_init,
|
||||
(GInstanceInitFunc) gst_rtp_amr_pay_init,
|
||||
};
|
||||
|
||||
rtpamrenc_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpAMREnc",
|
||||
&rtpamrenc_info, 0);
|
||||
rtpamrpay_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpAMRPay",
|
||||
&rtpamrpay_info, 0);
|
||||
}
|
||||
return rtpamrenc_type;
|
||||
return rtpamrpay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrenc_base_init (GstRtpAMREncClass * klass)
|
||||
gst_rtp_amr_pay_base_init (GstRtpAMRPayClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpamrenc_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_amr_pay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpamrenc_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_amr_pay_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_amrenc_details);
|
||||
gst_element_class_set_details (element_class, &gst_rtp_amrpay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrenc_class_init (GstRtpAMREncClass * klass)
|
||||
gst_rtp_amr_pay_class_init (GstRtpAMRPayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -126,21 +126,21 @@ gst_rtpamrenc_class_init (GstRtpAMREncClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpamrenc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpamrenc_handle_buffer;
|
||||
gstbasertppayload_class->set_caps = gst_rtp_amr_pay_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtp_amr_pay_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpamrenc_init (GstRtpAMREnc * rtpamrenc)
|
||||
gst_rtp_amr_pay_init (GstRtpAMRPay * rtpamrpay)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
|
||||
gst_rtp_amr_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
|
||||
{
|
||||
GstRtpAMREnc *rtpamrenc;
|
||||
GstRtpAMRPay *rtpamrpay;
|
||||
|
||||
rtpamrenc = GST_RTP_AMR_ENC (basepayload);
|
||||
rtpamrpay = GST_RTP_AMR_PAY (basepayload);
|
||||
|
||||
gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR", 8000);
|
||||
gst_basertppayload_set_outcaps (basepayload,
|
||||
|
@ -157,17 +157,17 @@ gst_rtpamrenc_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpamrenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
gst_rtp_amr_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpAMREnc *rtpamrenc;
|
||||
GstRtpAMRPay *rtpamrpay;
|
||||
GstFlowReturn ret;
|
||||
guint size, payload_len;
|
||||
GstBuffer *outbuf;
|
||||
guint8 *payload, *data;
|
||||
GstClockTime timestamp;
|
||||
|
||||
rtpamrenc = GST_RTP_AMR_ENC (basepayload);
|
||||
rtpamrpay = GST_RTP_AMR_PAY (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
@ -180,15 +180,15 @@ gst_rtpamrenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
* data */
|
||||
payload_len = size + 1;
|
||||
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
||||
/* FIXME, assert for now */
|
||||
g_assert (GST_BUFFER_SIZE (outbuf) < GST_BASE_RTP_PAYLOAD_MTU (rtpamrenc));
|
||||
g_assert (GST_BUFFER_SIZE (outbuf) < GST_BASE_RTP_PAYLOAD_MTU (rtpamrpay));
|
||||
|
||||
/* copy timestamp */
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
||||
|
||||
/* get payload */
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
payload = gst_rtp_buffer_get_payload (outbuf);
|
||||
|
||||
/* 0 1 2 3 4 5 6 7
|
||||
* +-+-+-+-+-+-+-+-+
|
||||
|
@ -218,8 +218,8 @@ gst_rtpamrenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpamrenc_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_amr_pay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpamrenc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_AMR_ENC);
|
||||
return gst_element_register (plugin, "rtpamrpay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_AMR_PAY);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_AMR_ENC_H__
|
||||
#define __GST_RTP_AMR_ENC_H__
|
||||
#ifndef __GST_RTP_AMR_PAY_H__
|
||||
#define __GST_RTP_AMR_PAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
|
@ -26,32 +26,32 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_AMR_ENC \
|
||||
(gst_rtpamrenc_get_type())
|
||||
#define GST_RTP_AMR_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_AMR_ENC,GstRtpAMREnc))
|
||||
#define GST_RTP_AMR_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_AMR_ENC,GstRtpAMREnc))
|
||||
#define GST_IS_RTP_AMR_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_AMR_ENC))
|
||||
#define GST_IS_RTP_AMR_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_AMR_ENC))
|
||||
#define GST_TYPE_RTP_AMR_PAY \
|
||||
(gst_rtp_amr_pay_get_type())
|
||||
#define GST_RTP_AMR_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_AMR_PAY,GstRtpAMRPay))
|
||||
#define GST_RTP_AMR_PAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_AMR_PAY,GstRtpAMRPay))
|
||||
#define GST_IS_RTP_AMR_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_AMR_PAY))
|
||||
#define GST_IS_RTP_AMR_PAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_AMR_PAY))
|
||||
|
||||
typedef struct _GstRtpAMREnc GstRtpAMREnc;
|
||||
typedef struct _GstRtpAMREncClass GstRtpAMREncClass;
|
||||
typedef struct _GstRtpAMRPay GstRtpAMRPay;
|
||||
typedef struct _GstRtpAMRPayClass GstRtpAMRPayClass;
|
||||
|
||||
struct _GstRtpAMREnc
|
||||
struct _GstRtpAMRPay
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
};
|
||||
|
||||
struct _GstRtpAMREncClass
|
||||
struct _GstRtpAMRPayClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpamrenc_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_amr_pay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_AMR_ENC_H__ */
|
||||
#endif /* __GST_RTP_AMR_PAY_H__ */
|
||||
|
|
|
@ -1,284 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
/* Element-Checklist-Version: 5 */
|
||||
|
||||
#include "gstrtpdec.h"
|
||||
|
||||
GST_DEBUG_CATEGORY (rtpdec_debug);
|
||||
#define GST_CAT_DEFAULT (rtpdec_debug)
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails rtpdec_details = GST_ELEMENT_DETAILS ("RTP Decoder",
|
||||
"Codec/Parser/Network",
|
||||
"Accepts raw RTP and RTCP packets and sends them forward",
|
||||
"Wim Taymans <wim@fluendo.com>");
|
||||
|
||||
/* GstRTPDec signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_SKIP
|
||||
/* FILL ME */
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpdec_src_rtp_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("srcrtp",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpdec_src_rtcp_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("srcrtcp",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtcp")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpdec_sink_rtp_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sinkrtp",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpdec_sink_rtcp_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sinkrtcp",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtcp")
|
||||
);
|
||||
|
||||
static void gst_rtpdec_class_init (gpointer g_class);
|
||||
static void gst_rtpdec_init (GstRTPDec * rtpdec);
|
||||
|
||||
static GstCaps *gst_rtpdec_getcaps (GstPad * pad);
|
||||
static GstFlowReturn gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer);
|
||||
static GstFlowReturn gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer);
|
||||
|
||||
static void gst_rtpdec_set_property (GObject * object,
|
||||
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpdec_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtpdec_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
/*static guint gst_rtpdec_signals[LAST_SIGNAL] = { 0 };*/
|
||||
|
||||
GType
|
||||
gst_rtpdec_get_type (void)
|
||||
{
|
||||
static GType rtpdec_type = 0;
|
||||
|
||||
if (!rtpdec_type) {
|
||||
static const GTypeInfo rtpdec_info = {
|
||||
sizeof (GstRTPDecClass), NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpdec_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRTPDec),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpdec_init,
|
||||
};
|
||||
|
||||
rtpdec_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRTPDec", &rtpdec_info, 0);
|
||||
}
|
||||
return rtpdec_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpdec_class_init (gpointer g_class)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstRTPDecClass *klass;
|
||||
|
||||
klass = (GstRTPDecClass *) g_class;
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rtpdec_src_rtp_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rtpdec_src_rtcp_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rtpdec_sink_rtp_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rtpdec_sink_rtcp_template));
|
||||
gst_element_class_set_details (gstelement_class, &rtpdec_details);
|
||||
|
||||
gobject_class->set_property = gst_rtpdec_set_property;
|
||||
gobject_class->get_property = gst_rtpdec_get_property;
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SKIP, g_param_spec_int ("skip", "skip", "skip", G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); /* CHECKME */
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gstelement_class->change_state = gst_rtpdec_change_state;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (rtpdec_debug, "rtpdec", 0, "RTP decoder");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpdec_init (GstRTPDec * rtpdec)
|
||||
{
|
||||
/* the input rtp pad */
|
||||
rtpdec->sink_rtp =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpdec_sink_rtp_template), "sinkrtp");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtp);
|
||||
gst_pad_set_getcaps_function (rtpdec->sink_rtp, gst_rtpdec_getcaps);
|
||||
gst_pad_set_chain_function (rtpdec->sink_rtp, gst_rtpdec_chain_rtp);
|
||||
|
||||
/* the input rtcp pad */
|
||||
rtpdec->sink_rtcp =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpdec_sink_rtcp_template), "sinkrtcp");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtcp);
|
||||
gst_pad_set_chain_function (rtpdec->sink_rtcp, gst_rtpdec_chain_rtcp);
|
||||
|
||||
/* the output rtp pad */
|
||||
rtpdec->src_rtp =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpdec_src_rtp_template), "srcrtp");
|
||||
gst_pad_set_getcaps_function (rtpdec->src_rtp, gst_rtpdec_getcaps);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtp);
|
||||
|
||||
/* the output rtcp pad */
|
||||
rtpdec->src_rtcp =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpdec_src_rtcp_template), "srcrtcp");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtcp);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_rtpdec_getcaps (GstPad * pad)
|
||||
{
|
||||
GstRTPDec *src;
|
||||
GstPad *other;
|
||||
GstCaps *caps;
|
||||
|
||||
src = GST_RTPDEC (GST_PAD_PARENT (pad));
|
||||
|
||||
other = pad == src->src_rtp ? src->sink_rtp : src->src_rtp;
|
||||
|
||||
caps = gst_pad_peer_get_caps (other);
|
||||
|
||||
if (caps == NULL)
|
||||
caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
GstRTPDec *src;
|
||||
|
||||
src = GST_RTPDEC (GST_PAD_PARENT (pad));
|
||||
|
||||
GST_DEBUG ("got rtp packet");
|
||||
return gst_pad_push (src->src_rtp, buffer);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
GST_DEBUG ("got rtcp packet");
|
||||
|
||||
gst_buffer_unref (buffer);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpdec_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRTPDec *src;
|
||||
|
||||
src = GST_RTPDEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SKIP:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpdec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRTPDec *src;
|
||||
|
||||
src = GST_RTPDEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SKIP:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpdec_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstStateChangeReturn ret;
|
||||
GstRTPDec *rtpdec;
|
||||
|
||||
rtpdec = GST_RTPDEC (element);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpdec_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpdec",
|
||||
GST_RANK_NONE, GST_TYPE_RTPDEC);
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTPDEC_H__
|
||||
#define __GST_RTPDEC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTPDEC (gst_rtpdec_get_type())
|
||||
#define GST_IS_RTPDEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTPDEC))
|
||||
#define GST_IS_RTPDEC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTPDEC))
|
||||
#define GST_RTPDEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTPDEC, GstRTPDec))
|
||||
#define GST_RTPDEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTPDEC, GstRTPDecClass))
|
||||
|
||||
typedef struct _GstRTPDec GstRTPDec;
|
||||
typedef struct _GstRTPDecClass GstRTPDecClass;
|
||||
|
||||
struct _GstRTPDec {
|
||||
GstElement element;
|
||||
|
||||
GstPad *sink_rtp;
|
||||
GstPad *sink_rtcp;
|
||||
GstPad *src_rtp;
|
||||
GstPad *src_rtcp;
|
||||
};
|
||||
|
||||
struct _GstRTPDecClass {
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpdec_plugin_init (GstPlugin * plugin);
|
||||
|
||||
GType gst_rtpdec_get_type(void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTPDEC_H__ */
|
|
@ -18,18 +18,19 @@
|
|||
*/
|
||||
/* Element-Checklist-Version: 5 */
|
||||
|
||||
#include "gstrtpdec.h"
|
||||
#include "gstrtpdepay.h"
|
||||
|
||||
GST_DEBUG_CATEGORY (rtpdec_debug);
|
||||
#define GST_CAT_DEFAULT (rtpdec_debug)
|
||||
GST_DEBUG_CATEGORY (rtpdepay_debug);
|
||||
#define GST_CAT_DEFAULT (rtpdepay_debug)
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails rtpdec_details = GST_ELEMENT_DETAILS ("RTP Decoder",
|
||||
static GstElementDetails rtpdepay_details =
|
||||
GST_ELEMENT_DETAILS ("RTP Payloader",
|
||||
"Codec/Parser/Network",
|
||||
"Accepts raw RTP and RTCP packets and sends them forward",
|
||||
"Wim Taymans <wim@fluendo.com>");
|
||||
|
||||
/* GstRTPDec signals and args */
|
||||
/* GstRTPDepay signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
|
@ -43,149 +44,151 @@ enum
|
|||
/* FILL ME */
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpdec_src_rtp_template =
|
||||
static GstStaticPadTemplate gst_rtp_depay_src_rtp_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("srcrtp",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpdec_src_rtcp_template =
|
||||
static GstStaticPadTemplate gst_rtp_depay_src_rtcp_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("srcrtcp",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtcp")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpdec_sink_rtp_template =
|
||||
static GstStaticPadTemplate gst_rtp_depay_sink_rtp_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sinkrtp",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpdec_sink_rtcp_template =
|
||||
static GstStaticPadTemplate gst_rtp_depay_sink_rtcp_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sinkrtcp",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtcp")
|
||||
);
|
||||
|
||||
static void gst_rtpdec_class_init (gpointer g_class);
|
||||
static void gst_rtpdec_init (GstRTPDec * rtpdec);
|
||||
static void gst_rtp_depay_class_init (gpointer g_class);
|
||||
static void gst_rtp_depay_init (GstRTPDepay * rtpdepay);
|
||||
|
||||
static GstCaps *gst_rtpdec_getcaps (GstPad * pad);
|
||||
static GstFlowReturn gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer);
|
||||
static GstFlowReturn gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer);
|
||||
static GstCaps *gst_rtp_depay_getcaps (GstPad * pad);
|
||||
static GstFlowReturn gst_rtp_depay_chain_rtp (GstPad * pad, GstBuffer * buffer);
|
||||
static GstFlowReturn gst_rtp_depay_chain_rtcp (GstPad * pad,
|
||||
GstBuffer * buffer);
|
||||
|
||||
static void gst_rtpdec_set_property (GObject * object,
|
||||
static void gst_rtp_depay_set_property (GObject * object,
|
||||
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpdec_get_property (GObject * object,
|
||||
static void gst_rtp_depay_get_property (GObject * object,
|
||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtpdec_change_state (GstElement * element,
|
||||
static GstStateChangeReturn gst_rtp_depay_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
/*static guint gst_rtpdec_signals[LAST_SIGNAL] = { 0 };*/
|
||||
/*static guint gst_rtp_depay_signals[LAST_SIGNAL] = { 0 };*/
|
||||
|
||||
GType
|
||||
gst_rtpdec_get_type (void)
|
||||
gst_rtp_depay_get_type (void)
|
||||
{
|
||||
static GType rtpdec_type = 0;
|
||||
static GType rtpdepay_type = 0;
|
||||
|
||||
if (!rtpdec_type) {
|
||||
static const GTypeInfo rtpdec_info = {
|
||||
sizeof (GstRTPDecClass), NULL,
|
||||
if (!rtpdepay_type) {
|
||||
static const GTypeInfo rtpdepay_info = {
|
||||
sizeof (GstRTPDepayClass), NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpdec_class_init,
|
||||
(GClassInitFunc) gst_rtp_depay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRTPDec),
|
||||
sizeof (GstRTPDepay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpdec_init,
|
||||
(GInstanceInitFunc) gst_rtp_depay_init,
|
||||
};
|
||||
|
||||
rtpdec_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRTPDec", &rtpdec_info, 0);
|
||||
rtpdepay_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRTPDepay", &rtpdepay_info,
|
||||
0);
|
||||
}
|
||||
return rtpdec_type;
|
||||
return rtpdepay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpdec_class_init (gpointer g_class)
|
||||
gst_rtp_depay_class_init (gpointer g_class)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstRTPDecClass *klass;
|
||||
GstRTPDepayClass *klass;
|
||||
|
||||
klass = (GstRTPDecClass *) g_class;
|
||||
klass = (GstRTPDepayClass *) g_class;
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rtpdec_src_rtp_template));
|
||||
gst_static_pad_template_get (&gst_rtp_depay_src_rtp_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rtpdec_src_rtcp_template));
|
||||
gst_static_pad_template_get (&gst_rtp_depay_src_rtcp_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rtpdec_sink_rtp_template));
|
||||
gst_static_pad_template_get (&gst_rtp_depay_sink_rtp_template));
|
||||
gst_element_class_add_pad_template (gstelement_class,
|
||||
gst_static_pad_template_get (&gst_rtpdec_sink_rtcp_template));
|
||||
gst_element_class_set_details (gstelement_class, &rtpdec_details);
|
||||
gst_static_pad_template_get (&gst_rtp_depay_sink_rtcp_template));
|
||||
gst_element_class_set_details (gstelement_class, &rtpdepay_details);
|
||||
|
||||
gobject_class->set_property = gst_rtpdec_set_property;
|
||||
gobject_class->get_property = gst_rtpdec_get_property;
|
||||
gobject_class->set_property = gst_rtp_depay_set_property;
|
||||
gobject_class->get_property = gst_rtp_depay_get_property;
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SKIP, g_param_spec_int ("skip", "skip", "skip", G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); /* CHECKME */
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gstelement_class->change_state = gst_rtpdec_change_state;
|
||||
gstelement_class->change_state = gst_rtp_depay_change_state;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (rtpdec_debug, "rtpdec", 0, "RTP decoder");
|
||||
GST_DEBUG_CATEGORY_INIT (rtpdepay_debug, "rtpdepay", 0, "RTP decoder");
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpdec_init (GstRTPDec * rtpdec)
|
||||
gst_rtp_depay_init (GstRTPDepay * rtpdepay)
|
||||
{
|
||||
/* the input rtp pad */
|
||||
rtpdec->sink_rtp =
|
||||
rtpdepay->sink_rtp =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpdec_sink_rtp_template), "sinkrtp");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtp);
|
||||
gst_pad_set_getcaps_function (rtpdec->sink_rtp, gst_rtpdec_getcaps);
|
||||
gst_pad_set_chain_function (rtpdec->sink_rtp, gst_rtpdec_chain_rtp);
|
||||
(&gst_rtp_depay_sink_rtp_template), "sinkrtp");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdepay), rtpdepay->sink_rtp);
|
||||
gst_pad_set_getcaps_function (rtpdepay->sink_rtp, gst_rtp_depay_getcaps);
|
||||
gst_pad_set_chain_function (rtpdepay->sink_rtp, gst_rtp_depay_chain_rtp);
|
||||
|
||||
/* the input rtcp pad */
|
||||
rtpdec->sink_rtcp =
|
||||
rtpdepay->sink_rtcp =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpdec_sink_rtcp_template), "sinkrtcp");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->sink_rtcp);
|
||||
gst_pad_set_chain_function (rtpdec->sink_rtcp, gst_rtpdec_chain_rtcp);
|
||||
(&gst_rtp_depay_sink_rtcp_template), "sinkrtcp");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdepay), rtpdepay->sink_rtcp);
|
||||
gst_pad_set_chain_function (rtpdepay->sink_rtcp, gst_rtp_depay_chain_rtcp);
|
||||
|
||||
/* the output rtp pad */
|
||||
rtpdec->src_rtp =
|
||||
rtpdepay->src_rtp =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpdec_src_rtp_template), "srcrtp");
|
||||
gst_pad_set_getcaps_function (rtpdec->src_rtp, gst_rtpdec_getcaps);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtp);
|
||||
(&gst_rtp_depay_src_rtp_template), "srcrtp");
|
||||
gst_pad_set_getcaps_function (rtpdepay->src_rtp, gst_rtp_depay_getcaps);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdepay), rtpdepay->src_rtp);
|
||||
|
||||
/* the output rtcp pad */
|
||||
rtpdec->src_rtcp =
|
||||
rtpdepay->src_rtcp =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpdec_src_rtcp_template), "srcrtcp");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdec), rtpdec->src_rtcp);
|
||||
(&gst_rtp_depay_src_rtcp_template), "srcrtcp");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpdepay), rtpdepay->src_rtcp);
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_rtpdec_getcaps (GstPad * pad)
|
||||
gst_rtp_depay_getcaps (GstPad * pad)
|
||||
{
|
||||
GstRTPDec *src;
|
||||
GstRTPDepay *src;
|
||||
GstPad *other;
|
||||
GstCaps *caps;
|
||||
|
||||
src = GST_RTPDEC (GST_PAD_PARENT (pad));
|
||||
src = GST_RTP_DEPAY (GST_PAD_PARENT (pad));
|
||||
|
||||
other = pad == src->src_rtp ? src->sink_rtp : src->src_rtp;
|
||||
|
||||
|
@ -198,18 +201,18 @@ gst_rtpdec_getcaps (GstPad * pad)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpdec_chain_rtp (GstPad * pad, GstBuffer * buffer)
|
||||
gst_rtp_depay_chain_rtp (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
GstRTPDec *src;
|
||||
GstRTPDepay *src;
|
||||
|
||||
src = GST_RTPDEC (GST_PAD_PARENT (pad));
|
||||
src = GST_RTP_DEPAY (GST_PAD_PARENT (pad));
|
||||
|
||||
GST_DEBUG ("got rtp packet");
|
||||
return gst_pad_push (src->src_rtp, buffer);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer)
|
||||
gst_rtp_depay_chain_rtcp (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
GST_DEBUG ("got rtcp packet");
|
||||
|
||||
|
@ -218,12 +221,12 @@ gst_rtpdec_chain_rtcp (GstPad * pad, GstBuffer * buffer)
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpdec_set_property (GObject * object, guint prop_id,
|
||||
gst_rtp_depay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRTPDec *src;
|
||||
GstRTPDepay *src;
|
||||
|
||||
src = GST_RTPDEC (object);
|
||||
src = GST_RTP_DEPAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SKIP:
|
||||
|
@ -234,12 +237,12 @@ gst_rtpdec_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpdec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
gst_rtp_depay_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRTPDec *src;
|
||||
GstRTPDepay *src;
|
||||
|
||||
src = GST_RTPDEC (object);
|
||||
src = GST_RTP_DEPAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SKIP:
|
||||
|
@ -250,12 +253,12 @@ gst_rtpdec_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpdec_change_state (GstElement * element, GstStateChange transition)
|
||||
gst_rtp_depay_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstStateChangeReturn ret;
|
||||
GstRTPDec *rtpdec;
|
||||
GstRTPDepay *rtpdepay;
|
||||
|
||||
rtpdec = GST_RTPDEC (element);
|
||||
rtpdepay = GST_RTP_DEPAY (element);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
|
@ -277,8 +280,8 @@ gst_rtpdec_change_state (GstElement * element, GstStateChange transition)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpdec_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_depay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpdec",
|
||||
GST_RANK_NONE, GST_TYPE_RTPDEC);
|
||||
return gst_element_register (plugin, "rtpdepay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_DEPAY);
|
||||
}
|
||||
|
|
|
@ -17,23 +17,23 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTPDEC_H__
|
||||
#define __GST_RTPDEC_H__
|
||||
#ifndef __GST_RTP_DEPAY_H__
|
||||
#define __GST_RTP_DEPAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTPDEC (gst_rtpdec_get_type())
|
||||
#define GST_IS_RTPDEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTPDEC))
|
||||
#define GST_IS_RTPDEC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTPDEC))
|
||||
#define GST_RTPDEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTPDEC, GstRTPDec))
|
||||
#define GST_RTPDEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTPDEC, GstRTPDecClass))
|
||||
#define GST_TYPE_RTP_DEPAY (gst_rtp_depay_get_type())
|
||||
#define GST_IS_RTP_DEPAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_DEPAY))
|
||||
#define GST_IS_RTP_DEPAY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_DEPAY))
|
||||
#define GST_RTP_DEPAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_DEPAY, GstRTPDepay))
|
||||
#define GST_RTP_DEPAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_DEPAY, GstRTPDepayClass))
|
||||
|
||||
typedef struct _GstRTPDec GstRTPDec;
|
||||
typedef struct _GstRTPDecClass GstRTPDecClass;
|
||||
typedef struct _GstRTPDepay GstRTPDepay;
|
||||
typedef struct _GstRTPDepayClass GstRTPDepayClass;
|
||||
|
||||
struct _GstRTPDec {
|
||||
struct _GstRTPDepay {
|
||||
GstElement element;
|
||||
|
||||
GstPad *sink_rtp;
|
||||
|
@ -42,14 +42,14 @@ struct _GstRTPDec {
|
|||
GstPad *src_rtcp;
|
||||
};
|
||||
|
||||
struct _GstRTPDecClass {
|
||||
struct _GstRTPDepayClass {
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpdec_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_depay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
GType gst_rtpdec_get_type(void);
|
||||
GType gst_rtp_depay_get_type(void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTPDEC_H__ */
|
||||
#endif /* __GST_RTP_DEPAY_H__ */
|
||||
|
|
|
@ -1,183 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
||||
* Copyright (C) <2005> Zeeshan Ali <zeenix@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
#include "gstrtpg711dec.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_g711dec_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts PCMU/PCMA audio from RTP packets",
|
||||
"Edgard Lima <edgard.lima@indt.org.br>, Zeeshan Ali <zeenix@gmail.com>"
|
||||
};
|
||||
|
||||
/* RtpG711Dec signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpg711dec_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp, "
|
||||
"media = (string) \"audio\", "
|
||||
"payload = (int) [ 0, 255 ], "
|
||||
"clock-rate = (int) 8000, "
|
||||
"encoding-name = (string) \"PCMU\"; "
|
||||
"application/x-rtp, "
|
||||
"media = (string) \"audio\", "
|
||||
"payload = (int) [ 0, 255 ], "
|
||||
"clock-rate = (int) 8000, " "encoding-name = (string) \"PCMA\"")
|
||||
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpg711dec_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-mulaw, "
|
||||
"channels = (int) 1; " "audio/x-alaw, " "channels = (int) 1")
|
||||
);
|
||||
|
||||
static GstBuffer *gst_rtpg711dec_process (GstBaseRTPDepayload * depayload,
|
||||
GstBuffer * buf);
|
||||
static gboolean gst_rtpg711dec_setcaps (GstBaseRTPDepayload * depayload,
|
||||
GstCaps * caps);
|
||||
|
||||
GST_BOILERPLATE (GstRtpG711Dec, gst_rtpg711dec, GstBaseRTPDepayload,
|
||||
GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpg711dec_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpg711dec_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpg711dec_sink_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_g711dec_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpg711dec_class_init (GstRtpG711DecClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
gstbasertpdepayload_class->process = gst_rtpg711dec_process;
|
||||
gstbasertpdepayload_class->set_caps = gst_rtpg711dec_setcaps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpg711dec_init (GstRtpG711Dec * rtpg711dec, GstRtpG711DecClass * klass)
|
||||
{
|
||||
GstBaseRTPDepayload *depayload;
|
||||
|
||||
depayload = GST_BASE_RTP_DEPAYLOAD (rtpg711dec);
|
||||
|
||||
depayload->clock_rate = 8000;
|
||||
gst_pad_use_fixed_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpg711dec_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||
{
|
||||
GstCaps *srccaps;
|
||||
const gchar *enc_name;
|
||||
GstStructure *structure;
|
||||
gboolean ret;
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
enc_name = gst_structure_get_string (structure, "encoding-name");
|
||||
|
||||
if (NULL == enc_name) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (0 == strcmp ("PCMU", enc_name)) {
|
||||
srccaps = gst_caps_new_simple ("audio/x-mulaw",
|
||||
"channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
|
||||
} else if (0 == strcmp ("PCMA", enc_name)) {
|
||||
srccaps = gst_caps_new_simple ("audio/x-alaw",
|
||||
"channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), srccaps);
|
||||
gst_caps_unref (srccaps);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
gst_rtpg711dec_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||
{
|
||||
GstCaps *srccaps;
|
||||
GstBuffer *outbuf = NULL;
|
||||
gint payload_len;
|
||||
guint8 *payload;
|
||||
|
||||
GST_DEBUG ("process : got %d bytes, mark %d ts %u seqn %d",
|
||||
GST_BUFFER_SIZE (buf),
|
||||
gst_rtpbuffer_get_marker (buf),
|
||||
gst_rtpbuffer_get_timestamp (buf), gst_rtpbuffer_get_seq (buf));
|
||||
|
||||
srccaps = GST_PAD_CAPS (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload));
|
||||
if (!srccaps) {
|
||||
/* Set the default caps */
|
||||
srccaps = gst_caps_new_simple ("audio/x-mulaw",
|
||||
"channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
|
||||
gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), srccaps);
|
||||
gst_caps_unref (srccaps);
|
||||
}
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpg711dec_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpg711dec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_G711_DEC);
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_G711_DEC_H__
|
||||
#define __GST_RTP_G711_DEC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertpdepayload.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstRtpG711Dec GstRtpG711Dec;
|
||||
typedef struct _GstRtpG711DecClass GstRtpG711DecClass;
|
||||
|
||||
#define GST_TYPE_RTP_G711_DEC \
|
||||
(gst_rtpg711dec_get_type())
|
||||
#define GST_RTP_G711_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_G711_DEC,GstRtpG711Dec))
|
||||
#define GST_RTP_G711_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_G711_DEC,GstRtpG711Dec))
|
||||
#define GST_IS_RTP_G711_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_G711_DEC))
|
||||
#define GST_IS_RTP_G711_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_G711_DEC))
|
||||
|
||||
struct _GstRtpG711Dec
|
||||
{
|
||||
GstBaseRTPDepayload depayload;
|
||||
};
|
||||
|
||||
struct _GstRtpG711DecClass
|
||||
{
|
||||
GstBaseRTPDepayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpg711dec_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_G711_DEC_H__ */
|
|
@ -20,17 +20,17 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
#include "gstrtpg711dec.h"
|
||||
#include "gstrtpg711depay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_g711dec_details = {
|
||||
static GstElementDetails gst_rtp_g711depay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts PCMU/PCMA audio from RTP packets",
|
||||
"Edgard Lima <edgard.lima@indt.org.br>, Zeeshan Ali <zeenix@gmail.com>"
|
||||
};
|
||||
|
||||
/* RtpG711Dec signals and args */
|
||||
/* RtpG711Depay signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
|
@ -42,7 +42,7 @@ enum
|
|||
ARG_0
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpg711dec_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_g711_depay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -58,7 +58,7 @@ static GstStaticPadTemplate gst_rtpg711dec_sink_template =
|
|||
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpg711dec_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_g711_depay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -66,28 +66,28 @@ static GstStaticPadTemplate gst_rtpg711dec_src_template =
|
|||
"channels = (int) 1; " "audio/x-alaw, " "channels = (int) 1")
|
||||
);
|
||||
|
||||
static GstBuffer *gst_rtpg711dec_process (GstBaseRTPDepayload * depayload,
|
||||
static GstBuffer *gst_rtp_g711_depay_process (GstBaseRTPDepayload * depayload,
|
||||
GstBuffer * buf);
|
||||
static gboolean gst_rtpg711dec_setcaps (GstBaseRTPDepayload * depayload,
|
||||
static gboolean gst_rtp_g711_depay_setcaps (GstBaseRTPDepayload * depayload,
|
||||
GstCaps * caps);
|
||||
|
||||
GST_BOILERPLATE (GstRtpG711Dec, gst_rtpg711dec, GstBaseRTPDepayload,
|
||||
GST_BOILERPLATE (GstRtpG711Depay, gst_rtp_g711_depay, GstBaseRTPDepayload,
|
||||
GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpg711dec_base_init (gpointer klass)
|
||||
gst_rtp_g711_depay_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpg711dec_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_g711_depay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpg711dec_sink_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_g711dec_details);
|
||||
gst_static_pad_template_get (&gst_rtp_g711_depay_sink_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_g711depay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpg711dec_class_init (GstRtpG711DecClass * klass)
|
||||
gst_rtp_g711_depay_class_init (GstRtpG711DepayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -99,40 +99,41 @@ gst_rtpg711dec_class_init (GstRtpG711DecClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
gstbasertpdepayload_class->process = gst_rtpg711dec_process;
|
||||
gstbasertpdepayload_class->set_caps = gst_rtpg711dec_setcaps;
|
||||
gstbasertpdepayload_class->process = gst_rtp_g711_depay_process;
|
||||
gstbasertpdepayload_class->set_caps = gst_rtp_g711_depay_setcaps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpg711dec_init (GstRtpG711Dec * rtpg711dec, GstRtpG711DecClass * klass)
|
||||
gst_rtp_g711_depay_init (GstRtpG711Depay * rtpg711depay,
|
||||
GstRtpG711DepayClass * klass)
|
||||
{
|
||||
GstBaseRTPDepayload *depayload;
|
||||
|
||||
depayload = GST_BASE_RTP_DEPAYLOAD (rtpg711dec);
|
||||
depayload = GST_BASE_RTP_DEPAYLOAD (rtpg711depay);
|
||||
|
||||
depayload->clock_rate = 8000;
|
||||
gst_pad_use_fixed_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpg711dec_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||
gst_rtp_g711_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||
{
|
||||
GstCaps *srccaps;
|
||||
const gchar *enc_name;
|
||||
const gchar *pay_name;
|
||||
GstStructure *structure;
|
||||
gboolean ret;
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
enc_name = gst_structure_get_string (structure, "encoding-name");
|
||||
pay_name = gst_structure_get_string (structure, "encoding-name");
|
||||
|
||||
if (NULL == enc_name) {
|
||||
if (NULL == pay_name) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (0 == strcmp ("PCMU", enc_name)) {
|
||||
if (0 == strcmp ("PCMU", pay_name)) {
|
||||
srccaps = gst_caps_new_simple ("audio/x-mulaw",
|
||||
"channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
|
||||
} else if (0 == strcmp ("PCMA", enc_name)) {
|
||||
} else if (0 == strcmp ("PCMA", pay_name)) {
|
||||
srccaps = gst_caps_new_simple ("audio/x-alaw",
|
||||
"channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL);
|
||||
} else {
|
||||
|
@ -146,7 +147,7 @@ gst_rtpg711dec_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
|||
}
|
||||
|
||||
static GstBuffer *
|
||||
gst_rtpg711dec_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||
gst_rtp_g711_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||
{
|
||||
GstCaps *srccaps;
|
||||
GstBuffer *outbuf = NULL;
|
||||
|
@ -155,8 +156,8 @@ gst_rtpg711dec_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
|
||||
GST_DEBUG ("process : got %d bytes, mark %d ts %u seqn %d",
|
||||
GST_BUFFER_SIZE (buf),
|
||||
gst_rtpbuffer_get_marker (buf),
|
||||
gst_rtpbuffer_get_timestamp (buf), gst_rtpbuffer_get_seq (buf));
|
||||
gst_rtp_buffer_get_marker (buf),
|
||||
gst_rtp_buffer_get_timestamp (buf), gst_rtp_buffer_get_seq (buf));
|
||||
|
||||
srccaps = GST_PAD_CAPS (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload));
|
||||
if (!srccaps) {
|
||||
|
@ -167,8 +168,8 @@ gst_rtpg711dec_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
gst_caps_unref (srccaps);
|
||||
}
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
payload_len = gst_rtp_buffer_get_payload_len (buf);
|
||||
payload = gst_rtp_buffer_get_payload (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
|
@ -176,8 +177,8 @@ gst_rtpg711dec_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpg711dec_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_g711_depay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpg711dec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_G711_DEC);
|
||||
return gst_element_register (plugin, "rtpg711depay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_G711_DEPAY);
|
||||
}
|
||||
|
|
|
@ -12,40 +12,40 @@
|
|||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_G711_DEC_H__
|
||||
#define __GST_RTP_G711_DEC_H__
|
||||
#ifndef __GST_RTP_G711_DEPAY_H__
|
||||
#define __GST_RTP_G711_DEPAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertpdepayload.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstRtpG711Dec GstRtpG711Dec;
|
||||
typedef struct _GstRtpG711DecClass GstRtpG711DecClass;
|
||||
typedef struct _GstRtpG711Depay GstRtpG711Depay;
|
||||
typedef struct _GstRtpG711DepayClass GstRtpG711DepayClass;
|
||||
|
||||
#define GST_TYPE_RTP_G711_DEC \
|
||||
(gst_rtpg711dec_get_type())
|
||||
#define GST_RTP_G711_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_G711_DEC,GstRtpG711Dec))
|
||||
#define GST_RTP_G711_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_G711_DEC,GstRtpG711Dec))
|
||||
#define GST_IS_RTP_G711_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_G711_DEC))
|
||||
#define GST_IS_RTP_G711_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_G711_DEC))
|
||||
#define GST_TYPE_RTP_G711_DEPAY \
|
||||
(gst_rtp_g711_depay_get_type())
|
||||
#define GST_RTP_G711_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_G711_DEPAY,GstRtpG711Depay))
|
||||
#define GST_RTP_G711_DEPAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_G711_DEPAY,GstRtpG711Depay))
|
||||
#define GST_IS_RTP_G711_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_G711_DEPAY))
|
||||
#define GST_IS_RTP_G711_DEPAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_G711_DEPAY))
|
||||
|
||||
struct _GstRtpG711Dec
|
||||
struct _GstRtpG711Depay
|
||||
{
|
||||
GstBaseRTPDepayload depayload;
|
||||
};
|
||||
|
||||
struct _GstRtpG711DecClass
|
||||
struct _GstRtpG711DepayClass
|
||||
{
|
||||
GstBaseRTPDepayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpg711dec_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_g711_depay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_G711_DEC_H__ */
|
||||
#endif /* __GST_RTP_G711_DEPAY_H__ */
|
||||
|
|
|
@ -1,234 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpg711enc.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtpg711enc_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes PCMU/PCMA audio into a RTP packet",
|
||||
"Edgard Lima <edgard.lima@indt.org.br>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpg711enc_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-mulaw, channels=(int)1, rate=(int)8000 ;"
|
||||
"audio/x-alaw, channels=(int)1, rate=(int)8000")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpg711enc_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp, "
|
||||
"media = (string) \"audio\", "
|
||||
"payload = (int) " GST_RTP_PAYLOAD_PCMU_STRING ", "
|
||||
"clock-rate = (int) 8000, "
|
||||
"encoding-name = (string) \"PCMU\"; "
|
||||
"application/x-rtp, "
|
||||
"media = (string) \"audio\", "
|
||||
"payload = (int) " GST_RTP_PAYLOAD_PCMA_STRING ", "
|
||||
"clock-rate = (int) 8000, " "encoding-name = (string) \"PCMA\"")
|
||||
);
|
||||
|
||||
static gboolean gst_rtpg711enc_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpg711enc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
static void gst_rtpg711enc_finalize (GObject * object);
|
||||
|
||||
GST_BOILERPLATE (GstRtpG711Enc, gst_rtpg711enc, GstBaseRTPPayload,
|
||||
GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpg711enc_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpg711enc_sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpg711enc_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtpg711enc_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpg711enc_class_init (GstRtpG711EncClass * 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);
|
||||
gobject_class->finalize = gst_rtpg711enc_finalize;
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpg711enc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpg711enc_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpg711enc_init (GstRtpG711Enc * rtpg711enc, GstRtpG711EncClass * klass)
|
||||
{
|
||||
rtpg711enc->adapter = gst_adapter_new ();
|
||||
GST_BASE_RTP_PAYLOAD (rtpg711enc)->clock_rate = 8000;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpg711enc_finalize (GObject * object)
|
||||
{
|
||||
GstRtpG711Enc *rtpg711enc;
|
||||
|
||||
rtpg711enc = GST_RTP_G711_ENC (object);
|
||||
|
||||
g_object_unref (rtpg711enc->adapter);
|
||||
rtpg711enc->adapter = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpg711enc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
|
||||
const char *stname;
|
||||
GstStructure *structure;
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
stname = gst_structure_get_name (structure);
|
||||
|
||||
if (0 == strcmp ("audio/x-mulaw", stname)) {
|
||||
payload->pt = GST_RTP_PAYLOAD_PCMU;
|
||||
gst_basertppayload_set_options (payload, "audio", FALSE, "PCMU", 8000);
|
||||
} else if (0 == strcmp ("audio/x-alaw", stname)) {
|
||||
payload->pt = GST_RTP_PAYLOAD_PCMA;
|
||||
gst_basertppayload_set_options (payload, "audio", FALSE, "PCMA", 8000);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_basertppayload_set_outcaps (payload, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpg711enc_flush (GstRtpG711Enc * rtpg711enc)
|
||||
{
|
||||
guint avail;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret;
|
||||
|
||||
/* the data available in the adapter is either smaller
|
||||
* than the MTU or bigger. In the case it is smaller, the complete
|
||||
* adapter contents can be put in one packet. */
|
||||
avail = gst_adapter_available (rtpg711enc->adapter);
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
|
||||
while (avail > 0) {
|
||||
guint towrite;
|
||||
guint8 *payload;
|
||||
guint8 *data;
|
||||
guint payload_len;
|
||||
guint packet_len;
|
||||
|
||||
/* this will be the total lenght of the packet */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (avail, 0, 0);
|
||||
/* fill one MTU or all available bytes */
|
||||
towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpg711enc));
|
||||
/* 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);
|
||||
|
||||
/* copy payload */
|
||||
gst_rtpbuffer_set_payload_type (outbuf,
|
||||
GST_BASE_RTP_PAYLOAD_PT (rtpg711enc));
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
data = (guint8 *) gst_adapter_peek (rtpg711enc->adapter, payload_len);
|
||||
memcpy (payload, data, payload_len);
|
||||
gst_adapter_flush (rtpg711enc->adapter, payload_len);
|
||||
|
||||
avail -= payload_len;
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtpg711enc->first_ts;
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpg711enc), outbuf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpg711enc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpG711Enc *rtpg711enc;
|
||||
guint size, packet_len, avail;
|
||||
GstFlowReturn ret;
|
||||
GstClockTime duration;
|
||||
|
||||
rtpg711enc = GST_RTP_G711_ENC (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
duration = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
avail = gst_adapter_available (rtpg711enc->adapter);
|
||||
if (avail == 0) {
|
||||
rtpg711enc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpg711enc->duration = 0;
|
||||
}
|
||||
|
||||
/* get packet length of data and see if we exceeded MTU. */
|
||||
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 (gst_basertppayload_is_filled (basepayload,
|
||||
packet_len, rtpg711enc->duration + duration)) {
|
||||
ret = gst_rtpg711enc_flush (rtpg711enc);
|
||||
rtpg711enc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpg711enc->duration = 0;
|
||||
} else {
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
|
||||
gst_adapter_push (rtpg711enc->adapter, buffer);
|
||||
rtpg711enc->duration += duration;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpg711enc_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpg711enc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_G711_ENC);
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GST_RTP_G711_ENC_H__
|
||||
#define __GST_RTP_G711_ENC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstRtpG711Enc GstRtpG711Enc;
|
||||
typedef struct _GstRtpG711EncClass GstRtpG711EncClass;
|
||||
|
||||
#define GST_TYPE_RTP_G711_ENC \
|
||||
(gst_rtpg711enc_get_type())
|
||||
#define GST_RTP_G711_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_G711_ENC,GstRtpG711Enc))
|
||||
#define GST_RTP_G711_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_G711_ENC,GstRtpG711Enc))
|
||||
#define GST_IS_RTP_G711_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_G711_ENC))
|
||||
#define GST_IS_RTP_G711_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_G711_ENC))
|
||||
|
||||
struct _GstRtpG711Enc
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
GstAdapter *adapter;
|
||||
|
||||
GstClockTime first_ts;
|
||||
GstClockTime duration;
|
||||
};
|
||||
|
||||
struct _GstRtpG711EncClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpg711enc_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_G711_ENC_H__ */
|
|
@ -21,17 +21,17 @@
|
|||
#include <string.h>
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpg711enc.h"
|
||||
#include "gstrtpg711pay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtpg711enc_details = {
|
||||
static GstElementDetails gst_rtp_g711_pay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes PCMU/PCMA audio into a RTP packet",
|
||||
"Codec/Payloader/Network",
|
||||
"Payodes PCMU/PCMA audio into a RTP packet",
|
||||
"Edgard Lima <edgard.lima@indt.org.br>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpg711enc_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_g711_pay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -39,7 +39,7 @@ static GstStaticPadTemplate gst_rtpg711enc_sink_template =
|
|||
"audio/x-alaw, channels=(int)1, rate=(int)8000")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpg711enc_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_g711_pay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -54,29 +54,29 @@ static GstStaticPadTemplate gst_rtpg711enc_src_template =
|
|||
"clock-rate = (int) 8000, " "encoding-name = (string) \"PCMA\"")
|
||||
);
|
||||
|
||||
static gboolean gst_rtpg711enc_setcaps (GstBaseRTPPayload * payload,
|
||||
static gboolean gst_rtp_g711_pay_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpg711enc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
static void gst_rtpg711enc_finalize (GObject * object);
|
||||
static GstFlowReturn gst_rtp_g711_pay_handle_buffer (GstBaseRTPPayload *
|
||||
payload, GstBuffer * buffer);
|
||||
static void gst_rtp_g711_pay_finalize (GObject * object);
|
||||
|
||||
GST_BOILERPLATE (GstRtpG711Enc, gst_rtpg711enc, GstBaseRTPPayload,
|
||||
GST_BOILERPLATE (GstRtpG711Pay, gst_rtp_g711_pay, GstBaseRTPPayload,
|
||||
GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpg711enc_base_init (gpointer klass)
|
||||
gst_rtp_g711_pay_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpg711enc_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_g711_pay_sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpg711enc_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtpg711enc_details);
|
||||
gst_static_pad_template_get (&gst_rtp_g711_pay_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_g711_pay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpg711enc_class_init (GstRtpG711EncClass * klass)
|
||||
gst_rtp_g711_pay_class_init (GstRtpG711PayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -87,34 +87,34 @@ gst_rtpg711enc_class_init (GstRtpG711EncClass * klass)
|
|||
gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
gobject_class->finalize = gst_rtpg711enc_finalize;
|
||||
gobject_class->finalize = gst_rtp_g711_pay_finalize;
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpg711enc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpg711enc_handle_buffer;
|
||||
gstbasertppayload_class->set_caps = gst_rtp_g711_pay_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtp_g711_pay_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpg711enc_init (GstRtpG711Enc * rtpg711enc, GstRtpG711EncClass * klass)
|
||||
gst_rtp_g711_pay_init (GstRtpG711Pay * rtpg711pay, GstRtpG711PayClass * klass)
|
||||
{
|
||||
rtpg711enc->adapter = gst_adapter_new ();
|
||||
GST_BASE_RTP_PAYLOAD (rtpg711enc)->clock_rate = 8000;
|
||||
rtpg711pay->adapter = gst_adapter_new ();
|
||||
GST_BASE_RTP_PAYLOAD (rtpg711pay)->clock_rate = 8000;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpg711enc_finalize (GObject * object)
|
||||
gst_rtp_g711_pay_finalize (GObject * object)
|
||||
{
|
||||
GstRtpG711Enc *rtpg711enc;
|
||||
GstRtpG711Pay *rtpg711pay;
|
||||
|
||||
rtpg711enc = GST_RTP_G711_ENC (object);
|
||||
rtpg711pay = GST_RTP_G711_PAY (object);
|
||||
|
||||
g_object_unref (rtpg711enc->adapter);
|
||||
rtpg711enc->adapter = NULL;
|
||||
g_object_unref (rtpg711pay->adapter);
|
||||
rtpg711pay->adapter = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpg711enc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
gst_rtp_g711_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
|
||||
const char *stname;
|
||||
|
@ -140,7 +140,7 @@ gst_rtpg711enc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpg711enc_flush (GstRtpG711Enc * rtpg711enc)
|
||||
gst_rtp_g711_pay_flush (GstRtpG711Pay * rtpg711pay)
|
||||
{
|
||||
guint avail;
|
||||
GstBuffer *outbuf;
|
||||
|
@ -149,7 +149,7 @@ gst_rtpg711enc_flush (GstRtpG711Enc * rtpg711enc)
|
|||
/* the data available in the adapter is either smaller
|
||||
* than the MTU or bigger. In the case it is smaller, the complete
|
||||
* adapter contents can be put in one packet. */
|
||||
avail = gst_adapter_available (rtpg711enc->adapter);
|
||||
avail = gst_adapter_available (rtpg711pay->adapter);
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
|
||||
|
@ -161,74 +161,74 @@ gst_rtpg711enc_flush (GstRtpG711Enc * rtpg711enc)
|
|||
guint packet_len;
|
||||
|
||||
/* this will be the total lenght of the packet */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (avail, 0, 0);
|
||||
packet_len = gst_rtp_buffer_calc_packet_len (avail, 0, 0);
|
||||
/* fill one MTU or all available bytes */
|
||||
towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpg711enc));
|
||||
towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpg711pay));
|
||||
/* this is the payload length */
|
||||
payload_len = gst_rtpbuffer_calc_payload_len (towrite, 0, 0);
|
||||
payload_len = gst_rtp_buffer_calc_payload_len (towrite, 0, 0);
|
||||
/* create buffer to hold the payload */
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
||||
|
||||
/* copy payload */
|
||||
gst_rtpbuffer_set_payload_type (outbuf,
|
||||
GST_BASE_RTP_PAYLOAD_PT (rtpg711enc));
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
data = (guint8 *) gst_adapter_peek (rtpg711enc->adapter, payload_len);
|
||||
gst_rtp_buffer_set_payload_type (outbuf,
|
||||
GST_BASE_RTP_PAYLOAD_PT (rtpg711pay));
|
||||
payload = gst_rtp_buffer_get_payload (outbuf);
|
||||
data = (guint8 *) gst_adapter_peek (rtpg711pay->adapter, payload_len);
|
||||
memcpy (payload, data, payload_len);
|
||||
gst_adapter_flush (rtpg711enc->adapter, payload_len);
|
||||
gst_adapter_flush (rtpg711pay->adapter, payload_len);
|
||||
|
||||
avail -= payload_len;
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtpg711enc->first_ts;
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpg711enc), outbuf);
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtpg711pay->first_ts;
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpg711pay), outbuf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpg711enc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
gst_rtp_g711_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpG711Enc *rtpg711enc;
|
||||
GstRtpG711Pay *rtpg711pay;
|
||||
guint size, packet_len, avail;
|
||||
GstFlowReturn ret;
|
||||
GstClockTime duration;
|
||||
|
||||
rtpg711enc = GST_RTP_G711_ENC (basepayload);
|
||||
rtpg711pay = GST_RTP_G711_PAY (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
duration = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
avail = gst_adapter_available (rtpg711enc->adapter);
|
||||
avail = gst_adapter_available (rtpg711pay->adapter);
|
||||
if (avail == 0) {
|
||||
rtpg711enc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpg711enc->duration = 0;
|
||||
rtpg711pay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpg711pay->duration = 0;
|
||||
}
|
||||
|
||||
/* get packet length of data and see if we exceeded MTU. */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (avail + size, 0, 0);
|
||||
packet_len = gst_rtp_buffer_calc_packet_len (avail + size, 0, 0);
|
||||
|
||||
/* if this buffer is going to overflow the packet, flush what we
|
||||
* have. */
|
||||
if (gst_basertppayload_is_filled (basepayload,
|
||||
packet_len, rtpg711enc->duration + duration)) {
|
||||
ret = gst_rtpg711enc_flush (rtpg711enc);
|
||||
rtpg711enc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpg711enc->duration = 0;
|
||||
packet_len, rtpg711pay->duration + duration)) {
|
||||
ret = gst_rtp_g711_pay_flush (rtpg711pay);
|
||||
rtpg711pay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpg711pay->duration = 0;
|
||||
} else {
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
|
||||
gst_adapter_push (rtpg711enc->adapter, buffer);
|
||||
rtpg711enc->duration += duration;
|
||||
gst_adapter_push (rtpg711pay->adapter, buffer);
|
||||
rtpg711pay->duration += duration;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpg711enc_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_g711_pay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpg711enc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_G711_ENC);
|
||||
return gst_element_register (plugin, "rtpg711pay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_G711_PAY);
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef __GST_RTP_G711_ENC_H__
|
||||
#define __GST_RTP_G711_ENC_H__
|
||||
#ifndef __GST_RTP_G711_PAY_H__
|
||||
#define __GST_RTP_G711_PAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
|
@ -22,21 +22,21 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstRtpG711Enc GstRtpG711Enc;
|
||||
typedef struct _GstRtpG711EncClass GstRtpG711EncClass;
|
||||
typedef struct _GstRtpG711Pay GstRtpG711Pay;
|
||||
typedef struct _GstRtpG711PayClass GstRtpG711PayClass;
|
||||
|
||||
#define GST_TYPE_RTP_G711_ENC \
|
||||
(gst_rtpg711enc_get_type())
|
||||
#define GST_RTP_G711_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_G711_ENC,GstRtpG711Enc))
|
||||
#define GST_RTP_G711_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_G711_ENC,GstRtpG711Enc))
|
||||
#define GST_IS_RTP_G711_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_G711_ENC))
|
||||
#define GST_IS_RTP_G711_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_G711_ENC))
|
||||
#define GST_TYPE_RTP_G711_PAY \
|
||||
(gst_rtp_g711_pay_get_type())
|
||||
#define GST_RTP_G711_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_G711_PAY,GstRtpG711Pay))
|
||||
#define GST_RTP_G711_PAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_G711_PAY,GstRtpG711Pay))
|
||||
#define GST_IS_RTP_G711_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_G711_PAY))
|
||||
#define GST_IS_RTP_G711_PAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_G711_PAY))
|
||||
|
||||
struct _GstRtpG711Enc
|
||||
struct _GstRtpG711Pay
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
GstAdapter *adapter;
|
||||
|
@ -45,13 +45,13 @@ struct _GstRtpG711Enc
|
|||
GstClockTime duration;
|
||||
};
|
||||
|
||||
struct _GstRtpG711EncClass
|
||||
struct _GstRtpG711PayClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpg711enc_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_g711_pay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_G711_ENC_H__ */
|
||||
#endif /* __GST_RTP_G711_PAY_H__ */
|
||||
|
|
|
@ -36,14 +36,14 @@ enum
|
|||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpgsmparse_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_gsm_parse_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-gsm, " "rate = (int) 8000, " "channels = 1")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpgsmparse_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_gsm_parse_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -53,64 +53,65 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
"clock-rate = (int) 8000, " "encoding-name = (string) \"GSM\"")
|
||||
);
|
||||
|
||||
static GstBuffer *gst_rtpgsmparse_process (GstBaseRTPDepayload * depayload,
|
||||
static GstBuffer *gst_rtp_gsm_parse_process (GstBaseRTPDepayload * _depayload,
|
||||
GstBuffer * buf);
|
||||
static gboolean gst_rtpgsmparse_setcaps (GstBaseRTPDepayload * depayload,
|
||||
static gboolean gst_rtp_gsm_parse_setcaps (GstBaseRTPDepayload * _depayload,
|
||||
GstCaps * caps);
|
||||
|
||||
GST_BOILERPLATE (GstRTPGSMParse, gst_rtpgsmparse, GstBaseRTPDepayload,
|
||||
GST_BOILERPLATE (GstRTPGSMParse, gst_rtp_gsm_parse, GstBaseRTPDepayload,
|
||||
GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpgsmparse_base_init (gpointer klass)
|
||||
gst_rtp_gsm_parse_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpgsmparse_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_gsm_parse_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpgsmparse_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_gsm_parse_sink_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_gsmparse_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpgsmparse_class_init (GstRTPGSMParseClass * klass)
|
||||
gst_rtp_gsm_parse_class_init (GstRTPGSMParseClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
|
||||
GstBaseRTPDepayloadClass *gstbasertp_depayload_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
|
||||
gstbasertp_depayload_class = (GstBaseRTPDepayloadClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
gstbasertpdepayload_class->process = gst_rtpgsmparse_process;
|
||||
gstbasertpdepayload_class->set_caps = gst_rtpgsmparse_setcaps;
|
||||
gstbasertp_depayload_class->process = gst_rtp_gsm_parse_process;
|
||||
gstbasertp_depayload_class->set_caps = gst_rtp_gsm_parse_setcaps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpgsmparse_init (GstRTPGSMParse * rtpgsmparse, GstRTPGSMParseClass * klass)
|
||||
gst_rtp_gsm_parse_init (GstRTPGSMParse * rtpgsmparse,
|
||||
GstRTPGSMParseClass * klass)
|
||||
{
|
||||
GST_BASE_RTP_DEPAYLOAD (rtpgsmparse)->clock_rate = 8000;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpgsmparse_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||
gst_rtp_gsm_parse_setcaps (GstBaseRTPDepayload * _depayload, GstCaps * caps)
|
||||
{
|
||||
GstCaps *srccaps;
|
||||
gboolean ret;
|
||||
|
||||
srccaps = gst_static_pad_template_get_caps (&gst_rtpgsmparse_src_template);
|
||||
ret = gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), srccaps);
|
||||
srccaps = gst_static_pad_template_get_caps (&gst_rtp_gsm_parse_src_template);
|
||||
ret = gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (_depayload), srccaps);
|
||||
|
||||
gst_caps_unref (srccaps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
gst_rtpgsmparse_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||
gst_rtp_gsm_parse_process (GstBaseRTPDepayload * _depayload, GstBuffer * buf)
|
||||
{
|
||||
GstBuffer *outbuf = NULL;
|
||||
gint payload_len;
|
||||
|
@ -118,11 +119,11 @@ gst_rtpgsmparse_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
|
||||
GST_DEBUG ("process : got %d bytes, mark %d ts %u seqn %d",
|
||||
GST_BUFFER_SIZE (buf),
|
||||
gst_rtpbuffer_get_marker (buf),
|
||||
gst_rtpbuffer_get_timestamp (buf), gst_rtpbuffer_get_seq (buf));
|
||||
gst_rtp_buffer_get_marker (buf),
|
||||
gst_rtp_buffer_get_timestamp (buf), gst_rtp_buffer_get_seq (buf));
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
payload_len = gst_rtp_buffer_get_payload_len (buf);
|
||||
payload = gst_rtp_buffer_get_payload (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
|
@ -130,7 +131,7 @@ gst_rtpgsmparse_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpgsmparse_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_gsm_parse_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpgsmparse",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_GSM_PARSE);
|
||||
|
|
|
@ -29,7 +29,7 @@ typedef struct _GstRTPGSMParse GstRTPGSMParse;
|
|||
typedef struct _GstRTPGSMParseClass GstRTPGSMParseClass;
|
||||
|
||||
#define GST_TYPE_RTP_GSM_PARSE \
|
||||
(gst_rtpgsmparse_get_type())
|
||||
(gst_rtp_gsm_parse_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) \
|
||||
|
@ -41,7 +41,7 @@ typedef struct _GstRTPGSMParseClass GstRTPGSMParseClass;
|
|||
|
||||
struct _GstRTPGSMParse
|
||||
{
|
||||
GstBaseRTPDepayload depayload;
|
||||
GstBaseRTPDepayload _depayload;
|
||||
};
|
||||
|
||||
struct _GstRTPGSMParseClass
|
||||
|
@ -49,7 +49,7 @@ struct _GstRTPGSMParseClass
|
|||
GstBaseRTPDepayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpgsmparse_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_gsm_parse_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
* Copyright (C) <2005> Zeeshan Ali <zeenix@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpgsmenc.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtpgsmenc_details = {
|
||||
"RTP GSM Audio Encoder",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes GSM audio into a RTP packet",
|
||||
"Zeeshan Ali <zeenix@gmail.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpgsmenc_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-gsm, " "rate = (int) 8000, " "channels = (int) 1")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpgsmenc_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp, "
|
||||
"media = (string) \"audio\", "
|
||||
"payload = (int) " GST_RTP_PAYLOAD_GSM_STRING ", "
|
||||
"clock-rate = (int) 8000, " "encoding-name = (string) \"GSM\"")
|
||||
);
|
||||
|
||||
static gboolean gst_rtpgsmenc_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
|
||||
GST_BOILERPLATE (GstRTPGSMEnc, gst_rtpgsmenc, GstBaseRTPPayload,
|
||||
GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpgsmenc_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpgsmenc_sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpgsmenc_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtpgsmenc_details);
|
||||
}
|
||||
|
||||
static void
|
||||
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_BASE_RTP_PAYLOAD);
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpgsmenc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpgsmenc_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpgsmenc_init (GstRTPGSMEnc * rtpgsmenc, GstRTPGSMEncClass * klass)
|
||||
{
|
||||
GST_BASE_RTP_PAYLOAD (rtpgsmenc)->clock_rate = 8000;
|
||||
GST_BASE_RTP_PAYLOAD_PT (rtpgsmenc) = GST_RTP_PAYLOAD_GSM;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpgsmenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
const char *stname;
|
||||
GstStructure *structure;
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
stname = gst_structure_get_name (structure);
|
||||
|
||||
if (0 == strcmp ("audio/x-gsm", stname)) {
|
||||
gst_basertppayload_set_options (payload, "audio", FALSE, "GSM", 8000);
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_basertppayload_set_outcaps (payload, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRTPGSMEnc *rtpgsmenc;
|
||||
guint size, payload_len;
|
||||
GstBuffer *outbuf;
|
||||
guint8 *payload, *data;
|
||||
GstClockTime timestamp;
|
||||
GstFlowReturn ret;
|
||||
|
||||
rtpgsmenc = GST_RTP_GSM_ENC (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
/* FIXME, only one GSM frame per RTP packet for now */
|
||||
payload_len = size;
|
||||
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
/* FIXME, assert for now */
|
||||
g_assert (payload_len <= GST_BASE_RTP_PAYLOAD_MTU (rtpgsmenc));
|
||||
|
||||
/* copy timestamp */
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
||||
|
||||
/* get payload */
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
|
||||
data = GST_BUFFER_DATA (buffer);
|
||||
|
||||
/* copy data in payload */
|
||||
memcpy (&payload[0], data, size);
|
||||
|
||||
gst_buffer_unref (buffer);
|
||||
|
||||
GST_DEBUG ("gst_rtpgsmenc_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
ret = gst_basertppayload_push (basepayload, outbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpgsmenc_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpgsmenc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_GSM_ENC);
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GST_RTP_GSM_ENC_H__
|
||||
#define __GST_RTP_GSM_ENC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstRTPGSMEnc GstRTPGSMEnc;
|
||||
typedef struct _GstRTPGSMEncClass GstRTPGSMEncClass;
|
||||
|
||||
#define GST_TYPE_RTP_GSM_ENC \
|
||||
(gst_rtpgsmenc_get_type())
|
||||
#define GST_RTP_GSM_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_GSM_ENC,GstRTPGSMEnc))
|
||||
#define GST_RTP_GSM_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_GSM_ENC,GstRTPGSMEnc))
|
||||
#define GST_IS_RTP_GSM_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_GSM_ENC))
|
||||
#define GST_IS_RTP_GSM_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_GSM_ENC))
|
||||
|
||||
struct _GstRTPGSMEnc
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
};
|
||||
|
||||
struct _GstRTPGSMEncClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpgsmenc_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_GSM_ENC_H__ */
|
|
@ -36,14 +36,14 @@ enum
|
|||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpgsmparse_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_gsm_parse_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-gsm, " "rate = (int) 8000, " "channels = 1")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpgsmparse_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_gsm_parse_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -53,64 +53,65 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
"clock-rate = (int) 8000, " "encoding-name = (string) \"GSM\"")
|
||||
);
|
||||
|
||||
static GstBuffer *gst_rtpgsmparse_process (GstBaseRTPDepayload * depayload,
|
||||
static GstBuffer *gst_rtp_gsm_parse_process (GstBaseRTPDepayload * _depayload,
|
||||
GstBuffer * buf);
|
||||
static gboolean gst_rtpgsmparse_setcaps (GstBaseRTPDepayload * depayload,
|
||||
static gboolean gst_rtp_gsm_parse_setcaps (GstBaseRTPDepayload * _depayload,
|
||||
GstCaps * caps);
|
||||
|
||||
GST_BOILERPLATE (GstRTPGSMParse, gst_rtpgsmparse, GstBaseRTPDepayload,
|
||||
GST_BOILERPLATE (GstRTPGSMParse, gst_rtp_gsm_parse, GstBaseRTPDepayload,
|
||||
GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpgsmparse_base_init (gpointer klass)
|
||||
gst_rtp_gsm_parse_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpgsmparse_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_gsm_parse_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpgsmparse_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_gsm_parse_sink_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_gsmparse_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpgsmparse_class_init (GstRTPGSMParseClass * klass)
|
||||
gst_rtp_gsm_parse_class_init (GstRTPGSMParseClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
|
||||
GstBaseRTPDepayloadClass *gstbasertp_depayload_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
|
||||
gstbasertp_depayload_class = (GstBaseRTPDepayloadClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
gstbasertpdepayload_class->process = gst_rtpgsmparse_process;
|
||||
gstbasertpdepayload_class->set_caps = gst_rtpgsmparse_setcaps;
|
||||
gstbasertp_depayload_class->process = gst_rtp_gsm_parse_process;
|
||||
gstbasertp_depayload_class->set_caps = gst_rtp_gsm_parse_setcaps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpgsmparse_init (GstRTPGSMParse * rtpgsmparse, GstRTPGSMParseClass * klass)
|
||||
gst_rtp_gsm_parse_init (GstRTPGSMParse * rtpgsmparse,
|
||||
GstRTPGSMParseClass * klass)
|
||||
{
|
||||
GST_BASE_RTP_DEPAYLOAD (rtpgsmparse)->clock_rate = 8000;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpgsmparse_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||
gst_rtp_gsm_parse_setcaps (GstBaseRTPDepayload * _depayload, GstCaps * caps)
|
||||
{
|
||||
GstCaps *srccaps;
|
||||
gboolean ret;
|
||||
|
||||
srccaps = gst_static_pad_template_get_caps (&gst_rtpgsmparse_src_template);
|
||||
ret = gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), srccaps);
|
||||
srccaps = gst_static_pad_template_get_caps (&gst_rtp_gsm_parse_src_template);
|
||||
ret = gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (_depayload), srccaps);
|
||||
|
||||
gst_caps_unref (srccaps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
gst_rtpgsmparse_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||
gst_rtp_gsm_parse_process (GstBaseRTPDepayload * _depayload, GstBuffer * buf)
|
||||
{
|
||||
GstBuffer *outbuf = NULL;
|
||||
gint payload_len;
|
||||
|
@ -118,11 +119,11 @@ gst_rtpgsmparse_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
|
||||
GST_DEBUG ("process : got %d bytes, mark %d ts %u seqn %d",
|
||||
GST_BUFFER_SIZE (buf),
|
||||
gst_rtpbuffer_get_marker (buf),
|
||||
gst_rtpbuffer_get_timestamp (buf), gst_rtpbuffer_get_seq (buf));
|
||||
gst_rtp_buffer_get_marker (buf),
|
||||
gst_rtp_buffer_get_timestamp (buf), gst_rtp_buffer_get_seq (buf));
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
payload_len = gst_rtp_buffer_get_payload_len (buf);
|
||||
payload = gst_rtp_buffer_get_payload (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
|
@ -130,7 +131,7 @@ gst_rtpgsmparse_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpgsmparse_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_gsm_parse_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpgsmparse",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_GSM_PARSE);
|
||||
|
|
|
@ -29,7 +29,7 @@ typedef struct _GstRTPGSMParse GstRTPGSMParse;
|
|||
typedef struct _GstRTPGSMParseClass GstRTPGSMParseClass;
|
||||
|
||||
#define GST_TYPE_RTP_GSM_PARSE \
|
||||
(gst_rtpgsmparse_get_type())
|
||||
(gst_rtp_gsm_parse_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) \
|
||||
|
@ -41,7 +41,7 @@ typedef struct _GstRTPGSMParseClass GstRTPGSMParseClass;
|
|||
|
||||
struct _GstRTPGSMParse
|
||||
{
|
||||
GstBaseRTPDepayload depayload;
|
||||
GstBaseRTPDepayload _depayload;
|
||||
};
|
||||
|
||||
struct _GstRTPGSMParseClass
|
||||
|
@ -49,7 +49,7 @@ struct _GstRTPGSMParseClass
|
|||
GstBaseRTPDepayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpgsmparse_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_gsm_parse_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -26,24 +26,24 @@
|
|||
#include <string.h>
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpgsmenc.h"
|
||||
#include "gstrtpgsmpay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtpgsmenc_details = {
|
||||
"RTP GSM Audio Encoder",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes GSM audio into a RTP packet",
|
||||
static GstElementDetails gst_rtp_gsm_pay_details = {
|
||||
"RTP GSM Audio Payloader",
|
||||
"Codec/Payloader/Network",
|
||||
"Payodes GSM audio into a RTP packet",
|
||||
"Zeeshan Ali <zeenix@gmail.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpgsmenc_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_gsm_pay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-gsm, " "rate = (int) 8000, " "channels = (int) 1")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpgsmenc_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_gsm_pay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -53,28 +53,28 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
|||
"clock-rate = (int) 8000, " "encoding-name = (string) \"GSM\"")
|
||||
);
|
||||
|
||||
static gboolean gst_rtpgsmenc_setcaps (GstBaseRTPPayload * payload,
|
||||
static gboolean gst_rtp_gsm_pay_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
static GstFlowReturn gst_rtp_gsm_pay_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
|
||||
GST_BOILERPLATE (GstRTPGSMEnc, gst_rtpgsmenc, GstBaseRTPPayload,
|
||||
GST_BOILERPLATE (GstRTPGSMPay, gst_rtp_gsm_pay, GstBaseRTPPayload,
|
||||
GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpgsmenc_base_init (gpointer klass)
|
||||
gst_rtp_gsm_pay_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpgsmenc_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_gsm_pay_sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpgsmenc_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtpgsmenc_details);
|
||||
gst_static_pad_template_get (&gst_rtp_gsm_pay_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_gsm_pay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpgsmenc_class_init (GstRTPGSMEncClass * klass)
|
||||
gst_rtp_gsm_pay_class_init (GstRTPGSMPayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -86,19 +86,19 @@ gst_rtpgsmenc_class_init (GstRTPGSMEncClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpgsmenc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpgsmenc_handle_buffer;
|
||||
gstbasertppayload_class->set_caps = gst_rtp_gsm_pay_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtp_gsm_pay_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpgsmenc_init (GstRTPGSMEnc * rtpgsmenc, GstRTPGSMEncClass * klass)
|
||||
gst_rtp_gsm_pay_init (GstRTPGSMPay * rtpgsmpay, GstRTPGSMPayClass * klass)
|
||||
{
|
||||
GST_BASE_RTP_PAYLOAD (rtpgsmenc)->clock_rate = 8000;
|
||||
GST_BASE_RTP_PAYLOAD_PT (rtpgsmenc) = GST_RTP_PAYLOAD_GSM;
|
||||
GST_BASE_RTP_PAYLOAD (rtpgsmpay)->clock_rate = 8000;
|
||||
GST_BASE_RTP_PAYLOAD_PT (rtpgsmpay) = GST_RTP_PAYLOAD_GSM;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpgsmenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
gst_rtp_gsm_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
const char *stname;
|
||||
GstStructure *structure;
|
||||
|
@ -119,17 +119,17 @@ gst_rtpgsmenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
gst_rtp_gsm_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRTPGSMEnc *rtpgsmenc;
|
||||
GstRTPGSMPay *rtpgsmpay;
|
||||
guint size, payload_len;
|
||||
GstBuffer *outbuf;
|
||||
guint8 *payload, *data;
|
||||
GstClockTime timestamp;
|
||||
GstFlowReturn ret;
|
||||
|
||||
rtpgsmenc = GST_RTP_GSM_ENC (basepayload);
|
||||
rtpgsmpay = GST_RTP_GSM_PAY (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
@ -137,15 +137,15 @@ gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
/* FIXME, only one GSM frame per RTP packet for now */
|
||||
payload_len = size;
|
||||
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
||||
/* FIXME, assert for now */
|
||||
g_assert (payload_len <= GST_BASE_RTP_PAYLOAD_MTU (rtpgsmenc));
|
||||
g_assert (payload_len <= GST_BASE_RTP_PAYLOAD_MTU (rtpgsmpay));
|
||||
|
||||
/* copy timestamp */
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
||||
|
||||
/* get payload */
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
payload = gst_rtp_buffer_get_payload (outbuf);
|
||||
|
||||
data = GST_BUFFER_DATA (buffer);
|
||||
|
||||
|
@ -154,7 +154,7 @@ gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
|
||||
gst_buffer_unref (buffer);
|
||||
|
||||
GST_DEBUG ("gst_rtpgsmenc_chain: pushing buffer of size %d",
|
||||
GST_DEBUG ("gst_rtp_gsm_pay_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
ret = gst_basertppayload_push (basepayload, outbuf);
|
||||
|
@ -163,8 +163,8 @@ gst_rtpgsmenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpgsmenc_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_gsm_pay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpgsmenc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_GSM_ENC);
|
||||
return gst_element_register (plugin, "rtpgsmpay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_GSM_PAY);
|
||||
}
|
||||
|
|
|
@ -18,40 +18,40 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef __GST_RTP_GSM_ENC_H__
|
||||
#define __GST_RTP_GSM_ENC_H__
|
||||
#ifndef __GST_RTP_GSM_PAY_H__
|
||||
#define __GST_RTP_GSM_PAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstRTPGSMEnc GstRTPGSMEnc;
|
||||
typedef struct _GstRTPGSMEncClass GstRTPGSMEncClass;
|
||||
typedef struct _GstRTPGSMPay GstRTPGSMPay;
|
||||
typedef struct _GstRTPGSMPayClass GstRTPGSMPayClass;
|
||||
|
||||
#define GST_TYPE_RTP_GSM_ENC \
|
||||
(gst_rtpgsmenc_get_type())
|
||||
#define GST_RTP_GSM_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_GSM_ENC,GstRTPGSMEnc))
|
||||
#define GST_RTP_GSM_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_GSM_ENC,GstRTPGSMEnc))
|
||||
#define GST_IS_RTP_GSM_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_GSM_ENC))
|
||||
#define GST_IS_RTP_GSM_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_GSM_ENC))
|
||||
#define GST_TYPE_RTP_GSM_PAY \
|
||||
(gst_rtp_gsm_pay_get_type())
|
||||
#define GST_RTP_GSM_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_GSM_PAY,GstRTPGSMPay))
|
||||
#define GST_RTP_GSM_PAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_GSM_PAY,GstRTPGSMPay))
|
||||
#define GST_IS_RTP_GSM_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_GSM_PAY))
|
||||
#define GST_IS_RTP_GSM_PAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_GSM_PAY))
|
||||
|
||||
struct _GstRTPGSMEnc
|
||||
struct _GstRTPGSMPay
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
};
|
||||
|
||||
struct _GstRTPGSMEncClass
|
||||
struct _GstRTPGSMPayClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpgsmenc_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_gsm_pay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_GSM_ENC_H__ */
|
||||
#endif /* __GST_RTP_GSM_PAY_H__ */
|
||||
|
|
|
@ -1,380 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtph263enc.h"
|
||||
|
||||
#define GST_RFC2190A_HEADER_LEN 4
|
||||
|
||||
typedef struct _GstRFC2190AHeader
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
unsigned int ebit:3; /* End position */
|
||||
unsigned int sbit:3; /* Start position */
|
||||
unsigned int p:1; /* PB-frames mode */
|
||||
unsigned int f:1; /* flag bit */
|
||||
|
||||
unsigned int r1:1; /* Reserved */
|
||||
unsigned int a:1; /* Advanced Prediction */
|
||||
unsigned int s:1; /* syntax based arithmetic coding */
|
||||
unsigned int u:1; /* Unrestricted motion vector */
|
||||
unsigned int i:1; /* Picture coding type */
|
||||
unsigned int src:3; /* Source format */
|
||||
|
||||
unsigned int trb:3; /* Temporal ref for B frame */
|
||||
unsigned int dbq:2; /* Differential Quantisation parameter */
|
||||
unsigned int r2:3; /* Reserved */
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
unsigned int f:1; /* flag bit */
|
||||
unsigned int p:1; /* PB-frames mode */
|
||||
unsigned int sbit:3; /* Start position */
|
||||
unsigned int ebit:3; /* End position */
|
||||
|
||||
unsigned int src:3; /* Source format */
|
||||
unsigned int i:1; /* Picture coding type */
|
||||
unsigned int u:1; /* Unrestricted motion vector */
|
||||
unsigned int s:1; /* syntax based arithmetic coding */
|
||||
unsigned int a:1; /* Advanced Prediction */
|
||||
unsigned int r1:1; /* Reserved */
|
||||
|
||||
unsigned int r2:3; /* Reserved */
|
||||
unsigned int dbq:2; /* Differential Quantisation parameter */
|
||||
unsigned int trb:3; /* Temporal ref for B frame */
|
||||
#else
|
||||
#error "G_BYTE_ORDER should be big or little endian."
|
||||
#endif
|
||||
guint8 tr; /* Temporal ref for P frame */
|
||||
} GstRFC2190AHeader;
|
||||
|
||||
|
||||
#define GST_RFC2190A_HEADER_F(buf) (((GstRFC2190AHeader *)(buf))->f)
|
||||
#define GST_RFC2190A_HEADER_P(buf) (((GstRFC2190AHeader *)(buf))->p)
|
||||
#define GST_RFC2190A_HEADER_SBIT(buf) (((GstRFC2190AHeader *)(buf))->sbit)
|
||||
#define GST_RFC2190A_HEADER_EBIT(buf) (((GstRFC2190AHeader *)(buf))->ebit)
|
||||
#define GST_RFC2190A_HEADER_SRC(buf) (((GstRFC2190AHeader *)(buf))->src)
|
||||
#define GST_RFC2190A_HEADER_I(buf) (((GstRFC2190AHeader *)(buf))->i)
|
||||
#define GST_RFC2190A_HEADER_U(buf) (((GstRFC2190AHeader *)(buf))->u)
|
||||
#define GST_RFC2190A_HEADER_S(buf) (((GstRFC2190AHeader *)(buf))->s)
|
||||
#define GST_RFC2190A_HEADER_A(buf) (((GstRFC2190AHeader *)(buf))->a)
|
||||
#define GST_RFC2190A_HEADER_R1(buf) (((GstRFC2190AHeader *)(buf))->r1)
|
||||
#define GST_RFC2190A_HEADER_R2(buf) (((GstRFC2190AHeader *)(buf))->r2)
|
||||
#define GST_RFC2190A_HEADER_DBQ(buf) (((GstRFC2190AHeader *)(buf))->dbq)
|
||||
#define GST_RFC2190A_HEADER_TRB(buf) (((GstRFC2190AHeader *)(buf))->trb)
|
||||
#define GST_RFC2190A_HEADER_TR(buf) (((GstRFC2190AHeader *)(buf))->tr)
|
||||
|
||||
|
||||
typedef struct _GstH263PictureLayer
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
unsigned int psc1:16;
|
||||
|
||||
unsigned int tr1:2;
|
||||
unsigned int psc2:6;
|
||||
|
||||
unsigned int ptype_263:1;
|
||||
unsigned int ptype_start:1;
|
||||
unsigned int tr2:6;
|
||||
|
||||
unsigned int ptype_umvmode:1;
|
||||
unsigned int ptype_pictype:1;
|
||||
unsigned int ptype_srcformat:3;
|
||||
unsigned int ptype_freeze:1;
|
||||
unsigned int ptype_camera:1;
|
||||
unsigned int ptype_split:1;
|
||||
|
||||
unsigned int chaff:5;
|
||||
unsigned int ptype_pbmode:1;
|
||||
unsigned int ptype_apmode:1;
|
||||
unsigned int ptype_sacmode:1;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
unsigned int psc1:16;
|
||||
|
||||
unsigned int psc2:6;
|
||||
unsigned int tr1:2;
|
||||
|
||||
unsigned int tr2:6;
|
||||
unsigned int ptype_start:1;
|
||||
unsigned int ptype_263:1;
|
||||
|
||||
unsigned int ptype_split:1;
|
||||
unsigned int ptype_camera:1;
|
||||
unsigned int ptype_freeze:1;
|
||||
unsigned int ptype_srcformat:3;
|
||||
unsigned int ptype_pictype:1;
|
||||
unsigned int ptype_umvmode:1;
|
||||
|
||||
unsigned int ptype_sacmode:1;
|
||||
unsigned int ptype_apmode:1;
|
||||
unsigned int ptype_pbmode:1;
|
||||
unsigned int chaff:5;
|
||||
#else
|
||||
#error "G_BYTE_ORDER should be big or little endian."
|
||||
#endif
|
||||
} GstH263PictureLayer;
|
||||
|
||||
#define GST_H263_PICTURELAYER_PLSRC(buf) (((GstH263PictureLayer *)(buf))->ptype_srcformat)
|
||||
#define GST_H263_PICTURELAYER_PLTYPE(buf) (((GstH263PictureLayer *)(buf))->ptype_pictype)
|
||||
#define GST_H263_PICTURELAYER_PLUMV(buf) (((GstH263PictureLayer *)(buf))->ptype_umvmode)
|
||||
#define GST_H263_PICTURELAYER_PLSAC(buf) (((GstH263PictureLayer *)(buf))->ptype_sacmode)
|
||||
#define GST_H263_PICTURELAYER_PLAP(buf) (((GstH263PictureLayer *)(buf))->ptype_apmode)
|
||||
|
||||
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_h263enc_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes H263 video in RTP packets (RFC 2190)",
|
||||
"Neil Stratford <neils@vipadia.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263enc_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-h263")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263enc_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
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_rtph263enc_class_init (GstRtpH263EncClass * klass);
|
||||
static void gst_rtph263enc_base_init (GstRtpH263EncClass * klass);
|
||||
static void gst_rtph263enc_init (GstRtpH263Enc * rtph263enc);
|
||||
static void gst_rtph263enc_finalize (GObject * object);
|
||||
|
||||
static gboolean gst_rtph263enc_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtph263enc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
|
||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtph263enc_get_type (void)
|
||||
{
|
||||
static GType rtph263enc_type = 0;
|
||||
|
||||
if (!rtph263enc_type) {
|
||||
static const GTypeInfo rtph263enc_info = {
|
||||
sizeof (GstRtpH263EncClass),
|
||||
(GBaseInitFunc) gst_rtph263enc_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtph263enc_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpH263Enc),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtph263enc_init,
|
||||
};
|
||||
|
||||
rtph263enc_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpH263Enc",
|
||||
&rtph263enc_info, 0);
|
||||
}
|
||||
return rtph263enc_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263enc_base_init (GstRtpH263EncClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263enc_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263enc_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263enc_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263enc_class_init (GstRtpH263EncClass * 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);
|
||||
|
||||
gobject_class->finalize = gst_rtph263enc_finalize;
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtph263enc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtph263enc_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263enc_init (GstRtpH263Enc * rtph263enc)
|
||||
{
|
||||
rtph263enc->adapter = gst_adapter_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263enc_finalize (GObject * object)
|
||||
{
|
||||
GstRtpH263Enc *rtph263enc;
|
||||
|
||||
rtph263enc = GST_RTP_H263_ENC (object);
|
||||
|
||||
g_object_unref (rtph263enc->adapter);
|
||||
rtph263enc->adapter = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtph263enc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
gst_basertppayload_set_options (payload, "video", TRUE, "H263-1998", 90000);
|
||||
gst_basertppayload_set_outcaps (payload, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gst_rtph263enc_gobfiner (guint8 * data, guint len, guint curpos)
|
||||
{
|
||||
guint16 test = 0xffff;
|
||||
guint i;
|
||||
|
||||
/* If we are past the end, stop */
|
||||
if (curpos >= len)
|
||||
return 0;
|
||||
|
||||
/* start at curpos and loop looking for next gob start */
|
||||
for (i = curpos; i < len; i++) {
|
||||
test = (test << 8) | data[i];
|
||||
if ((test == 0) && (i > curpos + 4)) {
|
||||
return i - 3;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtph263enc_flush (GstRtpH263Enc * rtph263enc)
|
||||
{
|
||||
guint avail;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret = 0;
|
||||
gboolean fragmented;
|
||||
guint8 *data, *header;
|
||||
GstH263PictureLayer *piclayer;
|
||||
guint8 *payload;
|
||||
guint payload_len, total_len;
|
||||
guint curpos, nextgobpos;
|
||||
|
||||
avail = gst_adapter_available (rtph263enc->adapter);
|
||||
if (avail == 0)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
fragmented = FALSE;
|
||||
|
||||
/* Get a pointer to all the data for the frame */
|
||||
data = (guint8 *) gst_adapter_peek (rtph263enc->adapter, avail);
|
||||
|
||||
/* Start at the begining and loop looking for gobs */
|
||||
curpos = 0;
|
||||
|
||||
/* Picture header */
|
||||
piclayer = (GstH263PictureLayer *) data;
|
||||
|
||||
while ((nextgobpos = gst_rtph263enc_gobfiner (data, avail, curpos)) > 0) {
|
||||
|
||||
payload_len = nextgobpos - curpos;
|
||||
total_len = payload_len + GST_RFC2190A_HEADER_LEN;
|
||||
|
||||
outbuf = gst_rtpbuffer_new_allocate (total_len, 0, 0);
|
||||
|
||||
header = gst_rtpbuffer_get_payload (outbuf);
|
||||
payload = header + GST_RFC2190A_HEADER_LEN;
|
||||
|
||||
/* Build the headers */
|
||||
GST_RFC2190A_HEADER_F (header) = 0;
|
||||
GST_RFC2190A_HEADER_P (header) = 0;
|
||||
GST_RFC2190A_HEADER_SBIT (header) = 0;
|
||||
GST_RFC2190A_HEADER_EBIT (header) = 0;
|
||||
|
||||
GST_RFC2190A_HEADER_SRC (header) = GST_H263_PICTURELAYER_PLSRC (piclayer);
|
||||
GST_RFC2190A_HEADER_I (header) = GST_H263_PICTURELAYER_PLTYPE (piclayer);
|
||||
GST_RFC2190A_HEADER_U (header) = GST_H263_PICTURELAYER_PLUMV (piclayer);
|
||||
GST_RFC2190A_HEADER_S (header) = GST_H263_PICTURELAYER_PLSAC (piclayer);
|
||||
GST_RFC2190A_HEADER_A (header) = GST_H263_PICTURELAYER_PLAP (piclayer);
|
||||
GST_RFC2190A_HEADER_R1 (header) = 0;
|
||||
GST_RFC2190A_HEADER_R2 (header) = 0;
|
||||
GST_RFC2190A_HEADER_DBQ (header) = 0;
|
||||
GST_RFC2190A_HEADER_TRB (header) = 0;
|
||||
GST_RFC2190A_HEADER_TR (header) = 0;
|
||||
|
||||
/* last fragment gets the marker bit set */
|
||||
gst_rtpbuffer_set_marker (outbuf, nextgobpos < avail ? 0 : 1);
|
||||
|
||||
memcpy (payload, data + curpos, payload_len);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtph263enc->first_ts;
|
||||
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtph263enc), outbuf);
|
||||
|
||||
curpos = nextgobpos;
|
||||
}
|
||||
|
||||
/* Flush the whole packet */
|
||||
gst_adapter_flush (rtph263enc->adapter, avail);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtph263enc_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer)
|
||||
{
|
||||
GstRtpH263Enc *rtph263enc;
|
||||
GstFlowReturn ret;
|
||||
guint size;
|
||||
|
||||
rtph263enc = GST_RTP_H263_ENC (payload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
rtph263enc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
/* we always encode and flush a full picture */
|
||||
gst_adapter_push (rtph263enc->adapter, buffer);
|
||||
ret = gst_rtph263enc_flush (rtph263enc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtph263enc_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtph263enc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_H263_ENC);
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_H263_ENC_H__
|
||||
#define __GST_RTP_H263_ENC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_H263_ENC \
|
||||
(gst_rtph263enc_get_type())
|
||||
#define GST_RTP_H263_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_H263_ENC,GstRtpH263Enc))
|
||||
#define GST_RTP_H263_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_H263_ENC,GstRtpH263Enc))
|
||||
#define GST_IS_RTP_H263_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_H263_ENC))
|
||||
#define GST_IS_RTP_H263_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_H263_ENC))
|
||||
|
||||
typedef struct _GstRtpH263Enc GstRtpH263Enc;
|
||||
typedef struct _GstRtpH263EncClass GstRtpH263EncClass;
|
||||
|
||||
struct _GstRtpH263Enc
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
|
||||
GstAdapter *adapter;
|
||||
GstClockTime first_ts;
|
||||
};
|
||||
|
||||
struct _GstRtpH263EncClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtph263enc_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_H263_ENC_H__ */
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtph263enc.h"
|
||||
#include "gstrtph263pay.h"
|
||||
|
||||
#define GST_RFC2190A_HEADER_LEN 4
|
||||
|
||||
|
@ -139,21 +139,21 @@ typedef struct _GstH263PictureLayer
|
|||
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_h263enc_details = {
|
||||
static GstElementDetails gst_rtp_h263pay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes H263 video in RTP packets (RFC 2190)",
|
||||
"Codec/Payloader/Network",
|
||||
"Payodes H263 video in RTP packets (RFC 2190)",
|
||||
"Neil Stratford <neils@vipadia.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263enc_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_h263_pay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-h263")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263enc_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_h263_pay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -163,58 +163,58 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
|||
"clock-rate = (int) 90000, " "encoding-name = (string) \"H263-1998\"")
|
||||
);
|
||||
|
||||
static void gst_rtph263enc_class_init (GstRtpH263EncClass * klass);
|
||||
static void gst_rtph263enc_base_init (GstRtpH263EncClass * klass);
|
||||
static void gst_rtph263enc_init (GstRtpH263Enc * rtph263enc);
|
||||
static void gst_rtph263enc_finalize (GObject * object);
|
||||
static void gst_rtp_h263_pay_class_init (GstRtpH263PayClass * klass);
|
||||
static void gst_rtp_h263_pay_base_init (GstRtpH263PayClass * klass);
|
||||
static void gst_rtp_h263_pay_init (GstRtpH263Pay * rtph263pay);
|
||||
static void gst_rtp_h263_pay_finalize (GObject * object);
|
||||
|
||||
static gboolean gst_rtph263enc_setcaps (GstBaseRTPPayload * payload,
|
||||
static gboolean gst_rtp_h263_pay_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtph263enc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
static GstFlowReturn gst_rtp_h263_pay_handle_buffer (GstBaseRTPPayload *
|
||||
payload, GstBuffer * buffer);
|
||||
|
||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtph263enc_get_type (void)
|
||||
gst_rtp_h263_pay_get_type (void)
|
||||
{
|
||||
static GType rtph263enc_type = 0;
|
||||
static GType rtph263pay_type = 0;
|
||||
|
||||
if (!rtph263enc_type) {
|
||||
static const GTypeInfo rtph263enc_info = {
|
||||
sizeof (GstRtpH263EncClass),
|
||||
(GBaseInitFunc) gst_rtph263enc_base_init,
|
||||
if (!rtph263pay_type) {
|
||||
static const GTypeInfo rtph263pay_info = {
|
||||
sizeof (GstRtpH263PayClass),
|
||||
(GBaseInitFunc) gst_rtp_h263_pay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtph263enc_class_init,
|
||||
(GClassInitFunc) gst_rtp_h263_pay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpH263Enc),
|
||||
sizeof (GstRtpH263Pay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtph263enc_init,
|
||||
(GInstanceInitFunc) gst_rtp_h263_pay_init,
|
||||
};
|
||||
|
||||
rtph263enc_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpH263Enc",
|
||||
&rtph263enc_info, 0);
|
||||
rtph263pay_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpH263Pay",
|
||||
&rtph263pay_info, 0);
|
||||
}
|
||||
return rtph263enc_type;
|
||||
return rtph263pay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263enc_base_init (GstRtpH263EncClass * klass)
|
||||
gst_rtp_h263_pay_base_init (GstRtpH263PayClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263enc_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_h263_pay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263enc_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_h263_pay_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263enc_details);
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263pay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263enc_class_init (GstRtpH263EncClass * klass)
|
||||
gst_rtp_h263_pay_class_init (GstRtpH263PayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -226,33 +226,33 @@ gst_rtph263enc_class_init (GstRtpH263EncClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
gobject_class->finalize = gst_rtph263enc_finalize;
|
||||
gobject_class->finalize = gst_rtp_h263_pay_finalize;
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtph263enc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtph263enc_handle_buffer;
|
||||
gstbasertppayload_class->set_caps = gst_rtp_h263_pay_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtp_h263_pay_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263enc_init (GstRtpH263Enc * rtph263enc)
|
||||
gst_rtp_h263_pay_init (GstRtpH263Pay * rtph263pay)
|
||||
{
|
||||
rtph263enc->adapter = gst_adapter_new ();
|
||||
rtph263pay->adapter = gst_adapter_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263enc_finalize (GObject * object)
|
||||
gst_rtp_h263_pay_finalize (GObject * object)
|
||||
{
|
||||
GstRtpH263Enc *rtph263enc;
|
||||
GstRtpH263Pay *rtph263pay;
|
||||
|
||||
rtph263enc = GST_RTP_H263_ENC (object);
|
||||
rtph263pay = GST_RTP_H263_PAY (object);
|
||||
|
||||
g_object_unref (rtph263enc->adapter);
|
||||
rtph263enc->adapter = NULL;
|
||||
g_object_unref (rtph263pay->adapter);
|
||||
rtph263pay->adapter = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtph263enc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
gst_rtp_h263_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
gst_basertppayload_set_options (payload, "video", TRUE, "H263-1998", 90000);
|
||||
gst_basertppayload_set_outcaps (payload, NULL);
|
||||
|
@ -261,7 +261,7 @@ gst_rtph263enc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
|||
}
|
||||
|
||||
static guint
|
||||
gst_rtph263enc_gobfiner (guint8 * data, guint len, guint curpos)
|
||||
gst_rtp_h263_pay_gobfiner (guint8 * data, guint len, guint curpos)
|
||||
{
|
||||
guint16 test = 0xffff;
|
||||
guint i;
|
||||
|
@ -281,7 +281,7 @@ gst_rtph263enc_gobfiner (guint8 * data, guint len, guint curpos)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtph263enc_flush (GstRtpH263Enc * rtph263enc)
|
||||
gst_rtp_h263_pay_flush (GstRtpH263Pay * rtph263pay)
|
||||
{
|
||||
guint avail;
|
||||
GstBuffer *outbuf;
|
||||
|
@ -293,14 +293,14 @@ gst_rtph263enc_flush (GstRtpH263Enc * rtph263enc)
|
|||
guint payload_len, total_len;
|
||||
guint curpos, nextgobpos;
|
||||
|
||||
avail = gst_adapter_available (rtph263enc->adapter);
|
||||
avail = gst_adapter_available (rtph263pay->adapter);
|
||||
if (avail == 0)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
fragmented = FALSE;
|
||||
|
||||
/* Get a pointer to all the data for the frame */
|
||||
data = (guint8 *) gst_adapter_peek (rtph263enc->adapter, avail);
|
||||
data = (guint8 *) gst_adapter_peek (rtph263pay->adapter, avail);
|
||||
|
||||
/* Start at the begining and loop looking for gobs */
|
||||
curpos = 0;
|
||||
|
@ -308,14 +308,14 @@ gst_rtph263enc_flush (GstRtpH263Enc * rtph263enc)
|
|||
/* Picture header */
|
||||
piclayer = (GstH263PictureLayer *) data;
|
||||
|
||||
while ((nextgobpos = gst_rtph263enc_gobfiner (data, avail, curpos)) > 0) {
|
||||
while ((nextgobpos = gst_rtp_h263_pay_gobfiner (data, avail, curpos)) > 0) {
|
||||
|
||||
payload_len = nextgobpos - curpos;
|
||||
total_len = payload_len + GST_RFC2190A_HEADER_LEN;
|
||||
|
||||
outbuf = gst_rtpbuffer_new_allocate (total_len, 0, 0);
|
||||
outbuf = gst_rtp_buffer_new_allocate (total_len, 0, 0);
|
||||
|
||||
header = gst_rtpbuffer_get_payload (outbuf);
|
||||
header = gst_rtp_buffer_get_payload (outbuf);
|
||||
payload = header + GST_RFC2190A_HEADER_LEN;
|
||||
|
||||
/* Build the headers */
|
||||
|
@ -336,45 +336,45 @@ gst_rtph263enc_flush (GstRtpH263Enc * rtph263enc)
|
|||
GST_RFC2190A_HEADER_TR (header) = 0;
|
||||
|
||||
/* last fragment gets the marker bit set */
|
||||
gst_rtpbuffer_set_marker (outbuf, nextgobpos < avail ? 0 : 1);
|
||||
gst_rtp_buffer_set_marker (outbuf, nextgobpos < avail ? 0 : 1);
|
||||
|
||||
memcpy (payload, data + curpos, payload_len);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtph263enc->first_ts;
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtph263pay->first_ts;
|
||||
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtph263enc), outbuf);
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtph263pay), outbuf);
|
||||
|
||||
curpos = nextgobpos;
|
||||
}
|
||||
|
||||
/* Flush the whole packet */
|
||||
gst_adapter_flush (rtph263enc->adapter, avail);
|
||||
gst_adapter_flush (rtph263pay->adapter, avail);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtph263enc_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer)
|
||||
gst_rtp_h263_pay_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer)
|
||||
{
|
||||
GstRtpH263Enc *rtph263enc;
|
||||
GstRtpH263Pay *rtph263pay;
|
||||
GstFlowReturn ret;
|
||||
guint size;
|
||||
|
||||
rtph263enc = GST_RTP_H263_ENC (payload);
|
||||
rtph263pay = GST_RTP_H263_PAY (payload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
rtph263enc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtph263pay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
/* we always encode and flush a full picture */
|
||||
gst_adapter_push (rtph263enc->adapter, buffer);
|
||||
ret = gst_rtph263enc_flush (rtph263enc);
|
||||
gst_adapter_push (rtph263pay->adapter, buffer);
|
||||
ret = gst_rtp_h263_pay_flush (rtph263pay);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtph263enc_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_h263_pay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtph263enc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_H263_ENC);
|
||||
return gst_element_register (plugin, "rtph263pay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_H263_PAY);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_H263_ENC_H__
|
||||
#define __GST_RTP_H263_ENC_H__
|
||||
#ifndef __GST_RTP_H263_PAY_H__
|
||||
#define __GST_RTP_H263_PAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
|
@ -26,21 +26,21 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_H263_ENC \
|
||||
(gst_rtph263enc_get_type())
|
||||
#define GST_RTP_H263_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_H263_ENC,GstRtpH263Enc))
|
||||
#define GST_RTP_H263_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_H263_ENC,GstRtpH263Enc))
|
||||
#define GST_IS_RTP_H263_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_H263_ENC))
|
||||
#define GST_IS_RTP_H263_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_H263_ENC))
|
||||
#define GST_TYPE_RTP_H263_PAY \
|
||||
(gst_rtp_h263_pay_get_type())
|
||||
#define GST_RTP_H263_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_H263_PAY,GstRtpH263Pay))
|
||||
#define GST_RTP_H263_PAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_H263_PAY,GstRtpH263Pay))
|
||||
#define GST_IS_RTP_H263_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_H263_PAY))
|
||||
#define GST_IS_RTP_H263_PAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_H263_PAY))
|
||||
|
||||
typedef struct _GstRtpH263Enc GstRtpH263Enc;
|
||||
typedef struct _GstRtpH263EncClass GstRtpH263EncClass;
|
||||
typedef struct _GstRtpH263Pay GstRtpH263Pay;
|
||||
typedef struct _GstRtpH263PayClass GstRtpH263PayClass;
|
||||
|
||||
struct _GstRtpH263Enc
|
||||
struct _GstRtpH263Pay
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
|
||||
|
@ -48,13 +48,13 @@ struct _GstRtpH263Enc
|
|||
GstClockTime first_ts;
|
||||
};
|
||||
|
||||
struct _GstRtpH263EncClass
|
||||
struct _GstRtpH263PayClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtph263enc_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_h263_pay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_H263_ENC_H__ */
|
||||
#endif /* __GST_RTP_H263_PAY_H__ */
|
||||
|
|
|
@ -1,342 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
#include "gstrtph263pdec.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_h263pdec_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts H263+ video from RTP packets (RFC 2429)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
/* RtpH263PDec signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_FREQUENCY
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263pdec_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-h263")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263pdec_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
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);
|
||||
|
||||
static void gst_rtph263pdec_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtph263pdec_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtph263pdec_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtph263pdec_get_type (void)
|
||||
{
|
||||
static GType rtph263pdec_type = 0;
|
||||
|
||||
if (!rtph263pdec_type) {
|
||||
static const GTypeInfo rtph263pdec_info = {
|
||||
sizeof (GstRtpH263PDecClass),
|
||||
(GBaseInitFunc) gst_rtph263pdec_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtph263pdec_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpH263PDec),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtph263pdec_init,
|
||||
};
|
||||
|
||||
rtph263pdec_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpH263PDec",
|
||||
&rtph263pdec_info, 0);
|
||||
}
|
||||
return rtph263pdec_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263pdec_base_init (GstRtpH263PDecClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263pdec_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263pdec_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263pdec_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263pdec_class_init (GstRtpH263PDecClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) 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;
|
||||
|
||||
gstelement_class->change_state = gst_rtph263pdec_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263pdec_init (GstRtpH263PDec * rtph263pdec)
|
||||
{
|
||||
rtph263pdec->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtph263pdec_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtph263pdec), rtph263pdec->srcpad);
|
||||
|
||||
rtph263pdec->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtph263pdec_sink_template), "sink");
|
||||
gst_pad_set_chain_function (rtph263pdec->sinkpad, gst_rtph263pdec_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtph263pdec), rtph263pdec->sinkpad);
|
||||
|
||||
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)
|
||||
{
|
||||
GstRtpH263PDec *rtph263pdec;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret;
|
||||
|
||||
/* GstRTPPayload pt; */
|
||||
|
||||
rtph263pdec = GST_RTP_H263P_DEC (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (!gst_rtpbuffer_validate (buf))
|
||||
goto bad_packet;
|
||||
|
||||
/*
|
||||
if ((pt = gst_rtpbuffer_get_payload_type (buf)) != 0)
|
||||
goto bad_payload;
|
||||
*/
|
||||
|
||||
{
|
||||
gint payload_len;
|
||||
guint8 *payload;
|
||||
gboolean P, V, M;
|
||||
guint32 timestamp;
|
||||
guint header_len;
|
||||
guint8 PLEN;
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
|
||||
header_len = 2;
|
||||
|
||||
M = gst_rtpbuffer_get_marker (buf);
|
||||
P = (payload[0] & 0x04) == 0x04;
|
||||
V = (payload[0] & 0x02) == 0x02;
|
||||
PLEN = ((payload[0] & 0x1) << 5) | (payload[1] >> 3);
|
||||
|
||||
if (V) {
|
||||
header_len++;
|
||||
}
|
||||
if (PLEN) {
|
||||
header_len += PLEN;
|
||||
}
|
||||
|
||||
if (P) {
|
||||
header_len -= 2;
|
||||
payload[header_len] = 0;
|
||||
payload[header_len + 1] = 0;
|
||||
}
|
||||
|
||||
/* strip off header */
|
||||
payload += header_len;
|
||||
payload_len -= header_len;
|
||||
|
||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||
|
||||
if (M) {
|
||||
/* frame is completed: append to previous, push it out */
|
||||
guint avail;
|
||||
guint8 *data;
|
||||
|
||||
avail = gst_adapter_available (rtph263pdec->adapter);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (avail + payload_len);
|
||||
|
||||
/* prepend previous data */
|
||||
if (avail > 0) {
|
||||
data = (guint8 *) gst_adapter_peek (rtph263pdec->adapter, avail);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), data, avail);
|
||||
gst_adapter_flush (rtph263pdec->adapter, avail);
|
||||
}
|
||||
memcpy (GST_BUFFER_DATA (outbuf) + avail, payload, payload_len);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / 90000;
|
||||
gst_buffer_set_caps (outbuf,
|
||||
(GstCaps *) gst_pad_get_pad_template_caps (rtph263pdec->srcpad));
|
||||
|
||||
ret = gst_pad_push (rtph263pdec->srcpad, outbuf);
|
||||
} else {
|
||||
/* frame not completed: store in adapter */
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
|
||||
gst_adapter_push (rtph263pdec->adapter, outbuf);
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
|
||||
gst_buffer_unref (buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
bad_packet:
|
||||
{
|
||||
GST_DEBUG ("Packet does 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
|
||||
gst_rtph263pdec_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpH263PDec *rtph263pdec;
|
||||
|
||||
rtph263pdec = GST_RTP_H263P_DEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263pdec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRtpH263PDec *rtph263pdec;
|
||||
|
||||
rtph263pdec = GST_RTP_H263P_DEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtph263pdec_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstRtpH263PDec *rtph263pdec;
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
rtph263pdec = GST_RTP_H263P_DEC (element);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_rtph263pdec_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtph263pdec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_H263P_DEC);
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_H263P_DEC_H__
|
||||
#define __GST_RTP_H263P_DEC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_H263P_DEC \
|
||||
(gst_rtph263pdec_get_type())
|
||||
#define GST_RTP_H263P_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_H263P_DEC,GstRtpH263PDec))
|
||||
#define GST_RTP_H263P_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_H263P_DEC,GstRtpH263PDec))
|
||||
#define GST_IS_RTP_H263P_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_H263P_DEC))
|
||||
#define GST_IS_RTP_H263P_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_H263P_DEC))
|
||||
|
||||
typedef struct _GstRtpH263PDec GstRtpH263PDec;
|
||||
typedef struct _GstRtpH263PDecClass GstRtpH263PDecClass;
|
||||
|
||||
struct _GstRtpH263PDec
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
GstAdapter *adapter;
|
||||
|
||||
guint frequency;
|
||||
};
|
||||
|
||||
struct _GstRtpH263PDecClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtph263pdec_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_H263P_DEC_H__ */
|
|
@ -19,17 +19,17 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
#include "gstrtph263pdec.h"
|
||||
#include "gstrtph263pdepay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_h263pdec_details = {
|
||||
static GstElementDetails gst_rtp_h263pdepay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts H263+ video from RTP packets (RFC 2429)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
/* RtpH263PDec signals and args */
|
||||
/* RtpH263PDepay signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
|
@ -42,14 +42,14 @@ enum
|
|||
ARG_FREQUENCY
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263pdec_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_h263p_depay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-h263")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263pdec_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_h263p_depay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -60,63 +60,64 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
);
|
||||
|
||||
|
||||
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 void gst_rtp_h263p_depay_class_init (GstRtpH263PDepayClass * klass);
|
||||
static void gst_rtp_h263p_depay_base_init (GstRtpH263PDepayClass * klass);
|
||||
static void gst_rtp_h263p_depay_init (GstRtpH263PDepay * rtph263pdepay);
|
||||
static void gst_rtp_h263p_depay_finalize (GObject * object);
|
||||
|
||||
static GstFlowReturn gst_rtph263pdec_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static GstFlowReturn gst_rtp_h263p_depay_chain (GstPad * pad,
|
||||
GstBuffer * buffer);
|
||||
|
||||
static void gst_rtph263pdec_set_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_h263p_depay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtph263pdec_get_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_h263p_depay_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtph263pdec_change_state (GstElement *
|
||||
static GstStateChangeReturn gst_rtp_h263p_depay_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtph263pdec_get_type (void)
|
||||
gst_rtp_h263p_depay_get_type (void)
|
||||
{
|
||||
static GType rtph263pdec_type = 0;
|
||||
static GType rtph263pdepay_type = 0;
|
||||
|
||||
if (!rtph263pdec_type) {
|
||||
static const GTypeInfo rtph263pdec_info = {
|
||||
sizeof (GstRtpH263PDecClass),
|
||||
(GBaseInitFunc) gst_rtph263pdec_base_init,
|
||||
if (!rtph263pdepay_type) {
|
||||
static const GTypeInfo rtph263pdepay_info = {
|
||||
sizeof (GstRtpH263PDepayClass),
|
||||
(GBaseInitFunc) gst_rtp_h263p_depay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtph263pdec_class_init,
|
||||
(GClassInitFunc) gst_rtp_h263p_depay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpH263PDec),
|
||||
sizeof (GstRtpH263PDepay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtph263pdec_init,
|
||||
(GInstanceInitFunc) gst_rtp_h263p_depay_init,
|
||||
};
|
||||
|
||||
rtph263pdec_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpH263PDec",
|
||||
&rtph263pdec_info, 0);
|
||||
rtph263pdepay_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpH263PDepay",
|
||||
&rtph263pdepay_info, 0);
|
||||
}
|
||||
return rtph263pdec_type;
|
||||
return rtph263pdepay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263pdec_base_init (GstRtpH263PDecClass * klass)
|
||||
gst_rtp_h263p_depay_base_init (GstRtpH263PDepayClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263pdec_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_h263p_depay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263pdec_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_h263p_depay_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263pdec_details);
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263pdepay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263pdec_class_init (GstRtpH263PDecClass * klass)
|
||||
gst_rtp_h263p_depay_class_init (GstRtpH263PDepayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -126,60 +127,61 @@ gst_rtph263pdec_class_init (GstRtpH263PDecClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->finalize = gst_rtph263pdec_finalize;
|
||||
gobject_class->finalize = gst_rtp_h263p_depay_finalize;
|
||||
|
||||
gobject_class->set_property = gst_rtph263pdec_set_property;
|
||||
gobject_class->get_property = gst_rtph263pdec_get_property;
|
||||
gobject_class->set_property = gst_rtp_h263p_depay_set_property;
|
||||
gobject_class->get_property = gst_rtp_h263p_depay_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtph263pdec_change_state;
|
||||
gstelement_class->change_state = gst_rtp_h263p_depay_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263pdec_init (GstRtpH263PDec * rtph263pdec)
|
||||
gst_rtp_h263p_depay_init (GstRtpH263PDepay * rtph263pdepay)
|
||||
{
|
||||
rtph263pdec->srcpad =
|
||||
rtph263pdepay->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtph263pdec_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtph263pdec), rtph263pdec->srcpad);
|
||||
(&gst_rtp_h263p_depay_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtph263pdepay), rtph263pdepay->srcpad);
|
||||
|
||||
rtph263pdec->sinkpad =
|
||||
rtph263pdepay->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtph263pdec_sink_template), "sink");
|
||||
gst_pad_set_chain_function (rtph263pdec->sinkpad, gst_rtph263pdec_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtph263pdec), rtph263pdec->sinkpad);
|
||||
(&gst_rtp_h263p_depay_sink_template), "sink");
|
||||
gst_pad_set_chain_function (rtph263pdepay->sinkpad,
|
||||
gst_rtp_h263p_depay_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtph263pdepay), rtph263pdepay->sinkpad);
|
||||
|
||||
rtph263pdec->adapter = gst_adapter_new ();
|
||||
rtph263pdepay->adapter = gst_adapter_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263pdec_finalize (GObject * object)
|
||||
gst_rtp_h263p_depay_finalize (GObject * object)
|
||||
{
|
||||
GstRtpH263PDec *rtph263pdec;
|
||||
GstRtpH263PDepay *rtph263pdepay;
|
||||
|
||||
rtph263pdec = GST_RTP_H263P_DEC (object);
|
||||
rtph263pdepay = GST_RTP_H263P_DEPAY (object);
|
||||
|
||||
g_object_unref (rtph263pdec->adapter);
|
||||
rtph263pdec->adapter = NULL;
|
||||
g_object_unref (rtph263pdepay->adapter);
|
||||
rtph263pdepay->adapter = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtph263pdec_chain (GstPad * pad, GstBuffer * buf)
|
||||
gst_rtp_h263p_depay_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstRtpH263PDec *rtph263pdec;
|
||||
GstRtpH263PDepay *rtph263pdepay;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret;
|
||||
|
||||
/* GstRTPPayload pt; */
|
||||
|
||||
rtph263pdec = GST_RTP_H263P_DEC (GST_OBJECT_PARENT (pad));
|
||||
rtph263pdepay = GST_RTP_H263P_DEPAY (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (!gst_rtpbuffer_validate (buf))
|
||||
if (!gst_rtp_buffer_validate (buf))
|
||||
goto bad_packet;
|
||||
|
||||
/*
|
||||
if ((pt = gst_rtpbuffer_get_payload_type (buf)) != 0)
|
||||
if ((pt = gst_rtp_buffer_get_payload_type (buf)) != 0)
|
||||
goto bad_payload;
|
||||
*/
|
||||
|
||||
|
@ -191,12 +193,12 @@ gst_rtph263pdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
guint header_len;
|
||||
guint8 PLEN;
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
payload_len = gst_rtp_buffer_get_payload_len (buf);
|
||||
payload = gst_rtp_buffer_get_payload (buf);
|
||||
|
||||
header_len = 2;
|
||||
|
||||
M = gst_rtpbuffer_get_marker (buf);
|
||||
M = gst_rtp_buffer_get_marker (buf);
|
||||
P = (payload[0] & 0x04) == 0x04;
|
||||
V = (payload[0] & 0x02) == 0x02;
|
||||
PLEN = ((payload[0] & 0x1) << 5) | (payload[1] >> 3);
|
||||
|
@ -218,37 +220,37 @@ gst_rtph263pdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
payload += header_len;
|
||||
payload_len -= header_len;
|
||||
|
||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||
timestamp = gst_rtp_buffer_get_timestamp (buf);
|
||||
|
||||
if (M) {
|
||||
/* frame is completed: append to previous, push it out */
|
||||
guint avail;
|
||||
guint8 *data;
|
||||
|
||||
avail = gst_adapter_available (rtph263pdec->adapter);
|
||||
avail = gst_adapter_available (rtph263pdepay->adapter);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (avail + payload_len);
|
||||
|
||||
/* prepend previous data */
|
||||
if (avail > 0) {
|
||||
data = (guint8 *) gst_adapter_peek (rtph263pdec->adapter, avail);
|
||||
data = (guint8 *) gst_adapter_peek (rtph263pdepay->adapter, avail);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), data, avail);
|
||||
gst_adapter_flush (rtph263pdec->adapter, avail);
|
||||
gst_adapter_flush (rtph263pdepay->adapter, avail);
|
||||
}
|
||||
memcpy (GST_BUFFER_DATA (outbuf) + avail, payload, payload_len);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / 90000;
|
||||
gst_buffer_set_caps (outbuf,
|
||||
(GstCaps *) gst_pad_get_pad_template_caps (rtph263pdec->srcpad));
|
||||
(GstCaps *) gst_pad_get_pad_template_caps (rtph263pdepay->srcpad));
|
||||
|
||||
ret = gst_pad_push (rtph263pdec->srcpad, outbuf);
|
||||
ret = gst_pad_push (rtph263pdepay->srcpad, outbuf);
|
||||
} else {
|
||||
/* frame not completed: store in adapter */
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
|
||||
gst_adapter_push (rtph263pdec->adapter, outbuf);
|
||||
gst_adapter_push (rtph263pdepay->adapter, outbuf);
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
|
@ -276,12 +278,12 @@ bad_packet:
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtph263pdec_set_property (GObject * object, guint prop_id,
|
||||
gst_rtp_h263p_depay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpH263PDec *rtph263pdec;
|
||||
GstRtpH263PDepay *rtph263pdepay;
|
||||
|
||||
rtph263pdec = GST_RTP_H263P_DEC (object);
|
||||
rtph263pdepay = GST_RTP_H263P_DEPAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -291,12 +293,12 @@ gst_rtph263pdec_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtph263pdec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
gst_rtp_h263p_depay_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpH263PDec *rtph263pdec;
|
||||
GstRtpH263PDepay *rtph263pdepay;
|
||||
|
||||
rtph263pdec = GST_RTP_H263P_DEC (object);
|
||||
rtph263pdepay = GST_RTP_H263P_DEPAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -306,18 +308,19 @@ gst_rtph263pdec_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtph263pdec_change_state (GstElement * element, GstStateChange transition)
|
||||
gst_rtp_h263p_depay_change_state (GstElement * element,
|
||||
GstStateChange transition)
|
||||
{
|
||||
GstRtpH263PDec *rtph263pdec;
|
||||
GstRtpH263PDepay *rtph263pdepay;
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
rtph263pdec = GST_RTP_H263P_DEC (element);
|
||||
rtph263pdepay = GST_RTP_H263P_DEPAY (element);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
gst_adapter_clear (rtph263pdec->adapter);
|
||||
gst_adapter_clear (rtph263pdepay->adapter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -335,8 +338,8 @@ gst_rtph263pdec_change_state (GstElement * element, GstStateChange transition)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtph263pdec_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_h263p_depay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtph263pdec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_H263P_DEC);
|
||||
return gst_element_register (plugin, "rtph263pdepay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_H263P_DEPAY);
|
||||
}
|
||||
|
|
|
@ -17,29 +17,29 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_H263P_DEC_H__
|
||||
#define __GST_RTP_H263P_DEC_H__
|
||||
#ifndef __GST_RTP_H263P_DEPAY_H__
|
||||
#define __GST_RTP_H263P_DEPAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_H263P_DEC \
|
||||
(gst_rtph263pdec_get_type())
|
||||
#define GST_RTP_H263P_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_H263P_DEC,GstRtpH263PDec))
|
||||
#define GST_RTP_H263P_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_H263P_DEC,GstRtpH263PDec))
|
||||
#define GST_IS_RTP_H263P_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_H263P_DEC))
|
||||
#define GST_IS_RTP_H263P_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_H263P_DEC))
|
||||
#define GST_TYPE_RTP_H263P_DEPAY \
|
||||
(gst_rtp_h263p_depay_get_type())
|
||||
#define GST_RTP_H263P_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_H263P_DEPAY,GstRtpH263PDepay))
|
||||
#define GST_RTP_H263P_DEPAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_H263P_DEPAY,GstRtpH263PDepay))
|
||||
#define GST_IS_RTP_H263P_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_H263P_DEPAY))
|
||||
#define GST_IS_RTP_H263P_DEPAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_H263P_DEPAY))
|
||||
|
||||
typedef struct _GstRtpH263PDec GstRtpH263PDec;
|
||||
typedef struct _GstRtpH263PDecClass GstRtpH263PDecClass;
|
||||
typedef struct _GstRtpH263PDepay GstRtpH263PDepay;
|
||||
typedef struct _GstRtpH263PDepayClass GstRtpH263PDepayClass;
|
||||
|
||||
struct _GstRtpH263PDec
|
||||
struct _GstRtpH263PDepay
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
|
@ -51,13 +51,13 @@ struct _GstRtpH263PDec
|
|||
guint frequency;
|
||||
};
|
||||
|
||||
struct _GstRtpH263PDecClass
|
||||
struct _GstRtpH263PDepayClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtph263pdec_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_h263p_depay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_H263P_DEC_H__ */
|
||||
#endif /* __GST_RTP_H263P_DEPAY_H__ */
|
||||
|
|
|
@ -1,232 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtph263penc.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_h263penc_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes H263+ video in RTP packets (RFC 2429)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263penc_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-h263")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263penc_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
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 gboolean gst_rtph263penc_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtph263penc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
|
||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtph263penc_get_type (void)
|
||||
{
|
||||
static GType rtph263penc_type = 0;
|
||||
|
||||
if (!rtph263penc_type) {
|
||||
static const GTypeInfo rtph263penc_info = {
|
||||
sizeof (GstRtpH263PEncClass),
|
||||
(GBaseInitFunc) gst_rtph263penc_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtph263penc_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpH263PEnc),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtph263penc_init,
|
||||
};
|
||||
|
||||
rtph263penc_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpH263PEnc",
|
||||
&rtph263penc_info, 0);
|
||||
}
|
||||
return rtph263penc_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263penc_base_init (GstRtpH263PEncClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263penc_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263penc_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263penc_details);
|
||||
}
|
||||
|
||||
static void
|
||||
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);
|
||||
|
||||
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->adapter = gst_adapter_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263penc_finalize (GObject * object)
|
||||
{
|
||||
GstRtpH263PEnc *rtph263penc;
|
||||
|
||||
rtph263penc = GST_RTP_H263P_ENC (object);
|
||||
|
||||
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)
|
||||
{
|
||||
guint avail;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret;
|
||||
gboolean fragmented;
|
||||
|
||||
avail = gst_adapter_available (rtph263penc->adapter);
|
||||
if (avail == 0)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
fragmented = FALSE;
|
||||
|
||||
while (avail > 0) {
|
||||
guint towrite;
|
||||
guint8 *payload;
|
||||
guint8 *data;
|
||||
guint payload_len;
|
||||
gint header_len;
|
||||
|
||||
/* FIXME, do better mtu packing, header len etc should be
|
||||
* included in this calculation. */
|
||||
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 */
|
||||
header_len = (fragmented ? 2 : 0);
|
||||
payload_len = header_len + towrite;
|
||||
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
/* last fragment gets the marker bit set */
|
||||
gst_rtpbuffer_set_marker (outbuf, avail > towrite ? 0 : 1);
|
||||
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
|
||||
data = (guint8 *) gst_adapter_peek (rtph263penc->adapter, towrite);
|
||||
memcpy (&payload[header_len], data, towrite);
|
||||
|
||||
/* 0 1
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | RR |P|V| PLEN |PEBIT|
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
payload[0] = fragmented ? 0x00 : 0x04;
|
||||
payload[1] = 0;
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtph263penc->first_ts;
|
||||
gst_adapter_flush (rtph263penc->adapter, towrite);
|
||||
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtph263penc), outbuf);
|
||||
|
||||
avail -= towrite;
|
||||
fragmented = TRUE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtph263penc_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer)
|
||||
{
|
||||
GstRtpH263PEnc *rtph263penc;
|
||||
GstFlowReturn ret;
|
||||
guint size;
|
||||
|
||||
rtph263penc = GST_RTP_H263P_ENC (payload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
rtph263penc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
/* we always encode and flush a full picture */
|
||||
gst_adapter_push (rtph263penc->adapter, buffer);
|
||||
ret = gst_rtph263penc_flush (rtph263penc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtph263penc_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtph263penc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_H263P_ENC);
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_H263P_ENC_H__
|
||||
#define __GST_RTP_H263P_ENC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_H263P_ENC \
|
||||
(gst_rtph263penc_get_type())
|
||||
#define GST_RTP_H263P_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_H263P_ENC,GstRtpH263PEnc))
|
||||
#define GST_RTP_H263P_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_H263P_ENC,GstRtpH263PEnc))
|
||||
#define GST_IS_RTP_H263P_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_H263P_ENC))
|
||||
#define GST_IS_RTP_H263P_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_H263P_ENC))
|
||||
|
||||
typedef struct _GstRtpH263PEnc GstRtpH263PEnc;
|
||||
typedef struct _GstRtpH263PEncClass GstRtpH263PEncClass;
|
||||
|
||||
struct _GstRtpH263PEnc
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
|
||||
GstAdapter *adapter;
|
||||
GstClockTime first_ts;
|
||||
};
|
||||
|
||||
struct _GstRtpH263PEncClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtph263penc_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_H263P_ENC_H__ */
|
|
@ -20,24 +20,24 @@
|
|||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtph263penc.h"
|
||||
#include "gstrtph263ppay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_h263penc_details = {
|
||||
static GstElementDetails gst_rtp_h263ppay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes H263+ video in RTP packets (RFC 2429)",
|
||||
"Codec/Payloader/Network",
|
||||
"Payodes H263+ video in RTP packets (RFC 2429)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263penc_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_h263p_pay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/x-h263")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtph263penc_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_h263p_pay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -47,58 +47,58 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
|||
"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 void gst_rtp_h263p_pay_class_init (GstRtpH263PPayClass * klass);
|
||||
static void gst_rtp_h263p_pay_base_init (GstRtpH263PPayClass * klass);
|
||||
static void gst_rtp_h263p_pay_init (GstRtpH263PPay * rtph263ppay);
|
||||
static void gst_rtp_h263p_pay_finalize (GObject * object);
|
||||
|
||||
static gboolean gst_rtph263penc_setcaps (GstBaseRTPPayload * payload,
|
||||
static gboolean gst_rtp_h263p_pay_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtph263penc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
static GstFlowReturn gst_rtp_h263p_pay_handle_buffer (GstBaseRTPPayload *
|
||||
payload, GstBuffer * buffer);
|
||||
|
||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtph263penc_get_type (void)
|
||||
gst_rtp_h263p_pay_get_type (void)
|
||||
{
|
||||
static GType rtph263penc_type = 0;
|
||||
static GType rtph263ppay_type = 0;
|
||||
|
||||
if (!rtph263penc_type) {
|
||||
static const GTypeInfo rtph263penc_info = {
|
||||
sizeof (GstRtpH263PEncClass),
|
||||
(GBaseInitFunc) gst_rtph263penc_base_init,
|
||||
if (!rtph263ppay_type) {
|
||||
static const GTypeInfo rtph263ppay_info = {
|
||||
sizeof (GstRtpH263PPayClass),
|
||||
(GBaseInitFunc) gst_rtp_h263p_pay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtph263penc_class_init,
|
||||
(GClassInitFunc) gst_rtp_h263p_pay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpH263PEnc),
|
||||
sizeof (GstRtpH263PPay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtph263penc_init,
|
||||
(GInstanceInitFunc) gst_rtp_h263p_pay_init,
|
||||
};
|
||||
|
||||
rtph263penc_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpH263PEnc",
|
||||
&rtph263penc_info, 0);
|
||||
rtph263ppay_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpH263PPay",
|
||||
&rtph263ppay_info, 0);
|
||||
}
|
||||
return rtph263penc_type;
|
||||
return rtph263ppay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263penc_base_init (GstRtpH263PEncClass * klass)
|
||||
gst_rtp_h263p_pay_base_init (GstRtpH263PPayClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263penc_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_h263p_pay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtph263penc_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_h263p_pay_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263penc_details);
|
||||
gst_element_class_set_details (element_class, &gst_rtp_h263ppay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263penc_class_init (GstRtpH263PEncClass * klass)
|
||||
gst_rtp_h263p_pay_class_init (GstRtpH263PPayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -110,33 +110,33 @@ gst_rtph263penc_class_init (GstRtpH263PEncClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
gobject_class->finalize = gst_rtph263penc_finalize;
|
||||
gobject_class->finalize = gst_rtp_h263p_pay_finalize;
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtph263penc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtph263penc_handle_buffer;
|
||||
gstbasertppayload_class->set_caps = gst_rtp_h263p_pay_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtp_h263p_pay_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263penc_init (GstRtpH263PEnc * rtph263penc)
|
||||
gst_rtp_h263p_pay_init (GstRtpH263PPay * rtph263ppay)
|
||||
{
|
||||
rtph263penc->adapter = gst_adapter_new ();
|
||||
rtph263ppay->adapter = gst_adapter_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtph263penc_finalize (GObject * object)
|
||||
gst_rtp_h263p_pay_finalize (GObject * object)
|
||||
{
|
||||
GstRtpH263PEnc *rtph263penc;
|
||||
GstRtpH263PPay *rtph263ppay;
|
||||
|
||||
rtph263penc = GST_RTP_H263P_ENC (object);
|
||||
rtph263ppay = GST_RTP_H263P_PAY (object);
|
||||
|
||||
g_object_unref (rtph263penc->adapter);
|
||||
rtph263penc->adapter = NULL;
|
||||
g_object_unref (rtph263ppay->adapter);
|
||||
rtph263ppay->adapter = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtph263penc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
gst_rtp_h263p_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
gst_basertppayload_set_options (payload, "video", TRUE, "H263-1998", 90000);
|
||||
gst_basertppayload_set_outcaps (payload, NULL);
|
||||
|
@ -146,14 +146,14 @@ gst_rtph263penc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
|||
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
|
||||
gst_rtp_h263p_pay_flush (GstRtpH263PPay * rtph263ppay)
|
||||
{
|
||||
guint avail;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret;
|
||||
gboolean fragmented;
|
||||
|
||||
avail = gst_adapter_available (rtph263penc->adapter);
|
||||
avail = gst_adapter_available (rtph263ppay->adapter);
|
||||
if (avail == 0)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
|
@ -168,20 +168,20 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
|
|||
|
||||
/* FIXME, do better mtu packing, header len etc should be
|
||||
* included in this calculation. */
|
||||
towrite = MIN (avail, GST_BASE_RTP_PAYLOAD_MTU (rtph263penc));
|
||||
towrite = MIN (avail, GST_BASE_RTP_PAYLOAD_MTU (rtph263ppay));
|
||||
/* for fragmented frames we need 2 bytes header, for other
|
||||
* frames we must reuse the first 2 bytes of the data as the
|
||||
* header */
|
||||
header_len = (fragmented ? 2 : 0);
|
||||
payload_len = header_len + towrite;
|
||||
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
||||
/* last fragment gets the marker bit set */
|
||||
gst_rtpbuffer_set_marker (outbuf, avail > towrite ? 0 : 1);
|
||||
gst_rtp_buffer_set_marker (outbuf, avail > towrite ? 0 : 1);
|
||||
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
payload = gst_rtp_buffer_get_payload (outbuf);
|
||||
|
||||
data = (guint8 *) gst_adapter_peek (rtph263penc->adapter, towrite);
|
||||
data = (guint8 *) gst_adapter_peek (rtph263ppay->adapter, towrite);
|
||||
memcpy (&payload[header_len], data, towrite);
|
||||
|
||||
/* 0 1
|
||||
|
@ -193,10 +193,10 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
|
|||
payload[0] = fragmented ? 0x00 : 0x04;
|
||||
payload[1] = 0;
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtph263penc->first_ts;
|
||||
gst_adapter_flush (rtph263penc->adapter, towrite);
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtph263ppay->first_ts;
|
||||
gst_adapter_flush (rtph263ppay->adapter, towrite);
|
||||
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtph263penc), outbuf);
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtph263ppay), outbuf);
|
||||
|
||||
avail -= towrite;
|
||||
fragmented = TRUE;
|
||||
|
@ -206,27 +206,28 @@ gst_rtph263penc_flush (GstRtpH263PEnc * rtph263penc)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtph263penc_handle_buffer (GstBaseRTPPayload * payload, GstBuffer * buffer)
|
||||
gst_rtp_h263p_pay_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpH263PEnc *rtph263penc;
|
||||
GstRtpH263PPay *rtph263ppay;
|
||||
GstFlowReturn ret;
|
||||
guint size;
|
||||
|
||||
rtph263penc = GST_RTP_H263P_ENC (payload);
|
||||
rtph263ppay = GST_RTP_H263P_PAY (payload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
rtph263penc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtph263ppay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
/* we always encode and flush a full picture */
|
||||
gst_adapter_push (rtph263penc->adapter, buffer);
|
||||
ret = gst_rtph263penc_flush (rtph263penc);
|
||||
gst_adapter_push (rtph263ppay->adapter, buffer);
|
||||
ret = gst_rtp_h263p_pay_flush (rtph263ppay);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtph263penc_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_h263p_pay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtph263penc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_H263P_ENC);
|
||||
return gst_element_register (plugin, "rtph263ppay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_H263P_PAY);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_H263P_ENC_H__
|
||||
#define __GST_RTP_H263P_ENC_H__
|
||||
#ifndef __GST_RTP_H263P_PAY_H__
|
||||
#define __GST_RTP_H263P_PAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
|
@ -26,21 +26,21 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_H263P_ENC \
|
||||
(gst_rtph263penc_get_type())
|
||||
#define GST_RTP_H263P_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_H263P_ENC,GstRtpH263PEnc))
|
||||
#define GST_RTP_H263P_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_H263P_ENC,GstRtpH263PEnc))
|
||||
#define GST_IS_RTP_H263P_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_H263P_ENC))
|
||||
#define GST_IS_RTP_H263P_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_H263P_ENC))
|
||||
#define GST_TYPE_RTP_H263P_PAY \
|
||||
(gst_rtp_h263p_pay_get_type())
|
||||
#define GST_RTP_H263P_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_H263P_PAY,GstRtpH263PPay))
|
||||
#define GST_RTP_H263P_PAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_H263P_PAY,GstRtpH263PPay))
|
||||
#define GST_IS_RTP_H263P_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_H263P_PAY))
|
||||
#define GST_IS_RTP_H263P_PAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_H263P_PAY))
|
||||
|
||||
typedef struct _GstRtpH263PEnc GstRtpH263PEnc;
|
||||
typedef struct _GstRtpH263PEncClass GstRtpH263PEncClass;
|
||||
typedef struct _GstRtpH263PPay GstRtpH263PPay;
|
||||
typedef struct _GstRtpH263PPayClass GstRtpH263PPayClass;
|
||||
|
||||
struct _GstRtpH263PEnc
|
||||
struct _GstRtpH263PPay
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
|
||||
|
@ -48,13 +48,13 @@ struct _GstRtpH263PEnc
|
|||
GstClockTime first_ts;
|
||||
};
|
||||
|
||||
struct _GstRtpH263PEncClass
|
||||
struct _GstRtpH263PPayClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtph263penc_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_h263p_pay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_H263P_ENC_H__ */
|
||||
#endif /* __GST_RTP_H263P_PAY_H__ */
|
||||
|
|
|
@ -1,330 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "gstrtpmp4vdec.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_mp4vdec_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts MPEG4 video from RTP packets (RFC 3016)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
/* RtpMP4VDec signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_FREQUENCY
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmp4vdec_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/mpeg,"
|
||||
"mpegversion=(int) 4," "systemstream=(boolean)false")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmp4vdec_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
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
|
||||
*
|
||||
* "profile-level-id=[1,MAX]"
|
||||
* "config="
|
||||
*/
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
static void gst_rtpmp4vdec_class_init (GstRtpMP4VDecClass * klass);
|
||||
static void gst_rtpmp4vdec_base_init (GstRtpMP4VDecClass * klass);
|
||||
static void gst_rtpmp4vdec_init (GstRtpMP4VDec * rtpmp4vdec);
|
||||
|
||||
static gboolean gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpmp4vdec_chain (GstPad * pad, GstBuffer * buffer);
|
||||
|
||||
static void gst_rtpmp4vdec_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpmp4vdec_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtpmp4vdec_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpmp4vdec_get_type (void)
|
||||
{
|
||||
static GType rtpmp4vdec_type = 0;
|
||||
|
||||
if (!rtpmp4vdec_type) {
|
||||
static const GTypeInfo rtpmp4vdec_info = {
|
||||
sizeof (GstRtpMP4VDecClass),
|
||||
(GBaseInitFunc) gst_rtpmp4vdec_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpmp4vdec_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpMP4VDec),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpmp4vdec_init,
|
||||
};
|
||||
|
||||
rtpmp4vdec_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMP4VDec",
|
||||
&rtpmp4vdec_info, 0);
|
||||
}
|
||||
return rtpmp4vdec_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4vdec_base_init (GstRtpMP4VDecClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmp4vdec_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmp4vdec_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mp4vdec_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4vdec_class_init (GstRtpMP4VDecClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_rtpmp4vdec_set_property;
|
||||
gobject_class->get_property = gst_rtpmp4vdec_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtpmp4vdec_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4vdec_init (GstRtpMP4VDec * rtpmp4vdec)
|
||||
{
|
||||
rtpmp4vdec->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpmp4vdec_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmp4vdec), rtpmp4vdec->srcpad);
|
||||
|
||||
rtpmp4vdec->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpmp4vdec_sink_template), "sink");
|
||||
gst_pad_set_setcaps_function (rtpmp4vdec->sinkpad, gst_rtpmp4vdec_setcaps);
|
||||
gst_pad_set_chain_function (rtpmp4vdec->sinkpad, gst_rtpmp4vdec_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmp4vdec), rtpmp4vdec->sinkpad);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
GstRtpMP4VDec *rtpmp4vdec;
|
||||
GstCaps *srccaps;
|
||||
const gchar *str;
|
||||
|
||||
rtpmp4vdec = GST_RTP_MP4V_DEC (GST_OBJECT_PARENT (pad));
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
if (!gst_structure_get_int (structure, "clock-rate", &rtpmp4vdec->rate))
|
||||
rtpmp4vdec->rate = 90000;
|
||||
|
||||
srccaps = gst_caps_new_simple ("video/mpeg",
|
||||
"mpegversion", G_TYPE_INT, 4,
|
||||
"systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
|
||||
gst_pad_set_caps (rtpmp4vdec->srcpad, srccaps);
|
||||
gst_caps_unref (srccaps);
|
||||
|
||||
if ((str = gst_structure_get_string (structure, "config"))) {
|
||||
GValue v = { 0 };
|
||||
|
||||
g_value_init (&v, GST_TYPE_BUFFER);
|
||||
if (gst_value_deserialize (&v, str)) {
|
||||
GstBuffer *buffer;
|
||||
|
||||
buffer = gst_value_get_buffer (&v);
|
||||
gst_buffer_ref (buffer);
|
||||
g_value_unset (&v);
|
||||
|
||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (rtpmp4vdec->srcpad));
|
||||
|
||||
gst_pad_push (rtpmp4vdec->srcpad, buffer);
|
||||
} else {
|
||||
g_warning ("cannot convert config to buffer");
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpmp4vdec_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstRtpMP4VDec *rtpmp4vdec;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret;
|
||||
|
||||
rtpmp4vdec = GST_RTP_MP4V_DEC (gst_pad_get_parent (pad));
|
||||
|
||||
if (!gst_rtpbuffer_validate (buf))
|
||||
goto bad_packet;
|
||||
|
||||
{
|
||||
gint payload_len;
|
||||
guint8 *payload;
|
||||
guint32 timestamp;
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
|
||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
|
||||
gst_adapter_push (rtpmp4vdec->adapter, outbuf);
|
||||
|
||||
/* if this was the last packet of the VOP, create and push a buffer */
|
||||
if (gst_rtpbuffer_get_marker (buf)) {
|
||||
guint avail;
|
||||
|
||||
avail = gst_adapter_available (rtpmp4vdec->adapter);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (avail);
|
||||
GST_BUFFER_MALLOCDATA (outbuf) =
|
||||
gst_adapter_take (rtpmp4vdec->adapter, avail);
|
||||
GST_BUFFER_DATA (outbuf) = GST_BUFFER_MALLOCDATA (outbuf);
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpmp4vdec->srcpad));
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpmp4vdec->rate;
|
||||
|
||||
GST_DEBUG ("gst_rtpmp4vdec_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
ret = gst_pad_push (rtpmp4vdec->srcpad, outbuf);
|
||||
} else {
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
gst_buffer_unref (buf);
|
||||
}
|
||||
gst_object_unref (rtpmp4vdec);
|
||||
|
||||
return ret;
|
||||
bad_packet:
|
||||
{
|
||||
GST_DEBUG ("Packet did not validate");
|
||||
gst_buffer_unref (buf);
|
||||
gst_object_unref (rtpmp4vdec);
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4vdec_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpMP4VDec *rtpmp4vdec;
|
||||
|
||||
rtpmp4vdec = GST_RTP_MP4V_DEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4vdec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRtpMP4VDec *rtpmp4vdec;
|
||||
|
||||
rtpmp4vdec = GST_RTP_MP4V_DEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpmp4vdec_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstRtpMP4VDec *rtpmp4vdec;
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
rtpmp4vdec = GST_RTP_MP4V_DEC (element);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
rtpmp4vdec->adapter = gst_adapter_new ();
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
gst_adapter_clear (rtpmp4vdec->adapter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
g_object_unref (rtpmp4vdec->adapter);
|
||||
rtpmp4vdec->adapter = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpmp4vdec_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpmp4vdec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MP4V_DEC);
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_MP4V_DEC_H__
|
||||
#define __GST_RTP_MP4V_DEC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_MP4V_DEC \
|
||||
(gst_rtpmp4vdec_get_type())
|
||||
#define GST_RTP_MP4V_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MP4V_DEC,GstRtpMP4VDec))
|
||||
#define GST_RTP_MP4V_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MP4V_DEC,GstRtpMP4VDec))
|
||||
#define GST_IS_RTP_MP4V_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MP4V_DEC))
|
||||
#define GST_IS_RTP_MP4V_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MP4V_DEC))
|
||||
|
||||
typedef struct _GstRtpMP4VDec GstRtpMP4VDec;
|
||||
typedef struct _GstRtpMP4VDecClass GstRtpMP4VDecClass;
|
||||
|
||||
struct _GstRtpMP4VDec
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
GstAdapter *adapter;
|
||||
|
||||
gint rate;
|
||||
};
|
||||
|
||||
struct _GstRtpMP4VDecClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpmp4vdec_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_MP4V_DEC_H__ */
|
|
@ -19,17 +19,17 @@
|
|||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "gstrtpmp4vdec.h"
|
||||
#include "gstrtpmp4vdepay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_mp4vdec_details = {
|
||||
static GstElementDetails gst_rtp_mp4vdepay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts MPEG4 video from RTP packets (RFC 3016)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
/* RtpMP4VDec signals and args */
|
||||
/* RtpMP4VDepay signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
|
@ -42,7 +42,7 @@ enum
|
|||
ARG_FREQUENCY
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmp4vdec_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_mp4v_depay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -50,7 +50,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
|||
"mpegversion=(int) 4," "systemstream=(boolean)false")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmp4vdec_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_mp4v_depay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -67,63 +67,64 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
);
|
||||
|
||||
|
||||
static void gst_rtpmp4vdec_class_init (GstRtpMP4VDecClass * klass);
|
||||
static void gst_rtpmp4vdec_base_init (GstRtpMP4VDecClass * klass);
|
||||
static void gst_rtpmp4vdec_init (GstRtpMP4VDec * rtpmp4vdec);
|
||||
static void gst_rtp_mp4v_depay_class_init (GstRtpMP4VDepayClass * klass);
|
||||
static void gst_rtp_mp4v_depay_base_init (GstRtpMP4VDepayClass * klass);
|
||||
static void gst_rtp_mp4v_depay_init (GstRtpMP4VDepay * rtpmp4vdepay);
|
||||
|
||||
static gboolean gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpmp4vdec_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static gboolean gst_rtp_mp4v_depay_setcaps (GstPad * pad, GstCaps * caps);
|
||||
static GstFlowReturn gst_rtp_mp4v_depay_chain (GstPad * pad,
|
||||
GstBuffer * buffer);
|
||||
|
||||
static void gst_rtpmp4vdec_set_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_mp4v_depay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpmp4vdec_get_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_mp4v_depay_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtpmp4vdec_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
static GstStateChangeReturn gst_rtp_mp4v_depay_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpmp4vdec_get_type (void)
|
||||
gst_rtp_mp4v_depay_get_type (void)
|
||||
{
|
||||
static GType rtpmp4vdec_type = 0;
|
||||
static GType rtpmp4vdepay_type = 0;
|
||||
|
||||
if (!rtpmp4vdec_type) {
|
||||
static const GTypeInfo rtpmp4vdec_info = {
|
||||
sizeof (GstRtpMP4VDecClass),
|
||||
(GBaseInitFunc) gst_rtpmp4vdec_base_init,
|
||||
if (!rtpmp4vdepay_type) {
|
||||
static const GTypeInfo rtpmp4vdepay_info = {
|
||||
sizeof (GstRtpMP4VDepayClass),
|
||||
(GBaseInitFunc) gst_rtp_mp4v_depay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpmp4vdec_class_init,
|
||||
(GClassInitFunc) gst_rtp_mp4v_depay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpMP4VDec),
|
||||
sizeof (GstRtpMP4VDepay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpmp4vdec_init,
|
||||
(GInstanceInitFunc) gst_rtp_mp4v_depay_init,
|
||||
};
|
||||
|
||||
rtpmp4vdec_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMP4VDec",
|
||||
&rtpmp4vdec_info, 0);
|
||||
rtpmp4vdepay_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMP4VDepay",
|
||||
&rtpmp4vdepay_info, 0);
|
||||
}
|
||||
return rtpmp4vdec_type;
|
||||
return rtpmp4vdepay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4vdec_base_init (GstRtpMP4VDecClass * klass)
|
||||
gst_rtp_mp4v_depay_base_init (GstRtpMP4VDepayClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmp4vdec_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_mp4v_depay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmp4vdec_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_mp4v_depay_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mp4vdec_details);
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mp4vdepay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4vdec_class_init (GstRtpMP4VDecClass * klass)
|
||||
gst_rtp_mp4v_depay_class_init (GstRtpMP4VDepayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -133,47 +134,48 @@ gst_rtpmp4vdec_class_init (GstRtpMP4VDecClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_rtpmp4vdec_set_property;
|
||||
gobject_class->get_property = gst_rtpmp4vdec_get_property;
|
||||
gobject_class->set_property = gst_rtp_mp4v_depay_set_property;
|
||||
gobject_class->get_property = gst_rtp_mp4v_depay_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtpmp4vdec_change_state;
|
||||
gstelement_class->change_state = gst_rtp_mp4v_depay_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4vdec_init (GstRtpMP4VDec * rtpmp4vdec)
|
||||
gst_rtp_mp4v_depay_init (GstRtpMP4VDepay * rtpmp4vdepay)
|
||||
{
|
||||
rtpmp4vdec->srcpad =
|
||||
rtpmp4vdepay->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpmp4vdec_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmp4vdec), rtpmp4vdec->srcpad);
|
||||
(&gst_rtp_mp4v_depay_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmp4vdepay), rtpmp4vdepay->srcpad);
|
||||
|
||||
rtpmp4vdec->sinkpad =
|
||||
rtpmp4vdepay->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpmp4vdec_sink_template), "sink");
|
||||
gst_pad_set_setcaps_function (rtpmp4vdec->sinkpad, gst_rtpmp4vdec_setcaps);
|
||||
gst_pad_set_chain_function (rtpmp4vdec->sinkpad, gst_rtpmp4vdec_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmp4vdec), rtpmp4vdec->sinkpad);
|
||||
(&gst_rtp_mp4v_depay_sink_template), "sink");
|
||||
gst_pad_set_setcaps_function (rtpmp4vdepay->sinkpad,
|
||||
gst_rtp_mp4v_depay_setcaps);
|
||||
gst_pad_set_chain_function (rtpmp4vdepay->sinkpad, gst_rtp_mp4v_depay_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmp4vdepay), rtpmp4vdepay->sinkpad);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps)
|
||||
gst_rtp_mp4v_depay_setcaps (GstPad * pad, GstCaps * caps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
GstRtpMP4VDec *rtpmp4vdec;
|
||||
GstRtpMP4VDepay *rtpmp4vdepay;
|
||||
GstCaps *srccaps;
|
||||
const gchar *str;
|
||||
|
||||
rtpmp4vdec = GST_RTP_MP4V_DEC (GST_OBJECT_PARENT (pad));
|
||||
rtpmp4vdepay = GST_RTP_MP4V_DEPAY (GST_OBJECT_PARENT (pad));
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
if (!gst_structure_get_int (structure, "clock-rate", &rtpmp4vdec->rate))
|
||||
rtpmp4vdec->rate = 90000;
|
||||
if (!gst_structure_get_int (structure, "clock-rate", &rtpmp4vdepay->rate))
|
||||
rtpmp4vdepay->rate = 90000;
|
||||
|
||||
srccaps = gst_caps_new_simple ("video/mpeg",
|
||||
"mpegversion", G_TYPE_INT, 4,
|
||||
"systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
|
||||
gst_pad_set_caps (rtpmp4vdec->srcpad, srccaps);
|
||||
gst_pad_set_caps (rtpmp4vdepay->srcpad, srccaps);
|
||||
gst_caps_unref (srccaps);
|
||||
|
||||
if ((str = gst_structure_get_string (structure, "config"))) {
|
||||
|
@ -187,9 +189,9 @@ gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps)
|
|||
gst_buffer_ref (buffer);
|
||||
g_value_unset (&v);
|
||||
|
||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (rtpmp4vdec->srcpad));
|
||||
gst_buffer_set_caps (buffer, GST_PAD_CAPS (rtpmp4vdepay->srcpad));
|
||||
|
||||
gst_pad_push (rtpmp4vdec->srcpad, buffer);
|
||||
gst_pad_push (rtpmp4vdepay->srcpad, buffer);
|
||||
} else {
|
||||
g_warning ("cannot convert config to buffer");
|
||||
}
|
||||
|
@ -199,15 +201,15 @@ gst_rtpmp4vdec_setcaps (GstPad * pad, GstCaps * caps)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpmp4vdec_chain (GstPad * pad, GstBuffer * buf)
|
||||
gst_rtp_mp4v_depay_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstRtpMP4VDec *rtpmp4vdec;
|
||||
GstRtpMP4VDepay *rtpmp4vdepay;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret;
|
||||
|
||||
rtpmp4vdec = GST_RTP_MP4V_DEC (gst_pad_get_parent (pad));
|
||||
rtpmp4vdepay = GST_RTP_MP4V_DEPAY (gst_pad_get_parent (pad));
|
||||
|
||||
if (!gst_rtpbuffer_validate (buf))
|
||||
if (!gst_rtp_buffer_validate (buf))
|
||||
goto bad_packet;
|
||||
|
||||
{
|
||||
|
@ -215,58 +217,59 @@ gst_rtpmp4vdec_chain (GstPad * pad, GstBuffer * buf)
|
|||
guint8 *payload;
|
||||
guint32 timestamp;
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
payload_len = gst_rtp_buffer_get_payload_len (buf);
|
||||
payload = gst_rtp_buffer_get_payload (buf);
|
||||
|
||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||
timestamp = gst_rtp_buffer_get_timestamp (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
|
||||
gst_adapter_push (rtpmp4vdec->adapter, outbuf);
|
||||
gst_adapter_push (rtpmp4vdepay->adapter, outbuf);
|
||||
|
||||
/* if this was the last packet of the VOP, create and push a buffer */
|
||||
if (gst_rtpbuffer_get_marker (buf)) {
|
||||
if (gst_rtp_buffer_get_marker (buf)) {
|
||||
guint avail;
|
||||
|
||||
avail = gst_adapter_available (rtpmp4vdec->adapter);
|
||||
avail = gst_adapter_available (rtpmp4vdepay->adapter);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (avail);
|
||||
GST_BUFFER_MALLOCDATA (outbuf) =
|
||||
gst_adapter_take (rtpmp4vdec->adapter, avail);
|
||||
gst_adapter_take (rtpmp4vdepay->adapter, avail);
|
||||
GST_BUFFER_DATA (outbuf) = GST_BUFFER_MALLOCDATA (outbuf);
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpmp4vdec->srcpad));
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / rtpmp4vdec->rate;
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (rtpmp4vdepay->srcpad));
|
||||
GST_BUFFER_TIMESTAMP (outbuf) =
|
||||
timestamp * GST_SECOND / rtpmp4vdepay->rate;
|
||||
|
||||
GST_DEBUG ("gst_rtpmp4vdec_chain: pushing buffer of size %d",
|
||||
GST_DEBUG ("gst_rtp_mp4v_depay_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
ret = gst_pad_push (rtpmp4vdec->srcpad, outbuf);
|
||||
ret = gst_pad_push (rtpmp4vdepay->srcpad, outbuf);
|
||||
} else {
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
gst_buffer_unref (buf);
|
||||
}
|
||||
gst_object_unref (rtpmp4vdec);
|
||||
gst_object_unref (rtpmp4vdepay);
|
||||
|
||||
return ret;
|
||||
bad_packet:
|
||||
{
|
||||
GST_DEBUG ("Packet did not validate");
|
||||
gst_buffer_unref (buf);
|
||||
gst_object_unref (rtpmp4vdec);
|
||||
gst_object_unref (rtpmp4vdepay);
|
||||
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4vdec_set_property (GObject * object, guint prop_id,
|
||||
gst_rtp_mp4v_depay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpMP4VDec *rtpmp4vdec;
|
||||
GstRtpMP4VDepay *rtpmp4vdepay;
|
||||
|
||||
rtpmp4vdec = GST_RTP_MP4V_DEC (object);
|
||||
rtpmp4vdepay = GST_RTP_MP4V_DEPAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -276,12 +279,12 @@ gst_rtpmp4vdec_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4vdec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
gst_rtp_mp4v_depay_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpMP4VDec *rtpmp4vdec;
|
||||
GstRtpMP4VDepay *rtpmp4vdepay;
|
||||
|
||||
rtpmp4vdec = GST_RTP_MP4V_DEC (object);
|
||||
rtpmp4vdepay = GST_RTP_MP4V_DEPAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -291,19 +294,20 @@ gst_rtpmp4vdec_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpmp4vdec_change_state (GstElement * element, GstStateChange transition)
|
||||
gst_rtp_mp4v_depay_change_state (GstElement * element,
|
||||
GstStateChange transition)
|
||||
{
|
||||
GstRtpMP4VDec *rtpmp4vdec;
|
||||
GstRtpMP4VDepay *rtpmp4vdepay;
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
rtpmp4vdec = GST_RTP_MP4V_DEC (element);
|
||||
rtpmp4vdepay = GST_RTP_MP4V_DEPAY (element);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
rtpmp4vdec->adapter = gst_adapter_new ();
|
||||
rtpmp4vdepay->adapter = gst_adapter_new ();
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
gst_adapter_clear (rtpmp4vdec->adapter);
|
||||
gst_adapter_clear (rtpmp4vdepay->adapter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -313,8 +317,8 @@ gst_rtpmp4vdec_change_state (GstElement * element, GstStateChange transition)
|
|||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
g_object_unref (rtpmp4vdec->adapter);
|
||||
rtpmp4vdec->adapter = NULL;
|
||||
g_object_unref (rtpmp4vdepay->adapter);
|
||||
rtpmp4vdepay->adapter = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -323,8 +327,8 @@ gst_rtpmp4vdec_change_state (GstElement * element, GstStateChange transition)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpmp4vdec_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_mp4v_depay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpmp4vdec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MP4V_DEC);
|
||||
return gst_element_register (plugin, "rtpmp4vdepay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MP4V_DEPAY);
|
||||
}
|
||||
|
|
|
@ -17,29 +17,29 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_MP4V_DEC_H__
|
||||
#define __GST_RTP_MP4V_DEC_H__
|
||||
#ifndef __GST_RTP_MP4V_DEPAY_H__
|
||||
#define __GST_RTP_MP4V_DEPAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_MP4V_DEC \
|
||||
(gst_rtpmp4vdec_get_type())
|
||||
#define GST_RTP_MP4V_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MP4V_DEC,GstRtpMP4VDec))
|
||||
#define GST_RTP_MP4V_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MP4V_DEC,GstRtpMP4VDec))
|
||||
#define GST_IS_RTP_MP4V_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MP4V_DEC))
|
||||
#define GST_IS_RTP_MP4V_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MP4V_DEC))
|
||||
#define GST_TYPE_RTP_MP4V_DEPAY \
|
||||
(gst_rtp_mp4v_depay_get_type())
|
||||
#define GST_RTP_MP4V_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MP4V_DEPAY,GstRtpMP4VDepay))
|
||||
#define GST_RTP_MP4V_DEPAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MP4V_DEPAY,GstRtpMP4VDepay))
|
||||
#define GST_IS_RTP_MP4V_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MP4V_DEPAY))
|
||||
#define GST_IS_RTP_MP4V_DEPAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MP4V_DEPAY))
|
||||
|
||||
typedef struct _GstRtpMP4VDec GstRtpMP4VDec;
|
||||
typedef struct _GstRtpMP4VDecClass GstRtpMP4VDecClass;
|
||||
typedef struct _GstRtpMP4VDepay GstRtpMP4VDepay;
|
||||
typedef struct _GstRtpMP4VDepayClass GstRtpMP4VDepayClass;
|
||||
|
||||
struct _GstRtpMP4VDec
|
||||
struct _GstRtpMP4VDepay
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
|
@ -51,13 +51,13 @@ struct _GstRtpMP4VDec
|
|||
gint rate;
|
||||
};
|
||||
|
||||
struct _GstRtpMP4VDecClass
|
||||
struct _GstRtpMP4VDepayClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpmp4vdec_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_mp4v_depay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_MP4V_DEC_H__ */
|
||||
#endif /* __GST_RTP_MP4V_DEPAY_H__ */
|
||||
|
|
|
@ -1,449 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpmp4venc.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_mp4venc_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encode MPEG4 video as RTP packets (RFC 3016)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmp4venc_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("video/mpeg,"
|
||||
"mpegversion=(int) 4," "systemstream=(boolean)false")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmp4venc_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp, "
|
||||
"media = (string) \"video\", "
|
||||
"payload = (int) [ 96, 255 ], "
|
||||
"clock-rate = (int) [1, MAX ], " "encoding-name = (string) \"MP4V-ES\""
|
||||
/* two string params
|
||||
*
|
||||
"profile-level-id = (string) [1,MAX]"
|
||||
"config = (string) [1,MAX]"
|
||||
*/
|
||||
)
|
||||
);
|
||||
|
||||
#define DEFAULT_SEND_CONFIG FALSE
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_SEND_CONFIG
|
||||
};
|
||||
|
||||
|
||||
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 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 gboolean gst_rtpmp4venc_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpmp4venc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
|
||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpmp4venc_get_type (void)
|
||||
{
|
||||
static GType rtpmp4venc_type = 0;
|
||||
|
||||
if (!rtpmp4venc_type) {
|
||||
static const GTypeInfo rtpmp4venc_info = {
|
||||
sizeof (GstRtpMP4VEncClass),
|
||||
(GBaseInitFunc) gst_rtpmp4venc_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpmp4venc_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpMP4VEnc),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpmp4venc_init,
|
||||
};
|
||||
|
||||
rtpmp4venc_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpMP4VEnc",
|
||||
&rtpmp4venc_info, 0);
|
||||
}
|
||||
return rtpmp4venc_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4venc_base_init (GstRtpMP4VEncClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmp4venc_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmp4venc_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mp4venc_details);
|
||||
}
|
||||
|
||||
static void
|
||||
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_BASE_RTP_PAYLOAD);
|
||||
|
||||
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), ARG_SEND_CONFIG,
|
||||
g_param_spec_boolean ("send-config", "Send Config",
|
||||
"Send the config parameters in RTP packets as well",
|
||||
DEFAULT_SEND_CONFIG, G_PARAM_READWRITE));
|
||||
|
||||
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->adapter = gst_adapter_new ();
|
||||
rtpmp4venc->rate = 90000;
|
||||
rtpmp4venc->profile = 1;
|
||||
rtpmp4venc->send_config = DEFAULT_SEND_CONFIG;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4venc_finalize (GObject * object)
|
||||
{
|
||||
GstRtpMP4VEnc *rtpmp4venc;
|
||||
|
||||
rtpmp4venc = GST_RTP_MP4V_ENC (object);
|
||||
|
||||
g_object_unref (rtpmp4venc->adapter);
|
||||
rtpmp4venc->adapter = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4venc_new_caps (GstRtpMP4VEnc * rtpmp4venc)
|
||||
{
|
||||
gchar *profile, *config;
|
||||
GValue v = { 0 };
|
||||
|
||||
profile = g_strdup_printf ("%d", rtpmp4venc->profile);
|
||||
g_value_init (&v, GST_TYPE_BUFFER);
|
||||
gst_value_set_buffer (&v, rtpmp4venc->config);
|
||||
config = gst_value_serialize (&v);
|
||||
|
||||
gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4venc),
|
||||
"profile-level-id", G_TYPE_STRING, profile,
|
||||
"config", G_TYPE_STRING, config, NULL);
|
||||
|
||||
g_value_unset (&v);
|
||||
|
||||
g_free (profile);
|
||||
g_free (config);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
|
||||
{
|
||||
guint avail;
|
||||
GstBuffer *outbuf;
|
||||
GstFlowReturn ret;
|
||||
|
||||
/* the data available in the adapter is either smaller
|
||||
* than the MTU or bigger. In the case it is smaller, the complete
|
||||
* adapter contents can be put in one packet. In the case the
|
||||
* adapter has more than one MTU, we need to split the MP4V data
|
||||
* over multiple packets. */
|
||||
avail = gst_adapter_available (rtpmp4venc->adapter);
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
|
||||
while (avail > 0) {
|
||||
guint towrite;
|
||||
guint8 *payload;
|
||||
guint8 *data;
|
||||
guint payload_len;
|
||||
guint packet_len;
|
||||
|
||||
/* this will be the total lenght of the packet */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (avail, 0, 0);
|
||||
|
||||
/* fill one MTU or all available bytes */
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
|
||||
gst_rtpbuffer_set_marker (outbuf, avail == 0);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtpmp4venc->first_ts;
|
||||
|
||||
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,
|
||||
gint * strip)
|
||||
{
|
||||
guint32 code;
|
||||
gboolean result;
|
||||
|
||||
*strip = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
*strip = i;
|
||||
/* we need to flush out the current packet. */
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
case VOP_STARTCODE:
|
||||
/* VOP startcode, we don't have to flush the packet */
|
||||
result = FALSE;
|
||||
break;
|
||||
default:
|
||||
/* all other startcodes need a flush */
|
||||
result = TRUE;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* we expect buffers starting on startcodes.
|
||||
*/
|
||||
static GstFlowReturn
|
||||
gst_rtpmp4venc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpMP4VEnc *rtpmp4venc;
|
||||
GstFlowReturn ret;
|
||||
guint size, avail;
|
||||
guint packet_len;
|
||||
guint8 *data;
|
||||
gboolean flush;
|
||||
gint strip;
|
||||
GstClockTime duration;
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
|
||||
rtpmp4venc = GST_RTP_MP4V_ENC (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
data = GST_BUFFER_DATA (buffer);
|
||||
duration = GST_BUFFER_DURATION (buffer);
|
||||
avail = gst_adapter_available (rtpmp4venc->adapter);
|
||||
|
||||
/* empty buffer, take timestamp */
|
||||
if (avail == 0) {
|
||||
rtpmp4venc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmp4venc->duration = 0;
|
||||
}
|
||||
|
||||
/* parse incomming data and see if we need to start a new RTP
|
||||
* packet */
|
||||
flush = gst_rtpmp4venc_parse_data (rtpmp4venc, data, size, &strip);
|
||||
if (strip) {
|
||||
/* strip off config if requested */
|
||||
if (!rtpmp4venc->send_config) {
|
||||
GstBuffer *subbuf;
|
||||
|
||||
/* strip off header */
|
||||
subbuf = gst_buffer_create_sub (buffer, strip, size - strip);
|
||||
GST_BUFFER_TIMESTAMP (subbuf) = GST_BUFFER_TIMESTAMP (buffer);
|
||||
gst_buffer_unref (buffer);
|
||||
buffer = subbuf;
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
data = GST_BUFFER_DATA (buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* if we need to flush, do so now */
|
||||
if (flush) {
|
||||
ret = gst_rtpmp4venc_flush (rtpmp4venc);
|
||||
rtpmp4venc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmp4venc->duration = 0;
|
||||
avail = 0;
|
||||
}
|
||||
|
||||
/* get packet length of data and see if we exceeded MTU. */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (avail + size, 0, 0);
|
||||
|
||||
if (gst_basertppayload_is_filled (basepayload,
|
||||
packet_len, rtpmp4venc->duration + duration)) {
|
||||
ret = gst_rtpmp4venc_flush (rtpmp4venc);
|
||||
rtpmp4venc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmp4venc->duration = 0;
|
||||
}
|
||||
|
||||
/* push new data */
|
||||
gst_adapter_push (rtpmp4venc->adapter, buffer);
|
||||
rtpmp4venc->duration += duration;
|
||||
|
||||
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 ARG_SEND_CONFIG:
|
||||
rtpmp4venc->send_config = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
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 ARG_SEND_CONFIG:
|
||||
g_value_set_boolean (value, rtpmp4venc->send_config);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpmp4venc_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpmp4venc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MP4V_ENC);
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_MP4V_ENC_H__
|
||||
#define __GST_RTP_MP4V_ENC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_MP4V_ENC \
|
||||
(gst_rtpmp4venc_get_type())
|
||||
#define GST_RTP_MP4V_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MP4V_ENC,GstRtpMP4VEnc))
|
||||
#define GST_RTP_MP4V_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MP4V_ENC,GstRtpMP4VEnc))
|
||||
#define GST_IS_RTP_MP4V_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MP4V_ENC))
|
||||
#define GST_IS_RTP_MP4V_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MP4V_ENC))
|
||||
|
||||
typedef struct _GstRtpMP4VEnc GstRtpMP4VEnc;
|
||||
typedef struct _GstRtpMP4VEncClass GstRtpMP4VEncClass;
|
||||
|
||||
struct _GstRtpMP4VEnc
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
|
||||
GstAdapter *adapter;
|
||||
GstClockTime first_ts;
|
||||
GstClockTime duration;
|
||||
|
||||
gint rate;
|
||||
gint profile;
|
||||
GstBuffer *config;
|
||||
gboolean send_config;
|
||||
};
|
||||
|
||||
struct _GstRtpMP4VEncClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpmp4venc_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_MP4V_ENC_H__ */
|
|
@ -20,17 +20,17 @@
|
|||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpmp4venc.h"
|
||||
#include "gstrtpmp4vpay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_mp4venc_details = {
|
||||
static GstElementDetails gst_rtp_mp4vpay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encode MPEG4 video as RTP packets (RFC 3016)",
|
||||
"Codec/Payloader/Network",
|
||||
"Payode MPEG4 video as RTP packets (RFC 3016)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmp4venc_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_mp4v_pay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -38,7 +38,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
"mpegversion=(int) 4," "systemstream=(boolean)false")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmp4venc_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_mp4v_pay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -63,63 +63,63 @@ enum
|
|||
};
|
||||
|
||||
|
||||
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 void gst_rtp_mp4v_pay_class_init (GstRtpMP4VPayClass * klass);
|
||||
static void gst_rtp_mp4v_pay_base_init (GstRtpMP4VPayClass * klass);
|
||||
static void gst_rtp_mp4v_pay_init (GstRtpMP4VPay * rtpmp4vpay);
|
||||
static void gst_rtp_mp4v_pay_finalize (GObject * object);
|
||||
|
||||
static void gst_rtpmp4venc_set_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_mp4v_pay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpmp4venc_get_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_mp4v_pay_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean gst_rtpmp4venc_setcaps (GstBaseRTPPayload * payload,
|
||||
static gboolean gst_rtp_mp4v_pay_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpmp4venc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
static GstFlowReturn gst_rtp_mp4v_pay_handle_buffer (GstBaseRTPPayload *
|
||||
payload, GstBuffer * buffer);
|
||||
|
||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpmp4venc_get_type (void)
|
||||
gst_rtp_mp4v_pay_get_type (void)
|
||||
{
|
||||
static GType rtpmp4venc_type = 0;
|
||||
static GType rtpmp4vpay_type = 0;
|
||||
|
||||
if (!rtpmp4venc_type) {
|
||||
static const GTypeInfo rtpmp4venc_info = {
|
||||
sizeof (GstRtpMP4VEncClass),
|
||||
(GBaseInitFunc) gst_rtpmp4venc_base_init,
|
||||
if (!rtpmp4vpay_type) {
|
||||
static const GTypeInfo rtpmp4vpay_info = {
|
||||
sizeof (GstRtpMP4VPayClass),
|
||||
(GBaseInitFunc) gst_rtp_mp4v_pay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpmp4venc_class_init,
|
||||
(GClassInitFunc) gst_rtp_mp4v_pay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpMP4VEnc),
|
||||
sizeof (GstRtpMP4VPay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpmp4venc_init,
|
||||
(GInstanceInitFunc) gst_rtp_mp4v_pay_init,
|
||||
};
|
||||
|
||||
rtpmp4venc_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpMP4VEnc",
|
||||
&rtpmp4venc_info, 0);
|
||||
rtpmp4vpay_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpMP4VPay",
|
||||
&rtpmp4vpay_info, 0);
|
||||
}
|
||||
return rtpmp4venc_type;
|
||||
return rtpmp4vpay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4venc_base_init (GstRtpMP4VEncClass * klass)
|
||||
gst_rtp_mp4v_pay_base_init (GstRtpMP4VPayClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmp4venc_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_mp4v_pay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmp4venc_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_mp4v_pay_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mp4venc_details);
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mp4vpay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4venc_class_init (GstRtpMP4VEncClass * klass)
|
||||
gst_rtp_mp4v_pay_class_init (GstRtpMP4VPayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -131,54 +131,54 @@ gst_rtpmp4venc_class_init (GstRtpMP4VEncClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
gobject_class->set_property = gst_rtpmp4venc_set_property;
|
||||
gobject_class->get_property = gst_rtpmp4venc_get_property;
|
||||
gobject_class->set_property = gst_rtp_mp4v_pay_set_property;
|
||||
gobject_class->get_property = gst_rtp_mp4v_pay_get_property;
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SEND_CONFIG,
|
||||
g_param_spec_boolean ("send-config", "Send Config",
|
||||
"Send the config parameters in RTP packets as well",
|
||||
DEFAULT_SEND_CONFIG, G_PARAM_READWRITE));
|
||||
|
||||
gobject_class->finalize = gst_rtpmp4venc_finalize;
|
||||
gobject_class->finalize = gst_rtp_mp4v_pay_finalize;
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpmp4venc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpmp4venc_handle_buffer;
|
||||
gstbasertppayload_class->set_caps = gst_rtp_mp4v_pay_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtp_mp4v_pay_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4venc_init (GstRtpMP4VEnc * rtpmp4venc)
|
||||
gst_rtp_mp4v_pay_init (GstRtpMP4VPay * rtpmp4vpay)
|
||||
{
|
||||
rtpmp4venc->adapter = gst_adapter_new ();
|
||||
rtpmp4venc->rate = 90000;
|
||||
rtpmp4venc->profile = 1;
|
||||
rtpmp4venc->send_config = DEFAULT_SEND_CONFIG;
|
||||
rtpmp4vpay->adapter = gst_adapter_new ();
|
||||
rtpmp4vpay->rate = 90000;
|
||||
rtpmp4vpay->profile = 1;
|
||||
rtpmp4vpay->send_config = DEFAULT_SEND_CONFIG;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4venc_finalize (GObject * object)
|
||||
gst_rtp_mp4v_pay_finalize (GObject * object)
|
||||
{
|
||||
GstRtpMP4VEnc *rtpmp4venc;
|
||||
GstRtpMP4VPay *rtpmp4vpay;
|
||||
|
||||
rtpmp4venc = GST_RTP_MP4V_ENC (object);
|
||||
rtpmp4vpay = GST_RTP_MP4V_PAY (object);
|
||||
|
||||
g_object_unref (rtpmp4venc->adapter);
|
||||
rtpmp4venc->adapter = NULL;
|
||||
g_object_unref (rtpmp4vpay->adapter);
|
||||
rtpmp4vpay->adapter = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4venc_new_caps (GstRtpMP4VEnc * rtpmp4venc)
|
||||
gst_rtp_mp4v_pay_new_caps (GstRtpMP4VPay * rtpmp4vpay)
|
||||
{
|
||||
gchar *profile, *config;
|
||||
GValue v = { 0 };
|
||||
|
||||
profile = g_strdup_printf ("%d", rtpmp4venc->profile);
|
||||
profile = g_strdup_printf ("%d", rtpmp4vpay->profile);
|
||||
g_value_init (&v, GST_TYPE_BUFFER);
|
||||
gst_value_set_buffer (&v, rtpmp4venc->config);
|
||||
gst_value_set_buffer (&v, rtpmp4vpay->config);
|
||||
config = gst_value_serialize (&v);
|
||||
|
||||
gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4venc),
|
||||
gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4vpay),
|
||||
"profile-level-id", G_TYPE_STRING, profile,
|
||||
"config", G_TYPE_STRING, config, NULL);
|
||||
|
||||
|
@ -189,20 +189,20 @@ gst_rtpmp4venc_new_caps (GstRtpMP4VEnc * rtpmp4venc)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpmp4venc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
gst_rtp_mp4v_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
GstRtpMP4VEnc *rtpmp4venc;
|
||||
GstRtpMP4VPay *rtpmp4vpay;
|
||||
|
||||
rtpmp4venc = GST_RTP_MP4V_ENC (payload);
|
||||
rtpmp4vpay = GST_RTP_MP4V_PAY (payload);
|
||||
|
||||
gst_basertppayload_set_options (payload, "video", TRUE, "MP4V-ES",
|
||||
rtpmp4venc->rate);
|
||||
rtpmp4vpay->rate);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
|
||||
gst_rtp_mp4v_pay_flush (GstRtpMP4VPay * rtpmp4vpay)
|
||||
{
|
||||
guint avail;
|
||||
GstBuffer *outbuf;
|
||||
|
@ -213,7 +213,7 @@ gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
|
|||
* adapter contents can be put in one packet. In the case the
|
||||
* adapter has more than one MTU, we need to split the MP4V data
|
||||
* over multiple packets. */
|
||||
avail = gst_adapter_available (rtpmp4venc->adapter);
|
||||
avail = gst_adapter_available (rtpmp4vpay->adapter);
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
|
||||
|
@ -225,31 +225,31 @@ gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
|
|||
guint packet_len;
|
||||
|
||||
/* this will be the total lenght of the packet */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (avail, 0, 0);
|
||||
packet_len = gst_rtp_buffer_calc_packet_len (avail, 0, 0);
|
||||
|
||||
/* fill one MTU or all available bytes */
|
||||
towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpmp4venc));
|
||||
towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpmp4vpay));
|
||||
|
||||
/* this is the payload length */
|
||||
payload_len = gst_rtpbuffer_calc_payload_len (towrite, 0, 0);
|
||||
payload_len = gst_rtp_buffer_calc_payload_len (towrite, 0, 0);
|
||||
|
||||
/* create buffer to hold the payload */
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
||||
|
||||
/* copy payload */
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
data = (guint8 *) gst_adapter_peek (rtpmp4venc->adapter, payload_len);
|
||||
payload = gst_rtp_buffer_get_payload (outbuf);
|
||||
data = (guint8 *) gst_adapter_peek (rtpmp4vpay->adapter, payload_len);
|
||||
memcpy (payload, data, payload_len);
|
||||
|
||||
gst_adapter_flush (rtpmp4venc->adapter, payload_len);
|
||||
gst_adapter_flush (rtpmp4vpay->adapter, payload_len);
|
||||
|
||||
avail -= payload_len;
|
||||
|
||||
gst_rtpbuffer_set_marker (outbuf, avail == 0);
|
||||
gst_rtp_buffer_set_marker (outbuf, avail == 0);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtpmp4venc->first_ts;
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtpmp4vpay->first_ts;
|
||||
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmp4venc), outbuf);
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmp4vpay), outbuf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -263,7 +263,7 @@ gst_rtpmp4venc_flush (GstRtpMP4VEnc * rtpmp4venc)
|
|||
#define VOP_STARTCODE 0x000001B6
|
||||
|
||||
static gboolean
|
||||
gst_rtpmp4venc_parse_data (GstRtpMP4VEnc * enc, guint8 * data, guint size,
|
||||
gst_rtp_mp4v_pay_parse_data (GstRtpMP4VPay * enc, guint8 * data, guint size,
|
||||
gint * strip)
|
||||
{
|
||||
guint32 code;
|
||||
|
@ -314,7 +314,7 @@ gst_rtpmp4venc_parse_data (GstRtpMP4VEnc * enc, guint8 * data, guint size,
|
|||
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);
|
||||
gst_rtp_mp4v_pay_new_caps (enc);
|
||||
}
|
||||
*strip = i;
|
||||
/* we need to flush out the current packet. */
|
||||
|
@ -336,10 +336,10 @@ gst_rtpmp4venc_parse_data (GstRtpMP4VEnc * enc, guint8 * data, guint size,
|
|||
/* we expect buffers starting on startcodes.
|
||||
*/
|
||||
static GstFlowReturn
|
||||
gst_rtpmp4venc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
gst_rtp_mp4v_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpMP4VEnc *rtpmp4venc;
|
||||
GstRtpMP4VPay *rtpmp4vpay;
|
||||
GstFlowReturn ret;
|
||||
guint size, avail;
|
||||
guint packet_len;
|
||||
|
@ -350,25 +350,25 @@ gst_rtpmp4venc_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
|
||||
ret = GST_FLOW_OK;
|
||||
|
||||
rtpmp4venc = GST_RTP_MP4V_ENC (basepayload);
|
||||
rtpmp4vpay = GST_RTP_MP4V_PAY (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
data = GST_BUFFER_DATA (buffer);
|
||||
duration = GST_BUFFER_DURATION (buffer);
|
||||
avail = gst_adapter_available (rtpmp4venc->adapter);
|
||||
avail = gst_adapter_available (rtpmp4vpay->adapter);
|
||||
|
||||
/* empty buffer, take timestamp */
|
||||
if (avail == 0) {
|
||||
rtpmp4venc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmp4venc->duration = 0;
|
||||
rtpmp4vpay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmp4vpay->duration = 0;
|
||||
}
|
||||
|
||||
/* parse incomming data and see if we need to start a new RTP
|
||||
* packet */
|
||||
flush = gst_rtpmp4venc_parse_data (rtpmp4venc, data, size, &strip);
|
||||
flush = gst_rtp_mp4v_pay_parse_data (rtpmp4vpay, data, size, &strip);
|
||||
if (strip) {
|
||||
/* strip off config if requested */
|
||||
if (!rtpmp4venc->send_config) {
|
||||
if (!rtpmp4vpay->send_config) {
|
||||
GstBuffer *subbuf;
|
||||
|
||||
/* strip off header */
|
||||
|
@ -384,40 +384,40 @@ gst_rtpmp4venc_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
|
||||
/* if we need to flush, do so now */
|
||||
if (flush) {
|
||||
ret = gst_rtpmp4venc_flush (rtpmp4venc);
|
||||
rtpmp4venc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmp4venc->duration = 0;
|
||||
ret = gst_rtp_mp4v_pay_flush (rtpmp4vpay);
|
||||
rtpmp4vpay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmp4vpay->duration = 0;
|
||||
avail = 0;
|
||||
}
|
||||
|
||||
/* get packet length of data and see if we exceeded MTU. */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (avail + size, 0, 0);
|
||||
packet_len = gst_rtp_buffer_calc_packet_len (avail + size, 0, 0);
|
||||
|
||||
if (gst_basertppayload_is_filled (basepayload,
|
||||
packet_len, rtpmp4venc->duration + duration)) {
|
||||
ret = gst_rtpmp4venc_flush (rtpmp4venc);
|
||||
rtpmp4venc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmp4venc->duration = 0;
|
||||
packet_len, rtpmp4vpay->duration + duration)) {
|
||||
ret = gst_rtp_mp4v_pay_flush (rtpmp4vpay);
|
||||
rtpmp4vpay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmp4vpay->duration = 0;
|
||||
}
|
||||
|
||||
/* push new data */
|
||||
gst_adapter_push (rtpmp4venc->adapter, buffer);
|
||||
rtpmp4venc->duration += duration;
|
||||
gst_adapter_push (rtpmp4vpay->adapter, buffer);
|
||||
rtpmp4vpay->duration += duration;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4venc_set_property (GObject * object, guint prop_id,
|
||||
gst_rtp_mp4v_pay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpMP4VEnc *rtpmp4venc;
|
||||
GstRtpMP4VPay *rtpmp4vpay;
|
||||
|
||||
rtpmp4venc = GST_RTP_MP4V_ENC (object);
|
||||
rtpmp4vpay = GST_RTP_MP4V_PAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SEND_CONFIG:
|
||||
rtpmp4venc->send_config = g_value_get_boolean (value);
|
||||
rtpmp4vpay->send_config = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -425,16 +425,16 @@ gst_rtpmp4venc_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpmp4venc_get_property (GObject * object, guint prop_id,
|
||||
gst_rtp_mp4v_pay_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpMP4VEnc *rtpmp4venc;
|
||||
GstRtpMP4VPay *rtpmp4vpay;
|
||||
|
||||
rtpmp4venc = GST_RTP_MP4V_ENC (object);
|
||||
rtpmp4vpay = GST_RTP_MP4V_PAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SEND_CONFIG:
|
||||
g_value_set_boolean (value, rtpmp4venc->send_config);
|
||||
g_value_set_boolean (value, rtpmp4vpay->send_config);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -442,8 +442,8 @@ gst_rtpmp4venc_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpmp4venc_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_mp4v_pay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpmp4venc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MP4V_ENC);
|
||||
return gst_element_register (plugin, "rtpmp4vpay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MP4V_PAY);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_MP4V_ENC_H__
|
||||
#define __GST_RTP_MP4V_ENC_H__
|
||||
#ifndef __GST_RTP_MP4V_PAY_H__
|
||||
#define __GST_RTP_MP4V_PAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
|
@ -26,21 +26,21 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_MP4V_ENC \
|
||||
(gst_rtpmp4venc_get_type())
|
||||
#define GST_RTP_MP4V_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MP4V_ENC,GstRtpMP4VEnc))
|
||||
#define GST_RTP_MP4V_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MP4V_ENC,GstRtpMP4VEnc))
|
||||
#define GST_IS_RTP_MP4V_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MP4V_ENC))
|
||||
#define GST_IS_RTP_MP4V_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MP4V_ENC))
|
||||
#define GST_TYPE_RTP_MP4V_PAY \
|
||||
(gst_rtp_mp4v_pay_get_type())
|
||||
#define GST_RTP_MP4V_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MP4V_PAY,GstRtpMP4VPay))
|
||||
#define GST_RTP_MP4V_PAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MP4V_PAY,GstRtpMP4VPay))
|
||||
#define GST_IS_RTP_MP4V_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MP4V_PAY))
|
||||
#define GST_IS_RTP_MP4V_PAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MP4V_PAY))
|
||||
|
||||
typedef struct _GstRtpMP4VEnc GstRtpMP4VEnc;
|
||||
typedef struct _GstRtpMP4VEncClass GstRtpMP4VEncClass;
|
||||
typedef struct _GstRtpMP4VPay GstRtpMP4VPay;
|
||||
typedef struct _GstRtpMP4VPayClass GstRtpMP4VPayClass;
|
||||
|
||||
struct _GstRtpMP4VEnc
|
||||
struct _GstRtpMP4VPay
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
|
||||
|
@ -54,13 +54,13 @@ struct _GstRtpMP4VEnc
|
|||
gboolean send_config;
|
||||
};
|
||||
|
||||
struct _GstRtpMP4VEncClass
|
||||
struct _GstRtpMP4VPayClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpmp4venc_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_mp4v_pay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_MP4V_ENC_H__ */
|
||||
#endif /* __GST_RTP_MP4V_PAY_H__ */
|
||||
|
|
|
@ -1,283 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "gstrtpmpadec.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_mpadec_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts MPEG audio from RTP packets (RFC 2038)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
/* RtpMPADec signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
ARG_FREQUENCY
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmpadec_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/mpeg")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmpadec_sink_template =
|
||||
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) 90000, " "encoding-name = (string) \"MPA\"")
|
||||
);
|
||||
|
||||
|
||||
static void gst_rtpmpadec_class_init (GstRtpMPADecClass * klass);
|
||||
static void gst_rtpmpadec_base_init (GstRtpMPADecClass * klass);
|
||||
static void gst_rtpmpadec_init (GstRtpMPADec * rtpmpadec);
|
||||
|
||||
static GstFlowReturn gst_rtpmpadec_chain (GstPad * pad, GstBuffer * buffer);
|
||||
|
||||
static void gst_rtpmpadec_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpmpadec_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtpmpadec_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpmpadec_get_type (void)
|
||||
{
|
||||
static GType rtpmpadec_type = 0;
|
||||
|
||||
if (!rtpmpadec_type) {
|
||||
static const GTypeInfo rtpmpadec_info = {
|
||||
sizeof (GstRtpMPADecClass),
|
||||
(GBaseInitFunc) gst_rtpmpadec_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpmpadec_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpMPADec),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpmpadec_init,
|
||||
};
|
||||
|
||||
rtpmpadec_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMPADec",
|
||||
&rtpmpadec_info, 0);
|
||||
}
|
||||
return rtpmpadec_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpadec_base_init (GstRtpMPADecClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmpadec_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmpadec_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mpadec_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpadec_class_init (GstRtpMPADecClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_rtpmpadec_set_property;
|
||||
gobject_class->get_property = gst_rtpmpadec_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtpmpadec_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpadec_init (GstRtpMPADec * rtpmpadec)
|
||||
{
|
||||
rtpmpadec->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpmpadec_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmpadec), rtpmpadec->srcpad);
|
||||
|
||||
rtpmpadec->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpmpadec_sink_template), "sink");
|
||||
gst_pad_set_chain_function (rtpmpadec->sinkpad, gst_rtpmpadec_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmpadec), rtpmpadec->sinkpad);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpmpadec_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstRtpMPADec *rtpmpadec;
|
||||
GstBuffer *outbuf;
|
||||
guint8 pt;
|
||||
GstFlowReturn ret;
|
||||
|
||||
rtpmpadec = GST_RTP_MPA_DEC (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (!gst_rtpbuffer_validate (buf))
|
||||
goto bad_packet;
|
||||
|
||||
if ((pt = gst_rtpbuffer_get_payload_type (buf)) != GST_RTP_PAYLOAD_MPA)
|
||||
goto bad_payload;
|
||||
|
||||
|
||||
{
|
||||
gint payload_len;
|
||||
guint8 *payload;
|
||||
guint16 frag_offset;
|
||||
guint32 timestamp;
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
|
||||
frag_offset = (payload[2] << 8) | payload[3];
|
||||
|
||||
/* strip off header
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | MBZ | Frag_offset |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
payload_len -= 4;
|
||||
payload += 4;
|
||||
|
||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
|
||||
//GST_BUFFER_TIMESTAMP (outbuf) = timestamp * GST_SECOND / 90000;
|
||||
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
|
||||
GST_DEBUG ("gst_rtpmpadec_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
gst_buffer_unref (buf);
|
||||
|
||||
/* FIXME, we can push half mpeg frames when they are split over multiple
|
||||
* RTP packets */
|
||||
ret = gst_pad_push (rtpmpadec->srcpad, outbuf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
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
|
||||
gst_rtpmpadec_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpMPADec *rtpmpadec;
|
||||
|
||||
rtpmpadec = GST_RTP_MPA_DEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpadec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRtpMPADec *rtpmpadec;
|
||||
|
||||
rtpmpadec = GST_RTP_MPA_DEC (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpmpadec_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstRtpMPADec *rtpmpadec;
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
rtpmpadec = GST_RTP_MPA_DEC (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_rtpmpadec_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpmpadec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MPA_DEC);
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_MPA_DEC_H__
|
||||
#define __GST_RTP_MPA_DEC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_MPA_DEC \
|
||||
(gst_rtpmpadec_get_type())
|
||||
#define GST_RTP_MPA_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MPA_DEC,GstRtpMPADec))
|
||||
#define GST_RTP_MPA_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MPA_DEC,GstRtpMPADec))
|
||||
#define GST_IS_RTP_MPA_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MPA_DEC))
|
||||
#define GST_IS_RTP_MPA_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MPA_DEC))
|
||||
|
||||
typedef struct _GstRtpMPADec GstRtpMPADec;
|
||||
typedef struct _GstRtpMPADecClass GstRtpMPADecClass;
|
||||
|
||||
struct _GstRtpMPADec
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
guint frequency;
|
||||
};
|
||||
|
||||
struct _GstRtpMPADecClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpmpadec_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_MPA_DEC_H__ */
|
|
@ -19,17 +19,17 @@
|
|||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "gstrtpmpadec.h"
|
||||
#include "gstrtpmpadepay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_mpadec_details = {
|
||||
static GstElementDetails gst_rtp_mpadepay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts MPEG audio from RTP packets (RFC 2038)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
/* RtpMPADec signals and args */
|
||||
/* RtpMPADepay signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
|
@ -42,14 +42,14 @@ enum
|
|||
ARG_FREQUENCY
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmpadec_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_mpa_depay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/mpeg")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmpadec_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_mpa_depay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -60,62 +60,62 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
);
|
||||
|
||||
|
||||
static void gst_rtpmpadec_class_init (GstRtpMPADecClass * klass);
|
||||
static void gst_rtpmpadec_base_init (GstRtpMPADecClass * klass);
|
||||
static void gst_rtpmpadec_init (GstRtpMPADec * rtpmpadec);
|
||||
static void gst_rtp_mpa_depay_class_init (GstRtpMPADepayClass * klass);
|
||||
static void gst_rtp_mpa_depay_base_init (GstRtpMPADepayClass * klass);
|
||||
static void gst_rtp_mpa_depay_init (GstRtpMPADepay * rtpmpadepay);
|
||||
|
||||
static GstFlowReturn gst_rtpmpadec_chain (GstPad * pad, GstBuffer * buffer);
|
||||
static GstFlowReturn gst_rtp_mpa_depay_chain (GstPad * pad, GstBuffer * buffer);
|
||||
|
||||
static void gst_rtpmpadec_set_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_mpa_depay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_rtpmpadec_get_property (GObject * object, guint prop_id,
|
||||
static void gst_rtp_mpa_depay_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstStateChangeReturn gst_rtpmpadec_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
static GstStateChangeReturn gst_rtp_mpa_depay_change_state (GstElement *
|
||||
element, GstStateChange transition);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpmpadec_get_type (void)
|
||||
gst_rtp_mpa_depay_get_type (void)
|
||||
{
|
||||
static GType rtpmpadec_type = 0;
|
||||
static GType rtpmpadepay_type = 0;
|
||||
|
||||
if (!rtpmpadec_type) {
|
||||
static const GTypeInfo rtpmpadec_info = {
|
||||
sizeof (GstRtpMPADecClass),
|
||||
(GBaseInitFunc) gst_rtpmpadec_base_init,
|
||||
if (!rtpmpadepay_type) {
|
||||
static const GTypeInfo rtpmpadepay_info = {
|
||||
sizeof (GstRtpMPADepayClass),
|
||||
(GBaseInitFunc) gst_rtp_mpa_depay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpmpadec_class_init,
|
||||
(GClassInitFunc) gst_rtp_mpa_depay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpMPADec),
|
||||
sizeof (GstRtpMPADepay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpmpadec_init,
|
||||
(GInstanceInitFunc) gst_rtp_mpa_depay_init,
|
||||
};
|
||||
|
||||
rtpmpadec_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMPADec",
|
||||
&rtpmpadec_info, 0);
|
||||
rtpmpadepay_type =
|
||||
g_type_register_static (GST_TYPE_ELEMENT, "GstRtpMPADepay",
|
||||
&rtpmpadepay_info, 0);
|
||||
}
|
||||
return rtpmpadec_type;
|
||||
return rtpmpadepay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpadec_base_init (GstRtpMPADecClass * klass)
|
||||
gst_rtp_mpa_depay_base_init (GstRtpMPADepayClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmpadec_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_mpa_depay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmpadec_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_mpa_depay_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mpadec_details);
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mpadepay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpadec_class_init (GstRtpMPADecClass * klass)
|
||||
gst_rtp_mpa_depay_class_init (GstRtpMPADepayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -125,41 +125,41 @@ gst_rtpmpadec_class_init (GstRtpMPADecClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
|
||||
|
||||
gobject_class->set_property = gst_rtpmpadec_set_property;
|
||||
gobject_class->get_property = gst_rtpmpadec_get_property;
|
||||
gobject_class->set_property = gst_rtp_mpa_depay_set_property;
|
||||
gobject_class->get_property = gst_rtp_mpa_depay_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_rtpmpadec_change_state;
|
||||
gstelement_class->change_state = gst_rtp_mpa_depay_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpadec_init (GstRtpMPADec * rtpmpadec)
|
||||
gst_rtp_mpa_depay_init (GstRtpMPADepay * rtpmpadepay)
|
||||
{
|
||||
rtpmpadec->srcpad =
|
||||
rtpmpadepay->srcpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpmpadec_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmpadec), rtpmpadec->srcpad);
|
||||
(&gst_rtp_mpa_depay_src_template), "src");
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmpadepay), rtpmpadepay->srcpad);
|
||||
|
||||
rtpmpadec->sinkpad =
|
||||
rtpmpadepay->sinkpad =
|
||||
gst_pad_new_from_template (gst_static_pad_template_get
|
||||
(&gst_rtpmpadec_sink_template), "sink");
|
||||
gst_pad_set_chain_function (rtpmpadec->sinkpad, gst_rtpmpadec_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmpadec), rtpmpadec->sinkpad);
|
||||
(&gst_rtp_mpa_depay_sink_template), "sink");
|
||||
gst_pad_set_chain_function (rtpmpadepay->sinkpad, gst_rtp_mpa_depay_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (rtpmpadepay), rtpmpadepay->sinkpad);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpmpadec_chain (GstPad * pad, GstBuffer * buf)
|
||||
gst_rtp_mpa_depay_chain (GstPad * pad, GstBuffer * buf)
|
||||
{
|
||||
GstRtpMPADec *rtpmpadec;
|
||||
GstRtpMPADepay *rtpmpadepay;
|
||||
GstBuffer *outbuf;
|
||||
guint8 pt;
|
||||
GstFlowReturn ret;
|
||||
|
||||
rtpmpadec = GST_RTP_MPA_DEC (GST_OBJECT_PARENT (pad));
|
||||
rtpmpadepay = GST_RTP_MPA_DEPAY (GST_OBJECT_PARENT (pad));
|
||||
|
||||
if (!gst_rtpbuffer_validate (buf))
|
||||
if (!gst_rtp_buffer_validate (buf))
|
||||
goto bad_packet;
|
||||
|
||||
if ((pt = gst_rtpbuffer_get_payload_type (buf)) != GST_RTP_PAYLOAD_MPA)
|
||||
if ((pt = gst_rtp_buffer_get_payload_type (buf)) != GST_RTP_PAYLOAD_MPA)
|
||||
goto bad_payload;
|
||||
|
||||
|
||||
|
@ -169,8 +169,8 @@ gst_rtpmpadec_chain (GstPad * pad, GstBuffer * buf)
|
|||
guint16 frag_offset;
|
||||
guint32 timestamp;
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
payload_len = gst_rtp_buffer_get_payload_len (buf);
|
||||
payload = gst_rtp_buffer_get_payload (buf);
|
||||
|
||||
frag_offset = (payload[2] << 8) | payload[3];
|
||||
|
||||
|
@ -185,7 +185,7 @@ gst_rtpmpadec_chain (GstPad * pad, GstBuffer * buf)
|
|||
payload_len -= 4;
|
||||
payload += 4;
|
||||
|
||||
timestamp = gst_rtpbuffer_get_timestamp (buf);
|
||||
timestamp = gst_rtp_buffer_get_timestamp (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
|
||||
|
@ -193,14 +193,14 @@ gst_rtpmpadec_chain (GstPad * pad, GstBuffer * buf)
|
|||
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
|
||||
GST_DEBUG ("gst_rtpmpadec_chain: pushing buffer of size %d",
|
||||
GST_DEBUG ("gst_rtp_mpa_depay_chain: pushing buffer of size %d",
|
||||
GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
gst_buffer_unref (buf);
|
||||
|
||||
/* FIXME, we can push half mpeg frames when they are split over multiple
|
||||
* RTP packets */
|
||||
ret = gst_pad_push (rtpmpadec->srcpad, outbuf);
|
||||
ret = gst_pad_push (rtpmpadepay->srcpad, outbuf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -220,12 +220,12 @@ bad_payload:
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpadec_set_property (GObject * object, guint prop_id,
|
||||
gst_rtp_mpa_depay_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstRtpMPADec *rtpmpadec;
|
||||
GstRtpMPADepay *rtpmpadepay;
|
||||
|
||||
rtpmpadec = GST_RTP_MPA_DEC (object);
|
||||
rtpmpadepay = GST_RTP_MPA_DEPAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -235,12 +235,12 @@ gst_rtpmpadec_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpadec_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
gst_rtp_mpa_depay_get_property (GObject * object, guint prop_id, GValue * value,
|
||||
GParamSpec * pspec)
|
||||
{
|
||||
GstRtpMPADec *rtpmpadec;
|
||||
GstRtpMPADepay *rtpmpadepay;
|
||||
|
||||
rtpmpadec = GST_RTP_MPA_DEC (object);
|
||||
rtpmpadepay = GST_RTP_MPA_DEPAY (object);
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
|
@ -250,12 +250,12 @@ gst_rtpmpadec_get_property (GObject * object, guint prop_id, GValue * value,
|
|||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_rtpmpadec_change_state (GstElement * element, GstStateChange transition)
|
||||
gst_rtp_mpa_depay_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
GstRtpMPADec *rtpmpadec;
|
||||
GstRtpMPADepay *rtpmpadepay;
|
||||
GstStateChangeReturn ret;
|
||||
|
||||
rtpmpadec = GST_RTP_MPA_DEC (element);
|
||||
rtpmpadepay = GST_RTP_MPA_DEPAY (element);
|
||||
|
||||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
|
@ -276,8 +276,8 @@ gst_rtpmpadec_change_state (GstElement * element, GstStateChange transition)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpmpadec_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_mpa_depay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpmpadec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MPA_DEC);
|
||||
return gst_element_register (plugin, "rtpmpadepay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MPA_DEPAY);
|
||||
}
|
||||
|
|
|
@ -17,28 +17,28 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_MPA_DEC_H__
|
||||
#define __GST_RTP_MPA_DEC_H__
|
||||
#ifndef __GST_RTP_MPA_DEPAY_H__
|
||||
#define __GST_RTP_MPA_DEPAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_MPA_DEC \
|
||||
(gst_rtpmpadec_get_type())
|
||||
#define GST_RTP_MPA_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MPA_DEC,GstRtpMPADec))
|
||||
#define GST_RTP_MPA_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MPA_DEC,GstRtpMPADec))
|
||||
#define GST_IS_RTP_MPA_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MPA_DEC))
|
||||
#define GST_IS_RTP_MPA_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MPA_DEC))
|
||||
#define GST_TYPE_RTP_MPA_DEPAY \
|
||||
(gst_rtp_mpa_depay_get_type())
|
||||
#define GST_RTP_MPA_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MPA_DEPAY,GstRtpMPADepay))
|
||||
#define GST_RTP_MPA_DEPAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MPA_DEPAY,GstRtpMPADepay))
|
||||
#define GST_IS_RTP_MPA_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MPA_DEPAY))
|
||||
#define GST_IS_RTP_MPA_DEPAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MPA_DEPAY))
|
||||
|
||||
typedef struct _GstRtpMPADec GstRtpMPADec;
|
||||
typedef struct _GstRtpMPADecClass GstRtpMPADecClass;
|
||||
typedef struct _GstRtpMPADepay GstRtpMPADepay;
|
||||
typedef struct _GstRtpMPADepayClass GstRtpMPADepayClass;
|
||||
|
||||
struct _GstRtpMPADec
|
||||
struct _GstRtpMPADepay
|
||||
{
|
||||
GstElement element;
|
||||
|
||||
|
@ -48,13 +48,13 @@ struct _GstRtpMPADec
|
|||
guint frequency;
|
||||
};
|
||||
|
||||
struct _GstRtpMPADecClass
|
||||
struct _GstRtpMPADepayClass
|
||||
{
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpmpadec_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_mpa_depay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_MPA_DEC_H__ */
|
||||
#endif /* __GST_RTP_MPA_DEPAY_H__ */
|
||||
|
|
|
@ -1,268 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpmpaenc.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_mpaenc_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encode MPEG audio as RTP packets (RFC 2038)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmpaenc_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/mpeg")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmpaenc_src_template =
|
||||
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) 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 gboolean gst_rtpmpaenc_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpmpaenc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
|
||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpmpaenc_get_type (void)
|
||||
{
|
||||
static GType rtpmpaenc_type = 0;
|
||||
|
||||
if (!rtpmpaenc_type) {
|
||||
static const GTypeInfo rtpmpaenc_info = {
|
||||
sizeof (GstRtpMPAEncClass),
|
||||
(GBaseInitFunc) gst_rtpmpaenc_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpmpaenc_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpMPAEnc),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpmpaenc_init,
|
||||
};
|
||||
|
||||
rtpmpaenc_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpMPAEnc",
|
||||
&rtpmpaenc_info, 0);
|
||||
}
|
||||
return rtpmpaenc_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpaenc_base_init (GstRtpMPAEncClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmpaenc_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmpaenc_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mpaenc_details);
|
||||
}
|
||||
|
||||
static void
|
||||
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_BASE_RTP_PAYLOAD);
|
||||
|
||||
gobject_class->finalize = gst_rtpmpaenc_finalize;
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpmpaenc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpmpaenc_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpaenc_init (GstRtpMPAEnc * rtpmpaenc)
|
||||
{
|
||||
rtpmpaenc->adapter = gst_adapter_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpaenc_finalize (GObject * object)
|
||||
{
|
||||
GstRtpMPAEnc *rtpmpaenc;
|
||||
|
||||
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
|
||||
gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
|
||||
{
|
||||
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
|
||||
* adapter contents can be put in one packet. In the case the
|
||||
* adapter has more than one MTU, we need to split the MPA data
|
||||
* over multiple packets. The frag_offset in each packet header
|
||||
* needs to be updated with the position in the MPA frame. */
|
||||
avail = gst_adapter_available (rtpmpaenc->adapter);
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
|
||||
frag_offset = 0;
|
||||
while (avail > 0) {
|
||||
guint towrite;
|
||||
guint8 *payload;
|
||||
guint8 *data;
|
||||
guint payload_len;
|
||||
guint packet_len;
|
||||
|
||||
/* this will be the total lenght of the packet */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (4 + avail, 0, 0);
|
||||
|
||||
/* fill one MTU or all available bytes */
|
||||
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);
|
||||
|
||||
/* create buffer to hold the payload */
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
|
||||
payload_len -= 4;
|
||||
|
||||
gst_rtpbuffer_set_payload_type (outbuf, GST_RTP_PAYLOAD_MPA);
|
||||
|
||||
/*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | MBZ | Frag_offset |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
payload[0] = 0;
|
||||
payload[1] = 0;
|
||||
payload[2] = frag_offset >> 8;
|
||||
payload[3] = frag_offset & 0xff;
|
||||
|
||||
data = (guint8 *) gst_adapter_peek (rtpmpaenc->adapter, payload_len);
|
||||
memcpy (&payload[4], data, payload_len);
|
||||
gst_adapter_flush (rtpmpaenc->adapter, payload_len);
|
||||
|
||||
avail -= payload_len;
|
||||
frag_offset += payload_len;
|
||||
|
||||
if (avail == 0)
|
||||
gst_rtpbuffer_set_marker (outbuf, TRUE);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtpmpaenc->first_ts;
|
||||
GST_BUFFER_DURATION (outbuf) = rtpmpaenc->duration;
|
||||
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmpaenc), outbuf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpmpaenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpMPAEnc *rtpmpaenc;
|
||||
GstFlowReturn ret;
|
||||
guint size, avail;
|
||||
guint packet_len;
|
||||
GstClockTime duration;
|
||||
|
||||
rtpmpaenc = GST_RTP_MPA_ENC (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
duration = GST_BUFFER_DURATION (buffer);
|
||||
|
||||
avail = gst_adapter_available (rtpmpaenc->adapter);
|
||||
if (avail == 0) {
|
||||
rtpmpaenc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmpaenc->duration = 0;
|
||||
}
|
||||
|
||||
/* get packet length of previous data and this new data,
|
||||
* payload length includes a 4 byte header */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (4 + avail + size, 0, 0);
|
||||
|
||||
/* if this buffer is going to overflow the packet, flush what we
|
||||
* have. */
|
||||
if (gst_basertppayload_is_filled (basepayload,
|
||||
packet_len, rtpmpaenc->duration + duration)) {
|
||||
ret = gst_rtpmpaenc_flush (rtpmpaenc);
|
||||
rtpmpaenc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmpaenc->duration = 0;
|
||||
} else {
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
|
||||
gst_adapter_push (rtpmpaenc->adapter, buffer);
|
||||
rtpmpaenc->duration += duration;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpmpaenc_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpmpaenc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MPA_ENC);
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/* Gnome-Streamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_MPA_ENC_H__
|
||||
#define __GST_RTP_MPA_ENC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
#include <gst/base/gstadapter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_MPA_ENC \
|
||||
(gst_rtpmpaenc_get_type())
|
||||
#define GST_RTP_MPA_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MPA_ENC,GstRtpMPAEnc))
|
||||
#define GST_RTP_MPA_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MPA_ENC,GstRtpMPAEnc))
|
||||
#define GST_IS_RTP_MPA_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MPA_ENC))
|
||||
#define GST_IS_RTP_MPA_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MPA_ENC))
|
||||
|
||||
typedef struct _GstRtpMPAEnc GstRtpMPAEnc;
|
||||
typedef struct _GstRtpMPAEncClass GstRtpMPAEncClass;
|
||||
|
||||
struct _GstRtpMPAEnc
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
|
||||
GstAdapter *adapter;
|
||||
GstClockTime first_ts;
|
||||
GstClockTime duration;
|
||||
};
|
||||
|
||||
struct _GstRtpMPAEncClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpmpaenc_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_MPA_ENC_H__ */
|
|
@ -20,24 +20,24 @@
|
|||
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpmpaenc.h"
|
||||
#include "gstrtpmpapay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_mpaenc_details = {
|
||||
static GstElementDetails gst_rtp_mpapay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encode MPEG audio as RTP packets (RFC 2038)",
|
||||
"Codec/Payloader/Network",
|
||||
"Payode MPEG audio as RTP packets (RFC 2038)",
|
||||
"Wim Taymans <wim@fluendo.com>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmpaenc_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_mpa_pay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/mpeg")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpmpaenc_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_mpa_pay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -47,58 +47,58 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
|||
"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 void gst_rtp_mpa_pay_class_init (GstRtpMPAPayClass * klass);
|
||||
static void gst_rtp_mpa_pay_base_init (GstRtpMPAPayClass * klass);
|
||||
static void gst_rtp_mpa_pay_init (GstRtpMPAPay * rtpmpapay);
|
||||
static void gst_rtp_mpa_pay_finalize (GObject * object);
|
||||
|
||||
static gboolean gst_rtpmpaenc_setcaps (GstBaseRTPPayload * payload,
|
||||
static gboolean gst_rtp_mpa_pay_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpmpaenc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
static GstFlowReturn gst_rtp_mpa_pay_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
|
||||
static GstBaseRTPPayloadClass *parent_class = NULL;
|
||||
|
||||
static GType
|
||||
gst_rtpmpaenc_get_type (void)
|
||||
gst_rtp_mpa_pay_get_type (void)
|
||||
{
|
||||
static GType rtpmpaenc_type = 0;
|
||||
static GType rtpmpapay_type = 0;
|
||||
|
||||
if (!rtpmpaenc_type) {
|
||||
static const GTypeInfo rtpmpaenc_info = {
|
||||
sizeof (GstRtpMPAEncClass),
|
||||
(GBaseInitFunc) gst_rtpmpaenc_base_init,
|
||||
if (!rtpmpapay_type) {
|
||||
static const GTypeInfo rtpmpapay_info = {
|
||||
sizeof (GstRtpMPAPayClass),
|
||||
(GBaseInitFunc) gst_rtp_mpa_pay_base_init,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_rtpmpaenc_class_init,
|
||||
(GClassInitFunc) gst_rtp_mpa_pay_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstRtpMPAEnc),
|
||||
sizeof (GstRtpMPAPay),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_rtpmpaenc_init,
|
||||
(GInstanceInitFunc) gst_rtp_mpa_pay_init,
|
||||
};
|
||||
|
||||
rtpmpaenc_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpMPAEnc",
|
||||
&rtpmpaenc_info, 0);
|
||||
rtpmpapay_type =
|
||||
g_type_register_static (GST_TYPE_BASE_RTP_PAYLOAD, "GstRtpMPAPay",
|
||||
&rtpmpapay_info, 0);
|
||||
}
|
||||
return rtpmpaenc_type;
|
||||
return rtpmpapay_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpaenc_base_init (GstRtpMPAEncClass * klass)
|
||||
gst_rtp_mpa_pay_base_init (GstRtpMPAPayClass * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmpaenc_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_mpa_pay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpmpaenc_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_mpa_pay_sink_template));
|
||||
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mpaenc_details);
|
||||
gst_element_class_set_details (element_class, &gst_rtp_mpapay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpaenc_class_init (GstRtpMPAEncClass * klass)
|
||||
gst_rtp_mpa_pay_class_init (GstRtpMPAPayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -110,33 +110,33 @@ gst_rtpmpaenc_class_init (GstRtpMPAEncClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
gobject_class->finalize = gst_rtpmpaenc_finalize;
|
||||
gobject_class->finalize = gst_rtp_mpa_pay_finalize;
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpmpaenc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpmpaenc_handle_buffer;
|
||||
gstbasertppayload_class->set_caps = gst_rtp_mpa_pay_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtp_mpa_pay_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpaenc_init (GstRtpMPAEnc * rtpmpaenc)
|
||||
gst_rtp_mpa_pay_init (GstRtpMPAPay * rtpmpapay)
|
||||
{
|
||||
rtpmpaenc->adapter = gst_adapter_new ();
|
||||
rtpmpapay->adapter = gst_adapter_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpmpaenc_finalize (GObject * object)
|
||||
gst_rtp_mpa_pay_finalize (GObject * object)
|
||||
{
|
||||
GstRtpMPAEnc *rtpmpaenc;
|
||||
GstRtpMPAPay *rtpmpapay;
|
||||
|
||||
rtpmpaenc = GST_RTP_MPA_ENC (object);
|
||||
rtpmpapay = GST_RTP_MPA_PAY (object);
|
||||
|
||||
g_object_unref (rtpmpaenc->adapter);
|
||||
rtpmpaenc->adapter = NULL;
|
||||
g_object_unref (rtpmpapay->adapter);
|
||||
rtpmpapay->adapter = NULL;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpmpaenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
gst_rtp_mpa_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
gst_basertppayload_set_options (payload, "audio", TRUE, "MPA", 90000);
|
||||
gst_basertppayload_set_outcaps (payload, NULL);
|
||||
|
@ -145,7 +145,7 @@ gst_rtpmpaenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
|
||||
gst_rtp_mpa_pay_flush (GstRtpMPAPay * rtpmpapay)
|
||||
{
|
||||
guint avail;
|
||||
GstBuffer *outbuf;
|
||||
|
@ -158,7 +158,7 @@ gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
|
|||
* adapter has more than one MTU, we need to split the MPA data
|
||||
* over multiple packets. The frag_offset in each packet header
|
||||
* needs to be updated with the position in the MPA frame. */
|
||||
avail = gst_adapter_available (rtpmpaenc->adapter);
|
||||
avail = gst_adapter_available (rtpmpapay->adapter);
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
|
||||
|
@ -171,20 +171,20 @@ gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
|
|||
guint packet_len;
|
||||
|
||||
/* this will be the total lenght of the packet */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (4 + avail, 0, 0);
|
||||
packet_len = gst_rtp_buffer_calc_packet_len (4 + avail, 0, 0);
|
||||
|
||||
/* fill one MTU or all available bytes */
|
||||
towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpmpaenc));
|
||||
towrite = MIN (packet_len, GST_BASE_RTP_PAYLOAD_MTU (rtpmpapay));
|
||||
|
||||
/* this is the payload length */
|
||||
payload_len = gst_rtpbuffer_calc_payload_len (towrite, 0, 0);
|
||||
payload_len = gst_rtp_buffer_calc_payload_len (towrite, 0, 0);
|
||||
|
||||
/* create buffer to hold the payload */
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
||||
|
||||
payload_len -= 4;
|
||||
|
||||
gst_rtpbuffer_set_payload_type (outbuf, GST_RTP_PAYLOAD_MPA);
|
||||
gst_rtp_buffer_set_payload_type (outbuf, GST_RTP_PAYLOAD_MPA);
|
||||
|
||||
/*
|
||||
* 0 1 2 3
|
||||
|
@ -193,76 +193,76 @@ gst_rtpmpaenc_flush (GstRtpMPAEnc * rtpmpaenc)
|
|||
* | MBZ | Frag_offset |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
payload = gst_rtp_buffer_get_payload (outbuf);
|
||||
payload[0] = 0;
|
||||
payload[1] = 0;
|
||||
payload[2] = frag_offset >> 8;
|
||||
payload[3] = frag_offset & 0xff;
|
||||
|
||||
data = (guint8 *) gst_adapter_peek (rtpmpaenc->adapter, payload_len);
|
||||
data = (guint8 *) gst_adapter_peek (rtpmpapay->adapter, payload_len);
|
||||
memcpy (&payload[4], data, payload_len);
|
||||
gst_adapter_flush (rtpmpaenc->adapter, payload_len);
|
||||
gst_adapter_flush (rtpmpapay->adapter, payload_len);
|
||||
|
||||
avail -= payload_len;
|
||||
frag_offset += payload_len;
|
||||
|
||||
if (avail == 0)
|
||||
gst_rtpbuffer_set_marker (outbuf, TRUE);
|
||||
gst_rtp_buffer_set_marker (outbuf, TRUE);
|
||||
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtpmpaenc->first_ts;
|
||||
GST_BUFFER_DURATION (outbuf) = rtpmpaenc->duration;
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = rtpmpapay->first_ts;
|
||||
GST_BUFFER_DURATION (outbuf) = rtpmpapay->duration;
|
||||
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmpaenc), outbuf);
|
||||
ret = gst_basertppayload_push (GST_BASE_RTP_PAYLOAD (rtpmpapay), outbuf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpmpaenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
gst_rtp_mpa_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpMPAEnc *rtpmpaenc;
|
||||
GstRtpMPAPay *rtpmpapay;
|
||||
GstFlowReturn ret;
|
||||
guint size, avail;
|
||||
guint packet_len;
|
||||
GstClockTime duration;
|
||||
|
||||
rtpmpaenc = GST_RTP_MPA_ENC (basepayload);
|
||||
rtpmpapay = GST_RTP_MPA_PAY (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
duration = GST_BUFFER_DURATION (buffer);
|
||||
|
||||
avail = gst_adapter_available (rtpmpaenc->adapter);
|
||||
avail = gst_adapter_available (rtpmpapay->adapter);
|
||||
if (avail == 0) {
|
||||
rtpmpaenc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmpaenc->duration = 0;
|
||||
rtpmpapay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmpapay->duration = 0;
|
||||
}
|
||||
|
||||
/* get packet length of previous data and this new data,
|
||||
* payload length includes a 4 byte header */
|
||||
packet_len = gst_rtpbuffer_calc_packet_len (4 + avail + size, 0, 0);
|
||||
packet_len = gst_rtp_buffer_calc_packet_len (4 + avail + size, 0, 0);
|
||||
|
||||
/* if this buffer is going to overflow the packet, flush what we
|
||||
* have. */
|
||||
if (gst_basertppayload_is_filled (basepayload,
|
||||
packet_len, rtpmpaenc->duration + duration)) {
|
||||
ret = gst_rtpmpaenc_flush (rtpmpaenc);
|
||||
rtpmpaenc->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmpaenc->duration = 0;
|
||||
packet_len, rtpmpapay->duration + duration)) {
|
||||
ret = gst_rtp_mpa_pay_flush (rtpmpapay);
|
||||
rtpmpapay->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
||||
rtpmpapay->duration = 0;
|
||||
} else {
|
||||
ret = GST_FLOW_OK;
|
||||
}
|
||||
|
||||
gst_adapter_push (rtpmpaenc->adapter, buffer);
|
||||
rtpmpaenc->duration += duration;
|
||||
gst_adapter_push (rtpmpapay->adapter, buffer);
|
||||
rtpmpapay->duration += duration;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpmpaenc_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_mpa_pay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpmpaenc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MPA_ENC);
|
||||
return gst_element_register (plugin, "rtpmpapay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_MPA_PAY);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_MPA_ENC_H__
|
||||
#define __GST_RTP_MPA_ENC_H__
|
||||
#ifndef __GST_RTP_MPA_PAY_H__
|
||||
#define __GST_RTP_MPA_PAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
|
@ -26,21 +26,21 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_RTP_MPA_ENC \
|
||||
(gst_rtpmpaenc_get_type())
|
||||
#define GST_RTP_MPA_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MPA_ENC,GstRtpMPAEnc))
|
||||
#define GST_RTP_MPA_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MPA_ENC,GstRtpMPAEnc))
|
||||
#define GST_IS_RTP_MPA_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MPA_ENC))
|
||||
#define GST_IS_RTP_MPA_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MPA_ENC))
|
||||
#define GST_TYPE_RTP_MPA_PAY \
|
||||
(gst_rtp_mpa_pay_get_type())
|
||||
#define GST_RTP_MPA_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_MPA_PAY,GstRtpMPAPay))
|
||||
#define GST_RTP_MPA_PAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_MPA_PAY,GstRtpMPAPay))
|
||||
#define GST_IS_RTP_MPA_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_MPA_PAY))
|
||||
#define GST_IS_RTP_MPA_PAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_MPA_PAY))
|
||||
|
||||
typedef struct _GstRtpMPAEnc GstRtpMPAEnc;
|
||||
typedef struct _GstRtpMPAEncClass GstRtpMPAEncClass;
|
||||
typedef struct _GstRtpMPAPay GstRtpMPAPay;
|
||||
typedef struct _GstRtpMPAPayClass GstRtpMPAPayClass;
|
||||
|
||||
struct _GstRtpMPAEnc
|
||||
struct _GstRtpMPAPay
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
|
||||
|
@ -49,13 +49,13 @@ struct _GstRtpMPAEnc
|
|||
GstClockTime duration;
|
||||
};
|
||||
|
||||
struct _GstRtpMPAEncClass
|
||||
struct _GstRtpMPAPayClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpmpaenc_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_mpa_pay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_MPA_ENC_H__ */
|
||||
#endif /* __GST_RTP_MPA_PAY_H__ */
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
#include "gstrtpspeexdec.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_speexdec_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts Speex audio from RTP packets",
|
||||
"Edgard Lima <edgard.lima@indt.org.br>"
|
||||
};
|
||||
|
||||
/* RtpSPEEXDec signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpspeexdec_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp, "
|
||||
"media = (string) \"audio\", "
|
||||
"payload = (int) [ 96, 127 ], "
|
||||
"clock-rate = (int) [6000, 48000], "
|
||||
"encoding-name = (string) \"speex\", "
|
||||
"encoding-params = (string) \"1\"")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpspeexdec_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-speex")
|
||||
);
|
||||
|
||||
static GstBuffer *gst_rtpspeexdec_process (GstBaseRTPDepayload * depayload,
|
||||
GstBuffer * buf);
|
||||
static gboolean gst_rtpspeexdec_setcaps (GstBaseRTPDepayload * depayload,
|
||||
GstCaps * caps);
|
||||
|
||||
GST_BOILERPLATE (GstRtpSPEEXDec, gst_rtpspeexdec, GstBaseRTPDepayload,
|
||||
GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpspeexdec_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpspeexdec_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpspeexdec_sink_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_speexdec_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpspeexdec_class_init (GstRtpSPEEXDecClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
|
||||
|
||||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
|
||||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
gstbasertpdepayload_class->process = gst_rtpspeexdec_process;
|
||||
gstbasertpdepayload_class->set_caps = gst_rtpspeexdec_setcaps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpspeexdec_init (GstRtpSPEEXDec * rtpspeexdec, GstRtpSPEEXDecClass * klass)
|
||||
{
|
||||
GST_BASE_RTP_DEPAYLOAD (rtpspeexdec)->clock_rate = 8000;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpspeexdec_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||
{
|
||||
GstCaps *srccaps;
|
||||
gboolean ret;
|
||||
|
||||
srccaps = gst_static_pad_template_get_caps (&gst_rtpspeexdec_src_template);
|
||||
ret = gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), srccaps);
|
||||
|
||||
gst_caps_unref (srccaps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
gst_rtpspeexdec_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||
{
|
||||
GstBuffer *outbuf = NULL;
|
||||
gint payload_len;
|
||||
guint8 *payload;
|
||||
|
||||
GST_DEBUG ("process : got %d bytes, mark %d ts %u seqn %d",
|
||||
GST_BUFFER_SIZE (buf),
|
||||
gst_rtpbuffer_get_marker (buf),
|
||||
gst_rtpbuffer_get_timestamp (buf), gst_rtpbuffer_get_seq (buf));
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpspeexdec_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpspeexdec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_SPEEX_DEC);
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_SPEEX_DEC_H__
|
||||
#define __GST_RTP_SPEEX_DEC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertpdepayload.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstRtpSPEEXDec GstRtpSPEEXDec;
|
||||
typedef struct _GstRtpSPEEXDecClass GstRtpSPEEXDecClass;
|
||||
|
||||
#define GST_TYPE_RTP_SPEEX_DEC \
|
||||
(gst_rtpspeexdec_get_type())
|
||||
#define GST_RTP_SPEEX_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_SPEEX_DEC,GstRtpSPEEXDec))
|
||||
#define GST_RTP_SPEEX_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_SPEEX_DEC,GstRtpSPEEXDec))
|
||||
#define GST_IS_RTP_SPEEX_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_SPEEX_DEC))
|
||||
#define GST_IS_RTP_SPEEX_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_SPEEX_DEC))
|
||||
|
||||
struct _GstRtpSPEEXDec
|
||||
{
|
||||
GstBaseRTPDepayload depayload;
|
||||
};
|
||||
|
||||
struct _GstRtpSPEEXDecClass
|
||||
{
|
||||
GstBaseRTPDepayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpspeexdec_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_SPEEX_DEC_H__ */
|
|
@ -18,17 +18,17 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
#include "gstrtpspeexdec.h"
|
||||
#include "gstrtpspeexdepay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtp_speexdec_details = {
|
||||
static GstElementDetails gst_rtp_speexdepay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Parser/Network",
|
||||
"Extracts Speex audio from RTP packets",
|
||||
"Edgard Lima <edgard.lima@indt.org.br>"
|
||||
};
|
||||
|
||||
/* RtpSPEEXDec signals and args */
|
||||
/* RtpSPEEXDepay signals and args */
|
||||
enum
|
||||
{
|
||||
/* FILL ME */
|
||||
|
@ -40,7 +40,7 @@ enum
|
|||
ARG_0
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpspeexdec_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_speex_depay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -52,35 +52,35 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
"encoding-params = (string) \"1\"")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpspeexdec_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_speex_depay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-speex")
|
||||
);
|
||||
|
||||
static GstBuffer *gst_rtpspeexdec_process (GstBaseRTPDepayload * depayload,
|
||||
static GstBuffer *gst_rtp_speex_depay_process (GstBaseRTPDepayload * depayload,
|
||||
GstBuffer * buf);
|
||||
static gboolean gst_rtpspeexdec_setcaps (GstBaseRTPDepayload * depayload,
|
||||
static gboolean gst_rtp_speex_depay_setcaps (GstBaseRTPDepayload * depayload,
|
||||
GstCaps * caps);
|
||||
|
||||
GST_BOILERPLATE (GstRtpSPEEXDec, gst_rtpspeexdec, GstBaseRTPDepayload,
|
||||
GST_BOILERPLATE (GstRtpSPEEXDepay, gst_rtp_speex_depay, GstBaseRTPDepayload,
|
||||
GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpspeexdec_base_init (gpointer klass)
|
||||
gst_rtp_speex_depay_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpspeexdec_src_template));
|
||||
gst_static_pad_template_get (&gst_rtp_speex_depay_src_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpspeexdec_sink_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_speexdec_details);
|
||||
gst_static_pad_template_get (&gst_rtp_speex_depay_sink_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_speexdepay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpspeexdec_class_init (GstRtpSPEEXDecClass * klass)
|
||||
gst_rtp_speex_depay_class_init (GstRtpSPEEXDepayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -92,23 +92,25 @@ gst_rtpspeexdec_class_init (GstRtpSPEEXDecClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
gstbasertpdepayload_class->process = gst_rtpspeexdec_process;
|
||||
gstbasertpdepayload_class->set_caps = gst_rtpspeexdec_setcaps;
|
||||
gstbasertpdepayload_class->process = gst_rtp_speex_depay_process;
|
||||
gstbasertpdepayload_class->set_caps = gst_rtp_speex_depay_setcaps;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpspeexdec_init (GstRtpSPEEXDec * rtpspeexdec, GstRtpSPEEXDecClass * klass)
|
||||
gst_rtp_speex_depay_init (GstRtpSPEEXDepay * rtpspeexdepay,
|
||||
GstRtpSPEEXDepayClass * klass)
|
||||
{
|
||||
GST_BASE_RTP_DEPAYLOAD (rtpspeexdec)->clock_rate = 8000;
|
||||
GST_BASE_RTP_DEPAYLOAD (rtpspeexdepay)->clock_rate = 8000;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpspeexdec_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||
gst_rtp_speex_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||
{
|
||||
GstCaps *srccaps;
|
||||
gboolean ret;
|
||||
|
||||
srccaps = gst_static_pad_template_get_caps (&gst_rtpspeexdec_src_template);
|
||||
srccaps =
|
||||
gst_static_pad_template_get_caps (&gst_rtp_speex_depay_src_template);
|
||||
ret = gst_pad_set_caps (GST_BASE_RTP_DEPAYLOAD_SRCPAD (depayload), srccaps);
|
||||
|
||||
gst_caps_unref (srccaps);
|
||||
|
@ -116,7 +118,7 @@ gst_rtpspeexdec_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
|||
}
|
||||
|
||||
static GstBuffer *
|
||||
gst_rtpspeexdec_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||
gst_rtp_speex_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||
{
|
||||
GstBuffer *outbuf = NULL;
|
||||
gint payload_len;
|
||||
|
@ -124,11 +126,11 @@ gst_rtpspeexdec_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
|
||||
GST_DEBUG ("process : got %d bytes, mark %d ts %u seqn %d",
|
||||
GST_BUFFER_SIZE (buf),
|
||||
gst_rtpbuffer_get_marker (buf),
|
||||
gst_rtpbuffer_get_timestamp (buf), gst_rtpbuffer_get_seq (buf));
|
||||
gst_rtp_buffer_get_marker (buf),
|
||||
gst_rtp_buffer_get_timestamp (buf), gst_rtp_buffer_get_seq (buf));
|
||||
|
||||
payload_len = gst_rtpbuffer_get_payload_len (buf);
|
||||
payload = gst_rtpbuffer_get_payload (buf);
|
||||
payload_len = gst_rtp_buffer_get_payload_len (buf);
|
||||
payload = gst_rtp_buffer_get_payload (buf);
|
||||
|
||||
outbuf = gst_buffer_new_and_alloc (payload_len);
|
||||
memcpy (GST_BUFFER_DATA (outbuf), payload, payload_len);
|
||||
|
@ -136,8 +138,8 @@ gst_rtpspeexdec_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpspeexdec_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_speex_depay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpspeexdec",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_SPEEX_DEC);
|
||||
return gst_element_register (plugin, "rtpspeexdepay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_SPEEX_DEPAY);
|
||||
}
|
||||
|
|
|
@ -12,40 +12,40 @@
|
|||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifndef __GST_RTP_SPEEX_DEC_H__
|
||||
#define __GST_RTP_SPEEX_DEC_H__
|
||||
#ifndef __GST_RTP_SPEEX_DEPAY_H__
|
||||
#define __GST_RTP_SPEEX_DEPAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertpdepayload.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstRtpSPEEXDec GstRtpSPEEXDec;
|
||||
typedef struct _GstRtpSPEEXDecClass GstRtpSPEEXDecClass;
|
||||
typedef struct _GstRtpSPEEXDepay GstRtpSPEEXDepay;
|
||||
typedef struct _GstRtpSPEEXDepayClass GstRtpSPEEXDepayClass;
|
||||
|
||||
#define GST_TYPE_RTP_SPEEX_DEC \
|
||||
(gst_rtpspeexdec_get_type())
|
||||
#define GST_RTP_SPEEX_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_SPEEX_DEC,GstRtpSPEEXDec))
|
||||
#define GST_RTP_SPEEX_DEC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_SPEEX_DEC,GstRtpSPEEXDec))
|
||||
#define GST_IS_RTP_SPEEX_DEC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_SPEEX_DEC))
|
||||
#define GST_IS_RTP_SPEEX_DEC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_SPEEX_DEC))
|
||||
#define GST_TYPE_RTP_SPEEX_DEPAY \
|
||||
(gst_rtp_speex_depay_get_type())
|
||||
#define GST_RTP_SPEEX_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_SPEEX_DEPAY,GstRtpSPEEXDepay))
|
||||
#define GST_RTP_SPEEX_DEPAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_SPEEX_DEPAY,GstRtpSPEEXDepay))
|
||||
#define GST_IS_RTP_SPEEX_DEPAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_SPEEX_DEPAY))
|
||||
#define GST_IS_RTP_SPEEX_DEPAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_SPEEX_DEPAY))
|
||||
|
||||
struct _GstRtpSPEEXDec
|
||||
struct _GstRtpSPEEXDepay
|
||||
{
|
||||
GstBaseRTPDepayload depayload;
|
||||
};
|
||||
|
||||
struct _GstRtpSPEEXDecClass
|
||||
struct _GstRtpSPEEXDepayClass
|
||||
{
|
||||
GstBaseRTPDepayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpspeexdec_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_speex_depay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_SPEEX_DEC_H__ */
|
||||
#endif /* __GST_RTP_SPEEX_DEPAY_H__ */
|
||||
|
|
|
@ -1,149 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpspeexenc.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtpspeexenc_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes Speex audio into a RTP packet",
|
||||
"Edgard Lima <edgard.lima@indt.org.br>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpspeexenc_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-speex")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpspeexenc_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("application/x-rtp, " "media = (string) \"audio\", " "payload = (int) 110, " /* guaranties compatibility with Linphone
|
||||
Could be [96,127] See page 34 at http://www.ietf.org/rfc/rfc3551.txt */
|
||||
"clock-rate = (int) [6000, 48000], "
|
||||
"encoding-name = (string) \"speex\", "
|
||||
"encoding-params = (string) \"1\"")
|
||||
);
|
||||
|
||||
static gboolean gst_rtpspeexenc_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpspeexenc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
|
||||
GST_BOILERPLATE (GstRtpSPEEXEnc, gst_rtpspeexenc, GstBaseRTPPayload,
|
||||
GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpspeexenc_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpspeexenc_sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpspeexenc_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtpspeexenc_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpspeexenc_class_init (GstRtpSPEEXEncClass * 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);
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpspeexenc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpspeexenc_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpspeexenc_init (GstRtpSPEEXEnc * rtpspeexenc, GstRtpSPEEXEncClass * klass)
|
||||
{
|
||||
GST_BASE_RTP_PAYLOAD (rtpspeexenc)->clock_rate = 8000;
|
||||
GST_BASE_RTP_PAYLOAD_PT (rtpspeexenc) = 110; /* Create String */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpspeexenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
gst_basertppayload_set_options (payload, "audio", FALSE, "speex", 8000);
|
||||
gst_basertppayload_set_outcaps (payload, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpspeexenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpSPEEXEnc *rtpspeexenc;
|
||||
guint size, payload_len;
|
||||
GstBuffer *outbuf;
|
||||
guint8 *payload, *data;
|
||||
GstClockTime timestamp;
|
||||
GstFlowReturn ret;
|
||||
|
||||
rtpspeexenc = GST_RTP_SPEEX_ENC (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
||||
/* FIXME, only one SPEEX frame per RTP packet for now */
|
||||
payload_len = size;
|
||||
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
/* FIXME, assert for now */
|
||||
g_assert (payload_len <= GST_BASE_RTP_PAYLOAD_MTU (rtpspeexenc));
|
||||
|
||||
/* copy timestamp */
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
||||
/* get payload */
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
|
||||
data = GST_BUFFER_DATA (buffer);
|
||||
|
||||
/* copy data in payload */
|
||||
memcpy (&payload[0], data, size);
|
||||
|
||||
gst_buffer_unref (buffer);
|
||||
|
||||
ret = gst_basertppayload_push (basepayload, outbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpspeexenc_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpspeexenc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_SPEEX_ENC);
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Edgard Lima <edgard.lima@indt.org.br>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GST_RTP_SPEEX_ENC_H__
|
||||
#define __GST_RTP_SPEEX_ENC_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstRtpSPEEXEnc GstRtpSPEEXEnc;
|
||||
typedef struct _GstRtpSPEEXEncClass GstRtpSPEEXEncClass;
|
||||
|
||||
#define GST_TYPE_RTP_SPEEX_ENC \
|
||||
(gst_rtpspeexenc_get_type())
|
||||
#define GST_RTP_SPEEX_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_SPEEX_ENC,GstRtpSPEEXEnc))
|
||||
#define GST_RTP_SPEEX_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_SPEEX_ENC,GstRtpSPEEXEnc))
|
||||
#define GST_IS_RTP_SPEEX_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_SPEEX_ENC))
|
||||
#define GST_IS_RTP_SPEEX_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_SPEEX_ENC))
|
||||
|
||||
struct _GstRtpSPEEXEnc
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
};
|
||||
|
||||
struct _GstRtpSPEEXEncClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpspeexenc_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_SPEEX_ENC_H__ */
|
|
@ -20,24 +20,24 @@
|
|||
#include <string.h>
|
||||
#include <gst/rtp/gstrtpbuffer.h>
|
||||
|
||||
#include "gstrtpspeexenc.h"
|
||||
#include "gstrtpspeexpay.h"
|
||||
|
||||
/* elementfactory information */
|
||||
static GstElementDetails gst_rtpspeexenc_details = {
|
||||
static GstElementDetails gst_rtp_speex_pay_details = {
|
||||
"RTP packet parser",
|
||||
"Codec/Encoder/Network",
|
||||
"Encodes Speex audio into a RTP packet",
|
||||
"Codec/Payloader/Network",
|
||||
"Payodes Speex audio into a RTP packet",
|
||||
"Edgard Lima <edgard.lima@indt.org.br>"
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_rtpspeexenc_sink_template =
|
||||
static GstStaticPadTemplate gst_rtp_speex_pay_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("audio/x-speex")
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_rtpspeexenc_src_template =
|
||||
static GstStaticPadTemplate gst_rtp_speex_pay_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
|
@ -48,28 +48,28 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
|||
"encoding-params = (string) \"1\"")
|
||||
);
|
||||
|
||||
static gboolean gst_rtpspeexenc_setcaps (GstBaseRTPPayload * payload,
|
||||
static gboolean gst_rtp_speex_pay_setcaps (GstBaseRTPPayload * payload,
|
||||
GstCaps * caps);
|
||||
static GstFlowReturn gst_rtpspeexenc_handle_buffer (GstBaseRTPPayload * payload,
|
||||
GstBuffer * buffer);
|
||||
static GstFlowReturn gst_rtp_speex_pay_handle_buffer (GstBaseRTPPayload *
|
||||
payload, GstBuffer * buffer);
|
||||
|
||||
GST_BOILERPLATE (GstRtpSPEEXEnc, gst_rtpspeexenc, GstBaseRTPPayload,
|
||||
GST_BOILERPLATE (GstRtpSPEEXPay, gst_rtp_speex_pay, GstBaseRTPPayload,
|
||||
GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
static void
|
||||
gst_rtpspeexenc_base_init (gpointer klass)
|
||||
gst_rtp_speex_pay_base_init (gpointer klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpspeexenc_sink_template));
|
||||
gst_static_pad_template_get (&gst_rtp_speex_pay_sink_template));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&gst_rtpspeexenc_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtpspeexenc_details);
|
||||
gst_static_pad_template_get (&gst_rtp_speex_pay_src_template));
|
||||
gst_element_class_set_details (element_class, &gst_rtp_speex_pay_details);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpspeexenc_class_init (GstRtpSPEEXEncClass * klass)
|
||||
gst_rtp_speex_pay_class_init (GstRtpSPEEXPayClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
GstElementClass *gstelement_class;
|
||||
|
@ -81,19 +81,20 @@ gst_rtpspeexenc_class_init (GstRtpSPEEXEncClass * klass)
|
|||
|
||||
parent_class = g_type_class_ref (GST_TYPE_BASE_RTP_PAYLOAD);
|
||||
|
||||
gstbasertppayload_class->set_caps = gst_rtpspeexenc_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtpspeexenc_handle_buffer;
|
||||
gstbasertppayload_class->set_caps = gst_rtp_speex_pay_setcaps;
|
||||
gstbasertppayload_class->handle_buffer = gst_rtp_speex_pay_handle_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtpspeexenc_init (GstRtpSPEEXEnc * rtpspeexenc, GstRtpSPEEXEncClass * klass)
|
||||
gst_rtp_speex_pay_init (GstRtpSPEEXPay * rtpspeexpay,
|
||||
GstRtpSPEEXPayClass * klass)
|
||||
{
|
||||
GST_BASE_RTP_PAYLOAD (rtpspeexenc)->clock_rate = 8000;
|
||||
GST_BASE_RTP_PAYLOAD_PT (rtpspeexenc) = 110; /* Create String */
|
||||
GST_BASE_RTP_PAYLOAD (rtpspeexpay)->clock_rate = 8000;
|
||||
GST_BASE_RTP_PAYLOAD_PT (rtpspeexpay) = 110; /* Create String */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_rtpspeexenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
gst_rtp_speex_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
||||
{
|
||||
gst_basertppayload_set_options (payload, "audio", FALSE, "speex", 8000);
|
||||
gst_basertppayload_set_outcaps (payload, NULL);
|
||||
|
@ -102,17 +103,17 @@ gst_rtpspeexenc_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_rtpspeexenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
gst_rtp_speex_pay_handle_buffer (GstBaseRTPPayload * basepayload,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
GstRtpSPEEXEnc *rtpspeexenc;
|
||||
GstRtpSPEEXPay *rtpspeexpay;
|
||||
guint size, payload_len;
|
||||
GstBuffer *outbuf;
|
||||
guint8 *payload, *data;
|
||||
GstClockTime timestamp;
|
||||
GstFlowReturn ret;
|
||||
|
||||
rtpspeexenc = GST_RTP_SPEEX_ENC (basepayload);
|
||||
rtpspeexpay = GST_RTP_SPEEX_PAY (basepayload);
|
||||
|
||||
size = GST_BUFFER_SIZE (buffer);
|
||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||
|
@ -120,14 +121,14 @@ gst_rtpspeexenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
/* FIXME, only one SPEEX frame per RTP packet for now */
|
||||
payload_len = size;
|
||||
|
||||
outbuf = gst_rtpbuffer_new_allocate (payload_len, 0, 0);
|
||||
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
||||
/* FIXME, assert for now */
|
||||
g_assert (payload_len <= GST_BASE_RTP_PAYLOAD_MTU (rtpspeexenc));
|
||||
g_assert (payload_len <= GST_BASE_RTP_PAYLOAD_MTU (rtpspeexpay));
|
||||
|
||||
/* copy timestamp */
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
|
||||
/* get payload */
|
||||
payload = gst_rtpbuffer_get_payload (outbuf);
|
||||
payload = gst_rtp_buffer_get_payload (outbuf);
|
||||
|
||||
data = GST_BUFFER_DATA (buffer);
|
||||
|
||||
|
@ -142,8 +143,8 @@ gst_rtpspeexenc_handle_buffer (GstBaseRTPPayload * basepayload,
|
|||
}
|
||||
|
||||
gboolean
|
||||
gst_rtpspeexenc_plugin_init (GstPlugin * plugin)
|
||||
gst_rtp_speex_pay_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
return gst_element_register (plugin, "rtpspeexenc",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_SPEEX_ENC);
|
||||
return gst_element_register (plugin, "rtpspeexpay",
|
||||
GST_RANK_NONE, GST_TYPE_RTP_SPEEX_PAY);
|
||||
}
|
||||
|
|
|
@ -13,40 +13,40 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef __GST_RTP_SPEEX_ENC_H__
|
||||
#define __GST_RTP_SPEEX_ENC_H__
|
||||
#ifndef __GST_RTP_SPEEX_PAY_H__
|
||||
#define __GST_RTP_SPEEX_PAY_H__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/rtp/gstbasertppayload.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstRtpSPEEXEnc GstRtpSPEEXEnc;
|
||||
typedef struct _GstRtpSPEEXEncClass GstRtpSPEEXEncClass;
|
||||
typedef struct _GstRtpSPEEXPay GstRtpSPEEXPay;
|
||||
typedef struct _GstRtpSPEEXPayClass GstRtpSPEEXPayClass;
|
||||
|
||||
#define GST_TYPE_RTP_SPEEX_ENC \
|
||||
(gst_rtpspeexenc_get_type())
|
||||
#define GST_RTP_SPEEX_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_SPEEX_ENC,GstRtpSPEEXEnc))
|
||||
#define GST_RTP_SPEEX_ENC_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_SPEEX_ENC,GstRtpSPEEXEnc))
|
||||
#define GST_IS_RTP_SPEEX_ENC(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_SPEEX_ENC))
|
||||
#define GST_IS_RTP_SPEEX_ENC_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_SPEEX_ENC))
|
||||
#define GST_TYPE_RTP_SPEEX_PAY \
|
||||
(gst_rtp_speex_pay_get_type())
|
||||
#define GST_RTP_SPEEX_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_RTP_SPEEX_PAY,GstRtpSPEEXPay))
|
||||
#define GST_RTP_SPEEX_PAY_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_RTP_SPEEX_PAY,GstRtpSPEEXPay))
|
||||
#define GST_IS_RTP_SPEEX_PAY(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_RTP_SPEEX_PAY))
|
||||
#define GST_IS_RTP_SPEEX_PAY_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_RTP_SPEEX_PAY))
|
||||
|
||||
struct _GstRtpSPEEXEnc
|
||||
struct _GstRtpSPEEXPay
|
||||
{
|
||||
GstBaseRTPPayload payload;
|
||||
};
|
||||
|
||||
struct _GstRtpSPEEXEncClass
|
||||
struct _GstRtpSPEEXPayClass
|
||||
{
|
||||
GstBaseRTPPayloadClass parent_class;
|
||||
};
|
||||
|
||||
gboolean gst_rtpspeexenc_plugin_init (GstPlugin * plugin);
|
||||
gboolean gst_rtp_speex_pay_plugin_init (GstPlugin * plugin);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_RTP_SPEEX_ENC_H__ */
|
||||
#endif /* __GST_RTP_SPEEX_PAY_H__ */
|
||||
|
|
Loading…
Reference in a new issue