summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-01-14 18:57:31 +0100
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-01-14 19:52:18 +0100
commit889fac3823cc4f6ab5923a71d3e56d25f17df52e (patch)
tree9860d6caa3520bc693ebdcd214cdb0d78f35bacd
parentd0e14ec3089af20f75e12816368f0807b355af93 (diff)
vaapioverlay: unroll the recursive call
Recursive functions are elegant but dangerous since they might overflow the stack. It is better to turn them into a list tranversal if possible, as this case.
-rw-r--r--gst/vaapi/gstvaapioverlay.c72
1 files changed, 34 insertions, 38 deletions
diff --git a/gst/vaapi/gstvaapioverlay.c b/gst/vaapi/gstvaapioverlay.c
index 5f3f4541..7cdb21eb 100644
--- a/gst/vaapi/gstvaapioverlay.c
+++ b/gst/vaapi/gstvaapioverlay.c
@@ -374,49 +374,45 @@ gst_vaapi_overlay_surface_next (gpointer data)
generator = (GstVaapiOverlaySurfaceGenerator *) data;
/* at the end of the generator? */
- if (!generator->current)
- return NULL;
-
- /* get the current video aggregator sinkpad */
- vagg_pad = GST_VIDEO_AGGREGATOR_PAD (generator->current->data);
-
- /* increment list pointer */
- generator->current = generator->current->next;
-
- /* recycle the blend surface from the overlay surface generator */
- blend_surface = &generator->blend_surface;
- blend_surface->surface = NULL;
-
- inframe = gst_video_aggregator_pad_get_prepared_frame (vagg_pad);
- buf = gst_video_aggregator_pad_get_current_buffer (vagg_pad);
- pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad);
-
- if (gst_vaapi_plugin_base_pad_get_input_buffer (GST_VAAPI_PLUGIN_BASE
- (generator->overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK)
- return blend_surface;
-
- /* Current sinkpad may have reached EOS */
- if (!inframe || !inbuf)
- return gst_vaapi_overlay_surface_next (generator);
-
- inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf);
+ while (generator->current) {
+ /* get the current video aggregator sinkpad */
+ vagg_pad = GST_VIDEO_AGGREGATOR_PAD (generator->current->data);
+
+ /* increment list pointer */
+ generator->current = generator->current->next;
+
+ /* recycle the blend surface from the overlay surface generator */
+ blend_surface = &generator->blend_surface;
+ blend_surface->surface = NULL;
+
+ inframe = gst_video_aggregator_pad_get_prepared_frame (vagg_pad);
+ buf = gst_video_aggregator_pad_get_current_buffer (vagg_pad);
+ pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad);
+
+ if (gst_vaapi_plugin_base_pad_get_input_buffer (GST_VAAPI_PLUGIN_BASE
+ (generator->overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK)
+ return blend_surface;
+
+ /* Current sinkpad may have reached EOS */
+ if (!inframe || !inbuf)
+ continue;
+
+ inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf);
+ if (inbuf_meta) {
+ blend_surface->surface = gst_vaapi_video_meta_get_surface (inbuf_meta);
+ blend_surface->crop = gst_vaapi_video_meta_get_render_rect (inbuf_meta);
+ blend_surface->target.x = pad->xpos;
+ blend_surface->target.y = pad->ypos;
+ blend_surface->target.width = GST_VIDEO_FRAME_WIDTH (inframe);
+ blend_surface->target.height = GST_VIDEO_FRAME_HEIGHT (inframe);
+ blend_surface->alpha = pad->alpha;
+ }
- if (!inbuf_meta) {
gst_buffer_unref (inbuf);
return blend_surface;
}
- blend_surface->surface = gst_vaapi_video_meta_get_surface (inbuf_meta);
- blend_surface->crop = gst_vaapi_video_meta_get_render_rect (inbuf_meta);
- blend_surface->target.x = pad->xpos;
- blend_surface->target.y = pad->ypos;
- blend_surface->target.width = GST_VIDEO_FRAME_WIDTH (inframe);
- blend_surface->target.height = GST_VIDEO_FRAME_HEIGHT (inframe);
- blend_surface->alpha = pad->alpha;
-
- gst_buffer_unref (inbuf);
-
- return blend_surface;
+ return NULL;
}
static GstFlowReturn