diff options
Diffstat (limited to 'gst')
-rw-r--r-- | gst/audiovisualizers/gstaudiovisualizer.c | 313 | ||||
-rw-r--r-- | gst/audiovisualizers/gstaudiovisualizer.h | 24 |
2 files changed, 172 insertions, 165 deletions
diff --git a/gst/audiovisualizers/gstaudiovisualizer.c b/gst/audiovisualizers/gstaudiovisualizer.c index ee09e3974..1e7a3d1da 100644 --- a/gst/audiovisualizers/gstaudiovisualizer.c +++ b/gst/audiovisualizers/gstaudiovisualizer.c @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) <2011> Stefan Kost <ensonic@users.sf.net> + * Copyright (C) <2015> Luis de Bethencourt <luis@debethencourt.com> * * gstaudiovisualizer.h: base class for audio visualisation elements * @@ -92,6 +93,49 @@ static gboolean gst_audio_visualizer_do_bufferpool (GstAudioVisualizer * scope, static gboolean default_decide_allocation (GstAudioVisualizer * scope, GstQuery * query); +#define GST_AUDIO_VISUALIZER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_VISUALIZER, GstAudioVisualizerPrivate)) + +struct _GstAudioVisualizerPrivate +{ + gboolean negotiated; + + GstBufferPool *pool; + gboolean pool_active; + GstAllocator *allocator; + GstAllocationParams params; + GstQuery *query; + + /* pads */ + GstPad *srcpad, *sinkpad; + + GstAudioVisualizerShader shader_type; + GstAudioVisualizerShaderFunc shader; + guint32 shade_amount; + + GstAdapter *adapter; + + GstBuffer *inbuf; + GstBuffer *tempbuf; + GstVideoFrame tempframe; + + guint spf; /* samples per video frame */ + guint64 frame_duration; + + /* QoS stuff *//* with LOCK */ + gdouble proportion; + GstClockTime earliest_time; + + guint dropped; /* frames dropped / not dropped */ + guint processed; + + /* configuration mutex */ + GMutex config_lock; + + GstSegment segment; +}; + + /* shading functions */ #define GST_TYPE_AUDIO_VISUALIZER_SHADER (gst_audio_visualizer_shader_get_type()) @@ -159,9 +203,9 @@ shader_fade (GstAudioVisualizer * scope, const GstVideoFrame * sframe, GstVideoFrame * dframe) { guint i, j; - guint r = (scope->shade_amount >> 16) & 0xff; - guint g = (scope->shade_amount >> 8) & 0xff; - guint b = (scope->shade_amount >> 0) & 0xff; + guint r = (scope->priv->shade_amount >> 16) & 0xff; + guint g = (scope->priv->shade_amount >> 8) & 0xff; + guint b = (scope->priv->shade_amount >> 0) & 0xff; guint8 *s, *d; gint ss, ds, width, height; @@ -187,9 +231,9 @@ shader_fade_and_move_up (GstAudioVisualizer * scope, const GstVideoFrame * sframe, GstVideoFrame * dframe) { guint i, j; - guint r = (scope->shade_amount >> 16) & 0xff; - guint g = (scope->shade_amount >> 8) & 0xff; - guint b = (scope->shade_amount >> 0) & 0xff; + guint r = (scope->priv->shade_amount >> 16) & 0xff; + guint g = (scope->priv->shade_amount >> 8) & 0xff; + guint b = (scope->priv->shade_amount >> 0) & 0xff; guint8 *s, *d; gint ss, ds, width, height; @@ -215,9 +259,9 @@ shader_fade_and_move_down (GstAudioVisualizer * scope, const GstVideoFrame * sframe, GstVideoFrame * dframe) { guint i, j; - guint r = (scope->shade_amount >> 16) & 0xff; - guint g = (scope->shade_amount >> 8) & 0xff; - guint b = (scope->shade_amount >> 0) & 0xff; + guint r = (scope->priv->shade_amount >> 16) & 0xff; + guint g = (scope->priv->shade_amount >> 8) & 0xff; + guint b = (scope->priv->shade_amount >> 0) & 0xff; guint8 *s, *d; gint ss, ds, width, height; @@ -243,9 +287,9 @@ shader_fade_and_move_left (GstAudioVisualizer * scope, const GstVideoFrame * sframe, GstVideoFrame * dframe) { guint i, j; - guint r = (scope->shade_amount >> 16) & 0xff; - guint g = (scope->shade_amount >> 8) & 0xff; - guint b = (scope->shade_amount >> 0) & 0xff; + guint r = (scope->priv->shade_amount >> 16) & 0xff; + guint g = (scope->priv->shade_amount >> 8) & 0xff; + guint b = (scope->priv->shade_amount >> 0) & 0xff; guint8 *s, *d; gint ss, ds, width, height; @@ -275,9 +319,9 @@ shader_fade_and_move_right (GstAudioVisualizer * scope, const GstVideoFrame * sframe, GstVideoFrame * dframe) { guint i, j; - guint r = (scope->shade_amount >> 16) & 0xff; - guint g = (scope->shade_amount >> 8) & 0xff; - guint b = (scope->shade_amount >> 0) & 0xff; + guint r = (scope->priv->shade_amount >> 16) & 0xff; + guint g = (scope->priv->shade_amount >> 8) & 0xff; + guint b = (scope->priv->shade_amount >> 0) & 0xff; guint8 *s, *d; gint ss, ds, width, height; @@ -307,9 +351,9 @@ shader_fade_and_move_horiz_out (GstAudioVisualizer * scope, const GstVideoFrame * sframe, GstVideoFrame * dframe) { guint i, j; - guint r = (scope->shade_amount >> 16) & 0xff; - guint g = (scope->shade_amount >> 8) & 0xff; - guint b = (scope->shade_amount >> 0) & 0xff; + guint r = (scope->priv->shade_amount >> 16) & 0xff; + guint g = (scope->priv->shade_amount >> 8) & 0xff; + guint b = (scope->priv->shade_amount >> 0) & 0xff; guint8 *s, *d; gint ss, ds, width, height; @@ -344,9 +388,9 @@ shader_fade_and_move_horiz_in (GstAudioVisualizer * scope, const GstVideoFrame * sframe, GstVideoFrame * dframe) { guint i, j; - guint r = (scope->shade_amount >> 16) & 0xff; - guint g = (scope->shade_amount >> 8) & 0xff; - guint b = (scope->shade_amount >> 0) & 0xff; + guint r = (scope->priv->shade_amount >> 16) & 0xff; + guint g = (scope->priv->shade_amount >> 8) & 0xff; + guint b = (scope->priv->shade_amount >> 0) & 0xff; guint8 *s, *d; gint ss, ds, width, height; @@ -381,9 +425,9 @@ shader_fade_and_move_vert_out (GstAudioVisualizer * scope, const GstVideoFrame * sframe, GstVideoFrame * dframe) { guint i, j; - guint r = (scope->shade_amount >> 16) & 0xff; - guint g = (scope->shade_amount >> 8) & 0xff; - guint b = (scope->shade_amount >> 0) & 0xff; + guint r = (scope->priv->shade_amount >> 16) & 0xff; + guint g = (scope->priv->shade_amount >> 8) & 0xff; + guint b = (scope->priv->shade_amount >> 0) & 0xff; guint8 *s, *s1, *d, *d1; gint ss, ds, width, height; @@ -416,9 +460,9 @@ shader_fade_and_move_vert_in (GstAudioVisualizer * scope, const GstVideoFrame * sframe, GstVideoFrame * dframe) { guint i, j; - guint r = (scope->shade_amount >> 16) & 0xff; - guint g = (scope->shade_amount >> 8) & 0xff; - guint b = (scope->shade_amount >> 0) & 0xff; + guint r = (scope->priv->shade_amount >> 16) & 0xff; + guint g = (scope->priv->shade_amount >> 8) & 0xff; + guint b = (scope->priv->shade_amount >> 0) & 0xff; guint8 *s, *s1, *d, *d1; gint ss, ds, width, height; @@ -449,63 +493,46 @@ shader_fade_and_move_vert_in (GstAudioVisualizer * scope, static void gst_audio_visualizer_change_shader (GstAudioVisualizer * scope) { - switch (scope->shader_type) { + switch (scope->priv->shader_type) { case GST_AUDIO_VISUALIZER_SHADER_NONE: - scope->shader = NULL; + scope->priv->shader = NULL; break; case GST_AUDIO_VISUALIZER_SHADER_FADE: - scope->shader = shader_fade; + scope->priv->shader = shader_fade; break; case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP: - scope->shader = shader_fade_and_move_up; + scope->priv->shader = shader_fade_and_move_up; break; case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN: - scope->shader = shader_fade_and_move_down; + scope->priv->shader = shader_fade_and_move_down; break; case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT: - scope->shader = shader_fade_and_move_left; + scope->priv->shader = shader_fade_and_move_left; break; case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT: - scope->shader = shader_fade_and_move_right; + scope->priv->shader = shader_fade_and_move_right; break; case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT: - scope->shader = shader_fade_and_move_horiz_out; + scope->priv->shader = shader_fade_and_move_horiz_out; break; case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN: - scope->shader = shader_fade_and_move_horiz_in; + scope->priv->shader = shader_fade_and_move_horiz_in; break; case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT: - scope->shader = shader_fade_and_move_vert_out; + scope->priv->shader = shader_fade_and_move_vert_out; break; case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN: - scope->shader = shader_fade_and_move_vert_in; + scope->priv->shader = shader_fade_and_move_vert_in; break; default: GST_ERROR ("invalid shader function"); - scope->shader = NULL; + scope->priv->shader = NULL; break; } } /* base class */ -#define GST_AUDIO_VISUALIZER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_VISUALIZER, GstAudioVisualizerPrivate)) - -struct _GstAudioVisualizerPrivate -{ - gboolean negotiated; - - GstBufferPool *pool; - gboolean pool_active; - GstAllocator *allocator; - GstAllocationParams params; - GstQuery *query; - - guint dropped; /* frames dropped / not dropped */ - guint processed; -}; - GType gst_audio_visualizer_get_type (void) { @@ -580,40 +607,40 @@ gst_audio_visualizer_init (GstAudioVisualizer * scope, pad_template = gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink"); g_return_if_fail (pad_template != NULL); - scope->sinkpad = gst_pad_new_from_template (pad_template, "sink"); - gst_pad_set_chain_function (scope->sinkpad, + scope->priv->sinkpad = gst_pad_new_from_template (pad_template, "sink"); + gst_pad_set_chain_function (scope->priv->sinkpad, GST_DEBUG_FUNCPTR (gst_audio_visualizer_chain)); - gst_pad_set_event_function (scope->sinkpad, + gst_pad_set_event_function (scope->priv->sinkpad, GST_DEBUG_FUNCPTR (gst_audio_visualizer_sink_event)); - gst_element_add_pad (GST_ELEMENT (scope), scope->sinkpad); + gst_element_add_pad (GST_ELEMENT (scope), scope->priv->sinkpad); pad_template = gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src"); g_return_if_fail (pad_template != NULL); - scope->srcpad = gst_pad_new_from_template (pad_template, "src"); - gst_pad_set_event_function (scope->srcpad, + scope->priv->srcpad = gst_pad_new_from_template (pad_template, "src"); + gst_pad_set_event_function (scope->priv->srcpad, GST_DEBUG_FUNCPTR (gst_audio_visualizer_src_event)); - gst_pad_set_query_function (scope->srcpad, + gst_pad_set_query_function (scope->priv->srcpad, GST_DEBUG_FUNCPTR (gst_audio_visualizer_src_query)); - gst_element_add_pad (GST_ELEMENT (scope), scope->srcpad); + gst_element_add_pad (GST_ELEMENT (scope), scope->priv->srcpad); - scope->adapter = gst_adapter_new (); - scope->inbuf = gst_buffer_new (); + scope->priv->adapter = gst_adapter_new (); + scope->priv->inbuf = gst_buffer_new (); /* properties */ - scope->shader_type = DEFAULT_SHADER; + scope->priv->shader_type = DEFAULT_SHADER; gst_audio_visualizer_change_shader (scope); - scope->shade_amount = DEFAULT_SHADE_AMOUNT; + scope->priv->shade_amount = DEFAULT_SHADE_AMOUNT; /* reset the initial video state */ gst_video_info_init (&scope->vinfo); - scope->frame_duration = GST_CLOCK_TIME_NONE; + scope->priv->frame_duration = GST_CLOCK_TIME_NONE; /* reset the initial state */ gst_audio_info_init (&scope->ainfo); gst_video_info_init (&scope->vinfo); - g_mutex_init (&scope->config_lock); + g_mutex_init (&scope->priv->config_lock); } static void @@ -624,11 +651,11 @@ gst_audio_visualizer_set_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_SHADER: - scope->shader_type = g_value_get_enum (value); + scope->priv->shader_type = g_value_get_enum (value); gst_audio_visualizer_change_shader (scope); break; case PROP_SHADE_AMOUNT: - scope->shade_amount = g_value_get_uint (value); + scope->priv->shade_amount = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -644,10 +671,10 @@ gst_audio_visualizer_get_property (GObject * object, guint prop_id, switch (prop_id) { case PROP_SHADER: - g_value_set_enum (value, scope->shader_type); + g_value_set_enum (value, scope->priv->shader_type); break; case PROP_SHADE_AMOUNT: - g_value_set_uint (value, scope->shade_amount); + g_value_set_uint (value, scope->priv->shade_amount); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -660,21 +687,21 @@ gst_audio_visualizer_finalize (GObject * object) { GstAudioVisualizer *scope = GST_AUDIO_VISUALIZER (object); - if (scope->adapter) { - g_object_unref (scope->adapter); - scope->adapter = NULL; + if (scope->priv->adapter) { + g_object_unref (scope->priv->adapter); + scope->priv->adapter = NULL; } - if (scope->inbuf) { - gst_buffer_unref (scope->inbuf); - scope->inbuf = NULL; + if (scope->priv->inbuf) { + gst_buffer_unref (scope->priv->inbuf); + scope->priv->inbuf = NULL; } - if (scope->tempbuf) { - gst_video_frame_unmap (&scope->tempframe); - gst_buffer_unref (scope->tempbuf); - scope->tempbuf = NULL; + if (scope->priv->tempbuf) { + gst_video_frame_unmap (&scope->priv->tempframe); + gst_buffer_unref (scope->priv->tempbuf); + scope->priv->tempbuf = NULL; } - g_mutex_clear (&scope->config_lock); + g_mutex_clear (&scope->priv->config_lock); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -682,12 +709,12 @@ gst_audio_visualizer_finalize (GObject * object) static void gst_audio_visualizer_reset (GstAudioVisualizer * scope) { - gst_adapter_clear (scope->adapter); - gst_segment_init (&scope->segment, GST_FORMAT_UNDEFINED); + gst_adapter_clear (scope->priv->adapter); + gst_segment_init (&scope->priv->segment, GST_FORMAT_UNDEFINED); GST_OBJECT_LOCK (scope); - scope->proportion = 1.0; - scope->earliest_time = -1; + scope->priv->proportion = 1.0; + scope->priv->earliest_time = -1; scope->priv->dropped = 0; scope->priv->processed = 0; GST_OBJECT_UNLOCK (scope); @@ -739,20 +766,21 @@ gst_audio_visualizer_src_setcaps (GstAudioVisualizer * scope, GstCaps * caps) scope->vinfo = info; - scope->frame_duration = gst_util_uint64_scale_int (GST_SECOND, + scope->priv->frame_duration = gst_util_uint64_scale_int (GST_SECOND, GST_VIDEO_INFO_FPS_D (&info), GST_VIDEO_INFO_FPS_N (&info)); - scope->spf = gst_util_uint64_scale_int (GST_AUDIO_INFO_RATE (&scope->ainfo), + scope->priv->spf = + gst_util_uint64_scale_int (GST_AUDIO_INFO_RATE (&scope->ainfo), GST_VIDEO_INFO_FPS_D (&info), GST_VIDEO_INFO_FPS_N (&info)); - scope->req_spf = scope->spf; + scope->req_spf = scope->priv->spf; - if (scope->tempbuf) { - gst_video_frame_unmap (&scope->tempframe); - gst_buffer_unref (scope->tempbuf); + if (scope->priv->tempbuf) { + gst_video_frame_unmap (&scope->priv->tempframe); + gst_buffer_unref (scope->priv->tempbuf); } - scope->tempbuf = gst_buffer_new_wrapped (g_malloc0 (scope->vinfo.size), + scope->priv->tempbuf = gst_buffer_new_wrapped (g_malloc0 (scope->vinfo.size), scope->vinfo.size); - gst_video_frame_map (&scope->tempframe, &scope->vinfo, scope->tempbuf, - GST_MAP_READWRITE); + gst_video_frame_map (&scope->priv->tempframe, &scope->vinfo, + scope->priv->tempbuf, GST_MAP_READWRITE); if (klass->setup && !klass->setup (scope)) goto setup_failed; @@ -761,9 +789,9 @@ gst_audio_visualizer_src_setcaps (GstAudioVisualizer * scope, GstCaps * caps) GST_VIDEO_INFO_WIDTH (&info), GST_VIDEO_INFO_HEIGHT (&info), GST_VIDEO_INFO_FPS_N (&info), GST_VIDEO_INFO_FPS_D (&info)); GST_DEBUG_OBJECT (scope, "blocks: spf %u, req_spf %u", - scope->spf, scope->req_spf); + scope->priv->spf, scope->req_spf); - gst_pad_set_caps (scope->srcpad, caps); + gst_pad_set_caps (scope->priv->srcpad, caps); /* find a pool for the negotiated caps now */ res = gst_audio_visualizer_do_bufferpool (scope, caps); @@ -794,12 +822,12 @@ gst_audio_visualizer_src_negotiate (GstAudioVisualizer * scope) GstCaps *templ; gboolean ret; - templ = gst_pad_get_pad_template_caps (scope->srcpad); + templ = gst_pad_get_pad_template_caps (scope->priv->srcpad); GST_DEBUG_OBJECT (scope, "performing negotiation"); /* see what the peer can do */ - othercaps = gst_pad_peer_query_caps (scope->srcpad, NULL); + othercaps = gst_pad_peer_query_caps (scope->priv->srcpad, NULL); if (othercaps) { target = gst_caps_intersect (othercaps, templ); gst_caps_unref (othercaps); @@ -892,7 +920,7 @@ gst_audio_visualizer_do_bufferpool (GstAudioVisualizer * scope, GST_DEBUG_OBJECT (scope, "doing allocation query"); query = gst_query_new_allocation (outcaps, TRUE); - if (!gst_pad_peer_query (scope->srcpad, query)) { + if (!gst_pad_peer_query (scope->priv->srcpad, query)) { /* not a problem, we use the query defaults */ GST_DEBUG_OBJECT (scope, "allocation query failed"); } @@ -1053,13 +1081,13 @@ gst_audio_visualizer_chain (GstPad * pad, GstObject * parent, /* resync on DISCONT */ if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { - gst_adapter_clear (scope->adapter); + gst_adapter_clear (scope->priv->adapter); } /* Make sure have an output format */ - if (gst_pad_check_reconfigure (scope->srcpad)) { + if (gst_pad_check_reconfigure (scope->priv->srcpad)) { if (!gst_audio_visualizer_src_negotiate (scope)) { - gst_pad_mark_reconfigure (scope->srcpad); + gst_pad_mark_reconfigure (scope->priv->srcpad); goto not_negotiated; } } @@ -1073,26 +1101,26 @@ gst_audio_visualizer_chain (GstPad * pad, GstObject * parent, goto beach; } - gst_adapter_push (scope->adapter, buffer); + gst_adapter_push (scope->priv->adapter, buffer); - g_mutex_lock (&scope->config_lock); + g_mutex_lock (&scope->priv->config_lock); /* this is what we want */ sbpf = scope->req_spf * channels * sizeof (gint16); - inbuf = scope->inbuf; + inbuf = scope->priv->inbuf; /* FIXME: the timestamp in the adapter would be different */ gst_buffer_copy_into (inbuf, buffer, GST_BUFFER_COPY_METADATA, 0, -1); /* this is what we have */ - avail = gst_adapter_available (scope->adapter); + avail = gst_adapter_available (scope->priv->adapter); GST_LOG_OBJECT (scope, "avail: %u, bpf: %u", avail, sbpf); while (avail >= sbpf) { GstBuffer *outbuf; GstVideoFrame outframe; /* get timestamp of the current adapter content */ - ts = gst_adapter_prev_pts (scope->adapter, &dist); + ts = gst_adapter_prev_pts (scope->priv->adapter, &dist); if (GST_CLOCK_TIME_IS_VALID (ts)) { /* convert bytes to time */ dist /= bps; @@ -1106,12 +1134,12 @@ gst_audio_visualizer_chain (GstPad * pad, GstObject * parent, gint64 qostime; qostime = - gst_segment_to_running_time (&scope->segment, GST_FORMAT_TIME, ts) + - scope->frame_duration; + gst_segment_to_running_time (&scope->priv->segment, GST_FORMAT_TIME, + ts) + scope->priv->frame_duration; GST_OBJECT_LOCK (scope); - earliest_time = scope->earliest_time; - proportion = scope->proportion; + earliest_time = scope->priv->earliest_time; + proportion = scope->priv->proportion; GST_OBJECT_UNLOCK (scope); if (GST_CLOCK_TIME_IS_VALID (earliest_time) && qostime <= earliest_time) { @@ -1123,7 +1151,7 @@ gst_audio_visualizer_chain (GstPad * pad, GstObject * parent, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time)); ++scope->priv->dropped; - stream_time = gst_segment_to_stream_time (&scope->segment, + stream_time = gst_segment_to_stream_time (&scope->priv->segment, GST_FORMAT_TIME, ts); jitter = GST_CLOCK_DIFF (qostime, earliest_time); qos_msg = gst_message_new_qos (GST_OBJECT (scope), FALSE, qostime, @@ -1139,9 +1167,9 @@ gst_audio_visualizer_chain (GstPad * pad, GstObject * parent, ++scope->priv->processed; - g_mutex_unlock (&scope->config_lock); + g_mutex_unlock (&scope->priv->config_lock); ret = default_prepare_output_buffer (scope, &outbuf); - g_mutex_lock (&scope->config_lock); + g_mutex_lock (&scope->priv->config_lock); /* recheck as the value could have changed */ sbpf = scope->req_spf * channels * sizeof (gint16); @@ -1154,16 +1182,16 @@ gst_audio_visualizer_chain (GstPad * pad, GstObject * parent, gst_object_sync_values (GST_OBJECT (scope), ts); GST_BUFFER_TIMESTAMP (outbuf) = ts; - GST_BUFFER_DURATION (outbuf) = scope->frame_duration; + GST_BUFFER_DURATION (outbuf) = scope->priv->frame_duration; /* this can fail as the data size we need could have changed */ - if (!(adata = (gpointer) gst_adapter_map (scope->adapter, sbpf))) + if (!(adata = (gpointer) gst_adapter_map (scope->priv->adapter, sbpf))) break; gst_video_frame_map (&outframe, &scope->vinfo, outbuf, GST_MAP_READWRITE); - if (scope->shader) { - gst_video_frame_copy (&outframe, &scope->tempframe); + if (scope->priv->shader) { + gst_video_frame_copy (&outframe, &scope->priv->tempframe); } else { /* gst_video_frame_clear() or is output frame already cleared */ gint i; @@ -1186,18 +1214,18 @@ gst_audio_visualizer_chain (GstPad * pad, GstObject * parent, } else { /* run various post processing (shading and geometric transformation) */ /* FIXME: SHADER assumes 32bpp */ - if (scope->shader && + if (scope->priv->shader && GST_VIDEO_INFO_COMP_PSTRIDE (&scope->vinfo, 0) == 4) { - scope->shader (scope, &outframe, &scope->tempframe); + scope->priv->shader (scope, &outframe, &scope->priv->tempframe); } } } gst_video_frame_unmap (&outframe); - g_mutex_unlock (&scope->config_lock); - ret = gst_pad_push (scope->srcpad, outbuf); + g_mutex_unlock (&scope->priv->config_lock); + ret = gst_pad_push (scope->priv->srcpad, outbuf); outbuf = NULL; - g_mutex_lock (&scope->config_lock); + g_mutex_lock (&scope->priv->config_lock); skip: /* recheck as the value could have changed */ @@ -1205,21 +1233,21 @@ gst_audio_visualizer_chain (GstPad * pad, GstObject * parent, GST_LOG_OBJECT (scope, "avail: %u, bpf: %u", avail, sbpf); /* we want to take less or more, depending on spf : req_spf */ if (avail - sbpf >= sbpf) { - gst_adapter_flush (scope->adapter, sbpf); - gst_adapter_unmap (scope->adapter); + gst_adapter_flush (scope->priv->adapter, sbpf); + gst_adapter_unmap (scope->priv->adapter); } else if (avail >= sbpf) { /* just flush a bit and stop */ - gst_adapter_flush (scope->adapter, (avail - sbpf)); - gst_adapter_unmap (scope->adapter); + gst_adapter_flush (scope->priv->adapter, (avail - sbpf)); + gst_adapter_unmap (scope->priv->adapter); break; } - avail = gst_adapter_available (scope->adapter); + avail = gst_adapter_available (scope->priv->adapter); if (ret != GST_FLOW_OK) break; } - g_mutex_unlock (&scope->config_lock); + g_mutex_unlock (&scope->priv->config_lock); beach: return ret; @@ -1252,16 +1280,17 @@ gst_audio_visualizer_src_event (GstPad * pad, GstObject * parent, /* save stuff for the _chain() function */ GST_OBJECT_LOCK (scope); - scope->proportion = proportion; + scope->priv->proportion = proportion; if (diff >= 0) /* we're late, this is a good estimate for next displayable * frame (see part-qos.txt) */ - scope->earliest_time = timestamp + 2 * diff + scope->frame_duration; + scope->priv->earliest_time = + timestamp + 2 * diff + scope->priv->frame_duration; else - scope->earliest_time = timestamp + diff; + scope->priv->earliest_time = timestamp + diff; GST_OBJECT_UNLOCK (scope); - res = gst_pad_push_event (scope->sinkpad, event); + res = gst_pad_push_event (scope->priv->sinkpad, event); break; } case GST_EVENT_RECONFIGURE: @@ -1298,16 +1327,16 @@ gst_audio_visualizer_sink_event (GstPad * pad, GstObject * parent, } case GST_EVENT_FLUSH_STOP: gst_audio_visualizer_reset (scope); - res = gst_pad_push_event (scope->srcpad, event); + res = gst_pad_push_event (scope->priv->srcpad, event); break; case GST_EVENT_SEGMENT: { /* the newsegment values are used to clip the input samples * and to convert the incomming timestamps to running time so * we can do QoS */ - gst_event_copy_segment (event, &scope->segment); + gst_event_copy_segment (event, &scope->priv->segment); - res = gst_pad_push_event (scope->srcpad, event); + res = gst_pad_push_event (scope->priv->srcpad, event); break; } default: @@ -1341,7 +1370,7 @@ gst_audio_visualizer_src_query (GstPad * pad, GstObject * parent, if (rate == 0) break; - if ((res = gst_pad_peer_query (scope->sinkpad, query))) { + if ((res = gst_pad_peer_query (scope->priv->sinkpad, query))) { gst_query_parse_latency (query, &us_live, &min_latency, &max_latency); GST_DEBUG_OBJECT (scope, "Peer latency: min %" @@ -1349,7 +1378,7 @@ gst_audio_visualizer_src_query (GstPad * pad, GstObject * parent, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); /* the max samples we must buffer buffer */ - max_samples = MAX (scope->req_spf, scope->spf); + max_samples = MAX (scope->req_spf, scope->priv->spf); our_latency = gst_util_uint64_scale_int (max_samples, GST_SECOND, rate); GST_DEBUG_OBJECT (scope, "Our latency: %" GST_TIME_FORMAT, diff --git a/gst/audiovisualizers/gstaudiovisualizer.h b/gst/audiovisualizers/gstaudiovisualizer.h index 90c36c49a..381de8173 100644 --- a/gst/audiovisualizers/gstaudiovisualizer.h +++ b/gst/audiovisualizers/gstaudiovisualizer.h @@ -1,5 +1,6 @@ /* GStreamer * Copyright (C) <2011> Stefan Kost <ensonic@users.sf.net> + * Copyright (C) <2015> Luis de Bethencourt <luis@debethencourt.com> * * gstaudiovisualizer.c: base class for audio visualisation elements * @@ -76,37 +77,14 @@ struct _GstAudioVisualizer { GstElement parent; - /* pads */ - GstPad *srcpad, *sinkpad; - - GstAdapter *adapter; - GstBuffer *inbuf; - GstBuffer *tempbuf; - GstVideoFrame tempframe; - - GstAudioVisualizerShader shader_type; - GstAudioVisualizerShaderFunc shader; - guint32 shade_amount; - - guint spf; /* samples per video frame */ guint req_spf; /* min samples per frame wanted by the subclass */ /* video state */ GstVideoInfo vinfo; - guint64 frame_duration; /* audio state */ GstAudioInfo ainfo; - /* configuration mutex */ - GMutex config_lock; - - /* QoS stuff *//* with LOCK */ - gdouble proportion; - GstClockTime earliest_time; - - GstSegment segment; - /* <private> */ GstAudioVisualizerPrivate *priv; }; |