diff --git a/ext/rtmp/gstrtmpsink.c b/ext/rtmp/gstrtmpsink.c index 90a1a79ec8..6137ee5acc 100644 --- a/ext/rtmp/gstrtmpsink.c +++ b/ext/rtmp/gstrtmpsink.c @@ -75,63 +75,50 @@ static gboolean gst_rtmp_sink_stop (GstBaseSink * sink); static gboolean gst_rtmp_sink_start (GstBaseSink * sink); static GstFlowReturn gst_rtmp_sink_render (GstBaseSink * sink, GstBuffer * buf); -static void -_do_init (GType gtype) -{ - 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"); -} - -GST_BOILERPLATE_FULL (GstRTMPSink, gst_rtmp_sink, GstBaseSink, - GST_TYPE_BASE_SINK, _do_init); - - -static void -gst_rtmp_sink_base_init (gpointer klass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - - gst_element_class_set_details_simple (element_class, - "RTMP output sink", - "Sink/Network", "Sends FLV content to a server via RTMP", - "Jan Schmidt "); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); -} +#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 gst_rtmp_sink_class_init (GstRTMPSinkClass * klass) { GObjectClass *gobject_class; - GstBaseSinkClass *gstbasesink_class = (GstBaseSinkClass *) klass; + GstElementClass *gstelement_class; + GstBaseSinkClass *gstbasesink_class; 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; + gst_element_class_install_std_props (gstelement_class, + "location", PROP_LOCATION, G_PARAM_READWRITE, NULL); + + gst_element_class_set_details_simple (gstelement_class, + "RTMP output sink", + "Sink/Network", "Sends FLV content to a server via RTMP", + "Jan Schmidt "); + + gst_element_class_add_pad_template (gstelement_class, + gst_static_pad_template_get (&sink_template)); + 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) { } @@ -194,6 +181,8 @@ gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf) { GstRTMPSink *sink = GST_RTMP_SINK (bsink); GstBuffer *reffed_buf = NULL; + guint8 *data; + gsize size; if (sink->first) { /* open the connection */ @@ -214,7 +203,7 @@ gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf) /* 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; @@ -222,40 +211,48 @@ gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf) 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", diff --git a/ext/rtmp/gstrtmpsrc.c b/ext/rtmp/gstrtmpsrc.c index e37ac06b73..36e74882b1 100644 --- a/ext/rtmp/gstrtmpsrc.c +++ b/ext/rtmp/gstrtmpsrc.c @@ -88,47 +88,21 @@ static GstFlowReturn gst_rtmp_src_create (GstPushSrc * pushsrc, 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 , " - "Sebastian Dröge "); -} +#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); @@ -137,9 +111,19 @@ gst_rtmp_src_class_init (GstRTMPSrcClass * 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 , " + "Sebastian Dröge "); + 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); @@ -148,10 +132,12 @@ gst_rtmp_src_class_init (GstRTMPSrcClass * klass) 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; @@ -175,13 +161,13 @@ gst_rtmp_src_finalize (GObject * object) */ 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", @@ -286,8 +272,9 @@ gst_rtmp_src_create (GstPushSrc * pushsrc, GstBuffer ** buffer) { GstRTMPSrc *src; GstBuffer *buf; - guint8 *data; + guint8 *data, *bdata; guint todo; + gsize bsize; int read; int size; @@ -300,15 +287,15 @@ gst_rtmp_src_create (GstPushSrc * pushsrc, GstBuffer ** buffer) 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); @@ -316,7 +303,6 @@ gst_rtmp_src_create (GstPushSrc * pushsrc, GstBuffer ** buffer) if (G_UNLIKELY (read == 0 && todo == size)) { goto eos; } else if (G_UNLIKELY (read == 0)) { - GST_BUFFER_SIZE (buf) -= todo; todo = 0; break; } @@ -325,13 +311,16 @@ gst_rtmp_src_create (GstPushSrc * pushsrc, GstBuffer ** buffer) 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); @@ -465,7 +454,7 @@ gst_rtmp_src_prepare_seek_segment (GstBaseSrc * basesrc, GstEvent * event, } 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;