/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include "config.h" #include #include "rb-debug.h" #include #include #define RB_TYPE_FM_RADIO_SRC (rb_fm_radio_src_get_type()) #define RB_FM_RADIO_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),RB_TYPE_FM_RADIO_SRC,RBFMRadioSrc)) #define RB_FM_RADIO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),RB_TYPE_FM_RADIO_SRC,RBFMRadioSrcClass)) #define RB_IS_LASTFM_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),RB_TYPE_FM_RADIO_SRC)) #define RB_IS_LASTFM_SRC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),RB_TYPE_FM_RADIO_SRC)) typedef struct _RBFMRadioSrc RBFMRadioSrc; typedef struct _RBFMRadioSrcClass RBFMRadioSrcClass; struct _RBFMRadioSrc { GstBaseSrc parent; guint64 next_sample; }; struct _RBFMRadioSrcClass { GstBaseSrcClass parent_class; }; static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, 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) 48000, " "channels = (int) 1")); static GstElementDetails rb_fm_radio_src_details = GST_ELEMENT_DETAILS ("RB Silence Source", "Source/File", "Outputs buffers of silence", "James Henstridge "); static void rb_fm_radio_src_uri_handler_init (gpointer g_iface, gpointer iface_data); static void _do_init (GType lastfm_src_type) { static const GInterfaceInfo urihandler_info = { rb_fm_radio_src_uri_handler_init, NULL, NULL }; g_type_add_interface_static (lastfm_src_type, GST_TYPE_URI_HANDLER, &urihandler_info); } GST_BOILERPLATE_FULL (RBFMRadioSrc, rb_fm_radio_src, GstBin, GST_TYPE_BASE_SRC, _do_init); static void rb_fm_radio_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 (element_class, &rb_fm_radio_src_details); } static void rb_fm_radio_src_init (RBFMRadioSrc *src, RBFMRadioSrcClass *klass) { rb_debug ("creating rb silence src element"); gst_base_src_set_live (GST_BASE_SRC (src), TRUE); gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME); } static void rb_fm_radio_src_set_uri (RBFMRadioSrc *src, const char *uri) { GstPad *pad; rb_debug ("stream uri: %s", uri); } static gboolean rb_fm_radio_src_start (GstBaseSrc *basesrc) { RBFMRadioSrc *src = RB_FM_RADIO_SRC (basesrc); rb_debug ("xrbsilencesrc: start"); src->next_sample = 0; return TRUE; } static gboolean rb_fm_radio_src_stop (GstBaseSrc *basesrc) { rb_debug ("xrbsilencesrc: stop"); return TRUE; } static void rb_fm_radio_src_get_times (GstBaseSrc *basesrc, GstBuffer *buffer, GstClockTime *start, GstClockTime *end) { rb_debug ("xrbsilencesrc: get_times"); *start = GST_BUFFER_TIMESTAMP (buffer); *end = *start + GST_BUFFER_DURATION (buffer); } static gboolean rb_fm_radio_src_get_size (GstBaseSrc *basesrc, guint64 *size) { rb_debug ("xrbsilencesrc: get_size"); return FALSE; } static gboolean rb_fm_radio_src_is_seekable (GstBaseSrc *basesrc) { rb_debug ("xrbsilencesrc: is_seekable"); return FALSE; } static gboolean rb_fm_radio_src_check_get_range (GstBaseSrc *basesrc) { rb_debug ("xrbsilencesrc: check_get_range"); return TRUE; } static GstFlowReturn rb_fm_radio_src_create (GstBaseSrc *basesrc, guint64 offset, guint length, GstBuffer **buffer) { RBFMRadioSrc *src = RB_FM_RADIO_SRC (basesrc); GstBuffer *buf; /* 16 bits per sample */ length -= length % 2; rb_debug ("xrbsilencesrc: create(%d, %d)", (int)offset, (int)length); buf = gst_buffer_new (); GST_BUFFER_MALLOCDATA (buf) = g_malloc0 (length); GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf); GST_BUFFER_SIZE (buf) = length; GST_BUFFER_TIMESTAMP (buf) = gst_util_uint64_scale_int ( src->next_sample, GST_SECOND, 48000); src->next_sample += length / 2; GST_BUFFER_DURATION (buf) = gst_util_uint64_scale_int ( src->next_sample, GST_SECOND, 48000) - GST_BUFFER_TIMESTAMP (buf); rb_debug ("xrbsilencesrc: %g -> %g", (double)GST_BUFFER_TIMESTAMP (buf) / GST_SECOND, (double)GST_BUFFER_DURATION (buf) / GST_SECOND); *buffer = buf; return GST_FLOW_OK; } static void rb_fm_radio_src_class_init (RBFMRadioSrcClass *klass) { GstElementClass *element_class; GstBaseSrcClass *basesrc_class; basesrc_class = GST_BASE_SRC_CLASS (klass); basesrc_class->start = GST_DEBUG_FUNCPTR (rb_fm_radio_src_start); basesrc_class->stop = GST_DEBUG_FUNCPTR (rb_fm_radio_src_stop); basesrc_class->get_times = GST_DEBUG_FUNCPTR (rb_fm_radio_src_get_times); basesrc_class->get_size = GST_DEBUG_FUNCPTR (rb_fm_radio_src_start); basesrc_class->is_seekable = GST_DEBUG_FUNCPTR (rb_fm_radio_src_is_seekable); basesrc_class->check_get_range = GST_DEBUG_FUNCPTR (rb_fm_radio_src_check_get_range); basesrc_class->create = GST_DEBUG_FUNCPTR (rb_fm_radio_src_create); } /* URI handler interface */ static guint rb_fm_radio_src_uri_get_type (void) { return GST_URI_SRC; } static gchar ** rb_fm_radio_src_uri_get_protocols (void) { static gchar *protocols[] = {"xrbsilence", NULL}; return protocols; } static const gchar * rb_fm_radio_src_uri_get_uri (GstURIHandler *handler) { return "xrbsilence:///"; } static gboolean rb_fm_radio_src_uri_set_uri (GstURIHandler *handler, const gchar *uri) { RBFMRadioSrc *src = RB_FM_RADIO_SRC (handler); char *http_uri; if (g_str_has_prefix (uri, "xrbsilence://") == FALSE) return FALSE; return TRUE; } static void rb_fm_radio_src_uri_handler_init (gpointer g_iface, gpointer iface_data) { GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; iface->get_type = rb_fm_radio_src_uri_get_type; iface->get_protocols = rb_fm_radio_src_uri_get_protocols; iface->get_uri = rb_fm_radio_src_uri_get_uri; iface->set_uri = rb_fm_radio_src_uri_set_uri; } static gboolean plugin_init (GstPlugin *plugin) { gboolean ret = gst_element_register (plugin, "rbsilencesrc", GST_RANK_PRIMARY, RB_TYPE_FM_RADIO_SRC); return ret; } GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR, GST_VERSION_MINOR, "rbsilencesrc", "element to output silence", plugin_init, VERSION, "GPL", PACKAGE, "");