drothlis/stb-tester — pull request #119 by wmanley (2014-03-19 00:36:49+00:00)
Title: Gstreamer 1.0: Improve performance back to pre-1.0 days

When migrating to GStreamer 1.0 we introduced a performance regression slowing down stb-tester by a factor of 4 or so. Based on profiling this was due to it being slow to create buffers (`Gst.Buffer.new_wrapped`) from the numpy arrays as required for drawing notes on the saved/displayed video. My best guess is that instead of doing a straight `memcpy` it was iterating through each element copying a byte at a time.

This commit fixes these performance issues and increases performance by ~10% vs. stb-tester 0.18. We do this by avoiding copys. Internally the numpy arrays are backed by the data directly in the `Gst.Buffer`s. Instead of 3 copies made during `detect_match` only one is made now.

Unfortunately some of the code is a little hairy. The proper way to do this with GStreamer 1.0 is to use `gst_buffer_map()` and access the data through the returned `GstMapInfo` struct. Unfortunately the `GstMapInfo` isn't properly exposed in Python (see [bz #678663]) so instead I use ctypes to call it more manually. Note: this issue should be fixed in the (as yet) unreleased python-gobject 3.12 (see [bz #710561]).

Every `gst_buffer_map()` must be accompanied with a `gst_buffer_unmap()` and the data must only be accessed between these two calls. To enforce this in Python we use a `contextmanager` although this isn't perfect. This means that the numpy array should not be used outside of the `with:` statement and the data should be copied instead using `numpy.ndarray.copy`.

[bz #678663]: https://bugzilla.gnome.org/show_bug.cgi?id=678663
[bz #710561]: https://bugzilla.gnome.org/show_bug.cgi?id=710561

I've tested this with a modified `run-performance-test.sh` with my HDPVR and performance is now slightly better than it was before gst-1.0. I have an updated `run-performance-test.sh` but it depends on some of the testing facilities introduced in #100 so I haven't included them in this pull request.