After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 797234 - overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream
overlaycomposition: New element that allows applications to draw GstVideoOver...
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
unspecified
Other All
: Normal enhancement
: 1.15.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2018-10-01 16:27 UTC by Sebastian Dröge (slomo)
Modified: 2018-10-28 17:05 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream (28.20 KB, patch)
2018-10-01 16:27 UTC, Sebastian Dröge (slomo)
none Details | Review
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream (28.23 KB, patch)
2018-10-03 21:22 UTC, Sebastian Dröge (slomo)
none Details | Review
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream (28.38 KB, patch)
2018-10-04 20:15 UTC, Sebastian Dröge (slomo)
none Details | Review
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream (35.31 KB, patch)
2018-10-11 07:18 UTC, Sebastian Dröge (slomo)
none Details | Review
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream (35.95 KB, patch)
2018-10-13 15:49 UTC, Sebastian Dröge (slomo)
none Details | Review
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream (51.04 KB, patch)
2018-10-24 14:19 UTC, Sebastian Dröge (slomo)
none Details | Review
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream (63.26 KB, patch)
2018-10-28 17:04 UTC, Sebastian Dröge (slomo)
committed Details | Review

Description Sebastian Dröge (slomo) 2018-10-01 16:27:42 UTC
Works basically like cairooverlay but is more efficient and allows the
application to render the overlays with any API they want.

Negotiation is based on textoverlay.
Comment 1 Sebastian Dröge (slomo) 2018-10-01 16:27:46 UTC
Created attachment 373821 [details] [review]
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream
Comment 2 Sebastian Dröge (slomo) 2018-10-03 21:22:01 UTC
Created attachment 373836 [details] [review]
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream
Comment 3 Sebastian Dröge (slomo) 2018-10-04 20:15:12 UTC
Created attachment 373848 [details] [review]
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream
Comment 4 Tim-Philipp Müller 2018-10-10 10:31:36 UTC
Comment on attachment 373848 [details] [review]
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream

What's the reason this is not a GstVideoFilter or GstBaseTransform subclass? To avoid mapping the buffer if we don't need to blend?

I'm fine with adding it to -base directly. It's very useful and straight forward enough, but I think it needs some documentation then (what is it for? when to use it rather than cairooverlay for example?) and a minimal unit test that ideally exercises all the common code paths.

Disclaimer: I didn't look at caps nego, I'll just assume it'll work at least as well as textoverlay if it's a direct copy from there.

>+  /**
>+   * GstOverlayComposition::draw:
>+   * @overlay: Overlay element emitting the signal.
>+   * @timestamp: Timestamp (see #GstClockTime) of the current buffer.
>+   * @duration: Duration (see #GstClockTime) of the current buffer.
>+   *
>+   * This signal is emitted when the overlay should be drawn.
>+   *
>+   * Returns: #GstVideoOverlayComposition or %NULL
>+   */

Should it be timestamp or running time, or both? I wonder if we should
actually pass the buffer here too, there might be metas on the buffer that
are relevant for what should be drawn (e.g. extra time metas or other kind
of metas).


>+  overlay_composition_signals[SIGNAL_DRAW] =
>+      g_signal_new ("draw",
>+      G_TYPE_FROM_CLASS (klass),
>+      0,
>+      0,
>+      NULL,
>+      NULL,
>+      g_cclosure_marshal_generic,
>+      GST_TYPE_VIDEO_OVERLAY_COMPOSITION, 2, G_TYPE_UINT64, G_TYPE_UINT64);

We have GST_TYPE_CLOCK_TIME defines fwiw, though they map to the same of course.


>+  /**
>+   * GstOverlayComposition::caps-changed:
>+   * @overlay: Overlay element emitting the signal.
>+   * @caps: The #GstCaps of the element.
>+   * @window_width: The window render width of downstream, or 0.
>+   * @window_height: The window render height of downstream, or 0.
>+   *
>+   * This signal is emitted when the caps of the element has changed.
>+   */

I think the "window render width" might need explaining? What does it mean here?


>+static GstFlowReturn
>+gst_overlay_composition_sink_chain (GstPad * pad, GstObject * parent,
>+    GstBuffer * buffer)
>+{
>+  ...
>+
>+  if (gst_pad_check_reconfigure (self->srcpad)) {
>+    if (!gst_overlay_composition_negotiate (self, NULL)) {
>+      gst_pad_mark_reconfigure (self->srcpad);
>+      gst_buffer_unref (buffer);
>+      if (GST_PAD_IS_FLUSHING (self->srcpad))
>+        return GST_FLOW_FLUSHING;
>+      else
>+        return GST_FLOW_NOT_NEGOTIATED;
>+    }
>+  }

Not sure the GST_PAD_IS_FLUSHING is thread-safe here, since we don't hold the srcpad object lock? Maybe we want a gst_pad_is_flushing() too?


>+  g_signal_emit (self, overlay_composition_signals[SIGNAL_DRAW], 0,
>+      GST_BUFFER_PTS (buffer), GST_BUFFER_DURATION (buffer), &compo);

As mentioned above, think we should maybe just pass the entire buffer here?


>+  /* If upstream attached a meta, we can safely add our own things
>+   * in it. Upstream must've checked that downstream supports it */
>+  upstream_compo_meta = gst_buffer_get_video_overlay_composition_meta (buffer);
>+  if (upstream_compo_meta) {
>+    GstVideoOverlayComposition *merged_compo =
>+        gst_video_overlay_composition_copy (upstream_compo_meta->overlay);
>+    guint i, n;
>+
>+    GST_DEBUG_OBJECT (self->sinkpad,
>+        "Appending to upstream overlay composition");
>+
>+    n = gst_video_overlay_composition_n_rectangles (compo);
>+    for (i = 0; i < n; i++) {
>+      GstVideoOverlayRectangle *rect =
>+          gst_video_overlay_composition_get_rectangle (compo, i);
>+      gst_video_overlay_composition_add_rectangle (merged_compo, rect);
>+    }
>+
>+    gst_video_overlay_composition_unref (compo);
>+    gst_video_overlay_composition_unref (upstream_compo_meta->overlay);

Maybe we should make a convenience function for this? I think we have similar code elsewhere?

>+map_failed:
>+  {
>+    GST_ERROR_OBJECT (self->sinkpad, "Failed to map buffer");

Nitpick: we can just use 'pad' here, but it's relaly not a pad-related error is it, so maybe just use 'self' instead?
Comment 5 Tim-Philipp Müller 2018-10-10 10:32:27 UTC
I also think we should make something like this into a public base class at some point, but that can be done independently/later.
Comment 6 Sebastian Dröge (slomo) 2018-10-10 14:33:42 UTC
(In reply to Tim-Philipp Müller from comment #4)
> Comment on attachment 373848 [details] [review] [review]
> overlaycomposition: New element that allows applications to draw
> GstVideoOverlayComposition on a stream
> 
> What's the reason this is not a GstVideoFilter or GstBaseTransform subclass?
> To avoid mapping the buffer if we don't need to blend?

You can't do caps negotiation and allocation query together in basetransform properly due to how the base class works. But it also prevents us from requiring a writable buffer (basetransform) or mapping it writable (videofilter).

> I'm fine with adding it to -base directly. It's very useful and straight
> forward enough, but I think it needs some documentation then (what is it
> for? when to use it rather than cairooverlay for example?) and a minimal
> unit test that ideally exercises all the common code paths.

Agreed, 

> Disclaimer: I didn't look at caps nego, I'll just assume it'll work at least
> as well as textoverlay if it's a direct copy from there.

It's a direct copy from there.

> >+  /**
> >+   * GstOverlayComposition::draw:
> >+   * @overlay: Overlay element emitting the signal.
> >+   * @timestamp: Timestamp (see #GstClockTime) of the current buffer.
> >+   * @duration: Duration (see #GstClockTime) of the current buffer.
> >+   *
> >+   * This signal is emitted when the overlay should be drawn.
> >+   *
> >+   * Returns: #GstVideoOverlayComposition or %NULL
> >+   */
> 
> Should it be timestamp or running time, or both? I wonder if we should
> actually pass the buffer here too, there might be metas on the buffer that
> are relevant for what should be drawn (e.g. extra time metas or other kind
> of metas).

Maybe we should just pass a GstSample here? Then we have the buffer and also the segment.

What do you think?

> >+  overlay_composition_signals[SIGNAL_DRAW] =
> >+      g_signal_new ("draw",
> >+      G_TYPE_FROM_CLASS (klass),
> >+      0,
> >+      0,
> >+      NULL,
> >+      NULL,
> >+      g_cclosure_marshal_generic,
> >+      GST_TYPE_VIDEO_OVERLAY_COMPOSITION, 2, G_TYPE_UINT64, G_TYPE_UINT64);
> 
> We have GST_TYPE_CLOCK_TIME defines fwiw, though they map to the same of
> course.

Will clean that up even if it doesn't make any practical difference

> >+  /**
> >+   * GstOverlayComposition::caps-changed:
> >+   * @overlay: Overlay element emitting the signal.
> >+   * @caps: The #GstCaps of the element.
> >+   * @window_width: The window render width of downstream, or 0.
> >+   * @window_height: The window render height of downstream, or 0.
> >+   *
> >+   * This signal is emitted when the caps of the element has changed.
> >+   */
> 
> I think the "window render width" might need explaining? What does it mean
> here?

If it's not 0 then this is the width/height that is used for the final rendering of the video (after rescaling and everything). E.g. the video sink's window size. I don't know why this API does not consider a pixel-aspect-ratio, but that's how it's implemented.

> >+static GstFlowReturn
> >+gst_overlay_composition_sink_chain (GstPad * pad, GstObject * parent,
> >+    GstBuffer * buffer)
> >+{
> >+  ...
> >+
> >+  if (gst_pad_check_reconfigure (self->srcpad)) {
> >+    if (!gst_overlay_composition_negotiate (self, NULL)) {
> >+      gst_pad_mark_reconfigure (self->srcpad);
> >+      gst_buffer_unref (buffer);
> >+      if (GST_PAD_IS_FLUSHING (self->srcpad))
> >+        return GST_FLOW_FLUSHING;
> >+      else
> >+        return GST_FLOW_NOT_NEGOTIATED;
> >+    }
> >+  }
> 
> Not sure the GST_PAD_IS_FLUSHING is thread-safe here, since we don't hold
> the srcpad object lock? Maybe we want a gst_pad_is_flushing() too?

If the negotiation failed due to flushing, then the relevant locks were all taken already before. But using gst_pad_is_flushing() would be cleaner, yes.
Comment 7 Sebastian Dröge (slomo) 2018-10-10 14:34:49 UTC
(In reply to Sebastian Dröge (slomo) from comment #6)

> 
> > I'm fine with adding it to -base directly. It's very useful and straight
> > forward enough, but I think it needs some documentation then (what is it
> > for? when to use it rather than cairooverlay for example?) and a minimal
> > unit test that ideally exercises all the common code paths.
> 
> Agreed, 

Forgot to continue writing. Agreed, I'll add those once we agree on an API and that this is a good idea in general :)
Comment 8 Tim-Philipp Müller 2018-10-10 17:34:00 UTC
> > I wonder if we should actually pass the buffer here too, 
> > there might be metas on the buffer that are relevant for
> > what should be drawn (e.g. extra time metas or other kind
> > of metas).
> 
> Maybe we should just pass a GstSample here? Then we have the
> buffer and also the segment.

Yes, sounds like a good idea, if we can implement it in a way that reuses a GstSample in the normal case and doesn't create a GstSample for each buffer.

> > >+  if (gst_pad_check_reconfigure (self->srcpad)) {
> > >+    if (!gst_overlay_composition_negotiate (self, NULL)) {
> > >+      gst_pad_mark_reconfigure (self->srcpad);
> > >+      gst_buffer_unref (buffer);
> > >+      if (GST_PAD_IS_FLUSHING (self->srcpad))
> > >+        return GST_FLOW_FLUSHING;
> > >+      ..
> > >+    }
> > >+  }
> > 
> > Not sure the GST_PAD_IS_FLUSHING is thread-safe here, since we don't hold
> > the srcpad object lock? Maybe we want a gst_pad_is_flushing() too?
> 
> If the negotiation failed due to flushing, then the relevant locks were all
> taken already before. But using gst_pad_is_flushing() would be cleaner, yes.

Negotiation could have failed for another reason, and we could have a flush-start event being processed at the same time in another thread, no? (unlikely as it may be, but still)
Comment 9 Sebastian Dröge (slomo) 2018-10-11 06:48:12 UTC
Ack, going for that then :)
Comment 10 Sebastian Dröge (slomo) 2018-10-11 07:18:16 UTC
Created attachment 373892 [details] [review]
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream
Comment 11 Sebastian Dröge (slomo) 2018-10-11 07:19:24 UTC
Review of attachment 373892 [details] [review]:

What do you think? Docs are also added with a simple example

::: gst/overlaycomposition/gstoverlaycomposition.c
@@ +24,3 @@
+ *
+ * The full example can be found in
+ * tests/examples/overlaycomposition/overlaycomposition.c

Need to write this example, and tests
Comment 12 Tim-Philipp Müller 2018-10-11 07:37:19 UTC
Looks good.

Maybe turn the reference to the example in the docs into a link to cgit instead.

For the window size description, it would be good to provide an example of what that could be used for, e.g. "In cases where the output window resolution is higher than the resolution of the current video, for example, it could make sense to render the overlay in the output window resolution in order to avoid scaling artefacts later." or somesuch.
Comment 13 Tim-Philipp Müller 2018-10-11 07:40:01 UTC
In the sample update part, we could probably optimise the bit where it sets the caps and/or segment so that those are only updated when they actually changed? Not sure if it's worth it, not so important I guess.
Comment 14 Tim-Philipp Müller 2018-10-13 15:31:00 UTC
Comment on attachment 373892 [details] [review]
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream

Also needs an entry in meson_options.txt
Comment 15 Sebastian Dröge (slomo) 2018-10-13 15:49:28 UTC
Created attachment 373915 [details] [review]
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream
Comment 16 Sebastian Dröge (slomo) 2018-10-24 14:19:42 UTC
Created attachment 374031 [details] [review]
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream
Comment 17 Sebastian Dröge (slomo) 2018-10-28 17:04:07 UTC
Created attachment 374089 [details] [review]
overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream
Comment 18 Sebastian Dröge (slomo) 2018-10-28 17:05:06 UTC
Attachment 374089 [details] pushed as 088b4c0 - overlaycomposition: New element that allows applications to draw GstVideoOverlayComposition on a stream