From: Stefan Kost Date: Fri, 27 May 2011 20:12:00 +0000 (+0300) Subject: basescope: allow subclasses telling how many sample they need per frame X-Git-Tag: 1.19.3~507^2~16050^2~34 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2271946d730848f61efa21984ca5bf5bd35ac4d5;p=platform%2Fupstream%2Fgstreamer.git basescope: allow subclasses telling how many sample they need per frame This allows e.g. FFT based elements to require enough data. If they need more data than what we get, we flush less from the adapter. https://bugzilla.gnome.org/show_bug.cgi?id=651536 --- diff --git a/gst/scopes/gstbasescope.c b/gst/scopes/gstbasescope.c index cd9a945..991b08d 100644 --- a/gst/scopes/gstbasescope.c +++ b/gst/scopes/gstbasescope.c @@ -278,13 +278,15 @@ gst_base_scope_src_setcaps (GstPad * pad, GstCaps * caps) scope->fps_d, scope->fps_n); scope->spf = gst_util_uint64_scale_int (scope->rate, scope->fps_d, scope->fps_n); + scope->req_spf = scope->spf; if (klass->setup) res = klass->setup (scope); - GST_DEBUG_OBJECT (scope, "video: dimension %dx%d, framerate %d/%d, spf %d", - scope->width, scope->height, scope->fps_n, scope->fps_d, scope->spf); - + GST_DEBUG_OBJECT (scope, "video: dimension %dx%d, framerate %d/%d", + scope->width, scope->height, scope->fps_n, scope->fps_d); + GST_DEBUG_OBJECT (scope, "blocks: spf %u, req_spf %u", + scope->spf, scope->req_spf); done: gst_object_unref (scope); return res; @@ -306,7 +308,7 @@ gst_base_scope_chain (GstPad * pad, GstBuffer * buffer) GstBaseScope *scope; GstBaseScopeClass *klass; GstBuffer *inbuf; - guint32 avail, bytesperread; + guint avail, sbpf; guint bpp; gboolean (*render) (GstBaseScope * scope, GstBuffer * audio, GstBuffer * video); @@ -336,7 +338,7 @@ gst_base_scope_chain (GstPad * pad, GstBuffer * buffer) gst_adapter_push (scope->adapter, buffer); /* this is what we want */ - bytesperread = scope->spf * scope->channels * sizeof (gint16); + sbpf = scope->req_spf * scope->channels * sizeof (gint16); bpp = gst_video_format_get_pixel_stride (scope->video_format, 0); @@ -346,7 +348,7 @@ gst_base_scope_chain (GstPad * pad, GstBuffer * buffer) /* this is what we have */ avail = gst_adapter_available (scope->adapter); - while (avail > bytesperread) { + while (avail > sbpf) { GstBuffer *outbuf; ret = gst_pad_alloc_buffer_and_set_caps (scope->srcpad, @@ -363,8 +365,8 @@ gst_base_scope_chain (GstPad * pad, GstBuffer * buffer) memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf)); GST_BUFFER_DATA (inbuf) = - (guint8 *) gst_adapter_peek (scope->adapter, bytesperread); - GST_BUFFER_SIZE (inbuf) = bytesperread; + (guint8 *) gst_adapter_peek (scope->adapter, sbpf); + GST_BUFFER_SIZE (inbuf) = sbpf; /* call class->render() vmethod */ if (render) @@ -375,10 +377,13 @@ gst_base_scope_chain (GstPad * pad, GstBuffer * buffer) ret = gst_pad_push (scope->srcpad, outbuf); outbuf = NULL; - /* FIXME: we want to ev. take less - * we need to align the audio-rate, video-rate and blocksize for render - */ - gst_adapter_flush (scope->adapter, bytesperread); + 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); + else if (avail - sbpf > 0) + gst_adapter_flush (scope->adapter, (avail - sbpf)); + avail = gst_adapter_available (scope->adapter); if (ret != GST_FLOW_OK) break; diff --git a/gst/scopes/gstbasescope.h b/gst/scopes/gstbasescope.h index 6db0c57..4bfdcd0 100644 --- a/gst/scopes/gstbasescope.h +++ b/gst/scopes/gstbasescope.h @@ -51,6 +51,7 @@ struct _GstBaseScope guint64 frame_duration; guint bps; /* bytes per sample */ guint spf; /* samples per video frame */ + guint req_spf; /* min samples per frame wanted by the subclass */ /* video state */ GstVideoFormat video_format; diff --git a/gst/scopes/gstspectrascope.c b/gst/scopes/gstspectrascope.c index a7a3715..dc745c9 100644 --- a/gst/scopes/gstspectrascope.c +++ b/gst/scopes/gstspectrascope.c @@ -125,8 +125,12 @@ gst_spectra_scope_setup (GstBaseScope * bscope) gst_fft_s16_free (scope->fft_ctx); if (scope->freq_data) g_free (scope->freq_data); - scope->fft_ctx = gst_fft_s16_new (bscope->width * 2 - 2, FALSE); + + /* we'd need this amount of samples per render() call */ + bscope->req_spf = bscope->width * 2 - 2; + scope->fft_ctx = gst_fft_s16_new (bscope->req_spf, FALSE); scope->freq_data = g_new (GstFFTS16Complex, bscope->width); + return TRUE; }