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 693037 - ximagesrc: delay image reconstruction when using DAMAGE
ximagesrc: delay image reconstruction when using DAMAGE
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-good
git master
Other Linux
: Normal enhancement
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
: 710323 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2013-02-01 21:21 UTC by Stirling Westrup
Modified: 2018-11-03 14:48 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Stirling Westrup 2013-02-01 21:21:42 UTC
ximagesrc has a feature where it will use the X Damage feature to only send updates for changed parts of the screen, rather than entire screens. However, when using damage, performance as a whole degrades badly, rather than improving.

This pipeline can easily handle 25 frames-per-second of updates on my system:

gst-launch-1.0 ximagesrc display-name=:1 use-damage=false ! videoconvert ! 'video/x-raw,pixel-aspect-ratio=(fraction)1/1' ! videorate ! xvimagesink display=:2

However, if one removes the 'use-damage=false' clause to permit ximagesrc to 'optimize' buffers, then one quickly gets results like this:

$ gst-launch-1.0 ximagesrc display-name=:1  ! videoconvert ! 'video/x-raw,pixel-aspect-ratio=(fraction)1/1' ! videorate ! xvimagesink display=:2
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
WARNING: from element /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0: A lot of buffers are being dropped.
Additional debug info:
gstbasesink.c(2675): gst_base_sink_is_too_late (): /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0:
There may be a timestamping problem, or this computer is too slow.
WARNING: from element /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0: A lot of buffers are being dropped.
Additional debug info:
gstbasesink.c(2675): gst_base_sink_is_too_late (): /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0:
There may be a timestamping problem, or this computer is too slow.
WARNING: from element /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0: A lot of buffers are being dropped.
Additional debug info:
gstbasesink.c(2675): gst_base_sink_is_too_late (): /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0:
There may be a timestamping problem, or this computer is too slow.
WARNING: from element /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0: A lot of buffers are being dropped.
Additional debug info:
gstbasesink.c(2675): gst_base_sink_is_too_late (): /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0:
There may be a timestamping problem, or this computer is too slow.
WARNING: from element /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0: A lot of buffers are being dropped.
Additional debug info:
gstbasesink.c(2675): gst_base_sink_is_too_late (): /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0:
There may be a timestamping problem, or this computer is too slow.
WARNING: from element /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0: A lot of buffers are being dropped.
Additional debug info:
gstbasesink.c(2675): gst_base_sink_is_too_late (): /GstPipeline:pipeline0/GstXvImageSink:xvimagesink0:
There may be a timestamping problem, or this computer is too slow.
^CCaught interrupt -- handling interrupt.
Comment 1 Stirling Westrup 2013-07-18 17:34:07 UTC
I've just checked and this issue is still extant for gstreamer 1.1.2 in git.

Is there any chance of someone looking into it? X image capture is quite slow at the moment and I was hoping that a working damage system would significantly increase perfomance.
Comment 2 Edward Hervey 2013-07-19 04:55:08 UTC
The problem is that, while damage allows to limit the throughput from ximage regarding updates (smaller data to read, you only get updates) ... it reconstructs the images straight away in the source (memcpy of the whole final size, potentially very slow)... and it does that in the same thread as the capture. That results in missing capture of the earliest next frame.

Ideally that reconstruction should happen later (when the data is actually being used) and the source should just send out buffers with the updated region (and a reference to the previous frame).

With 1.x, ximagesrc could create a new type of GstMemory for that:

* Store reference to previous image (or to none if it's a full image or has been reconstructed)
* When mapping (i.e. when someone wants to read it), reconstruct the full output image (based on on damage data + previous image, which might end up being recursive btw).

Maybe a bufferpool would also help with that also (keeping around common/last image).

This would allow getting fast acquisition (from X) and allow delayed reconstruction.
Comment 3 Stirling Westrup 2013-07-19 11:49:11 UTC
(In reply to comment #2)

> With 1.x, ximagesrc could create a new type of GstMemory for that:
> 
> * Store reference to previous image (or to none if it's a full image or has
> been reconstructed)
> * When mapping (i.e. when someone wants to read it), reconstruct the full
> output image (based on on damage data + previous image, which might end up
> being recursive btw).
> 
> Maybe a bufferpool would also help with that also (keeping around common/last
> image).
> 
> This would allow getting fast acquisition (from X) and allow delayed
> reconstruction.

This sounds like a good design, however I have a use-case where I'd like to convert the frames with damage data into jpegs which are transparent except for the changed data. That way I can simply overlay them on top of each other at the display end, and never have to reconstitute the images in memory. Although, I suppose it would make sense if every Nth frame were a full frame, for ease of recovery in case of loss of a frame.

I *may* be able to convince my boss to give me time to help out on this, as we have a definite use case for it. I'll have to ask.
Comment 4 Stirling Westrup 2013-07-23 20:40:30 UTC
(In reply to comment #3)

> 
> I *may* be able to convince my boss to give me time to help out on this, as we
> have a definite use case for it. I'll have to ask.

My Boss has, indeed, given me a green light to help out on this. However, I'm afraid my knowledge of gstreamer's memory architecture is scanty, although I'm a quickly learner. Feel free to contact me to coordinate work on this.
Comment 5 Antonio Ospite 2013-10-28 15:49:07 UTC
I experienced this problem too, maybe use-damage should be set to false by default until this issue is sorted out, what do you think?

Thanks,
   Antonio
Comment 6 Edward Hervey 2013-10-31 07:00:02 UTC
(In reply to comment #3)
> This sounds like a good design, however I have a use-case where I'd like to
> convert the frames with damage data into jpegs which are transparent except for
> the changed data. That way I can simply overlay them on top of each other at
> the display end, and never have to reconstitute the images in memory. Although,
> I suppose it would make sense if every Nth frame were a full frame, for ease of
> recovery in case of loss of a frame.

At the top of my head :

Indeed, you should be able to handle both usages (one for plugins who are not aware or care about damaged region and want whole (reconstructed) frames, and the other one for plugins who could make a more efficient usage of the damaged regions).

There are two parts to it:
* The actual data storage (i.e. custom GstMemory)
* The metadata about those damaged regions

In order for this system to work, you'll need a common (shared amongst all buffers/memory of a stream) structure to contain the last fully-reconstructed image/GstMemory. This could/should be stored in a GstBufferPool imho.

For the "damaged" GstMemory you want to know (and privately remember):
* Whether it is a whole or to-be-reconstructed image
* If to-be-reconstructed, a reference to the previous GstMemory (which will chain all the way to the last fully reconstructed image).
* a list of
** GstMemory for this image's partial memory (those are not stored in GstBuffer, otherwise the default gst_buffer_map would give you garbage).
** the x,y pixel offset of that memory in the whole frame
** the width,height pixel offset of that memory in the whole frame
* Implementations of map/unmap vmethod to reconstruct if needed (i.e. the fallback solution). Those would then chain-up and reconstruct a full video image (which further buffers/memory will then use).

That would take care of the "naive" delegated reconstruction (any plugin downstream wanting to map the memory will end up with a full image).

You'll also need to create a GstMeta to provide information on the "damaged" content, for the plugins that can handle it
* Glist of damage information
  * x,y position in pixels
  * width, height in pixels
  * GstMemory reference of the individual damaged area

That would allow plugins that know how to deal with damaged images to be able to get the individual regions.

You would then need to add support to your encoder to create those "transparent" images you mention.

The x,y,width,height would all be in pixels and you'd have to check the GstVideoMeta for the actual type and compute the bytes offsets/strides

Hope this helps
Comment 7 Edward Hervey 2018-05-04 09:07:28 UTC
*** Bug 710323 has been marked as a duplicate of this bug. ***
Comment 8 Edward Hervey 2018-05-04 09:12:15 UTC
Keeping this open. Has useful information regarding a backwards-compatible and transparent way of handling this use-case.
Comment 9 GStreamer system administrator 2018-11-03 14:48:30 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/issues/82.