mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
parent
1363b53a9f
commit
edca6efede
1 changed files with 62 additions and 43 deletions
|
@ -66,6 +66,15 @@ static GstStaticPadTemplate gst_vaapi_overlay_src_factory =
|
||||||
G_DEFINE_TYPE (GstVaapiOverlaySinkPad, gst_vaapi_overlay_sink_pad,
|
G_DEFINE_TYPE (GstVaapiOverlaySinkPad, gst_vaapi_overlay_sink_pad,
|
||||||
GST_TYPE_VIDEO_AGGREGATOR_PAD);
|
GST_TYPE_VIDEO_AGGREGATOR_PAD);
|
||||||
|
|
||||||
|
typedef struct _GstVaapiOverlaySurfaceGenerator GstVaapiOverlaySurfaceGenerator;
|
||||||
|
struct _GstVaapiOverlaySurfaceGenerator
|
||||||
|
{
|
||||||
|
GstVaapiBlendSurfaceGenerator parent;
|
||||||
|
GstVaapiOverlay *overlay;
|
||||||
|
GList *current;
|
||||||
|
GstVaapiBlendSurface blend_surface;
|
||||||
|
};
|
||||||
|
|
||||||
#define DEFAULT_PAD_XPOS 0
|
#define DEFAULT_PAD_XPOS 0
|
||||||
#define DEFAULT_PAD_YPOS 0
|
#define DEFAULT_PAD_YPOS 0
|
||||||
#define DEFAULT_PAD_ALPHA 1.0
|
#define DEFAULT_PAD_ALPHA 1.0
|
||||||
|
@ -330,53 +339,64 @@ gst_vaapi_overlay_decide_allocation (GstAggregator * agg, GstQuery * query)
|
||||||
(GST_VAAPI_PLUGIN_BASE (agg), query);
|
(GST_VAAPI_PLUGIN_BASE (agg), query);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static GstVaapiBlendSurface *
|
||||||
gst_vaapi_overlay_process_frames (GstVaapiOverlay * overlay)
|
gst_vaapi_overlay_surface_next (GstVaapiBlendSurfaceGenerator * generator)
|
||||||
{
|
{
|
||||||
GList *l;
|
GstVaapiOverlaySurfaceGenerator *ogenerator;
|
||||||
|
GstVideoAggregatorPad *vagg_pad;
|
||||||
|
GstVaapiOverlaySinkPad *pad;
|
||||||
|
GstVideoFrame *inframe;
|
||||||
|
GstBuffer *inbuf;
|
||||||
|
GstBuffer *buf;
|
||||||
|
GstVaapiVideoMeta *inbuf_meta;
|
||||||
|
GstVaapiBlendSurface *blend_surface;
|
||||||
|
|
||||||
for (l = GST_ELEMENT (overlay)->sinkpads; l; l = l->next) {
|
ogenerator = (GstVaapiOverlaySurfaceGenerator *) generator;
|
||||||
GstVideoAggregatorPad *vagg_pad = GST_VIDEO_AGGREGATOR_PAD (l->data);
|
|
||||||
GstVaapiOverlaySinkPad *pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad);
|
|
||||||
GstVideoFrame *inframe =
|
|
||||||
gst_video_aggregator_pad_get_prepared_frame (vagg_pad);
|
|
||||||
GstBuffer *inbuf = NULL;
|
|
||||||
GstBuffer *buf = gst_video_aggregator_pad_get_current_buffer (vagg_pad);
|
|
||||||
GstVaapiVideoMeta *inbuf_meta;
|
|
||||||
GstVaapiRectangle target_rect;
|
|
||||||
|
|
||||||
if (gst_vaapi_plugin_base_pad_get_input_buffer (GST_VAAPI_PLUGIN_BASE
|
/* at the end of the generator? */
|
||||||
(overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK)
|
if (!ogenerator->current)
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
|
||||||
/* Current sinkpad may have reached EOS */
|
/* get the current video aggregator sinkpad */
|
||||||
if (!inframe || !inbuf)
|
vagg_pad = GST_VIDEO_AGGREGATOR_PAD (ogenerator->current->data);
|
||||||
continue;
|
|
||||||
|
|
||||||
target_rect.x = pad->xpos;
|
/* increment list pointer */
|
||||||
target_rect.y = pad->ypos;
|
ogenerator->current = ogenerator->current->next;
|
||||||
target_rect.width = GST_VIDEO_FRAME_WIDTH (inframe);
|
|
||||||
target_rect.height = GST_VIDEO_FRAME_HEIGHT (inframe);
|
|
||||||
|
|
||||||
inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf);
|
/* recycle the blend surface from the overlay surface generator */
|
||||||
|
blend_surface = &ogenerator->blend_surface;
|
||||||
|
blend_surface->surface = NULL;
|
||||||
|
|
||||||
if (!inbuf_meta) {
|
inframe = gst_video_aggregator_pad_get_prepared_frame (vagg_pad);
|
||||||
gst_buffer_unref (inbuf);
|
buf = gst_video_aggregator_pad_get_current_buffer (vagg_pad);
|
||||||
return FALSE;
|
pad = GST_VAAPI_OVERLAY_SINK_PAD (vagg_pad);
|
||||||
}
|
|
||||||
|
|
||||||
if (!gst_vaapi_blend_process_render (overlay->blend,
|
if (gst_vaapi_plugin_base_pad_get_input_buffer (GST_VAAPI_PLUGIN_BASE
|
||||||
gst_vaapi_video_meta_get_surface (inbuf_meta),
|
(ogenerator->overlay), GST_PAD (pad), buf, &inbuf) != GST_FLOW_OK)
|
||||||
gst_vaapi_video_meta_get_render_rect (inbuf_meta),
|
return blend_surface;
|
||||||
&target_rect, pad->alpha)) {
|
|
||||||
gst_buffer_unref (inbuf);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Current sinkpad may have reached EOS */
|
||||||
|
if (!inframe || !inbuf)
|
||||||
|
return generator->next (generator);
|
||||||
|
|
||||||
|
inbuf_meta = gst_buffer_get_vaapi_video_meta (inbuf);
|
||||||
|
|
||||||
|
if (!inbuf_meta) {
|
||||||
gst_buffer_unref (inbuf);
|
gst_buffer_unref (inbuf);
|
||||||
|
return blend_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -387,6 +407,7 @@ gst_vaapi_overlay_aggregate_frames (GstVideoAggregator * vagg,
|
||||||
GstVaapiVideoMeta *outbuf_meta;
|
GstVaapiVideoMeta *outbuf_meta;
|
||||||
GstVaapiSurface *outbuf_surface;
|
GstVaapiSurface *outbuf_surface;
|
||||||
GstVaapiSurfaceProxy *proxy;
|
GstVaapiSurfaceProxy *proxy;
|
||||||
|
GstVaapiOverlaySurfaceGenerator generator;
|
||||||
|
|
||||||
if (!overlay->blend_pool) {
|
if (!overlay->blend_pool) {
|
||||||
GstVaapiVideoPool *pool =
|
GstVaapiVideoPool *pool =
|
||||||
|
@ -414,15 +435,13 @@ gst_vaapi_overlay_aggregate_frames (GstVideoAggregator * vagg,
|
||||||
|
|
||||||
outbuf_surface = gst_vaapi_video_meta_get_surface (outbuf_meta);
|
outbuf_surface = gst_vaapi_video_meta_get_surface (outbuf_meta);
|
||||||
|
|
||||||
if (!gst_vaapi_blend_process_begin (overlay->blend, outbuf_surface))
|
/* initialize the surface generator */
|
||||||
return GST_FLOW_ERROR;
|
generator.parent.next = gst_vaapi_overlay_surface_next;
|
||||||
|
generator.overlay = overlay;
|
||||||
|
generator.current = GST_ELEMENT (overlay)->sinkpads;
|
||||||
|
|
||||||
if (!gst_vaapi_overlay_process_frames (overlay)) {
|
if (!gst_vaapi_blend_process (overlay->blend, outbuf_surface,
|
||||||
gst_vaapi_blend_process_end (overlay->blend);
|
(GstVaapiBlendSurfaceGenerator *) & generator))
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gst_vaapi_blend_process_end (overlay->blend))
|
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
Loading…
Reference in a new issue