static gboolean gst_rtmp_sink_start (GstBaseSink * sink);
static GstFlowReturn gst_rtmp_sink_render (GstBaseSink * sink, GstBuffer * buf);
+#define gst_rtmp_sink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstRTMPSink, gst_rtmp_sink, GST_TYPE_BASE_SINK,
+ G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
+ gst_rtmp_sink_uri_handler_init));
+
+/* initialize the plugin's class */
static void
-_do_init (GType gtype)
+gst_rtmp_sink_class_init (GstRTMPSinkClass * klass)
{
- static const GInterfaceInfo urihandler_info = {
- gst_rtmp_sink_uri_handler_init,
- NULL,
- NULL
- };
-
- g_type_add_interface_static (gtype, GST_TYPE_URI_HANDLER, &urihandler_info);
-
- GST_DEBUG_CATEGORY_INIT (gst_rtmp_sink_debug, "rtmpsink", 0,
- "RTMP server element");
-}
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+ GstBaseSinkClass *gstbasesink_class;
-GST_BOILERPLATE_FULL (GstRTMPSink, gst_rtmp_sink, GstBaseSink,
- GST_TYPE_BASE_SINK, _do_init);
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+ gstbasesink_class = (GstBaseSinkClass *) klass;
+ gobject_class->set_property = gst_rtmp_sink_set_property;
+ gobject_class->get_property = gst_rtmp_sink_get_property;
-static void
-gst_rtmp_sink_base_init (gpointer klass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+ gst_element_class_install_std_props (gstelement_class,
+ "location", PROP_LOCATION, G_PARAM_READWRITE, NULL);
- gst_element_class_set_details_simple (element_class,
+ gst_element_class_set_details_simple (gstelement_class,
"RTMP output sink",
"Sink/Network", "Sends FLV content to a server via RTMP",
"Jan Schmidt <thaytan@noraisin.net>");
- gst_element_class_add_pad_template (element_class,
+ gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&sink_template));
-}
-
-/* initialize the plugin's class */
-static void
-gst_rtmp_sink_class_init (GstRTMPSinkClass * klass)
-{
- GObjectClass *gobject_class;
- GstBaseSinkClass *gstbasesink_class = (GstBaseSinkClass *) klass;
-
- gobject_class = (GObjectClass *) klass;
- gobject_class->set_property = gst_rtmp_sink_set_property;
- gobject_class->get_property = gst_rtmp_sink_get_property;
gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_rtmp_sink_start);
gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_rtmp_sink_stop);
gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_rtmp_sink_render);
- gst_element_class_install_std_props (GST_ELEMENT_CLASS (klass),
- "location", PROP_LOCATION, G_PARAM_READWRITE, NULL);
+ GST_DEBUG_CATEGORY_INIT (gst_rtmp_sink_debug, "rtmpsink", 0,
+ "RTMP server element");
}
/* initialize the new element
* initialize instance structure
*/
static void
-gst_rtmp_sink_init (GstRTMPSink * sink, GstRTMPSinkClass * klass)
+gst_rtmp_sink_init (GstRTMPSink * sink)
{
}
{
GstRTMPSink *sink = GST_RTMP_SINK (bsink);
GstBuffer *reffed_buf = NULL;
+ guint8 *data;
+ gsize size;
if (sink->first) {
/* open the connection */
/* FIXME: Parse the first buffer and see if it contains a header plus a packet instead
* of just assuming it's only the header */
GST_LOG_OBJECT (sink, "Caching first buffer of size %d for concatenation",
- GST_BUFFER_SIZE (buf));
+ gst_buffer_get_size (buf));
gst_buffer_replace (&sink->cache, buf);
sink->first = FALSE;
return GST_FLOW_OK;
if (sink->cache) {
GST_LOG_OBJECT (sink, "Joining 2nd buffer of size %d to cached buf",
- GST_BUFFER_SIZE (buf));
+ gst_buffer_get_size (buf));
gst_buffer_ref (buf);
reffed_buf = buf = gst_buffer_join (sink->cache, buf);
sink->cache = NULL;
}
GST_LOG_OBJECT (sink, "Sending %d bytes to RTMP server",
- GST_BUFFER_SIZE (buf));
+ gst_buffer_get_size (buf));
- if (!RTMP_Write (sink->rtmp,
- (char *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf))) {
- GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL), ("Failed to write data"));
- if (reffed_buf)
- gst_buffer_unref (reffed_buf);
- return GST_FLOW_ERROR;
- }
+ data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+ if (!RTMP_Write (sink->rtmp, (char *) data, size))
+ goto write_failed;
+
+ gst_buffer_unmap (buf, data, size);
if (reffed_buf)
gst_buffer_unref (reffed_buf);
return GST_FLOW_OK;
+
+ /* ERRORS */
+write_failed:
+ {
+ GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL), ("Failed to write data"));
+ gst_buffer_unmap (buf, data, size);
+ if (reffed_buf)
+ gst_buffer_unref (reffed_buf);
+ return GST_FLOW_ERROR;
+ }
}
/*
* URI interface support.
*/
static GstURIType
-gst_rtmp_sink_uri_get_type (void)
+gst_rtmp_sink_uri_get_type (GType type)
{
return GST_URI_SINK;
}
static gchar **
-gst_rtmp_sink_uri_get_protocols (void)
+gst_rtmp_sink_uri_get_protocols (GType type)
{
static gchar *protocols[] =
{ (char *) "rtmp", (char *) "rtmpt", (char *) "rtmps", (char *) "rtmpe",
GstBuffer ** buffer);
static gboolean gst_rtmp_src_query (GstBaseSrc * src, GstQuery * query);
-static void
-_do_init (GType gtype)
-{
- static const GInterfaceInfo urihandler_info = {
- gst_rtmp_src_uri_handler_init,
- NULL,
- NULL
- };
-
- g_type_add_interface_static (gtype, GST_TYPE_URI_HANDLER, &urihandler_info);
-
- GST_DEBUG_CATEGORY_INIT (rtmpsrc_debug, "rtmpsrc", 0, "RTMP Source");
-}
-
-GST_BOILERPLATE_FULL (GstRTMPSrc, gst_rtmp_src, GstPushSrc, GST_TYPE_PUSH_SRC,
- _do_init);
-
-static void
-gst_rtmp_src_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&srctemplate));
-
- gst_element_class_set_details_simple (element_class,
- "RTMP Source",
- "Source/File",
- "Read RTMP streams",
- "Bastien Nocera <hadess@hadess.net>, "
- "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-}
+#define gst_rtmp_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstRTMPSrc, gst_rtmp_src, GST_TYPE_PUSH_SRC,
+ G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
+ gst_rtmp_src_uri_handler_init));
static void
gst_rtmp_src_class_init (GstRTMPSrcClass * klass)
{
GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
GstBaseSrcClass *gstbasesrc_class;
GstPushSrcClass *gstpushsrc_class;
gobject_class = G_OBJECT_CLASS (klass);
+ gstelement_class = GST_ELEMENT_CLASS (klass);
gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);
gobject_class->get_property = gst_rtmp_src_get_property;
/* properties */
- gst_element_class_install_std_props (GST_ELEMENT_CLASS (klass),
+ gst_element_class_install_std_props (gstelement_class,
"location", PROP_LOCATION, G_PARAM_READWRITE, NULL);
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&srctemplate));
+
+ gst_element_class_set_details_simple (gstelement_class,
+ "RTMP Source",
+ "Source/File",
+ "Read RTMP streams",
+ "Bastien Nocera <hadess@hadess.net>, "
+ "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
+
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_rtmp_src_start);
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_rtmp_src_stop);
gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_rtmp_src_is_seekable);
gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_rtmp_src_do_seek);
gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_rtmp_src_create);
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_rtmp_src_query);
+
+ GST_DEBUG_CATEGORY_INIT (rtmpsrc_debug, "rtmpsrc", 0, "RTMP Source");
}
static void
-gst_rtmp_src_init (GstRTMPSrc * rtmpsrc, GstRTMPSrcClass * klass)
+gst_rtmp_src_init (GstRTMPSrc * rtmpsrc)
{
rtmpsrc->cur_offset = 0;
rtmpsrc->last_timestamp = 0;
*/
static GstURIType
-gst_rtmp_src_uri_get_type (void)
+gst_rtmp_src_uri_get_type (GType type)
{
return GST_URI_SRC;
}
static gchar **
-gst_rtmp_src_uri_get_protocols (void)
+gst_rtmp_src_uri_get_protocols (GType type)
{
static gchar *protocols[] =
{ (char *) "rtmp", (char *) "rtmpt", (char *) "rtmps", (char *) "rtmpe",
{
GstRTMPSrc *src;
GstBuffer *buf;
- guint8 *data;
+ guint8 *data, *bdata;
guint todo;
+ gsize bsize;
int read;
int size;
GST_DEBUG ("reading from %" G_GUINT64_FORMAT
", size %u", src->cur_offset, size);
- buf = gst_buffer_try_new_and_alloc (size);
+ buf = gst_buffer_new_allocate (NULL, size, 0);
if (G_UNLIKELY (buf == NULL)) {
GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
return GST_FLOW_ERROR;
}
- todo = size;
- data = GST_BUFFER_DATA (buf);
- read = 0;
+ bsize = todo = size;
+ bdata = data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+ read = bsize = 0;
while (todo > 0) {
read = RTMP_Read (src->rtmp, (char *) data, todo);
if (G_UNLIKELY (read == 0 && todo == size)) {
goto eos;
} else if (G_UNLIKELY (read == 0)) {
- GST_BUFFER_SIZE (buf) -= todo;
todo = 0;
break;
}
goto read_failed;
if (read < todo) {
- data = &data[read];
+ data += read;
todo -= read;
+ bsize += read;
} else {
todo = 0;
+ bsize += todo;
}
GST_LOG (" got size %d", read);
}
+ gst_buffer_unmap (buf, bdata, bsize);
if (src->discont) {
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
}
gst_segment_init (segment, GST_FORMAT_TIME);
- gst_segment_set_seek (segment, rate, format, flags, cur_type, cur, stop_type,
+ gst_segment_do_seek (segment, rate, format, flags, cur_type, cur, stop_type,
stop, NULL);
return TRUE;