}
static void
-pad_added_cb (GstElement * dbin2, GstPad * pad, gpointer * data)
+pad_added_cb (GstElement * dbin, GstPad * pad, gpointer * data)
{
- GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (data);
+ GstPulseAudioSink *pbin;
GstPad *sinkpad = NULL;
pbin = GST_PULSE_AUDIO_SINK (data);
/* Trap the newsegment events that we feed the decodebin and discard them */
sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink");
- pbin->event_probe_id = gst_pad_add_event_probe_full (sinkpad,
- G_CALLBACK (dbin2_event_probe), gst_object_ref (pbin),
- (GDestroyNotify) gst_object_unref);
++
+ if (pbin->event_probe_id == 0)
+ pbin->event_probe_id =
+ gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+ dbin_event_probe, gst_object_ref (pbin),
+ (GDestroyNotify) gst_object_unref);
++
gst_object_unref (sinkpad);
sinkpad = NULL;
static GstStateChangeReturn gst_pulsesrc_change_state (GstElement *
element, GstStateChange transition);
-static void gst_pulsesrc_init_interfaces (GType type);
-
#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
-# define ENDIANNESS "LITTLE_ENDIAN, BIG_ENDIAN"
+# define FORMATS "{ S16LE, S16BE, F32LE, F32BE, S32LE, S32BE, U8 }"
#else
-# define ENDIANNESS "BIG_ENDIAN, LITTLE_ENDIAN"
-#endif
-
-GST_IMPLEMENT_PULSEMIXER_CTRL_METHODS (GstPulseSrc, gst_pulsesrc);
-GST_IMPLEMENT_PULSEPROBE_METHODS (GstPulseSrc, gst_pulsesrc);
-GST_BOILERPLATE_FULL (GstPulseSrc, gst_pulsesrc, GstAudioSrc,
- GST_TYPE_AUDIO_SRC, gst_pulsesrc_init_interfaces);
-
-static gboolean
-gst_pulsesrc_interface_supported (GstImplementsInterface *
- iface, GType interface_type)
-{
- GstPulseSrc *this = GST_PULSESRC_CAST (iface);
-
- if (interface_type == GST_TYPE_MIXER && this->mixer)
- return TRUE;
-
- if (interface_type == GST_TYPE_PROPERTY_PROBE && this->probe)
- return TRUE;
-
-#ifdef HAVE_PULSE_1_0
- if (interface_type == GST_TYPE_STREAM_VOLUME)
- return TRUE;
+# define FORMATS "{ S16BE, S16LE, F32BE, F32LE, S32BE, S32LE, U8 }"
#endif
- return FALSE;
-}
+static GstStaticPadTemplate pad_template = GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("audio/x-raw, "
+ "format = (string) " FORMATS ", "
+ "rate = (int) [ 1, MAX ], "
+ "channels = (int) [ 1, 32 ];"
+ "audio/x-alaw, "
+ "rate = (int) [ 1, MAX], "
+ "channels = (int) [ 1, 32 ];"
+ "audio/x-mulaw, "
+ "rate = (int) [ 1, MAX], " "channels = (int) [ 1, 32 ]")
+ );
-static void
-gst_pulsesrc_implements_interface_init (GstImplementsInterfaceClass * klass)
-{
- klass->supported = gst_pulsesrc_interface_supported;
-}
-static void
-gst_pulsesrc_init_interfaces (GType type)
-{
-#ifdef HAVE_PULSE_1_0
- static const GInterfaceInfo svol_iface_info = {
- NULL, NULL, NULL,
- };
-#endif
- static const GInterfaceInfo implements_iface_info = {
- (GInterfaceInitFunc) gst_pulsesrc_implements_interface_init,
- NULL,
- NULL,
- };
- static const GInterfaceInfo mixer_iface_info = {
- (GInterfaceInitFunc) gst_pulsesrc_mixer_interface_init,
- NULL,
- NULL,
- };
- static const GInterfaceInfo probe_iface_info = {
- (GInterfaceInitFunc) gst_pulsesrc_property_probe_interface_init,
- NULL,
- NULL,
- };
-
-#ifdef HAVE_PULSE_1_0
- g_type_add_interface_static (type, GST_TYPE_STREAM_VOLUME, &svol_iface_info);
-#endif
- g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
- &implements_iface_info);
- g_type_add_interface_static (type, GST_TYPE_MIXER, &mixer_iface_info);
- g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE,
- &probe_iface_info);
-}
-
-static void
-gst_pulsesrc_base_init (gpointer g_class)
-{
+GST_IMPLEMENT_PULSEMIXER_CTRL_METHODS (GstPulseSrc, gst_pulsesrc);
+GST_IMPLEMENT_PULSEPROBE_METHODS (GstPulseSrc, gst_pulsesrc);
- static GstStaticPadTemplate pad_template = GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
- "endianness = (int) { " ENDIANNESS " }, "
- "signed = (boolean) TRUE, "
- "width = (int) 16, "
- "depth = (int) 16, "
- "rate = (int) [ 1, MAX ], "
- "channels = (int) [ 1, 32 ];"
- "audio/x-raw-float, "
- "endianness = (int) { " ENDIANNESS " }, "
- "width = (int) 32, "
- "rate = (int) [ 1, MAX ], "
- "channels = (int) [ 1, 32 ];"
- "audio/x-raw-int, "
- "endianness = (int) { " ENDIANNESS " }, "
- "signed = (boolean) TRUE, "
- "width = (int) 32, "
- "depth = (int) 32, "
- "rate = (int) [ 1, MAX ], "
- "channels = (int) [ 1, 32 ];"
- "audio/x-raw-int, "
- "signed = (boolean) FALSE, "
- "width = (int) 8, "
- "depth = (int) 8, "
- "rate = (int) [ 1, MAX ], "
- "channels = (int) [ 1, 32 ];"
- "audio/x-alaw, "
- "rate = (int) [ 1, MAX], "
- "channels = (int) [ 1, 32 ];"
- "audio/x-mulaw, "
- "rate = (int) [ 1, MAX], " "channels = (int) [ 1, 32 ]")
- );
-
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_set_details_simple (element_class,
- "PulseAudio Audio Source",
- "Source/Audio",
- "Captures audio from a PulseAudio server", "Lennart Poettering");
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&pad_template));
-}
+#define gst_pulsesrc_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstPulseSrc, gst_pulsesrc, GST_TYPE_AUDIO_SRC,
+ G_IMPLEMENT_INTERFACE (GST_TYPE_MIXER, gst_pulsesrc_mixer_interface_init);
+ G_IMPLEMENT_INTERFACE (GST_TYPE_PROPERTY_PROBE,
- gst_pulsesrc_property_probe_interface_init));
++ gst_pulsesrc_property_probe_interface_init);
++ G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL));
static void
gst_pulsesrc_class_init (GstPulseSrcClass * klass)
"record stream", 0, G_MAXUINT, PA_INVALID_INDEX,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ gst_element_class_set_details_simple (gstelement_class,
+ "PulseAudio Audio Source",
+ "Source/Audio",
+ "Captures audio from a PulseAudio server", "Lennart Poettering");
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&pad_template));
++
+ #ifdef HAVE_PULSE_1_0
+ /**
+ * GstPulseSrc:volume
+ *
+ * The volume of the record stream. Only works when using PulseAudio 1.0 or
+ * later.
+ *
+ * Since: 0.10.36
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_VOLUME, g_param_spec_double ("volume", "Volume",
+ "Linear volume of this stream, 1.0=100%",
+ 0.0, MAX_VOLUME, DEFAULT_VOLUME,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GstPulseSrc:mute
+ *
+ * Whether the stream is muted or not. Only works when using PulseAudio 1.0
+ * or later.
+ *
+ * Since: 0.10.36
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_MUTE, g_param_spec_boolean ("mute", "Mute",
+ "Mute state of this stream",
+ DEFAULT_MUTE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ #endif
}
static void
pa_sample_spec_init (&pulsesrc->sample_spec);
pulsesrc->operation_success = FALSE;
- pulsesrc->paused = FALSE;
+ pulsesrc->paused = TRUE;
pulsesrc->in_read = FALSE;
+ #ifdef HAVE_PULSE_1_0
+ pulsesrc->volume = DEFAULT_VOLUME;
+ pulsesrc->volume_set = FALSE;
+
+ pulsesrc->mute = DEFAULT_MUTE;
+ pulsesrc->mute_set = FALSE;
+
+ pulsesrc->notify = 0;
+ #endif
+
pulsesrc->mixer = NULL;
pulsesrc->properties = NULL;
GST_INFO_OBJECT (pulsesrc, "minreq: %d", wanted.minreq);
GST_INFO_OBJECT (pulsesrc, "fragsize: %d", wanted.fragsize);
+ flags = PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE |
+ PA_STREAM_NOT_MONOTONIC | PA_STREAM_ADJUST_LATENCY |
+ PA_STREAM_START_CORKED;
+
+ #ifdef HAVE_PULSE_1_0
+ if (pulsesrc->mute_set && pulsesrc->mute)
+ flags |= PA_STREAM_START_MUTED;
+ #endif
+
if (pa_stream_connect_record (pulsesrc->stream, pulsesrc->device, &wanted,
- PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE |
- PA_STREAM_NOT_MONOTONIC | PA_STREAM_ADJUST_LATENCY |
- PA_STREAM_START_CORKED) < 0)
+ flags) < 0) {
- GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED,
- ("Failed to connect stream: %s",
- pa_strerror (pa_context_errno (pulsesrc->context))), (NULL));
- goto unlock_and_fail;
+ goto connect_failed;
+ }
pulsesrc->corked = TRUE;
GstPulseMixerCtrl *mixer;
GstPulseProbe *probe;
+ #ifdef HAVE_PULSE_1_0
+ gdouble volume;
+ gboolean volume_set:1;
+ gboolean mute:1;
+ gboolean mute_set:1;
+
+ gint notify; /* atomic */
+ #endif
+
gboolean corked:1;
+ gboolean stream_connected:1;
gboolean operation_success:1;
gboolean paused:1;
gboolean in_read:1;
static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse,
GstCaps * caps);
-static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse);
++static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse,
++ GstCaps * filter);
- gboolean gst_aac_parse_check_valid_frame (GstBaseParse * parse,
+ static gboolean gst_aac_parse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * size, gint * skipsize);
- GstFlowReturn gst_aac_parse_parse_frame (GstBaseParse * parse,
+ static GstFlowReturn gst_aac_parse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
-#define _do_init(bla) \
- GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0, \
- "AAC audio stream parser");
+gboolean gst_aac_parse_convert (GstBaseParse * parse,
+ GstFormat src_format,
+ gint64 src_value, GstFormat dest_format, gint64 * dest_value);
-GST_BOILERPLATE_FULL (GstAacParse, gst_aac_parse, GstBaseParse,
- GST_TYPE_BASE_PARSE, _do_init);
+gint gst_aac_parse_get_frame_overhead (GstBaseParse * parse,
+ GstBuffer * buffer);
+
+gboolean gst_aac_parse_event (GstBaseParse * parse, GstEvent * event);
+
+G_DEFINE_TYPE (GstAacParse, gst_aac_parse, GST_TYPE_BASE_PARSE);
static inline gint
gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
GST_DEBUG ("stop");
return TRUE;
}
-gst_aac_parse_sink_getcaps (GstBaseParse * parse)
+
+ static GstCaps *
++gst_aac_parse_sink_getcaps (GstBaseParse * parse, GstCaps * filter)
+ {
+ GstCaps *peercaps;
+ GstCaps *res;
+
++ /* FIXME: handle filter caps */
++
+ peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
+ if (peercaps) {
+ guint i, n;
+
+ /* Remove the framed field */
+ peercaps = gst_caps_make_writable (peercaps);
+ n = gst_caps_get_size (peercaps);
+ for (i = 0; i < n; i++) {
+ GstStructure *s = gst_caps_get_structure (peercaps, i);
+
+ gst_structure_remove_field (s, "framed");
+ }
+
+ res =
+ gst_caps_intersect_full (peercaps,
+ gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)),
+ GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (peercaps);
+ } else {
+ res =
+ gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD
+ (parse)));
+ }
+
+ return res;
+ }
GstBaseParseFrame * frame);
static gboolean gst_ac3_parse_src_event (GstBaseParse * parse,
GstEvent * event);
-static GstCaps *gst_ac3_parse_get_sink_caps (GstBaseParse * parse);
++static GstCaps *gst_ac3_parse_get_sink_caps (GstBaseParse * parse,
++ GstCaps * filter);
-GST_BOILERPLATE (GstAc3Parse, gst_ac3_parse, GstBaseParse, GST_TYPE_BASE_PARSE);
+#define gst_ac3_parse_parent_class parent_class
+G_DEFINE_TYPE (GstAc3Parse, gst_ac3_parse, GST_TYPE_BASE_PARSE);
static void
-gst_ac3_parse_base_init (gpointer klass)
+gst_ac3_parse_class_init (GstAc3ParseClass * klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+ GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
+
+ GST_DEBUG_CATEGORY_INIT (ac3_parse_debug, "ac3parse", 0,
+ "AC3 audio stream parser");
+
+ object_class->finalize = gst_ac3_parse_finalize;
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_template));
return GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
}
-gst_ac3_parse_get_sink_caps (GstBaseParse * parse)
+
+ static GstCaps *
++gst_ac3_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
+ {
+ GstCaps *peercaps;
+ GstCaps *res;
+
++ /* FIXME: handle filter */
++
+ peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
+ if (peercaps) {
+ guint i, n;
+
+ /* Remove the framed and alignment field. We can convert
+ * between different alignments. */
+ peercaps = gst_caps_make_writable (peercaps);
+ n = gst_caps_get_size (peercaps);
+ for (i = 0; i < n; i++) {
+ GstStructure *s = gst_caps_get_structure (peercaps, i);
+
+ gst_structure_remove_field (s, "framed");
+ gst_structure_remove_field (s, "alignment");
+ }
+
+ res =
+ gst_caps_intersect_full (peercaps,
+ gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)),
+ GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (peercaps);
+ } else {
+ res =
+ gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD
+ (parse)));
+ }
+
+ return res;
+ }
static gboolean gst_amr_parse_sink_setcaps (GstBaseParse * parse,
GstCaps * caps);
-static GstCaps *gst_amr_parse_sink_getcaps (GstBaseParse * parse);
++static GstCaps *gst_amr_parse_sink_getcaps (GstBaseParse * parse,
++ GstCaps * filter);
- gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse,
+ static gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse,
GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
- GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse,
+ static GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
-#define _do_init(bla) \
- GST_DEBUG_CATEGORY_INIT (amrparse_debug, "amrparse", 0, \
- "AMR-NB audio stream parser");
-
-GST_BOILERPLATE_FULL (GstAmrParse, gst_amr_parse, GstBaseParse,
- GST_TYPE_BASE_PARSE, _do_init);
+G_DEFINE_TYPE (GstAmrParse, gst_amr_parse, GST_TYPE_BASE_PARSE);
/**
- * gst_amr_parse_base_init:
- * @klass: #GstElementClass.
+ * gst_amr_parse_class_init:
+ * @klass: GstAmrParseClass.
*
*/
static void
amrparse->header = 0;
return TRUE;
}
-gst_amr_parse_sink_getcaps (GstBaseParse * parse)
+
+ static GstCaps *
++gst_amr_parse_sink_getcaps (GstBaseParse * parse, GstCaps * filter)
+ {
+ GstCaps *peercaps;
+ GstCaps *res;
+
++ /* FIXME: handle filter caps */
++
+ peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
+ if (peercaps) {
+ guint i, n;
+
+ /* Rename structure names */
+ peercaps = gst_caps_make_writable (peercaps);
+ n = gst_caps_get_size (peercaps);
+ for (i = 0; i < n; i++) {
+ GstStructure *s = gst_caps_get_structure (peercaps, i);
+
+ if (gst_structure_has_name (s, "audio/AMR"))
+ gst_structure_set_name (s, "audio/x-amr-nb-sh");
+ else
+ gst_structure_set_name (s, "audio/x-amr-wb-sh");
+ }
+
+ res =
+ gst_caps_intersect_full (peercaps,
+ gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)),
+ GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (peercaps);
+ } else {
+ res =
+ gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD
+ (parse)));
+ }
+
+ return res;
+ }
GstBaseParseFrame * frame, guint * size, gint * skipsize);
static GstFlowReturn gst_dca_parse_parse_frame (GstBaseParse * parse,
GstBaseParseFrame * frame);
-static GstCaps *gst_dca_parse_get_sink_caps (GstBaseParse * parse);
++static GstCaps *gst_dca_parse_get_sink_caps (GstBaseParse * parse,
++ GstCaps * filter);
-GST_BOILERPLATE (GstDcaParse, gst_dca_parse, GstBaseParse, GST_TYPE_BASE_PARSE);
-
-static void
-gst_dca_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 (&sink_template));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_template));
-
- gst_element_class_set_details_simple (element_class,
- "DTS Coherent Acoustics audio stream parser", "Codec/Parser/Audio",
- "DCA parser", "Tim-Philipp Müller <tim centricular net>");
-}
+#define gst_dca_parse_parent_class parent_class
+G_DEFINE_TYPE (GstDcaParse, gst_dca_parse, GST_TYPE_BASE_PARSE);
static void
gst_dca_parse_class_init (GstDcaParseClass * klass)
parse_class->check_valid_frame =
GST_DEBUG_FUNCPTR (gst_dca_parse_check_valid_frame);
parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_dca_parse_parse_frame);
+ parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_dca_parse_get_sink_caps);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_template));
+
+ gst_element_class_set_details_simple (element_class,
+ "DTS Coherent Acoustics audio stream parser", "Codec/Parser/Audio",
+ "DCA parser", "Tim-Philipp Müller <tim centricular net>");
}
static void
return GST_FLOW_ERROR;
}
}
-gst_dca_parse_get_sink_caps (GstBaseParse * parse)
+
+ static GstCaps *
++gst_dca_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
+ {
+ GstCaps *peercaps;
+ GstCaps *res;
+
++ /* FIXME: handle filter caps */
++
+ peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
+ if (peercaps) {
+ guint i, n;
+
+ /* Remove the framed field */
+ peercaps = gst_caps_make_writable (peercaps);
+ n = gst_caps_get_size (peercaps);
+ for (i = 0; i < n; i++) {
+ GstStructure *s = gst_caps_get_structure (peercaps, i);
+
+ gst_structure_remove_field (s, "framed");
+ }
+
+ res =
+ gst_caps_intersect_full (peercaps,
+ gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)),
+ GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (peercaps);
+ } else {
+ res =
+ gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD
+ (parse)));
+ }
+
+ return res;
+ }
static gboolean gst_flac_parse_convert (GstBaseParse * parse,
GstFormat src_format, gint64 src_value, GstFormat dest_format,
gint64 * dest_value);
-static GstCaps *gst_flac_parse_get_sink_caps (GstBaseParse * parse);
++static GstCaps *gst_flac_parse_get_sink_caps (GstBaseParse * parse,
++ GstCaps * filter);
-GST_BOILERPLATE (GstFlacParse, gst_flac_parse, GstBaseParse,
- GST_TYPE_BASE_PARSE);
-
-static void
-gst_flac_parse_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 (&src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_factory));
-
- gst_element_class_set_details_simple (element_class, "FLAC audio parser",
- "Codec/Parser/Audio",
- "Parses audio with the FLAC lossless audio codec",
- "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-
- GST_DEBUG_CATEGORY_INIT (flacparse_debug, "flacparse", 0,
- "Flac parser element");
-}
+#define gst_flac_parse_parent_class parent_class
+G_DEFINE_TYPE (GstFlacParse, gst_flac_parse, GST_TYPE_BASE_PARSE);
static void
gst_flac_parse_class_init (GstFlacParseClass * klass)
baseparse_class->pre_push_frame =
GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_frame);
baseparse_class->convert = GST_DEBUG_FUNCPTR (gst_flac_parse_convert);
+ baseparse_class->get_sink_caps =
+ GST_DEBUG_FUNCPTR (gst_flac_parse_get_sink_caps);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_factory));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_factory));
+
+ gst_element_class_set_details_simple (element_class, "FLAC audio parser",
+ "Codec/Parser/Audio",
+ "Parses audio with the FLAC lossless audio codec",
+ "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
}
static void
return GST_BASE_PARSE_CLASS (parent_class)->convert (parse, src_format,
src_value, dest_format, dest_value);
}
-gst_flac_parse_get_sink_caps (GstBaseParse * parse)
+
+ static GstCaps *
++gst_flac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
+ {
+ GstCaps *peercaps;
+ GstCaps *res;
+
++ /* FIXME: handle filter caps */
++
+ peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
+ if (peercaps) {
+ guint i, n;
+
+ /* Remove the framed field */
+ peercaps = gst_caps_make_writable (peercaps);
+ n = gst_caps_get_size (peercaps);
+ for (i = 0; i < n; i++) {
+ GstStructure *s = gst_caps_get_structure (peercaps, i);
+
+ gst_structure_remove_field (s, "framed");
+ }
+
+ res =
+ gst_caps_intersect_full (peercaps,
+ gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)),
+ GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (peercaps);
+ } else {
+ res =
+ gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD
+ (parse)));
+ }
+
+ return res;
+ }
static gboolean gst_mpeg_audio_parse_convert (GstBaseParse * parse,
GstFormat src_format, gint64 src_value,
GstFormat dest_format, gint64 * dest_value);
-static GstCaps *gst_mpeg_audio_parse_get_sink_caps (GstBaseParse * parse);
++static GstCaps *gst_mpeg_audio_parse_get_sink_caps (GstBaseParse * parse,
++ GstCaps * filter);
-GST_BOILERPLATE (GstMpegAudioParse, gst_mpeg_audio_parse, GstBaseParse,
- GST_TYPE_BASE_PARSE);
+#define gst_mpeg_audio_parse_parent_class parent_class
+G_DEFINE_TYPE (GstMpegAudioParse, gst_mpeg_audio_parse, GST_TYPE_BASE_PARSE);
#define GST_TYPE_MPEG_AUDIO_CHANNEL_MODE \
(gst_mpeg_audio_channel_mode_get_type())
return GST_FLOW_OK;
}
-gst_mpeg_audio_parse_get_sink_caps (GstBaseParse * parse)
+
+ static GstCaps *
++gst_mpeg_audio_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
+ {
+ GstCaps *peercaps;
+ GstCaps *res;
+
++ /* FIXME: handle filter caps */
++
+ peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
+ if (peercaps) {
+ guint i, n;
+
+ /* Remove the parsed field */
+ peercaps = gst_caps_make_writable (peercaps);
+ n = gst_caps_get_size (peercaps);
+ for (i = 0; i < n; i++) {
+ GstStructure *s = gst_caps_get_structure (peercaps, i);
+
+ gst_structure_remove_field (s, "parsed");
+ }
+
+ res =
+ gst_caps_intersect_full (peercaps,
+ gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)),
+ GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (peercaps);
+ } else {
+ res =
+ gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD
+ (parse)));
+ }
+
+ return res;
+ }
#define RATIO 0.95
static guint32 palettes[COLORS * PATTERN];
+ static gint swap_tab[] = { 2, 1, 0, 3 };
-GST_BOILERPLATE (GstRadioacTV, gst_radioactv, GstVideoFilter,
- GST_TYPE_VIDEO_FILTER);
+#define gst_radioactv_parent_class parent_class
+G_DEFINE_TYPE (GstRadioacTV, gst_radioactv, GST_TYPE_VIDEO_FILTER);
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- #define CAPS_STR GST_VIDEO_CAPS_MAKE ("RGBx")
-#define CAPS_STR GST_VIDEO_CAPS_RGBx "; " GST_VIDEO_CAPS_BGRx
++#define CAPS_STR GST_VIDEO_CAPS_MAKE ("{ RGBx, BGRx }")
#else
- #define CAPS_STR GST_VIDEO_CAPS_MAKE ("xBGR")
-#define CAPS_STR GST_VIDEO_CAPS_xBGR "; " GST_VIDEO_CAPS_xRGB
++#define CAPS_STR GST_VIDEO_CAPS_MAKE ("{ xBGR, xRGB }")
#endif
static GstStaticPadTemplate gst_radioactv_src_template =
GST_TIME_ARGS (timestamp));
if (GST_CLOCK_TIME_IS_VALID (stream_time))
- gst_object_sync_values (G_OBJECT (filter), stream_time);
+ gst_object_sync_values (GST_OBJECT (filter), stream_time);
+
+ if (!gst_video_frame_map (&in_frame, &filter->info, in, GST_MAP_READ))
+ goto invalid_in;
+
+ if (!gst_video_frame_map (&out_frame, &filter->info, out, GST_MAP_WRITE))
+ goto invalid_out;
- src = (guint32 *) GST_BUFFER_DATA (in);
- dest = (guint32 *) GST_BUFFER_DATA (out);
+ src = GST_VIDEO_FRAME_PLANE_DATA (&in_frame, 0);
+ dest = GST_VIDEO_FRAME_PLANE_DATA (&out_frame, 0);
+
+ width = GST_VIDEO_FRAME_WIDTH (&in_frame);
+ height = GST_VIDEO_FRAME_HEIGHT (&in_frame);
GST_OBJECT_LOCK (filter);
- palette = &palettes[COLORS * filter->color];
+ #if G_BYTE_ORDER == G_LITTLE_ENDIAN
- if (filter->format == GST_VIDEO_FORMAT_RGBx) {
++ if (GST_VIDEO_FRAME_FORMAT (&in_frame) == GST_VIDEO_FORMAT_RGBx) {
+ palette = &palettes[COLORS * filter->color];
+ } else {
+ palette = &palettes[COLORS * swap_tab[filter->color]];
+ }
+ #else
- if (filter->format == GST_VIDEO_FORMAT_xBGR) {
++ if (GST_VIDEO_FRAME_FORMAT (&in_frame) == GST_VIDEO_FORMAT_xBGR) {
+ palette = &palettes[COLORS * filter->color];
+ } else {
+ palette = &palettes[COLORS * swap_tab[filter->color]];
+ }
+ #endif
diff = filter->diff;
if (filter->mode == 3 && filter->trigger)
{
GstRippleTV *filter = GST_RIPPLETV (trans);
guint32 *src, *dest;
- GstFlowReturn ret = GST_FLOW_OK;
+ GstVideoFrame in_frame, out_frame;
gint x, y, i;
- gint dx, dy;
+ gint dx, dy, o_dx;
gint h, v;
- gint width, height;
+ gint m_w, m_h, v_w, v_h;
gint *p, *q, *r;
gint8 *vp;
GstClockTime timestamp, stream_time;
else
motiondetect (filter, src);
- v_w = filter->width;
- v_h = filter->height;
+ m_w = filter->map_w;
+ m_h = filter->map_h;
++ v_w = GST_VIDEO_FRAME_WIDTH (&in_frame);
++ v_h = GST_VIDEO_FRAME_HEIGHT (&in_frame);
+
/* simulate surface wave */
- width = filter->map_w;
- height = filter->map_h;
/* This function is called only 30 times per second. To increase a speed
* of wave, iterates this loop several times. */
GstCaps * outcaps)
{
GstRippleTV *filter = GST_RIPPLETV (btrans);
- GstStructure *structure;
- gboolean ret = FALSE;
+ GstVideoInfo info;
+ gint width, height;
- structure = gst_caps_get_structure (incaps, 0);
+ if (!gst_video_info_from_caps (&info, incaps))
+ goto invalid_caps;
- GST_OBJECT_LOCK (filter);
- if (gst_structure_get_int (structure, "width", &filter->width) &&
- gst_structure_get_int (structure, "height", &filter->height)) {
+ filter->info = info;
- filter->map_h = filter->height / 2 + 1;
- filter->map_w = filter->width / 2 + 1;
+ width = GST_VIDEO_INFO_WIDTH (&info);
+ height = GST_VIDEO_INFO_HEIGHT (&info);
- /* we over allocate the buffers, as the render code does not handle clipping
- * very well */
- if (filter->map)
- g_free (filter->map);
- filter->map = g_new0 (gint, (1 + filter->map_h) * filter->map_w * 3);
+ GST_OBJECT_LOCK (filter);
+ filter->map_h = height / 2 + 1;
+ filter->map_w = width / 2 + 1;
- filter->map1 = filter->map;
- filter->map2 = filter->map + filter->map_w * filter->map_h;
- filter->map3 = filter->map + filter->map_w * filter->map_h * 2;
++ /* we over allocate the buffers, as the render code does not handle clipping
++ * very well */
+ if (filter->map)
+ g_free (filter->map);
- filter->map = g_new0 (gint, filter->map_h * filter->map_w * 3);
++ filter->map = g_new0 (gint, (1 + filter->map_h) * filter->map_w * 3);
- if (filter->vtable)
- g_free (filter->vtable);
- filter->vtable = g_new0 (gint8, (1 + filter->map_h) * filter->map_w * 2);
+ filter->map1 = filter->map;
+ filter->map2 = filter->map + filter->map_w * filter->map_h;
+ filter->map3 = filter->map + filter->map_w * filter->map_h * 2;
- if (filter->background)
- g_free (filter->background);
- filter->background = g_new0 (gint16, filter->width * (filter->height + 1));
+ if (filter->vtable)
+ g_free (filter->vtable);
- filter->vtable = g_new0 (gint8, filter->map_h * filter->map_w * 2);
++ filter->vtable = g_new0 (gint8, (1 + filter->map_h) * filter->map_w * 2);
- if (filter->diff)
- g_free (filter->diff);
- filter->diff = g_new0 (guint8, filter->width * (filter->height + 1));
+ if (filter->background)
+ g_free (filter->background);
- filter->background = g_new0 (gint16, width * height);
++ filter->background = g_new0 (gint16, width * (height + 1));
- ret = TRUE;
- }
+ if (filter->diff)
+ g_free (filter->diff);
- filter->diff = g_new0 (guint8, width * height);
++ filter->diff = g_new0 (guint8, width * (height + 1));
GST_OBJECT_UNLOCK (filter);
- return ret;
+ return TRUE;
+
+ /* ERRORS */
+invalid_caps:
+ {
+ GST_DEBUG_OBJECT (filter, "invalid caps received");
+ return FALSE;
+ }
}
static gboolean
}
static void
-gst_streaktv_init (GstStreakTV * filter, GstStreakTVClass * klass)
+gst_streaktv_init (GstStreakTV * filter)
{
filter->feedback = DEFAULT_FEEDBACK;
-
- gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter));
- gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter));
}
{
gint32 halfw, halfh, *distptr;
gint x, y;
- #ifdef PS2
- float m;
- #else
float m;
- #endif
- halfw = filter->width >> 1;
- halfh = filter->height >> 1;
+ halfw = width >> 1;
+ halfh = height >> 1;
distptr = filter->disttable;
}
static void
-gst_warptv_init (GstWarpTV * warptv, GstWarpTVClass * klass)
+gst_warptv_init (GstWarpTV * warptv)
{
- gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (warptv));
- gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (warptv));
+ /* nothing to do */
}