appsink: Mapping a buffer as READWRITE always copies the data
It seems like after a combination of d00e0b61 (@meh) by and 6fa35140 (@slomo) no buffer pulled from an appsink can be mapped as READWRITE without copying the underlying data. Here's a minimal example to reproduce the problem:
#include <gst/gst.h>
#include <gst/app/gstappsink.h>
int
main (int argc, char *argv[])
{
gst_init (&argc, &argv);
GstElement *pipe = gst_parse_launch ("videotestsrc ! "
"appsink name=sink enable-last-sample=false max-buffers=1 drop=false",
NULL);
gst_element_set_state (pipe, GST_STATE_PLAYING);
GstAppSink *app = gst_bin_get_by_name (pipe, "sink");
/* Free the ref of the preroll */
GstSample *s = gst_app_sink_pull_preroll (app);
gst_sample_unref (s);
s = gst_app_sink_pull_sample (app);
g_print ("Sample refcount: %d\n", GST_MINI_OBJECT_REFCOUNT_VALUE (s));
GstBuffer *b = gst_sample_get_buffer (s);
g_print ("Buffer 1 refcount: %d\n", GST_MINI_OBJECT_REFCOUNT_VALUE (b));
g_print ("Buffer 1 is writable: %d\n", gst_buffer_is_writable (b));
b = gst_buffer_make_writable (gst_buffer_ref (b));
g_print ("Buffer 2 refcount: %d\n", GST_MINI_OBJECT_REFCOUNT_VALUE (b));
g_print ("Buffer 2 is writable: %d\n", gst_buffer_is_writable (b));
GstMapInfo info = GST_MAP_INFO_INIT;
g_print ("Memcpy below\n");
gst_buffer_map (b, &info, GST_MAP_READWRITE);
g_print ("Memcpy above\n");
gst_buffer_unmap (b, &info);
gst_buffer_unref (b);
gst_sample_unref (s);
return 0;
}
Build and run as:
cc -o gst gst.c `pkg-config --cflags --libs gstreamer-1.0 gstreamer-app-1.0`
GST_DEBUG=2,GST_PERFORMANCE:9,GST_BUFFER:9,GST_MEMORY:9,GST_LOCKING:9 ./gst
My run shows as follows:
Sample refcount: 2
Buffer 1 refcount: 1
Buffer 1 is writable: 0
Buffer 2 refcount: 1. <———— Made the buffer writable
Buffer 2 is writable: 1
Memcpy below
…
0:00:00.059691000 33882 0x7f9c55e0e000 TRACE GST_LOCKING gstminiobject.c:221:gboolean gst_mini_object_lock(GstMiniObject *, GstLockFlags): lock 0x7f9c58000000: state 00020000, access_mode 3
0:00:00.059706000 33882 0x7f9c55e0e000 DEBUG GST_LOCKING gstminiobject.c:256:gboolean gst_mini_object_lock(GstMiniObject *, GstLockFlags): lock failed 0x7f9c58000000: state 00020000, access_mode 3
...
0:00:00.059753000 33882 0x7f9c55e0e000 DEBUG GST_PERFORMANCE gstallocator.c:461:GstMemorySystem *_sysmem_copy(GstMemorySystem *, gssize, gsize): memcpy 115200 memory 0x7f9c58000000 -> 0x7f9c5804b000
...
Memcpy above