Skip to content

Commit

Permalink
Merge pull request #48 from adenexter/jb49430
Browse files Browse the repository at this point in the history
[gst-droid] Use the buffer pool proposed by droideglsink in camera and video decoder. Contributes to JB#49340
  • Loading branch information
adenexter committed Apr 21, 2020
2 parents 3135548 + b0a25ef commit b52b404
Show file tree
Hide file tree
Showing 19 changed files with 1,628 additions and 924 deletions.
10 changes: 7 additions & 3 deletions gst-libs/gst/droid/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ libgstdroid_@GST_API_VERSION@_ladir = $(libdir)
libgstdroid_@GST_API_VERSION@_la_includedir = \
$(includedir)/gstreamer-@GST_API_VERSION@/gst/allocators

libgstdroid_@GST_API_VERSION@_la_CFLAGS = $(GST_CFLAGS) -I/usr/include/droidmedia/
libgstdroid_@GST_API_VERSION@_la_CFLAGS = $(GST_CFLAGS) \
$(EGL_CFLAGS) \
-DEGL_NO_X11 \
-I/usr/include/droidmedia/

libgstdroid_@GST_API_VERSION@_la_LIBADD = $(GST_LIBS)
libgstdroid_@GST_API_VERSION@_la_LIBADD = $(GST_LIBS) \
$(EGL_LIBS)

noinst_HEADERS =

Expand All @@ -24,4 +28,4 @@ libgstdroid_@GST_API_VERSION@_la_include_HEADERS = \
gstdroidmediabuffer.h \
gstdroidbufferpool.h \
gstdroidquery.h \
gstdroidcodec.h
gstdroidcodec.h
272 changes: 200 additions & 72 deletions gst-libs/gst/droid/gstdroidbufferpool.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,16 @@
#include "gstdroidbufferpool.h"
#include "gstdroidmediabuffer.h"

/* Element signals and args */
enum
{
BUFFERS_INVALIDATED,
LAST_SIGNAL
};
#define gst_droid_buffer_pool_parent_class parent_class
G_DEFINE_TYPE (GstDroidBufferPool, gst_droid_buffer_pool, GST_TYPE_BUFFER_POOL);

static void
gst_droid_buffer_pool_reset_buffer (GstBufferPool * pool, GstBuffer * buffer)
{
GstDroidBufferPool *dpool = GST_DROID_BUFFER_POOL (pool);

// if the allocator is set then we should keep the memory
if (!dpool->allocator) {
gst_buffer_remove_all_memory (buffer);
GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
}

g_mutex_lock (&dpool->lock);
++dpool->num_buffers;
GST_DEBUG_OBJECT (dpool, "num buffers: %d", dpool->num_buffers);
g_cond_signal (&dpool->cond);
g_mutex_unlock (&dpool->lock);

return GST_BUFFER_POOL_CLASS (parent_class)->reset_buffer (pool, buffer);
}
static guint gst_droid_buffer_pool_signals[LAST_SIGNAL] = { 0 };

static gboolean
gst_droid_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
Expand All @@ -60,6 +48,8 @@ gst_droid_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
}
// If we have caps then we can create droid buffers
if (caps != NULL) {
GstCapsFeatures *features = gst_caps_get_features (caps, 0);

GST_OBJECT_LOCK (pool);

if (!gst_video_info_from_caps (&pool->video_info, caps)) {
Expand All @@ -69,6 +59,8 @@ gst_droid_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
}

pool->video_info.size = size;
pool->use_queue_buffers = gst_caps_features_contains
(features, GST_CAPS_FEATURE_MEMORY_DROID_MEDIA_QUEUE_BUFFER);

GST_DEBUG_OBJECT (pool, "Configured pool. caps: %" GST_PTR_FORMAT, caps);
pool->allocator = gst_droid_media_buffer_allocator_new ();
Expand Down Expand Up @@ -98,97 +90,222 @@ gst_droid_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buf,
GstBuffer *buffer;
GstMemory *memory;

if (!dpool->allocator) {
return GST_FLOW_ERROR;
}

buffer = gst_buffer_new ();
if (!buffer) {
return GST_FLOW_ERROR;
}
// if the allocator is set then we should create the memory too
if (dpool->allocator) {

if (!dpool->use_queue_buffers) {
memory = gst_droid_media_buffer_allocator_alloc_new (dpool->allocator,
&dpool->video_info, buffer);
&dpool->video_info);
if (!memory) {
gst_buffer_unref (buffer);
return GST_FLOW_ERROR;
}

gst_buffer_insert_memory (buffer, 0, memory);
}

g_mutex_lock (&dpool->lock);
++dpool->num_buffers;
*buf = buffer;
GST_DEBUG_OBJECT (dpool, "num buffers: %d", dpool->num_buffers);
g_cond_signal (&dpool->cond);
g_mutex_unlock (&dpool->lock);

return GST_FLOW_OK;
}

gboolean
gst_droid_buffer_pool_wait_for_buffer (GstBufferPool * pool)
static void
gst_droid_buffer_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
{
GstDroidBufferPool *dpool = GST_DROID_BUFFER_POOL (pool);
DroidMediaBuffer *droid_buffer = NULL;

if (GST_BUFFER_POOL_IS_FLUSHING (pool)) {
return FALSE;
if (dpool->use_queue_buffers) {
guint index;

g_mutex_lock (&dpool->binding_lock);

if (g_ptr_array_find (dpool->acquired_buffers, buffer, &index)) {
g_ptr_array_remove_index_fast (dpool->acquired_buffers, index);

droid_buffer =
gst_droid_media_buffer_memory_get_buffer_from_gst_buffer (buffer);

if (droid_media_buffer_get_user_data (droid_buffer) == buffer) {
g_ptr_array_add (dpool->bound_buffers, buffer);
} else {
droid_buffer = NULL;
}
}

g_mutex_unlock (&dpool->binding_lock);
}

g_mutex_lock (&dpool->lock);
if (droid_buffer) {
buffer->pool = gst_object_ref (pool);

droid_media_buffer_release (droid_buffer, dpool->display, NULL);
} else {
if (dpool->use_queue_buffers) {
gst_buffer_remove_all_memory (buffer);
GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
}

GST_BUFFER_POOL_CLASS (parent_class)->release_buffer (pool, buffer);
}
}

void
gst_droid_buffer_pool_set_egl_display (GstBufferPool * pool, EGLDisplay display)
{
GstDroidBufferPool *dpool = GST_DROID_BUFFER_POOL (pool);

if (dpool->num_buffers > 0) {
g_mutex_unlock (&dpool->lock);
return TRUE;
if (dpool) {
dpool->display = display;
}
}

gboolean
gst_droid_buffer_pool_bind_media_buffer (GstBufferPool * pool,
DroidMediaBuffer * buffer)
{
GstDroidBufferPool *dpool;
GstBuffer *gst_buffer;
GstMemory *mem;

g_cond_wait (&dpool->cond, &dpool->lock);
g_mutex_unlock (&dpool->lock);
if (!GST_IS_DROID_BUFFER_POOL (pool)) {
return FALSE;
}

if (GST_BUFFER_POOL_IS_FLUSHING (pool)) {
if (gst_buffer_pool_acquire_buffer (pool, &gst_buffer, NULL) != GST_FLOW_OK) {
return FALSE;
}

dpool = GST_DROID_BUFFER_POOL (pool);

mem =
gst_droid_media_buffer_allocator_alloc_from_buffer (dpool->allocator,
buffer);

if (!mem) {
gst_buffer_unref (gst_buffer);

return FALSE;
}

gst_buffer_insert_memory (gst_buffer, 0, mem);

g_mutex_lock (&dpool->binding_lock);

droid_media_buffer_set_user_data (buffer, gst_buffer);

g_ptr_array_add (dpool->bound_buffers, gst_buffer);

g_mutex_unlock (&dpool->binding_lock);

return TRUE;
}

static void
gst_droid_buffer_pool_flush_start (GstBufferPool * pool)
gst_droid_buffer_pool_clear_buffers_user_data (GPtrArray * buffers)
{
GstDroidBufferPool *dpool = GST_DROID_BUFFER_POOL (pool);
guint i;

for (i = 0; i < buffers->len; ++i) {
DroidMediaBuffer *buffer =
gst_droid_media_buffer_memory_get_buffer_from_gst_buffer ((GstBuffer *)
g_ptr_array_index (buffers, i));

g_mutex_lock (&dpool->lock);
g_cond_signal (&dpool->cond);
g_mutex_unlock (&dpool->lock);
if (buffer) {
droid_media_buffer_set_user_data (buffer, NULL);
}
}
}

static GstFlowReturn
gst_droid_buffer_pool_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
GstBufferPoolAcquireParams * params)
GstBuffer *
gst_droid_buffer_pool_acquire_media_buffer (GstBufferPool * pool,
DroidMediaBuffer * buffer)
{
guint index;
GstBuffer *gst_buffer = NULL;
GstDroidBufferPool *dpool = GST_DROID_BUFFER_POOL (pool);
GstFlowReturn ret;

ret =
GST_BUFFER_POOL_CLASS (parent_class)->acquire_buffer (pool, buffer,
params);
if (!dpool) {
return NULL;
}

g_mutex_lock (&dpool->binding_lock);

gst_buffer = (GstBuffer *) droid_media_buffer_get_user_data (buffer);

if (gst_buffer->pool != pool) {
droid_media_buffer_set_user_data (buffer, NULL);

g_mutex_unlock (&dpool->binding_lock);

if (!gst_droid_buffer_pool_bind_media_buffer (pool, buffer)) {
return NULL;
}

if (gst_buffer) {
gst_buffer_unref (gst_buffer);
}

g_mutex_lock (&dpool->binding_lock);

gst_buffer = (GstBuffer *) droid_media_buffer_get_user_data (buffer);
}

if (gst_buffer && g_ptr_array_find (dpool->bound_buffers, gst_buffer, &index)) {
g_ptr_array_remove_index_fast (dpool->bound_buffers, index);

if (G_LIKELY (ret == GST_FLOW_OK)) {
g_mutex_lock (&dpool->lock);
--dpool->num_buffers;
GST_DEBUG_OBJECT (dpool, "num buffers: %d", dpool->num_buffers);
g_mutex_unlock (&dpool->lock);
g_ptr_array_add (dpool->acquired_buffers, gst_buffer);
}

return ret;
g_mutex_unlock (&dpool->binding_lock);

return gst_buffer;
}

static gboolean
gst_droid_buffer_pool_start (GstBufferPool * pool)
void
gst_droid_buffer_pool_media_buffers_invalidated (GstBufferPool * pool)
{
GstDroidBufferPool *dpool = GST_DROID_BUFFER_POOL (pool);
GPtrArray *buffers_to_release = NULL;
guint i;
GstDroidBufferPool *dpool;

if (!pool || !GST_IS_DROID_BUFFER_POOL (pool)) {
GST_WARNING_OBJECT (pool, "Pool is not a GstDroidBufferPool");
return;
}

dpool = GST_DROID_BUFFER_POOL (pool);

g_mutex_lock (&dpool->binding_lock);

gst_droid_buffer_pool_clear_buffers_user_data (dpool->bound_buffers);
gst_droid_buffer_pool_clear_buffers_user_data (dpool->acquired_buffers);

if (dpool->bound_buffers->len != 0) {
buffers_to_release = dpool->bound_buffers;

g_mutex_lock (&dpool->lock);
dpool->num_buffers = 0;
GST_DEBUG_OBJECT (dpool, "num buffers: %d", dpool->num_buffers);
g_mutex_unlock (&dpool->lock);
dpool->bound_buffers = g_ptr_array_new ();
}

g_ptr_array_set_size (dpool->acquired_buffers, 0);

g_mutex_unlock (&dpool->binding_lock);

if (buffers_to_release) {
for (i = 0; i < buffers_to_release->len; ++i) {
gst_buffer_unref ((GstBuffer *) g_ptr_array_index (buffers_to_release,
i));
}
g_ptr_array_free (buffers_to_release, TRUE);
}

return GST_BUFFER_POOL_CLASS (parent_class)->start (pool);
g_signal_emit (pool, gst_droid_buffer_pool_signals[BUFFERS_INVALIDATED], 0);
}

static void
Expand All @@ -199,8 +316,11 @@ gst_droid_buffer_pool_finalize (GObject * object)
gst_object_unref (pool->allocator);
pool->allocator = 0;
}
g_mutex_clear (&pool->lock);
g_cond_clear (&pool->cond);

g_ptr_array_free (pool->bound_buffers, TRUE);
g_ptr_array_free (pool->acquired_buffers, TRUE);

g_mutex_clear (&pool->binding_lock);

G_OBJECT_CLASS (parent_class)->finalize (object);
}
Expand All @@ -212,22 +332,30 @@ gst_droid_buffer_pool_class_init (GstDroidBufferPoolClass * klass G_GNUC_UNUSED)
GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;

gobject_class->finalize = gst_droid_buffer_pool_finalize;
gstbufferpool_class->start = gst_droid_buffer_pool_start;
gstbufferpool_class->acquire_buffer = gst_droid_buffer_pool_acquire_buffer;
gstbufferpool_class->reset_buffer = gst_droid_buffer_pool_reset_buffer;
gstbufferpool_class->alloc_buffer = gst_droid_buffer_pool_alloc;
gstbufferpool_class->flush_start = gst_droid_buffer_pool_flush_start;
gstbufferpool_class->release_buffer = gst_droid_buffer_release_buffer;
gstbufferpool_class->get_options = gst_droid_buffer_pool_get_options;
gstbufferpool_class->set_config = gst_droid_buffer_pool_set_config;

gst_droid_buffer_pool_signals[BUFFERS_INVALIDATED] =
g_signal_new ("buffers-invalidated",
G_TYPE_FROM_CLASS (gstbufferpool_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstDroidBufferPoolClass, signal_buffers_invalidated),
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 0);
}

static void
gst_droid_buffer_pool_init (GstDroidBufferPool * object)
{
GstDroidBufferPool *pool = GST_DROID_BUFFER_POOL (object);
pool->allocator = 0;
g_mutex_init (&pool->lock);
g_cond_init (&pool->cond);

g_mutex_init (&pool->binding_lock);

pool->bound_buffers = g_ptr_array_new ();
pool->acquired_buffers = g_ptr_array_new ();
pool->use_queue_buffers = FALSE;
pool->display = NULL;
}

GstBufferPool *
Expand Down
Loading

0 comments on commit b52b404

Please sign in to comment.