diff options
author | Tim-Philipp Müller <tim.muller@collabora.co.uk> | 2011-11-26 13:34:10 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim.muller@collabora.co.uk> | 2011-11-26 13:34:10 +0000 |
commit | be0d6baac5960546ce7e3d812734481580078f9e (patch) | |
tree | 28afa7224232fbe31d8c6e4bb7c564bb0d5d977f | |
parent | a806ae2edddb0dd3fb82fda6fd2078c5fa2acab1 (diff) | |
parent | a3bc43192477baf4a8a0510fd55a762a408955c0 (diff) |
Merge remote-tracking branch 'origin/master' into 0.11
Conflicts:
ext/pulse/pulseaudiosink.c
ext/pulse/pulsesrc.c
gst/audioparsers/gstaacparse.c
gst/audioparsers/gstamrparse.c
gst/audioparsers/gstdcaparse.c
gst/audioparsers/gstflacparse.c
gst/effectv/gstradioac.c
gst/effectv/gstradioac.h
gst/effectv/gstripple.c
Some possible FIXMEs remaining in the audio parser getcaps functions.
-rw-r--r-- | ext/pulse/pulseaudiosink.c | 4 | ||||
-rw-r--r-- | ext/pulse/pulsesrc.c | 409 | ||||
-rw-r--r-- | ext/pulse/pulsesrc.h | 9 | ||||
-rw-r--r-- | gst/audioparsers/gstaacparse.c | 54 | ||||
-rw-r--r-- | gst/audioparsers/gstac3parse.c | 41 | ||||
-rw-r--r-- | gst/audioparsers/gstamrparse.c | 57 | ||||
-rw-r--r-- | gst/audioparsers/gstdcaparse.c | 38 | ||||
-rw-r--r-- | gst/audioparsers/gstflacparse.c | 39 | ||||
-rw-r--r-- | gst/audioparsers/gstmpegaudioparse.c | 39 | ||||
-rw-r--r-- | gst/effectv/gstedge.c | 6 | ||||
-rw-r--r-- | gst/effectv/gstquark.c | 3 | ||||
-rw-r--r-- | gst/effectv/gstradioac.c | 26 | ||||
-rw-r--r-- | gst/effectv/gstripple.c | 99 | ||||
-rw-r--r-- | gst/effectv/gstshagadelic.c | 3 | ||||
-rw-r--r-- | gst/effectv/gststreak.c | 3 | ||||
-rw-r--r-- | gst/effectv/gstvertigo.c | 3 | ||||
-rw-r--r-- | gst/effectv/gstwarp.c | 7 | ||||
-rw-r--r-- | gst/flv/gstflvdemux.c | 14 | ||||
-rw-r--r-- | gst/isomp4/gstqtmuxmap.c | 2 | ||||
-rw-r--r-- | gst/multifile/gstmultifilesink.c | 1 | ||||
-rw-r--r-- | gst/wavparse/gstwavparse.c | 3 | ||||
-rw-r--r-- | tests/check/elements/multifile.c | 13 |
22 files changed, 753 insertions, 120 deletions
diff --git a/ext/pulse/pulseaudiosink.c b/ext/pulse/pulseaudiosink.c index f77e1653e..e5e9ee447 100644 --- a/ext/pulse/pulseaudiosink.c +++ b/ext/pulse/pulseaudiosink.c @@ -535,7 +535,7 @@ dbin_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data) static void 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); @@ -584,11 +584,13 @@ gst_pulse_audio_sink_add_dbin (GstPulseAudioSink * pbin) /* Trap the newsegment events that we feed the decodebin and discard them */ sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink"); + 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; diff --git a/ext/pulse/pulsesrc.c b/ext/pulse/pulsesrc.c index 59dc96ede..7dddf9f33 100644 --- a/ext/pulse/pulsesrc.c +++ b/ext/pulse/pulsesrc.c @@ -43,6 +43,9 @@ #include <gst/base/gstbasesrc.h> #include <gst/gsttaglist.h> +#ifdef HAVE_PULSE_1_0 +#include <gst/interfaces/streamvolume.h> +#endif #include "pulsesrc.h" #include "pulseutil.h" @@ -55,6 +58,12 @@ GST_DEBUG_CATEGORY_EXTERN (pulse_debug); #define DEFAULT_DEVICE NULL #define DEFAULT_DEVICE_NAME NULL +#ifdef HAVE_PULSE_1_0 +#define DEFAULT_VOLUME 1.0 +#define DEFAULT_MUTE FALSE +#define MAX_VOLUME 10.0 +#endif + enum { PROP_0, @@ -64,6 +73,10 @@ enum PROP_CLIENT, PROP_STREAM_PROPERTIES, PROP_SOURCE_OUTPUT_INDEX, +#ifdef HAVE_PULSE_1_0 + PROP_VOLUME, + PROP_MUTE, +#endif PROP_LAST }; @@ -126,7 +139,8 @@ GST_IMPLEMENT_PULSEPROBE_METHODS (GstPulseSrc, gst_pulsesrc); 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) @@ -174,7 +188,7 @@ gst_pulsesrc_class_init (GstPulseSrcClass * klass) clientname = gst_pulse_client_name (); /** - * GstPulseSink:client + * GstPulseSrc:client * * The PulseAudio client name to use. * @@ -230,6 +244,35 @@ gst_pulsesrc_class_init (GstPulseSrcClass * klass) "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 @@ -254,6 +297,16 @@ gst_pulsesrc_init (GstPulseSrc * pulsesrc) 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; @@ -290,7 +343,15 @@ gst_pulsesrc_destroy_context (GstPulseSrc * pulsesrc) if (pulsesrc->context) { pa_context_disconnect (pulsesrc->context); + + /* Make sure we don't get any further callbacks */ + pa_context_set_state_callback (pulsesrc->context, NULL, NULL); +#ifdef HAVE_PULSE_1_0 + pa_context_set_subscribe_callback (pulsesrc->context, NULL, NULL); +#endif + pa_context_unref (pulsesrc->context); + pulsesrc->context = NULL; } } @@ -408,6 +469,260 @@ no_mainloop: } } +#ifdef HAVE_PULSE_1_0 +static void +gst_pulsesrc_source_output_info_cb (pa_context * c, + const pa_source_output_info * i, int eol, void *userdata) +{ + GstPulseSrc *psrc; + + psrc = GST_PULSESRC_CAST (userdata); + + if (!i) + goto done; + + /* If the index doesn't match our current stream, + * it implies we just recreated the stream (caps change) + */ + if (i->index == psrc->source_output_idx) { + psrc->volume = pa_sw_volume_to_linear (pa_cvolume_max (&i->volume)); + psrc->mute = i->mute; + } + +done: + pa_threaded_mainloop_signal (psrc->mainloop, 0); +} + +static gdouble +gst_pulsesrc_get_stream_volume (GstPulseSrc * pulsesrc) +{ + pa_operation *o = NULL; + gdouble v; + + if (!pulsesrc->mainloop) + goto no_mainloop; + + if (pulsesrc->source_output_idx == PA_INVALID_INDEX) + goto no_index; + + pa_threaded_mainloop_lock (pulsesrc->mainloop); + + if (!(o = pa_context_get_source_output_info (pulsesrc->context, + pulsesrc->source_output_idx, gst_pulsesrc_source_output_info_cb, + pulsesrc))) + goto info_failed; + + while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) { + pa_threaded_mainloop_wait (pulsesrc->mainloop); + if (gst_pulsesrc_is_dead (pulsesrc, TRUE)) + goto unlock; + } + +unlock: + v = pulsesrc->volume; + + if (o) + pa_operation_unref (o); + + pa_threaded_mainloop_unlock (pulsesrc->mainloop); + + if (v > MAX_VOLUME) { + GST_WARNING_OBJECT (pulsesrc, "Clipped volume from %f to %f", v, + MAX_VOLUME); + v = MAX_VOLUME; + } + + return v; + + /* ERRORS */ +no_mainloop: + { + v = pulsesrc->volume; + GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop"); + return v; + } +no_index: + { + v = pulsesrc->volume; + GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index"); + return v; + } +info_failed: + { + GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, + ("pa_context_get_source_output_info() failed: %s", + pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); + goto unlock; + } +} + +static gboolean +gst_pulsesrc_get_stream_mute (GstPulseSrc * pulsesrc) +{ + pa_operation *o = NULL; + gboolean mute; + + if (!pulsesrc->mainloop) + goto no_mainloop; + + if (pulsesrc->source_output_idx == PA_INVALID_INDEX) + goto no_index; + + pa_threaded_mainloop_lock (pulsesrc->mainloop); + + if (!(o = pa_context_get_source_output_info (pulsesrc->context, + pulsesrc->source_output_idx, gst_pulsesrc_source_output_info_cb, + pulsesrc))) + goto info_failed; + + while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) { + pa_threaded_mainloop_wait (pulsesrc->mainloop); + if (gst_pulsesrc_is_dead (pulsesrc, TRUE)) + goto unlock; + } + +unlock: + mute = pulsesrc->mute; + + if (o) + pa_operation_unref (o); + + pa_threaded_mainloop_unlock (pulsesrc->mainloop); + + return mute; + + /* ERRORS */ +no_mainloop: + { + mute = pulsesrc->mute; + GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop"); + return mute; + } +no_index: + { + mute = pulsesrc->mute; + GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index"); + return mute; + } +info_failed: + { + GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, + ("pa_context_get_source_output_info() failed: %s", + pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); + goto unlock; + } +} + +static void +gst_pulsesrc_set_stream_volume (GstPulseSrc * pulsesrc, gdouble volume) +{ + pa_cvolume v; + pa_operation *o = NULL; + + if (!pulsesrc->mainloop) + goto no_mainloop; + + if (!pulsesrc->source_output_idx) + goto no_index; + + pa_threaded_mainloop_lock (pulsesrc->mainloop); + + GST_DEBUG_OBJECT (pulsesrc, "setting volume to %f", volume); + + gst_pulse_cvolume_from_linear (&v, pulsesrc->sample_spec.channels, volume); + + if (!(o = pa_context_set_source_output_volume (pulsesrc->context, + pulsesrc->source_output_idx, &v, NULL, NULL))) + goto volume_failed; + + /* We don't really care about the result of this call */ +unlock: + + if (o) + pa_operation_unref (o); + + pa_threaded_mainloop_unlock (pulsesrc->mainloop); + + return; + + /* ERRORS */ +no_mainloop: + { + pulsesrc->volume = volume; + pulsesrc->volume_set = TRUE; + GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop"); + return; + } +no_index: + { + pulsesrc->volume = volume; + pulsesrc->volume_set = TRUE; + GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index"); + return; + } +volume_failed: + { + GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, + ("pa_stream_set_source_output_volume() failed: %s", + pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); + goto unlock; + } +} + +static void +gst_pulsesrc_set_stream_mute (GstPulseSrc * pulsesrc, gboolean mute) +{ + pa_operation *o = NULL; + + if (!pulsesrc->mainloop) + goto no_mainloop; + + if (!pulsesrc->source_output_idx) + goto no_index; + + pa_threaded_mainloop_lock (pulsesrc->mainloop); + + GST_DEBUG_OBJECT (pulsesrc, "setting mute state to %d", mute); + + if (!(o = pa_context_set_source_output_mute (pulsesrc->context, + pulsesrc->source_output_idx, mute, NULL, NULL))) + goto mute_failed; + + /* We don't really care about the result of this call */ +unlock: + + if (o) + pa_operation_unref (o); + + pa_threaded_mainloop_unlock (pulsesrc->mainloop); + + return; + + /* ERRORS */ +no_mainloop: + { + pulsesrc->mute = mute; + pulsesrc->mute_set = TRUE; + GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop"); + return; + } +no_index: + { + pulsesrc->mute = mute; + pulsesrc->mute_set = TRUE; + GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index"); + return; + } +mute_failed: + { + GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, + ("pa_stream_set_source_output_mute() failed: %s", + pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); + goto unlock; + } +} +#endif + static void gst_pulsesrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -444,6 +759,14 @@ gst_pulsesrc_set_property (GObject * object, pa_proplist_free (pulsesrc->proplist); pulsesrc->proplist = gst_pulse_make_proplist (pulsesrc->properties); break; +#ifdef HAVE_PULSE_1_0 + case PROP_VOLUME: + gst_pulsesrc_set_stream_volume (pulsesrc, g_value_get_double (value)); + break; + case PROP_MUTE: + gst_pulsesrc_set_stream_mute (pulsesrc, g_value_get_boolean (value)); + break; +#endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -476,6 +799,14 @@ gst_pulsesrc_get_property (GObject * object, case PROP_SOURCE_OUTPUT_INDEX: g_value_set_uint (value, pulsesrc->source_output_idx); break; +#ifdef HAVE_PULSE_1_0 + case PROP_VOLUME: + g_value_set_double (value, gst_pulsesrc_get_stream_volume (pulsesrc)); + break; + case PROP_MUTE: + g_value_set_boolean (value, gst_pulsesrc_get_stream_mute (pulsesrc)); + break; +#endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -569,6 +900,30 @@ gst_pulsesrc_stream_overflow_cb (pa_stream * s, void *userdata) GST_WARNING_OBJECT (GST_PULSESRC_CAST (userdata), "Got overflow"); } +#ifdef HAVE_PULSE_1_0 +static void +gst_pulsesrc_context_subscribe_cb (pa_context * c, + pa_subscription_event_type_t t, uint32_t idx, void *userdata) +{ + GstPulseSrc *psrc = GST_PULSESRC (userdata); + + if (t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT | PA_SUBSCRIPTION_EVENT_CHANGE) + && t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT | PA_SUBSCRIPTION_EVENT_NEW)) + return; + + if (idx != psrc->source_output_idx) + return; + + /* Actually this event is also triggered when other properties of the stream + * change that are unrelated to the volume. However it is probably cheaper to + * signal the change here and check for the volume when the GObject property + * is read instead of querying it always. */ + + /* inform streaming thread to notify */ + g_atomic_int_compare_and_exchange (&psrc->notify, 0, 1); +} +#endif + static gboolean gst_pulsesrc_open (GstAudioSrc * asrc) { @@ -591,6 +946,10 @@ gst_pulsesrc_open (GstAudioSrc * asrc) pa_context_set_state_callback (pulsesrc->context, gst_pulsesrc_context_state_cb, pulsesrc); +#ifdef HAVE_PULSE_1_0 + pa_context_set_subscribe_callback (pulsesrc->context, + gst_pulsesrc_context_subscribe_cb, pulsesrc); +#endif GST_DEBUG_OBJECT (pulsesrc, "connect to server %s", GST_STR_NULL (pulsesrc->server)); @@ -672,6 +1031,13 @@ gst_pulsesrc_read (GstAudioSrc * asrc, gpointer data, guint length) pa_threaded_mainloop_lock (pulsesrc->mainloop); pulsesrc->in_read = TRUE; +#ifdef HAVE_PULSE_1_0 + if (g_atomic_int_compare_and_exchange (&pulsesrc->notify, 1, 0)) { + g_object_notify (G_OBJECT (pulsesrc), "volume"); + g_object_notify (G_OBJECT (pulsesrc), "mute"); + } +#endif + if (pulsesrc->paused) goto was_paused; @@ -985,9 +1351,27 @@ gst_pulsesrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec) pa_buffer_attr wanted; const pa_buffer_attr *actual; GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc); + pa_stream_flags_t flags; +#ifdef HAVE_PULSE_1_0 + pa_operation *o; +#endif pa_threaded_mainloop_lock (pulsesrc->mainloop); +#ifdef HAVE_PULSE_1_0 + /* enable event notifications */ + GST_LOG_OBJECT (pulsesrc, "subscribing to context events"); + if (!(o = pa_context_subscribe (pulsesrc->context, + PA_SUBSCRIPTION_MASK_SINK_INPUT, NULL, NULL))) { + GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, + ("pa_context_subscribe() failed: %s", + pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); + goto unlock_and_fail; + } + + pa_operation_unref (o); +#endif + wanted.maxlength = -1; wanted.tlength = -1; wanted.prebuf = 0; @@ -1000,11 +1384,19 @@ gst_pulsesrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec) 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) { goto connect_failed; + } pulsesrc->corked = TRUE; @@ -1028,6 +1420,13 @@ gst_pulsesrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec) pulsesrc->source_output_idx = pa_stream_get_index (pulsesrc->stream); g_object_notify (G_OBJECT (pulsesrc), "source-output-index"); +#ifdef HAVE_PULSE_1_0 + if (pulsesrc->volume_set) { + gst_pulsesrc_set_stream_volume (pulsesrc, pulsesrc->volume); + pulsesrc->volume_set = FALSE; + } +#endif + /* get the actual buffering properties now */ actual = pa_stream_get_buffer_attr (pulsesrc->stream); diff --git a/ext/pulse/pulsesrc.h b/ext/pulse/pulsesrc.h index f62f73375..a9acc8713 100644 --- a/ext/pulse/pulsesrc.h +++ b/ext/pulse/pulsesrc.h @@ -72,6 +72,15 @@ struct _GstPulseSrc 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; diff --git a/gst/audioparsers/gstaacparse.c b/gst/audioparsers/gstaacparse.c index 9a49e08bd..5c0d88a06 100644 --- a/gst/audioparsers/gstaacparse.c +++ b/gst/audioparsers/gstaacparse.c @@ -69,16 +69,18 @@ GST_DEBUG_CATEGORY_STATIC (aacparse_debug); #define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec) -gboolean gst_aac_parse_start (GstBaseParse * parse); -gboolean gst_aac_parse_stop (GstBaseParse * parse); +static gboolean gst_aac_parse_start (GstBaseParse * parse); +static gboolean gst_aac_parse_stop (GstBaseParse * parse); static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps); +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); gboolean gst_aac_parse_convert (GstBaseParse * parse, @@ -131,6 +133,7 @@ gst_aac_parse_class_init (GstAacParseClass * klass) parse_class->start = GST_DEBUG_FUNCPTR (gst_aac_parse_start); parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop); parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_setcaps); + parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_getcaps); parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_parse_frame); parse_class->check_valid_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_check_valid_frame); @@ -568,7 +571,7 @@ gst_aac_parse_detect_stream (GstAacParse * aacparse, * * Returns: TRUE if buffer contains a valid frame. */ -gboolean +static gboolean gst_aac_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize) { @@ -643,7 +646,7 @@ gst_aac_parse_check_valid_frame (GstBaseParse * parse, * Returns: GST_FLOW_OK if frame was successfully parsed and can be pushed * forward. Otherwise appropriate error is returned. */ -GstFlowReturn +static GstFlowReturn gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) { GstAacParse *aacparse; @@ -700,7 +703,7 @@ gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) * * Returns: TRUE if startup succeeded. */ -gboolean +static gboolean gst_aac_parse_start (GstBaseParse * parse) { GstAacParse *aacparse; @@ -721,9 +724,44 @@ gst_aac_parse_start (GstBaseParse * parse) * * Returns: TRUE is stopping succeeded. */ -gboolean +static gboolean gst_aac_parse_stop (GstBaseParse * parse) { GST_DEBUG ("stop"); return TRUE; } + +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; +} diff --git a/gst/audioparsers/gstac3parse.c b/gst/audioparsers/gstac3parse.c index 608fc93b7..26b619585 100644 --- a/gst/audioparsers/gstac3parse.c +++ b/gst/audioparsers/gstac3parse.c @@ -165,6 +165,8 @@ static GstFlowReturn gst_ac3_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame); static gboolean gst_ac3_parse_src_event (GstBaseParse * parse, GstEvent * event); +static GstCaps *gst_ac3_parse_get_sink_caps (GstBaseParse * parse, + GstCaps * filter); #define gst_ac3_parse_parent_class parent_class G_DEFINE_TYPE (GstAc3Parse, gst_ac3_parse, GST_TYPE_BASE_PARSE); @@ -195,8 +197,8 @@ gst_ac3_parse_class_init (GstAc3ParseClass * klass) parse_class->check_valid_frame = GST_DEBUG_FUNCPTR (gst_ac3_parse_check_valid_frame); parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_ac3_parse_parse_frame); - parse_class->src_event = GST_DEBUG_FUNCPTR (gst_ac3_parse_src_event); + parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_ac3_parse_get_sink_caps); } static void @@ -702,3 +704,40 @@ gst_ac3_parse_src_event (GstBaseParse * parse, GstEvent * event) return GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event); } + +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; +} diff --git a/gst/audioparsers/gstamrparse.c b/gst/audioparsers/gstamrparse.c index c5ad92046..eacce78d0 100644 --- a/gst/audioparsers/gstamrparse.c +++ b/gst/audioparsers/gstamrparse.c @@ -71,16 +71,18 @@ static const gint block_size_wb[16] = #define AMR_FRAME_DURATION (GST_SECOND/AMR_FRAMES_PER_SECOND) #define AMR_MIME_HEADER_SIZE 9 -gboolean gst_amr_parse_start (GstBaseParse * parse); -gboolean gst_amr_parse_stop (GstBaseParse * parse); +static gboolean gst_amr_parse_start (GstBaseParse * parse); +static gboolean gst_amr_parse_stop (GstBaseParse * parse); static gboolean gst_amr_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps); +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); G_DEFINE_TYPE (GstAmrParse, gst_amr_parse, GST_TYPE_BASE_PARSE); @@ -112,6 +114,7 @@ gst_amr_parse_class_init (GstAmrParseClass * klass) parse_class->start = GST_DEBUG_FUNCPTR (gst_amr_parse_start); parse_class->stop = GST_DEBUG_FUNCPTR (gst_amr_parse_stop); parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_amr_parse_sink_setcaps); + parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_amr_parse_sink_getcaps); parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_amr_parse_parse_frame); parse_class->check_valid_frame = GST_DEBUG_FUNCPTR (gst_amr_parse_check_valid_frame); @@ -251,7 +254,7 @@ gst_amr_parse_parse_header (GstAmrParse * amrparse, * * Returns: TRUE if the given data contains valid frame. */ -gboolean +static gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize) { @@ -338,7 +341,7 @@ done: * * Returns: #GstFlowReturn defining the parsing status. */ -GstFlowReturn +static GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) { return GST_FLOW_OK; @@ -353,7 +356,7 @@ gst_amr_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) * * Returns: TRUE on success. */ -gboolean +static gboolean gst_amr_parse_start (GstBaseParse * parse) { GstAmrParse *amrparse; @@ -374,7 +377,7 @@ gst_amr_parse_start (GstBaseParse * parse) * * Returns: TRUE on success. */ -gboolean +static gboolean gst_amr_parse_stop (GstBaseParse * parse) { GstAmrParse *amrparse; @@ -385,3 +388,41 @@ gst_amr_parse_stop (GstBaseParse * parse) amrparse->header = 0; return TRUE; } + +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; +} diff --git a/gst/audioparsers/gstdcaparse.c b/gst/audioparsers/gstdcaparse.c index 4aa071c18..7c11e0b73 100644 --- a/gst/audioparsers/gstdcaparse.c +++ b/gst/audioparsers/gstdcaparse.c @@ -78,6 +78,8 @@ static gboolean gst_dca_parse_check_valid_frame (GstBaseParse * parse, 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, + GstCaps * filter); #define gst_dca_parse_parent_class parent_class G_DEFINE_TYPE (GstDcaParse, gst_dca_parse, GST_TYPE_BASE_PARSE); @@ -99,6 +101,7 @@ 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)); @@ -464,3 +467,38 @@ broken_header: return GST_FLOW_ERROR; } } + +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; +} diff --git a/gst/audioparsers/gstflacparse.c b/gst/audioparsers/gstflacparse.c index c91e3c064..c9a555078 100644 --- a/gst/audioparsers/gstflacparse.c +++ b/gst/audioparsers/gstflacparse.c @@ -201,6 +201,8 @@ static GstFlowReturn gst_flac_parse_pre_push_frame (GstBaseParse * parse, 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, + GstCaps * filter); #define gst_flac_parse_parent_class parent_class G_DEFINE_TYPE (GstFlacParse, gst_flac_parse, GST_TYPE_BASE_PARSE); @@ -233,6 +235,8 @@ 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)); @@ -1502,3 +1506,38 @@ gst_flac_parse_convert (GstBaseParse * parse, return GST_BASE_PARSE_CLASS (parent_class)->convert (parse, src_format, src_value, dest_format, dest_value); } + +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; +} diff --git a/gst/audioparsers/gstmpegaudioparse.c b/gst/audioparsers/gstmpegaudioparse.c index 5e332ab82..d09990d9e 100644 --- a/gst/audioparsers/gstmpegaudioparse.c +++ b/gst/audioparsers/gstmpegaudioparse.c @@ -100,6 +100,8 @@ static GstFlowReturn gst_mpeg_audio_parse_pre_push_frame (GstBaseParse * parse, 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, + GstCaps * filter); #define gst_mpeg_audio_parse_parent_class parent_class G_DEFINE_TYPE (GstMpegAudioParse, gst_mpeg_audio_parse, GST_TYPE_BASE_PARSE); @@ -161,6 +163,8 @@ gst_mpeg_audio_parse_class_init (GstMpegAudioParseClass * klass) parse_class->pre_push_frame = GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_pre_push_frame); parse_class->convert = GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_convert); + parse_class->get_sink_caps = + GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_get_sink_caps); /* register tags */ #define GST_TAG_CRC "has-crc" @@ -1288,3 +1292,38 @@ gst_mpeg_audio_parse_pre_push_frame (GstBaseParse * parse, return GST_FLOW_OK; } + +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; +} diff --git a/gst/effectv/gstedge.c b/gst/effectv/gstedge.c index eddac91d5..5ba182e45 100644 --- a/gst/effectv/gstedge.c +++ b/gst/effectv/gstedge.c @@ -140,7 +140,7 @@ gst_edgetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out) p = *src; q = *(src - 4); - /* difference between the current pixel and right neighbor. */ + /* difference between the current pixel and left neighbor. */ r = ((p & 0xff0000) - (q & 0xff0000)) >> 16; g = ((p & 0xff00) - (q & 0xff00)) >> 8; b = (p & 0xff) - (q & 0xff); @@ -199,8 +199,12 @@ gst_edgetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out) dest[width + 3] = v3; dest[width * 2] = v2; dest[width * 2 + 1] = v2; + dest[width * 2 + 2] = 0; + dest[width * 2 + 3] = 0; dest[width * 3] = v2; dest[width * 3 + 1] = v2; + dest[width * 3 + 2] = 0; + dest[width * 3 + 3] = 0; src += 4; dest += 4; diff --git a/gst/effectv/gstquark.c b/gst/effectv/gstquark.c index 1c4434757..4ae7ecb19 100644 --- a/gst/effectv/gstquark.c +++ b/gst/effectv/gstquark.c @@ -328,7 +328,4 @@ gst_quarktv_init (GstQuarkTV * filter) { filter->planes = PLANES; filter->current_plane = filter->planes - 1; - - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } diff --git a/gst/effectv/gstradioac.c b/gst/effectv/gstradioac.c index 66d13e535..57b6d5db3 100644 --- a/gst/effectv/gstradioac.c +++ b/gst/effectv/gstradioac.c @@ -131,14 +131,15 @@ enum #define RATIO 0.95 static guint32 palettes[COLORS * PATTERN]; +static gint swap_tab[] = { 2, 1, 0, 3 }; #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_MAKE ("{ RGBx, BGRx }") #else -#define CAPS_STR GST_VIDEO_CAPS_MAKE ("xBGR") +#define CAPS_STR GST_VIDEO_CAPS_MAKE ("{ xBGR, xRGB }") #endif static GstStaticPadTemplate gst_radioactv_src_template = @@ -162,18 +163,20 @@ makePalette (void) #define DELTA (255/(COLORS/2-1)) + /* red, gree, blue */ for (i = 0; i < COLORS / 2; i++) { palettes[i] = i * DELTA; palettes[COLORS + i] = (i * DELTA) << 8; palettes[COLORS * 2 + i] = (i * DELTA) << 16; } for (i = 0; i < COLORS / 2; i++) { - palettes[+i + COLORS / 2] = 255 | (i * DELTA) << 16 | (i * DELTA) << 8; + palettes[i + COLORS / 2] = 255 | (i * DELTA) << 16 | (i * DELTA) << 8; palettes[COLORS + i + COLORS / 2] = (255 << 8) | (i * DELTA) << 16 | i * DELTA; palettes[COLORS * 2 + i + COLORS / 2] = (255 << 16) | (i * DELTA) << 8 | i * DELTA; } + /* white */ for (i = 0; i < COLORS; i++) { palettes[COLORS * 3 + i] = (255 * i / COLORS) * 0x10101; } @@ -347,7 +350,19 @@ gst_radioactv_transform (GstBaseTransform * trans, GstBuffer * in, height = GST_VIDEO_FRAME_HEIGHT (&in_frame); GST_OBJECT_LOCK (filter); - palette = &palettes[COLORS * filter->color]; +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + 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 (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) @@ -643,7 +658,4 @@ gst_radioactv_init (GstRadioacTV * filter) filter->color = DEFAULT_COLOR; filter->interval = DEFAULT_INTERVAL; filter->trigger = DEFAULT_TRIGGER; - - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } diff --git a/gst/effectv/gstripple.c b/gst/effectv/gstripple.c index 8f1f64a98..285b92ad6 100644 --- a/gst/effectv/gstripple.c +++ b/gst/effectv/gstripple.c @@ -311,9 +311,9 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in, guint32 *src, *dest; 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; @@ -344,22 +344,24 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in, else motiondetect (filter, src); + 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. */ for (i = loopnum; i > 0; i--) { /* wave simulation */ - p = filter->map1 + width + 1; - q = filter->map2 + width + 1; - r = filter->map3 + width + 1; - for (y = height - 2; y > 0; y--) { - for (x = width - 2; x > 0; x--) { - h = *(p - width - 1) + *(p - width + 1) + *(p + width - 1) + *(p + - width + 1) - + *(p - width) + *(p - 1) + *(p + 1) + *(p + width) - (*p) * 9; + p = filter->map1 + m_w + 1; + q = filter->map2 + m_w + 1; + r = filter->map3 + m_w + 1; + for (y = m_h - 2; y > 0; y--) { + for (x = m_w - 2; x > 0; x--) { + h = *(p - m_w - 1) + *(p - m_w + 1) + *(p + m_w - 1) + *(p + m_w + 1) + + *(p - m_w) + *(p - 1) + *(p + 1) + *(p + m_w) - (*p) * 9; h = h >> 3; v = *p - *q; v += h - (v >> decay); @@ -374,11 +376,11 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in, } /* low pass filter */ - p = filter->map3 + width + 1; - q = filter->map2 + width + 1; - for (y = height - 2; y > 0; y--) { - for (x = width - 2; x > 0; x--) { - h = *(p - width) + *(p - 1) + *(p + 1) + *(p + width) + (*p) * 60; + p = filter->map3 + m_w + 1; + q = filter->map2 + m_w + 1; + for (y = m_h - 2; y > 0; y--) { + for (x = m_w - 2; x > 0; x--) { + h = *(p - m_w) + *(p - 1) + *(p + 1) + *(p + m_w) + (*p) * 60; *q = h >> 6; p++; q++; @@ -394,12 +396,12 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in, vp = filter->vtable; p = filter->map1; - for (y = height - 1; y > 0; y--) { - for (x = width - 1; x > 0; x--) { + for (y = m_h - 1; y > 0; y--) { + for (x = m_w - 1; x > 0; x--) { /* difference of the height between two voxel. They are twiced to * emphasise the wave. */ vp[0] = sqrtable[((p[0] - p[1]) >> (point - 1)) & 0xff]; - vp[1] = sqrtable[((p[0] - p[width]) >> (point - 1)) & 0xff]; + vp[1] = sqrtable[((p[0] - p[m_w]) >> (point - 1)) & 0xff]; p++; vp += 2; } @@ -407,48 +409,34 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in, vp += 2; } - width = GST_VIDEO_FRAME_WIDTH (&in_frame); - height = GST_VIDEO_FRAME_HEIGHT (&in_frame); vp = filter->vtable; /* draw refracted image. The vector table is stretched. */ - for (y = 0; y < height; y += 2) { - for (x = 0; x < width; x += 2) { + for (y = 0; y < v_h; y += 2) { + for (x = 0; x < v_w; x += 2) { h = (gint) vp[0]; v = (gint) vp[1]; dx = x + h; dy = y + v; - if (dx < 0) - dx = 0; - if (dy < 0) - dy = 0; - if (dx >= width) - dx = width - 1; - if (dy >= height) - dy = height - 1; - dest[0] = src[dy * width + dx]; - - i = dx; + dx = CLAMP (dx, 0, (v_w - 1)); + dy = CLAMP (dy, 0, (v_h - 1)); + dest[0] = src[dy * v_w + dx]; + + o_dx = dx; dx = x + 1 + (h + (gint) vp[2]) / 2; - if (dx < 0) - dx = 0; - if (dx >= width) - dx = width - 1; - dest[1] = src[dy * width + dx]; - - dy = y + 1 + (v + (gint) vp[filter->map_w * 2 + 1]) / 2; - if (dy < 0) - dy = 0; - if (dy >= height) - dy = height - 1; - dest[width] = src[dy * width + i]; - - dest[width + 1] = src[dy * width + dx]; + dx = CLAMP (dx, 0, (v_w - 1)); + dest[1] = src[dy * v_w + dx]; + + dy = y + 1 + (v + (gint) vp[m_w * 2 + 1]) / 2; + dy = CLAMP (dy, 0, (v_h - 1)); + dest[v_w] = src[dy * v_w + o_dx]; + + dest[v_w + 1] = src[dy * v_w + dx]; dest += 2; vp += 2; } - dest += width; + dest += v_w; vp += 2; } GST_OBJECT_UNLOCK (filter); @@ -493,9 +481,11 @@ gst_rippletv_set_caps (GstBaseTransform * btrans, GstCaps * incaps, filter->map_h = height / 2 + 1; filter->map_w = width / 2 + 1; + /* 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); filter->map1 = filter->map; filter->map2 = filter->map + filter->map_w * filter->map_h; @@ -503,15 +493,15 @@ gst_rippletv_set_caps (GstBaseTransform * btrans, GstCaps * incaps, 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->background) g_free (filter->background); - filter->background = g_new0 (gint16, width * height); + filter->background = g_new0 (gint16, width * (height + 1)); 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 TRUE; @@ -650,6 +640,7 @@ gst_rippletv_init (GstRippleTV * filter) { filter->mode = DEFAULT_MODE; + /* FIXME: remove this when memory corruption after resizes are fixed */ gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } diff --git a/gst/effectv/gstshagadelic.c b/gst/effectv/gstshagadelic.c index f2af50fad..6e56430c6 100644 --- a/gst/effectv/gstshagadelic.c +++ b/gst/effectv/gstshagadelic.c @@ -289,7 +289,4 @@ gst_shagadelictv_init (GstShagadelicTV * filter) { filter->ripple = NULL; filter->spiral = NULL; - - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } diff --git a/gst/effectv/gststreak.c b/gst/effectv/gststreak.c index 45d71a2df..9ae451aee 100644 --- a/gst/effectv/gststreak.c +++ b/gst/effectv/gststreak.c @@ -296,7 +296,4 @@ static void 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)); } diff --git a/gst/effectv/gstvertigo.c b/gst/effectv/gstvertigo.c index 44a367d17..592231990 100644 --- a/gst/effectv/gstvertigo.c +++ b/gst/effectv/gstvertigo.c @@ -351,7 +351,4 @@ gst_vertigotv_init (GstVertigoTV * filter) filter->phase = 0.0; filter->phase_increment = 0.02; filter->zoomrate = 1.01; - - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } diff --git a/gst/effectv/gstwarp.c b/gst/effectv/gstwarp.c index c4d7a73a3..80161a7b1 100644 --- a/gst/effectv/gstwarp.c +++ b/gst/effectv/gstwarp.c @@ -133,11 +133,7 @@ initDistTable (GstWarpTV * filter, gint width, gint height) { gint32 halfw, halfh, *distptr; gint x, y; -#ifdef PS2 - float m; -#else float m; -#endif halfw = width >> 1; halfh = height >> 1; @@ -304,6 +300,5 @@ gst_warptv_class_init (GstWarpTVClass * klass) static void 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 */ } diff --git a/gst/flv/gstflvdemux.c b/gst/flv/gstflvdemux.c index 0189b3117..fe88ad6bd 100644 --- a/gst/flv/gstflvdemux.c +++ b/gst/flv/gstflvdemux.c @@ -781,10 +781,10 @@ gst_flv_demux_push_tags (GstFlvDemux * demux) } static void -gst_flv_demux_update_resync (GstFlvDemux * demux, guint32 pts, guint32 * last, - GstClockTime * offset) +gst_flv_demux_update_resync (GstFlvDemux * demux, guint32 pts, gboolean discont, + guint32 * last, GstClockTime * offset) { - if (ABS (pts - *last) >= RESYNC_THRESHOLD) { + if (!discont && ABS (pts - *last) >= RESYNC_THRESHOLD) { /* Theoretically, we should use substract the duration of the last buffer, but this demuxer sends no durations on buffers, not sure if it cannot know, or just does not care to calculate. */ @@ -992,8 +992,8 @@ gst_flv_demux_parse_tag_audio (GstFlvDemux * demux, GstBuffer * buffer) } /* detect (and deem to be resyncs) large pts gaps */ - gst_flv_demux_update_resync (demux, pts, &demux->last_audio_pts, - &demux->audio_time_offset); + gst_flv_demux_update_resync (demux, pts, demux->audio_need_discont, + &demux->last_audio_pts, &demux->audio_time_offset); /* Fill buffer with data */ GST_BUFFER_TIMESTAMP (outbuf) = pts * GST_MSECOND + demux->audio_time_offset; @@ -1369,8 +1369,8 @@ gst_flv_demux_parse_tag_video (GstFlvDemux * demux, GstBuffer * buffer) } /* detect (and deem to be resyncs) large pts gaps */ - gst_flv_demux_update_resync (demux, pts, &demux->last_video_pts, - &demux->video_time_offset); + gst_flv_demux_update_resync (demux, pts, demux->video_need_discont, + &demux->last_video_pts, &demux->video_time_offset); /* Fill buffer with data */ GST_BUFFER_TIMESTAMP (outbuf) = pts * GST_MSECOND + demux->video_time_offset; diff --git a/gst/isomp4/gstqtmuxmap.c b/gst/isomp4/gstqtmuxmap.c index a595c2234..eb376aaec 100644 --- a/gst/isomp4/gstqtmuxmap.c +++ b/gst/isomp4/gstqtmuxmap.c @@ -199,7 +199,7 @@ GstQTMuxFormatProp gst_qt_mux_format_list[] = { "ismlmux", "ISML", "GstISMLMux", - GST_STATIC_CAPS ("video/quicktime, variant = (string) iso"), + GST_STATIC_CAPS ("video/quicktime, variant = (string) iso-fragmented"), GST_STATIC_CAPS (MPEG4V_CAPS "; " H264_CAPS), GST_STATIC_CAPS (MP3_CAPS "; " AAC_CAPS) } diff --git a/gst/multifile/gstmultifilesink.c b/gst/multifile/gstmultifilesink.c index a692682b1..d2d560381 100644 --- a/gst/multifile/gstmultifilesink.c +++ b/gst/multifile/gstmultifilesink.c @@ -594,6 +594,7 @@ gst_multi_file_sink_ensure_max_files (GstMultiFileSink * multifilesink) multifilesink->n_files >= multifilesink->max_files) { filename = multifilesink->files->data; g_remove (filename); + g_free (filename); multifilesink->files = g_slist_delete_link (multifilesink->files, multifilesink->files); multifilesink->n_files -= 1; diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c index 056aacc7f..3758a9b88 100644 --- a/gst/wavparse/gstwavparse.c +++ b/gst/wavparse/gstwavparse.c @@ -1164,7 +1164,8 @@ gst_wavparse_stream_headers (GstWavParse * wav) if (tag == GST_RIFF_TAG_JUNK || tag == GST_RIFF_TAG_JUNQ || tag == GST_RIFF_TAG_bext || tag == GST_RIFF_TAG_BEXT || - tag == GST_RIFF_TAG_LIST) { + tag == GST_RIFF_TAG_LIST || tag == GST_RIFF_TAG_ID32 || + tag == GST_RIFF_TAG_IDVX) { GST_DEBUG_OBJECT (wav, "skipping %" GST_FOURCC_FORMAT " chunk", GST_FOURCC_ARGS (tag)); gst_buffer_unref (buf); diff --git a/tests/check/elements/multifile.c b/tests/check/elements/multifile.c index 479e028b6..52ce2ceb8 100644 --- a/tests/check/elements/multifile.c +++ b/tests/check/elements/multifile.c @@ -40,19 +40,19 @@ run_pipeline (GstElement * pipeline) gst_element_set_state (pipeline, GST_STATE_NULL); } +#if !GLIB_CHECK_VERSION(2,26,0) static gchar * -g_mkdtemp (const gchar * template) +g_mkdtemp (gchar * template) { - gchar *s; gchar *tmpdir; - s = g_strdup (template); - tmpdir = mkdtemp (s); + tmpdir = mkdtemp (template); if (tmpdir == NULL) { - g_free (s); + g_free (template); } return tmpdir; } +#endif GST_START_TEST (test_multifilesink_key_frame) { @@ -93,7 +93,6 @@ GST_START_TEST (test_multifilesink_key_frame) g_free (mfs_pattern); g_free (my_tmpdir); - g_free (template); } GST_END_TEST; @@ -144,7 +143,6 @@ GST_START_TEST (test_multifilesink_max_files) g_free (mfs_pattern); g_free (my_tmpdir); - g_free (template); } GST_END_TEST; @@ -202,7 +200,6 @@ GST_START_TEST (test_multifilesrc) g_free (mfs_pattern); g_free (my_tmpdir); - g_free (template); } GST_END_TEST; |