static void gst_compositor_pad_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstCompositorPad *pad = GST_COMPOSITOR_PAD (object); switch (prop_id) { case PROP_PAD_XPOS: pad->xpos = g_value_get_int (value); break; case PROP_PAD_YPOS: pad->ypos = g_value_get_int (value); break; case PROP_PAD_WIDTH: pad->width = g_value_get_int (value); break; case PROP_PAD_HEIGHT: pad->height = g_value_get_int (value); break; case PROP_PAD_ALPHA: pad->alpha = g_value_get_double (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static GstCaps * _update_caps (GstVideoAggregator * vagg, GstCaps * caps) { GList *l; gint best_width = -1, best_height = -1; GstVideoInfo info; GstCaps *ret = NULL; gst_video_info_from_caps (&info, caps); GST_OBJECT_LOCK (vagg); for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) { GstVideoAggregatorPad *vaggpad = l->data; GstCompositorPad *compositor_pad = GST_COMPOSITOR_PAD (vaggpad); gint this_width, this_height; gint width, height; width = GST_VIDEO_INFO_WIDTH (&vaggpad->info); height = GST_VIDEO_INFO_HEIGHT (&vaggpad->info); if (width == 0 || height == 0) continue; this_width = width + MAX (compositor_pad->xpos, 0); this_height = height + MAX (compositor_pad->ypos, 0); if (best_width < this_width) best_width = this_width; if (best_height < this_height) best_height = this_height; } GST_OBJECT_UNLOCK (vagg); if (best_width > 0 && best_height > 0) { info.width = best_width; info.height = best_height; if (set_functions (GST_COMPOSITOR (vagg), &info)) ret = gst_video_info_to_caps (&info); } return ret; }
static void gst_compositor_pad_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstCompositorPad *pad = GST_COMPOSITOR_PAD (object); switch (prop_id) { case PROP_PAD_ZORDER: g_value_set_uint (value, pad->zorder); break; case PROP_PAD_XPOS: g_value_set_int (value, pad->xpos); break; case PROP_PAD_YPOS: g_value_set_int (value, pad->ypos); break; case PROP_PAD_ALPHA: g_value_set_double (value, pad->alpha); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
pad_height = gst_util_uint64_scale_int (pad_width, dar_d, dar_n); } else { pad_width = gst_util_uint64_scale_int (pad_height, dar_n, dar_d); } *width = pad_width; *height = pad_height; } static gboolean gst_compositor_pad_set_info (GstVideoAggregatorPad * pad, GstVideoAggregator * vagg G_GNUC_UNUSED, GstVideoInfo * current_info, GstVideoInfo * wanted_info) { GstCompositor *comp = GST_COMPOSITOR (vagg); GstCompositorPad *cpad = GST_COMPOSITOR_PAD (pad); gchar *colorimetry, *best_colorimetry; const gchar *chroma, *best_chroma; gint width, height; if (!current_info->finfo) return TRUE; if (GST_VIDEO_INFO_FORMAT (current_info) == GST_VIDEO_FORMAT_UNKNOWN) return TRUE; if (cpad->convert) gst_video_converter_free (cpad->convert); cpad->convert = NULL;
static GstFlowReturn gst_compositor_aggregate_frames (GstVideoAggregator * vagg, GstBuffer * outbuf) { GList *l; GstCompositor *self = GST_COMPOSITOR (vagg); BlendFunction composite; GstVideoFrame out_frame, *outframe; if (!gst_video_frame_map (&out_frame, &vagg->info, outbuf, GST_MAP_WRITE)) { return GST_FLOW_ERROR; } outframe = &out_frame; /* default to blending */ composite = self->blend; switch (self->background) { case COMPOSITOR_BACKGROUND_CHECKER: self->fill_checker (outframe); break; case COMPOSITOR_BACKGROUND_BLACK: self->fill_color (outframe, 16, 128, 128); break; case COMPOSITOR_BACKGROUND_WHITE: self->fill_color (outframe, 240, 128, 128); break; case COMPOSITOR_BACKGROUND_TRANSPARENT: { guint i, plane, num_planes, height; num_planes = GST_VIDEO_FRAME_N_PLANES (outframe); for (plane = 0; plane < num_planes; ++plane) { guint8 *pdata; gsize rowsize, plane_stride; pdata = GST_VIDEO_FRAME_PLANE_DATA (outframe, plane); plane_stride = GST_VIDEO_FRAME_PLANE_STRIDE (outframe, plane); rowsize = GST_VIDEO_FRAME_COMP_WIDTH (outframe, plane) * GST_VIDEO_FRAME_COMP_PSTRIDE (outframe, plane); height = GST_VIDEO_FRAME_COMP_HEIGHT (outframe, plane); for (i = 0; i < height; ++i) { memset (pdata, 0, rowsize); pdata += plane_stride; } } /* use overlay to keep background transparent */ composite = self->overlay; break; } } GST_OBJECT_LOCK (vagg); for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) { GstVideoAggregatorPad *pad = l->data; GstCompositorPad *compo_pad = GST_COMPOSITOR_PAD (pad); if (pad->aggregated_frame != NULL) { composite (pad->aggregated_frame, compo_pad->xpos, compo_pad->ypos, compo_pad->alpha, outframe); } } GST_OBJECT_UNLOCK (vagg); gst_video_frame_unmap (outframe); return GST_FLOW_OK; }