metadata: use metadata for private buffer data
Use buffer metadata to store element private data.
This commit is contained in:
parent
d90a388289
commit
f229f4d192
@ -84,11 +84,32 @@ static gboolean gst_efence_activate_src_pull (GstPad * pad, gboolean active);
|
|||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
|
||||||
typedef struct _GstFencedData
|
typedef struct _GstMetaFenced
|
||||||
{
|
{
|
||||||
|
GstMeta meta;
|
||||||
|
|
||||||
void *region;
|
void *region;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
} GstFencedData;
|
} GstMetaFenced;
|
||||||
|
|
||||||
|
static const GstMetaInfo *
|
||||||
|
gst_meta_fenced_get_info (void)
|
||||||
|
{
|
||||||
|
static const GstMetaInfo *meta_fenced_info = NULL;
|
||||||
|
|
||||||
|
if (meta_fenced_info == NULL) {
|
||||||
|
meta_fenced_info = gst_meta_register ("GstMetaFenced", "GstMetaFenced",
|
||||||
|
sizeof (GstMetaFenced),
|
||||||
|
(GstMetaInitFunction) NULL,
|
||||||
|
(GstMetaFreeFunction) NULL,
|
||||||
|
(GstMetaCopyFunction) NULL,
|
||||||
|
(GstMetaSubFunction) NULL,
|
||||||
|
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
||||||
|
}
|
||||||
|
return meta_fenced_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GST_META_FENCED_GET(buf,create) ((GstMetaFenced *)gst_buffer_get_meta(buf,gst_meta_fenced_get_info(),create));
|
||||||
|
|
||||||
static void gst_fenced_buffer_dispose (GstBuffer * buf);
|
static void gst_fenced_buffer_dispose (GstBuffer * buf);
|
||||||
static GstBuffer *gst_fenced_buffer_copy (const GstBuffer * buffer);
|
static GstBuffer *gst_fenced_buffer_copy (const GstBuffer * buffer);
|
||||||
@ -99,8 +120,6 @@ static GstFlowReturn gst_efence_buffer_alloc (GstPad * pad, guint64 offset,
|
|||||||
guint size, GstCaps * caps, GstBuffer ** buf);
|
guint size, GstCaps * caps, GstBuffer ** buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GET_FENCED_DATA(buf) ((GstFencedData *) (GST_BUFFER_CAST(buf)->owner_priv))
|
|
||||||
|
|
||||||
GType
|
GType
|
||||||
gst_gst_efence_get_type (void)
|
gst_gst_efence_get_type (void)
|
||||||
{
|
{
|
||||||
@ -379,19 +398,17 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
|||||||
static void
|
static void
|
||||||
gst_fenced_buffer_dispose (GstBuffer * buffer)
|
gst_fenced_buffer_dispose (GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstFencedData *data;
|
GstMetaFenced *meta;
|
||||||
|
|
||||||
data = GET_FENCED_DATA (buffer);
|
meta = GST_META_FENCED_GET (buffer, FALSE);
|
||||||
|
|
||||||
GST_DEBUG ("free buffer=%p", buffer);
|
GST_DEBUG ("free buffer=%p", buffer);
|
||||||
|
|
||||||
/* free our data */
|
/* free our data */
|
||||||
if (GST_BUFFER_DATA (buffer)) {
|
if (GST_BUFFER_DATA (buffer)) {
|
||||||
GST_DEBUG ("free region %p %d", data->region, data->length);
|
GST_DEBUG ("free region %p %d", meta->region, meta->length);
|
||||||
munmap (data->region, data->length);
|
munmap (meta->region, meta->length);
|
||||||
}
|
}
|
||||||
g_slice_free (GstFencedData, data);
|
|
||||||
buffer->owner_priv = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
@ -440,7 +457,7 @@ gst_fenced_buffer_alloc (GstBuffer * buffer, unsigned int length,
|
|||||||
{
|
{
|
||||||
int alloc_size;
|
int alloc_size;
|
||||||
void *region;
|
void *region;
|
||||||
GstFencedData *data;
|
GstMetaFenced *meta;
|
||||||
int page_size;
|
int page_size;
|
||||||
|
|
||||||
GST_DEBUG ("buffer=%p length=%d fence_top=%d", buffer, length, fence_top);
|
GST_DEBUG ("buffer=%p length=%d fence_top=%d", buffer, length, fence_top);
|
||||||
@ -448,7 +465,6 @@ gst_fenced_buffer_alloc (GstBuffer * buffer, unsigned int length,
|
|||||||
if (length == 0)
|
if (length == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
#ifdef _SC_PAGESIZE
|
#ifdef _SC_PAGESIZE
|
||||||
page_size = sysconf (_SC_PAGESIZE);
|
page_size = sysconf (_SC_PAGESIZE);
|
||||||
#else
|
#else
|
||||||
@ -466,28 +482,28 @@ gst_fenced_buffer_alloc (GstBuffer * buffer, unsigned int length,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = g_slice_new (GstFencedData);
|
|
||||||
buffer->owner_priv = data;
|
|
||||||
GST_MINI_OBJECT_CAST (buffer)->dispose =
|
GST_MINI_OBJECT_CAST (buffer)->dispose =
|
||||||
(GstMiniObjectDisposeFunction) gst_fenced_buffer_dispose;
|
(GstMiniObjectDisposeFunction) gst_fenced_buffer_dispose;
|
||||||
GST_MINI_OBJECT_CAST (buffer)->copy =
|
GST_MINI_OBJECT_CAST (buffer)->copy =
|
||||||
(GstMiniObjectCopyFunction) gst_fenced_buffer_copy;
|
(GstMiniObjectCopyFunction) gst_fenced_buffer_copy;
|
||||||
|
|
||||||
|
meta = GST_META_FENCED_GET (buffer, TRUE);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
munmap (region, page_size);
|
munmap (region, page_size);
|
||||||
munmap (region + alloc_size - page_size, page_size);
|
munmap (region + alloc_size - page_size, page_size);
|
||||||
|
|
||||||
data->region = region + page_size;
|
meta->region = region + page_size;
|
||||||
data->length = alloc_size - page_size;
|
meta->length = alloc_size - page_size;
|
||||||
#else
|
#else
|
||||||
mprotect (region, page_size, PROT_NONE);
|
mprotect (region, page_size, PROT_NONE);
|
||||||
mprotect ((char *) region + alloc_size - page_size, page_size, PROT_NONE);
|
mprotect ((char *) region + alloc_size - page_size, page_size, PROT_NONE);
|
||||||
|
|
||||||
data->region = region;
|
meta->region = region;
|
||||||
data->length = alloc_size;
|
meta->length = alloc_size;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GST_DEBUG ("new region %p %d", data->region, data->length);
|
GST_DEBUG ("new region %p %d", meta->region, meta->length);
|
||||||
|
|
||||||
if (fence_top) {
|
if (fence_top) {
|
||||||
int offset;
|
int offset;
|
||||||
|
@ -59,17 +59,16 @@ GST_DEBUG_CATEGORY_EXTERN (v4l2_debug);
|
|||||||
static void
|
static void
|
||||||
gst_v4l2_buffer_dispose (GstBuffer * buffer)
|
gst_v4l2_buffer_dispose (GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstV4l2Data *data;
|
|
||||||
GstV4l2BufferPool *pool;
|
GstV4l2BufferPool *pool;
|
||||||
gboolean resuscitated = FALSE;
|
gboolean resuscitated = FALSE;
|
||||||
gint index;
|
gint index;
|
||||||
|
GstMetaV4l2 *meta;
|
||||||
|
|
||||||
data = GST_V4L2_GET_DATA (buffer);
|
meta = GST_META_V4L2_GET (buffer, FALSE);
|
||||||
g_assert (data != NULL);
|
g_assert (meta != NULL);
|
||||||
|
|
||||||
pool = data->pool;
|
pool = meta->pool;
|
||||||
|
index = meta->vbuffer.index;
|
||||||
index = data->vbuffer.index;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, "finalizing buffer %p %d", buffer, index);
|
GST_LOG_OBJECT (pool->v4l2elem, "finalizing buffer %p %d", buffer, index);
|
||||||
|
|
||||||
@ -106,61 +105,59 @@ gst_v4l2_buffer_dispose (GstBuffer * buffer)
|
|||||||
if (!resuscitated) {
|
if (!resuscitated) {
|
||||||
GST_LOG_OBJECT (pool->v4l2elem,
|
GST_LOG_OBJECT (pool->v4l2elem,
|
||||||
"buffer %p (data %p, len %u) not recovered, unmapping",
|
"buffer %p (data %p, len %u) not recovered, unmapping",
|
||||||
buffer, GST_BUFFER_DATA (buffer), data->vbuffer.length);
|
buffer, GST_BUFFER_DATA (buffer), meta->vbuffer.length);
|
||||||
v4l2_munmap ((void *) GST_BUFFER_DATA (buffer), data->vbuffer.length);
|
v4l2_munmap ((void *) GST_BUFFER_DATA (buffer), meta->vbuffer.length);
|
||||||
|
|
||||||
g_object_unref (pool);
|
g_object_unref (pool);
|
||||||
g_slice_free (GstV4l2Data, data);
|
|
||||||
buffer->owner_priv = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
gst_v4l2_buffer_new (GstV4l2BufferPool * pool, guint index, GstCaps * caps)
|
gst_v4l2_buffer_new (GstV4l2BufferPool * pool, guint index, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstV4l2Data *data;
|
|
||||||
GstBuffer *ret;
|
GstBuffer *ret;
|
||||||
guint8 *mem;
|
guint8 *mem;
|
||||||
|
GstMetaV4l2 *meta;
|
||||||
|
|
||||||
ret = gst_buffer_new ();
|
ret = gst_buffer_new ();
|
||||||
data = g_slice_new (GstV4l2Data);
|
|
||||||
ret->owner_priv = data;
|
|
||||||
GST_MINI_OBJECT_CAST (ret)->dispose =
|
GST_MINI_OBJECT_CAST (ret)->dispose =
|
||||||
(GstMiniObjectDisposeFunction) gst_v4l2_buffer_dispose;
|
(GstMiniObjectDisposeFunction) gst_v4l2_buffer_dispose;
|
||||||
|
|
||||||
|
meta = GST_META_V4L2_GET (ret, TRUE);
|
||||||
|
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, "creating buffer %u, %p in pool %p", index,
|
GST_LOG_OBJECT (pool->v4l2elem, "creating buffer %u, %p in pool %p", index,
|
||||||
ret, pool);
|
ret, pool);
|
||||||
|
|
||||||
data->pool = (GstV4l2BufferPool *) g_object_ref (pool);
|
meta->pool = (GstV4l2BufferPool *) g_object_ref (pool);
|
||||||
|
|
||||||
data->vbuffer.index = index;
|
meta->vbuffer.index = index;
|
||||||
data->vbuffer.type = pool->type;
|
meta->vbuffer.type = pool->type;
|
||||||
data->vbuffer.memory = V4L2_MEMORY_MMAP;
|
meta->vbuffer.memory = V4L2_MEMORY_MMAP;
|
||||||
|
|
||||||
if (v4l2_ioctl (pool->video_fd, VIDIOC_QUERYBUF, &data->vbuffer) < 0)
|
if (v4l2_ioctl (pool->video_fd, VIDIOC_QUERYBUF, &meta->vbuffer) < 0)
|
||||||
goto querybuf_failed;
|
goto querybuf_failed;
|
||||||
|
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, " index: %u", data->vbuffer.index);
|
GST_LOG_OBJECT (pool->v4l2elem, " index: %u", meta->vbuffer.index);
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, " type: %d", data->vbuffer.type);
|
GST_LOG_OBJECT (pool->v4l2elem, " type: %d", meta->vbuffer.type);
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, " bytesused: %u", data->vbuffer.bytesused);
|
GST_LOG_OBJECT (pool->v4l2elem, " bytesused: %u", meta->vbuffer.bytesused);
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, " flags: %08x", data->vbuffer.flags);
|
GST_LOG_OBJECT (pool->v4l2elem, " flags: %08x", meta->vbuffer.flags);
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, " field: %d", data->vbuffer.field);
|
GST_LOG_OBJECT (pool->v4l2elem, " field: %d", meta->vbuffer.field);
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, " memory: %d", data->vbuffer.memory);
|
GST_LOG_OBJECT (pool->v4l2elem, " memory: %d", meta->vbuffer.memory);
|
||||||
if (data->vbuffer.memory == V4L2_MEMORY_MMAP)
|
if (meta->vbuffer.memory == V4L2_MEMORY_MMAP)
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, " MMAP offset: %u",
|
GST_LOG_OBJECT (pool->v4l2elem, " MMAP offset: %u",
|
||||||
data->vbuffer.m.offset);
|
meta->vbuffer.m.offset);
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, " length: %u", data->vbuffer.length);
|
GST_LOG_OBJECT (pool->v4l2elem, " length: %u", meta->vbuffer.length);
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, " input: %u", data->vbuffer.input);
|
GST_LOG_OBJECT (pool->v4l2elem, " input: %u", meta->vbuffer.input);
|
||||||
|
|
||||||
mem = (guint8 *) v4l2_mmap (0, data->vbuffer.length,
|
mem = (guint8 *) v4l2_mmap (0, meta->vbuffer.length,
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED, pool->video_fd,
|
PROT_READ | PROT_WRITE, MAP_SHARED, pool->video_fd,
|
||||||
data->vbuffer.m.offset);
|
meta->vbuffer.m.offset);
|
||||||
|
|
||||||
if (mem == MAP_FAILED)
|
if (mem == MAP_FAILED)
|
||||||
goto mmap_failed;
|
goto mmap_failed;
|
||||||
|
|
||||||
GST_BUFFER_DATA (ret) = mem;
|
GST_BUFFER_DATA (ret) = mem;
|
||||||
GST_BUFFER_SIZE (ret) = data->vbuffer.length;
|
GST_BUFFER_SIZE (ret) = meta->vbuffer.length;
|
||||||
|
|
||||||
GST_BUFFER_FLAG_SET (ret, GST_BUFFER_FLAG_READONLY);
|
GST_BUFFER_FLAG_SET (ret, GST_BUFFER_FLAG_READONLY);
|
||||||
|
|
||||||
@ -454,8 +451,10 @@ gst_v4l2_buffer_pool_get (GstV4l2BufferPool * pool, gboolean blocking)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
|
GstMetaV4l2 *meta = GST_META_V4L2_GET (buf, FALSE);
|
||||||
|
|
||||||
GST_V4L2_BUFFER_POOL_LOCK (pool);
|
GST_V4L2_BUFFER_POOL_LOCK (pool);
|
||||||
GST_BUFFER_SIZE (buf) = GST_V4L2_GET_DATA (buf)->vbuffer.length;
|
GST_BUFFER_SIZE (buf) = meta->vbuffer.length;
|
||||||
GST_BUFFER_FLAG_UNSET (buf, 0xffffffff);
|
GST_BUFFER_FLAG_UNSET (buf, 0xffffffff);
|
||||||
GST_V4L2_BUFFER_POOL_UNLOCK (pool);
|
GST_V4L2_BUFFER_POOL_UNLOCK (pool);
|
||||||
}
|
}
|
||||||
@ -478,12 +477,14 @@ gst_v4l2_buffer_pool_get (GstV4l2BufferPool * pool, gboolean blocking)
|
|||||||
gboolean
|
gboolean
|
||||||
gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool * pool, GstBuffer * buf)
|
gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool * pool, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstV4l2Data *data = GST_V4L2_GET_DATA (buf);
|
GstMetaV4l2 *meta;
|
||||||
|
|
||||||
|
meta = GST_META_V4L2_GET (buf, FALSE);
|
||||||
|
|
||||||
GST_LOG_OBJECT (pool->v4l2elem, "enqueue pool buffer %d",
|
GST_LOG_OBJECT (pool->v4l2elem, "enqueue pool buffer %d",
|
||||||
data->vbuffer.index);
|
meta->vbuffer.index);
|
||||||
|
|
||||||
if (v4l2_ioctl (pool->video_fd, VIDIOC_QBUF, &data->vbuffer) < 0)
|
if (v4l2_ioctl (pool->video_fd, VIDIOC_QBUF, &meta->vbuffer) < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pool->num_live_buffers--;
|
pool->num_live_buffers--;
|
||||||
|
@ -46,7 +46,7 @@ GType gst_v4l2_buffer_pool_get_type (void);
|
|||||||
|
|
||||||
|
|
||||||
typedef struct _GstV4l2BufferPool GstV4l2BufferPool;
|
typedef struct _GstV4l2BufferPool GstV4l2BufferPool;
|
||||||
typedef struct _GstV4l2Data GstV4l2Data;
|
typedef struct _GstMetaV4l2 GstMetaV4l2;
|
||||||
|
|
||||||
|
|
||||||
struct _GstV4l2BufferPool
|
struct _GstV4l2BufferPool
|
||||||
@ -66,9 +66,9 @@ struct _GstV4l2BufferPool
|
|||||||
GstBuffer **buffers;
|
GstBuffer **buffers;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_V4L2_GET_DATA(buf) ((GstV4l2Data *) (GST_BUFFER_CAST (buf)->owner_priv))
|
struct _GstMetaV4l2 {
|
||||||
|
GstMeta meta;
|
||||||
|
|
||||||
struct _GstV4l2Data {
|
|
||||||
struct v4l2_buffer vbuffer;
|
struct v4l2_buffer vbuffer;
|
||||||
|
|
||||||
/* FIXME: have GstV4l2Src* instead, as this has GstV4l2BufferPool* */
|
/* FIXME: have GstV4l2Src* instead, as this has GstV4l2BufferPool* */
|
||||||
@ -78,6 +78,9 @@ struct _GstV4l2Data {
|
|||||||
GstV4l2BufferPool *pool;
|
GstV4l2BufferPool *pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const GstMetaInfo * gst_meta_v4l2_get_info (void);
|
||||||
|
#define GST_META_V4L2_GET(buf,create) ((GstMetaV4l2 *)gst_buffer_get_meta(buf,gst_meta_v4l2_get_info(),create))
|
||||||
|
|
||||||
void gst_v4l2_buffer_pool_destroy (GstV4l2BufferPool * pool);
|
void gst_v4l2_buffer_pool_destroy (GstV4l2BufferPool * pool);
|
||||||
GstV4l2BufferPool *gst_v4l2_buffer_pool_new (GstElement *v4l2elem, gint fd, gint num_buffers, GstCaps * caps, gboolean requeuebuf, enum v4l2_buf_type type);
|
GstV4l2BufferPool *gst_v4l2_buffer_pool_new (GstElement *v4l2elem, gint fd, gint num_buffers, GstCaps * caps, gboolean requeuebuf, enum v4l2_buf_type type);
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ queue_failed:
|
|||||||
(_("Could not enqueue buffers in device '%s'."),
|
(_("Could not enqueue buffers in device '%s'."),
|
||||||
v4l2src->v4l2object->videodev),
|
v4l2src->v4l2object->videodev),
|
||||||
("enqueing buffer %d/%d failed: %s",
|
("enqueing buffer %d/%d failed: %s",
|
||||||
GST_V4L2_GET_DATA (buf)->vbuffer.index, v4l2src->num_buffers,
|
GST_META_V4L2_GET (buf, FALSE)->vbuffer.index, v4l2src->num_buffers,
|
||||||
g_strerror (errno)));
|
g_strerror (errno)));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -82,16 +82,15 @@ static void gst_ximage_src_clear_bufpool (GstXImageSrc * ximagesrc);
|
|||||||
static void
|
static void
|
||||||
gst_ximage_src_return_buf (GstXImageSrc * ximagesrc, GstBuffer * ximage)
|
gst_ximage_src_return_buf (GstXImageSrc * ximagesrc, GstBuffer * ximage)
|
||||||
{
|
{
|
||||||
GstXImageData *data = GST_XIMAGE_GET_DATA (ximage);
|
GstMetaXImage *meta = GST_META_XIMAGE_GET (ximage, FALSE);
|
||||||
|
|
||||||
/* If our geometry changed we can't reuse that image. */
|
/* If our geometry changed we can't reuse that image. */
|
||||||
if ((data->width != ximagesrc->width) || (data->height != ximagesrc->height)) {
|
if ((meta->width != ximagesrc->width) || (meta->height != ximagesrc->height)) {
|
||||||
GST_DEBUG_OBJECT (ximagesrc,
|
GST_DEBUG_OBJECT (ximagesrc,
|
||||||
"destroy image %p as its size changed %dx%d vs current %dx%d",
|
"destroy image %p as its size changed %dx%d vs current %dx%d",
|
||||||
ximage, data->width, data->height, ximagesrc->width, ximagesrc->height);
|
ximage, meta->width, meta->height, ximagesrc->width, ximagesrc->height);
|
||||||
g_mutex_lock (ximagesrc->x_lock);
|
g_mutex_lock (ximagesrc->x_lock);
|
||||||
gst_ximageutil_ximage_destroy (ximagesrc->xcontext, ximage);
|
gst_ximageutil_ximage_destroy (ximagesrc->xcontext, ximage);
|
||||||
g_slice_free (GstXImageData, data);
|
|
||||||
g_mutex_unlock (ximagesrc->x_lock);
|
g_mutex_unlock (ximagesrc->x_lock);
|
||||||
} else {
|
} else {
|
||||||
/* In that case we can reuse the image and add it to our image pool. */
|
/* In that case we can reuse the image and add it to our image pool. */
|
||||||
@ -362,16 +361,16 @@ static GstBuffer *
|
|||||||
gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
||||||
{
|
{
|
||||||
GstBuffer *ximage = NULL;
|
GstBuffer *ximage = NULL;
|
||||||
GstXImageData *data;
|
GstMetaXImage *meta;
|
||||||
|
|
||||||
g_mutex_lock (ximagesrc->pool_lock);
|
g_mutex_lock (ximagesrc->pool_lock);
|
||||||
while (ximagesrc->buffer_pool != NULL) {
|
while (ximagesrc->buffer_pool != NULL) {
|
||||||
ximage = ximagesrc->buffer_pool->data;
|
ximage = ximagesrc->buffer_pool->data;
|
||||||
|
|
||||||
data = GST_XIMAGE_GET_DATA (ximage);
|
meta = GST_META_XIMAGE_GET (ximage, FALSE);
|
||||||
|
|
||||||
if ((data->width != ximagesrc->width) ||
|
if ((meta->width != ximagesrc->width) ||
|
||||||
(data->height != ximagesrc->height)) {
|
(meta->height != ximagesrc->height)) {
|
||||||
gst_ximage_buffer_free (ximage);
|
gst_ximage_buffer_free (ximage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,7 +423,7 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||||||
|
|
||||||
g_return_val_if_fail (GST_IS_XIMAGE_SRC (ximagesrc), NULL);
|
g_return_val_if_fail (GST_IS_XIMAGE_SRC (ximagesrc), NULL);
|
||||||
|
|
||||||
data = GST_XIMAGE_GET_DATA (ximage);
|
meta = GST_META_XIMAGE_GET (ximage, FALSE);
|
||||||
|
|
||||||
#ifdef HAVE_XDAMAGE
|
#ifdef HAVE_XDAMAGE
|
||||||
if (ximagesrc->have_xdamage && ximagesrc->use_damage &&
|
if (ximagesrc->have_xdamage && ximagesrc->use_damage &&
|
||||||
@ -498,7 +497,7 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||||||
startx, starty, width, height);
|
startx, starty, width, height);
|
||||||
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
||||||
startx, starty, width, height, AllPlanes, ZPixmap,
|
startx, starty, width, height, AllPlanes, ZPixmap,
|
||||||
data->ximage, startx - ximagesrc->startx,
|
meta->ximage, startx - ximagesrc->startx,
|
||||||
starty - ximagesrc->starty);
|
starty - ximagesrc->starty);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -510,7 +509,7 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||||||
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
||||||
rects[i].x, rects[i].y,
|
rects[i].x, rects[i].y,
|
||||||
rects[i].width, rects[i].height,
|
rects[i].width, rects[i].height,
|
||||||
AllPlanes, ZPixmap, data->ximage, rects[i].x, rects[i].y);
|
AllPlanes, ZPixmap, meta->ximage, rects[i].x, rects[i].y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free (rects);
|
free (rects);
|
||||||
@ -572,14 +571,14 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||||||
GST_DEBUG_OBJECT (ximagesrc, "Removing cursor from %d,%d", x, y);
|
GST_DEBUG_OBJECT (ximagesrc, "Removing cursor from %d,%d", x, y);
|
||||||
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
||||||
startx, starty, iwidth, iheight, AllPlanes, ZPixmap,
|
startx, starty, iwidth, iheight, AllPlanes, ZPixmap,
|
||||||
data->ximage, startx - ximagesrc->startx,
|
meta->ximage, startx - ximagesrc->startx,
|
||||||
starty - ximagesrc->starty);
|
starty - ximagesrc->starty);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ximagesrc, "Removing cursor from %d,%d", x, y);
|
GST_DEBUG_OBJECT (ximagesrc, "Removing cursor from %d,%d", x, y);
|
||||||
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
||||||
x, y, width, height, AllPlanes, ZPixmap, data->ximage, x, y);
|
x, y, width, height, AllPlanes, ZPixmap, meta->ximage, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -592,7 +591,7 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||||||
if (ximagesrc->xcontext->use_xshm) {
|
if (ximagesrc->xcontext->use_xshm) {
|
||||||
GST_DEBUG_OBJECT (ximagesrc, "Retrieving screen using XShm");
|
GST_DEBUG_OBJECT (ximagesrc, "Retrieving screen using XShm");
|
||||||
XShmGetImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
XShmGetImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
||||||
data->ximage, ximagesrc->startx, ximagesrc->starty, AllPlanes);
|
meta->ximage, ximagesrc->startx, ximagesrc->starty, AllPlanes);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_XSHM */
|
#endif /* HAVE_XSHM */
|
||||||
@ -601,9 +600,9 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||||||
if (ximagesrc->remote) {
|
if (ximagesrc->remote) {
|
||||||
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
||||||
ximagesrc->startx, ximagesrc->starty, ximagesrc->width,
|
ximagesrc->startx, ximagesrc->starty, ximagesrc->width,
|
||||||
ximagesrc->height, AllPlanes, ZPixmap, data->ximage, 0, 0);
|
ximagesrc->height, AllPlanes, ZPixmap, meta->ximage, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
data->ximage =
|
meta->ximage =
|
||||||
XGetImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
XGetImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
|
||||||
ximagesrc->startx, ximagesrc->starty, ximagesrc->width,
|
ximagesrc->startx, ximagesrc->starty, ximagesrc->width,
|
||||||
ximagesrc->height, AllPlanes, ZPixmap);
|
ximagesrc->height, AllPlanes, ZPixmap);
|
||||||
@ -683,7 +682,7 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
|
|||||||
(guint8 *) & (ximagesrc->cursor_image->pixels[((j -
|
(guint8 *) & (ximagesrc->cursor_image->pixels[((j -
|
||||||
cy) * ximagesrc->cursor_image->width + (i - cx))]);
|
cy) * ximagesrc->cursor_image->width + (i - cx))]);
|
||||||
dest =
|
dest =
|
||||||
(guint8 *) & (data->ximage->data[((j -
|
(guint8 *) & (meta->ximage->data[((j -
|
||||||
ximagesrc->starty) * ximagesrc->width + (i -
|
ximagesrc->starty) * ximagesrc->width + (i -
|
||||||
ximagesrc->startx)) * (ximagesrc->xcontext->bpp /
|
ximagesrc->startx)) * (ximagesrc->xcontext->bpp /
|
||||||
8)]);
|
8)]);
|
||||||
|
@ -23,6 +23,22 @@
|
|||||||
|
|
||||||
#include "ximageutil.h"
|
#include "ximageutil.h"
|
||||||
|
|
||||||
|
const GstMetaInfo *
|
||||||
|
gst_meta_ximage_get_info (void)
|
||||||
|
{
|
||||||
|
static const GstMetaInfo *meta_ximage_info = NULL;
|
||||||
|
|
||||||
|
if (meta_ximage_info == NULL) {
|
||||||
|
meta_ximage_info =
|
||||||
|
gst_meta_register ("GstMetaXImageSrc", "GstMetaXImageSrc",
|
||||||
|
sizeof (GstMetaXImage), (GstMetaInitFunction) NULL,
|
||||||
|
(GstMetaFreeFunction) NULL, (GstMetaCopyFunction) NULL,
|
||||||
|
(GstMetaSubFunction) NULL, (GstMetaSerializeFunction) NULL,
|
||||||
|
(GstMetaDeserializeFunction) NULL);
|
||||||
|
}
|
||||||
|
return meta_ximage_info;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_XSHM
|
#ifdef HAVE_XSHM
|
||||||
static gboolean error_caught = FALSE;
|
static gboolean error_caught = FALSE;
|
||||||
|
|
||||||
@ -300,18 +316,20 @@ static void
|
|||||||
gst_ximagesrc_buffer_dispose (GstBuffer * ximage)
|
gst_ximagesrc_buffer_dispose (GstBuffer * ximage)
|
||||||
{
|
{
|
||||||
GstElement *parent;
|
GstElement *parent;
|
||||||
GstXImageData *data = GST_XIMAGE_GET_DATA (ximage);
|
GstMetaXImage *meta;
|
||||||
|
|
||||||
g_return_if_fail (ximage != NULL);
|
g_return_if_fail (ximage != NULL);
|
||||||
|
|
||||||
parent = data->parent;
|
meta = GST_META_XIMAGE_GET (ximage, FALSE);
|
||||||
|
|
||||||
|
parent = meta->parent;
|
||||||
if (parent == NULL) {
|
if (parent == NULL) {
|
||||||
g_warning ("XImageSrcBuffer->ximagesrc == NULL");
|
g_warning ("XImageSrcBuffer->ximagesrc == NULL");
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->return_func)
|
if (meta->return_func)
|
||||||
data->return_func (parent, ximage);
|
meta->return_func (parent, ximage);
|
||||||
|
|
||||||
beach:
|
beach:
|
||||||
return;
|
return;
|
||||||
@ -320,10 +338,13 @@ beach:
|
|||||||
void
|
void
|
||||||
gst_ximage_buffer_free (GstBuffer * ximage)
|
gst_ximage_buffer_free (GstBuffer * ximage)
|
||||||
{
|
{
|
||||||
GstXImageData *data = GST_XIMAGE_GET_DATA (ximage);
|
GstMetaXImage *meta;
|
||||||
|
|
||||||
|
meta = GST_META_XIMAGE_GET (ximage, FALSE);
|
||||||
|
|
||||||
/* make sure it is not recycled */
|
/* make sure it is not recycled */
|
||||||
data->width = -1;
|
meta->width = -1;
|
||||||
data->height = -1;
|
meta->height = -1;
|
||||||
gst_buffer_unref (ximage);
|
gst_buffer_unref (ximage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,75 +354,74 @@ gst_ximageutil_ximage_new (GstXContext * xcontext,
|
|||||||
GstElement * parent, int width, int height, BufferReturnFunc return_func)
|
GstElement * parent, int width, int height, BufferReturnFunc return_func)
|
||||||
{
|
{
|
||||||
GstBuffer *ximage = NULL;
|
GstBuffer *ximage = NULL;
|
||||||
GstXImageData *data;
|
GstMetaXImage *meta;
|
||||||
gboolean succeeded = FALSE;
|
gboolean succeeded = FALSE;
|
||||||
|
|
||||||
ximage = gst_buffer_new ();
|
ximage = gst_buffer_new ();
|
||||||
data = g_slice_new (GstXImageData);
|
|
||||||
ximage->owner_priv = data;
|
|
||||||
GST_MINI_OBJECT_CAST (ximage)->dispose =
|
GST_MINI_OBJECT_CAST (ximage)->dispose =
|
||||||
(GstMiniObjectDisposeFunction) gst_ximagesrc_buffer_dispose;
|
(GstMiniObjectDisposeFunction) gst_ximagesrc_buffer_dispose;
|
||||||
|
|
||||||
data->width = width;
|
meta = GST_META_XIMAGE_GET (ximage, TRUE);
|
||||||
data->height = height;
|
meta->width = width;
|
||||||
|
meta->height = height;
|
||||||
|
|
||||||
#ifdef HAVE_XSHM
|
#ifdef HAVE_XSHM
|
||||||
data->SHMInfo.shmaddr = ((void *) -1);
|
meta->SHMInfo.shmaddr = ((void *) -1);
|
||||||
data->SHMInfo.shmid = -1;
|
meta->SHMInfo.shmid = -1;
|
||||||
|
|
||||||
if (xcontext->use_xshm) {
|
if (xcontext->use_xshm) {
|
||||||
data->ximage = XShmCreateImage (xcontext->disp,
|
meta->ximage = XShmCreateImage (xcontext->disp,
|
||||||
xcontext->visual, xcontext->depth,
|
xcontext->visual, xcontext->depth,
|
||||||
ZPixmap, NULL, &data->SHMInfo, data->width, data->height);
|
ZPixmap, NULL, &meta->SHMInfo, meta->width, meta->height);
|
||||||
if (!data->ximage) {
|
if (!meta->ximage) {
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we have to use the returned bytes_per_line for our shm size */
|
/* we have to use the returned bytes_per_line for our shm size */
|
||||||
data->size = data->ximage->bytes_per_line * data->ximage->height;
|
meta->size = meta->ximage->bytes_per_line * meta->ximage->height;
|
||||||
data->SHMInfo.shmid = shmget (IPC_PRIVATE, data->size, IPC_CREAT | 0777);
|
meta->SHMInfo.shmid = shmget (IPC_PRIVATE, meta->size, IPC_CREAT | 0777);
|
||||||
if (data->SHMInfo.shmid == -1)
|
if (meta->SHMInfo.shmid == -1)
|
||||||
goto beach;
|
goto beach;
|
||||||
|
|
||||||
data->SHMInfo.shmaddr = shmat (data->SHMInfo.shmid, 0, 0);
|
meta->SHMInfo.shmaddr = shmat (meta->SHMInfo.shmid, 0, 0);
|
||||||
if (data->SHMInfo.shmaddr == ((void *) -1))
|
if (meta->SHMInfo.shmaddr == ((void *) -1))
|
||||||
goto beach;
|
goto beach;
|
||||||
|
|
||||||
/* Delete the SHM segment. It will actually go away automatically
|
/* Delete the SHM segment. It will actually go away automatically
|
||||||
* when we detach now */
|
* when we detach now */
|
||||||
shmctl (data->SHMInfo.shmid, IPC_RMID, 0);
|
shmctl (meta->SHMInfo.shmid, IPC_RMID, 0);
|
||||||
|
|
||||||
data->ximage->data = data->SHMInfo.shmaddr;
|
meta->ximage->data = meta->SHMInfo.shmaddr;
|
||||||
data->SHMInfo.readOnly = FALSE;
|
meta->SHMInfo.readOnly = FALSE;
|
||||||
|
|
||||||
if (XShmAttach (xcontext->disp, &data->SHMInfo) == 0)
|
if (XShmAttach (xcontext->disp, &meta->SHMInfo) == 0)
|
||||||
goto beach;
|
goto beach;
|
||||||
|
|
||||||
XSync (xcontext->disp, FALSE);
|
XSync (xcontext->disp, FALSE);
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_XSHM */
|
#endif /* HAVE_XSHM */
|
||||||
{
|
{
|
||||||
data->ximage = XCreateImage (xcontext->disp,
|
meta->ximage = XCreateImage (xcontext->disp,
|
||||||
xcontext->visual,
|
xcontext->visual,
|
||||||
xcontext->depth,
|
xcontext->depth,
|
||||||
ZPixmap, 0, NULL, data->width, data->height, xcontext->bpp, 0);
|
ZPixmap, 0, NULL, meta->width, meta->height, xcontext->bpp, 0);
|
||||||
if (!data->ximage)
|
if (!meta->ximage)
|
||||||
goto beach;
|
goto beach;
|
||||||
|
|
||||||
/* we have to use the returned bytes_per_line for our image size */
|
/* we have to use the returned bytes_per_line for our image size */
|
||||||
data->size = data->ximage->bytes_per_line * data->ximage->height;
|
meta->size = meta->ximage->bytes_per_line * meta->ximage->height;
|
||||||
data->ximage->data = g_malloc (data->size);
|
meta->ximage->data = g_malloc (meta->size);
|
||||||
|
|
||||||
XSync (xcontext->disp, FALSE);
|
XSync (xcontext->disp, FALSE);
|
||||||
}
|
}
|
||||||
succeeded = TRUE;
|
succeeded = TRUE;
|
||||||
|
|
||||||
GST_BUFFER_DATA (ximage) = (guchar *) data->ximage->data;
|
GST_BUFFER_DATA (ximage) = (guchar *) meta->ximage->data;
|
||||||
GST_BUFFER_SIZE (ximage) = data->size;
|
GST_BUFFER_SIZE (ximage) = meta->size;
|
||||||
|
|
||||||
/* Keep a ref to our src */
|
/* Keep a ref to our src */
|
||||||
data->parent = gst_object_ref (parent);
|
meta->parent = gst_object_ref (parent);
|
||||||
data->return_func = return_func;
|
meta->return_func = return_func;
|
||||||
beach:
|
beach:
|
||||||
if (!succeeded) {
|
if (!succeeded) {
|
||||||
gst_ximage_buffer_free (ximage);
|
gst_ximage_buffer_free (ximage);
|
||||||
@ -415,9 +435,9 @@ beach:
|
|||||||
void
|
void
|
||||||
gst_ximageutil_ximage_destroy (GstXContext * xcontext, GstBuffer * ximage)
|
gst_ximageutil_ximage_destroy (GstXContext * xcontext, GstBuffer * ximage)
|
||||||
{
|
{
|
||||||
GstXImageData *data;
|
GstMetaXImage *meta;
|
||||||
|
|
||||||
data = GST_XIMAGE_GET_DATA (ximage);
|
meta = GST_META_XIMAGE_GET (ximage, FALSE);
|
||||||
|
|
||||||
/* We might have some buffers destroyed after changing state to NULL */
|
/* We might have some buffers destroyed after changing state to NULL */
|
||||||
if (!xcontext)
|
if (!xcontext)
|
||||||
@ -427,28 +447,28 @@ gst_ximageutil_ximage_destroy (GstXContext * xcontext, GstBuffer * ximage)
|
|||||||
|
|
||||||
#ifdef HAVE_XSHM
|
#ifdef HAVE_XSHM
|
||||||
if (xcontext->use_xshm) {
|
if (xcontext->use_xshm) {
|
||||||
if (data->SHMInfo.shmaddr != ((void *) -1)) {
|
if (meta->SHMInfo.shmaddr != ((void *) -1)) {
|
||||||
XShmDetach (xcontext->disp, &data->SHMInfo);
|
XShmDetach (xcontext->disp, &meta->SHMInfo);
|
||||||
XSync (xcontext->disp, 0);
|
XSync (xcontext->disp, 0);
|
||||||
shmdt (data->SHMInfo.shmaddr);
|
shmdt (meta->SHMInfo.shmaddr);
|
||||||
}
|
}
|
||||||
if (data->ximage)
|
if (meta->ximage)
|
||||||
XDestroyImage (data->ximage);
|
XDestroyImage (meta->ximage);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_XSHM */
|
#endif /* HAVE_XSHM */
|
||||||
{
|
{
|
||||||
if (data->ximage) {
|
if (meta->ximage) {
|
||||||
XDestroyImage (data->ximage);
|
XDestroyImage (meta->ximage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XSync (xcontext->disp, FALSE);
|
XSync (xcontext->disp, FALSE);
|
||||||
beach:
|
beach:
|
||||||
if (data->parent) {
|
if (meta->parent) {
|
||||||
/* Release the ref to our parent */
|
/* Release the ref to our parent */
|
||||||
gst_object_unref (data->parent);
|
gst_object_unref (meta->parent);
|
||||||
data->parent = NULL;
|
meta->parent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -43,7 +43,7 @@ G_BEGIN_DECLS
|
|||||||
typedef struct _GstXContext GstXContext;
|
typedef struct _GstXContext GstXContext;
|
||||||
typedef struct _GstXWindow GstXWindow;
|
typedef struct _GstXWindow GstXWindow;
|
||||||
typedef struct _GstXImage GstXImage;
|
typedef struct _GstXImage GstXImage;
|
||||||
typedef struct _GstXImageData GstXImageData;
|
typedef struct _GstMetaXImage GstMetaXImage;
|
||||||
|
|
||||||
/* Global X Context stuff */
|
/* Global X Context stuff */
|
||||||
/**
|
/**
|
||||||
@ -134,7 +134,7 @@ typedef void (*BufferReturnFunc) (GstElement *parent, GstBuffer *buf);
|
|||||||
|
|
||||||
#define GST_XIMAGE_GET_DATA(buf) ((GstXImageData *) (GST_BUFFER_CAST(buf)->owner_priv))
|
#define GST_XIMAGE_GET_DATA(buf) ((GstXImageData *) (GST_BUFFER_CAST(buf)->owner_priv))
|
||||||
/**
|
/**
|
||||||
* GstXImageData:
|
* GstMetaXImage:
|
||||||
* @parent: a reference to the element we belong to
|
* @parent: a reference to the element we belong to
|
||||||
* @ximage: the XImage of this buffer
|
* @ximage: the XImage of this buffer
|
||||||
* @width: the width in pixels of XImage @ximage
|
* @width: the width in pixels of XImage @ximage
|
||||||
@ -143,7 +143,9 @@ typedef void (*BufferReturnFunc) (GstElement *parent, GstBuffer *buf);
|
|||||||
*
|
*
|
||||||
* Extra data attached to buffers containing additional information about an XImage.
|
* Extra data attached to buffers containing additional information about an XImage.
|
||||||
*/
|
*/
|
||||||
struct _GstXImageData {
|
struct _GstMetaXImage {
|
||||||
|
GstMeta meta;
|
||||||
|
|
||||||
/* Reference to the ximagesrc we belong to */
|
/* Reference to the ximagesrc we belong to */
|
||||||
GstElement *parent;
|
GstElement *parent;
|
||||||
|
|
||||||
@ -159,6 +161,8 @@ struct _GstXImageData {
|
|||||||
BufferReturnFunc return_func;
|
BufferReturnFunc return_func;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const GstMetaInfo * gst_meta_ximage_get_info (void);
|
||||||
|
#define GST_META_XIMAGE_GET(buf,create) ((GstMetaXImage *)gst_buffer_get_meta(buf,gst_meta_ximage_get_info(),create));
|
||||||
|
|
||||||
GstBuffer *gst_ximageutil_ximage_new (GstXContext *xcontext,
|
GstBuffer *gst_ximageutil_ximage_new (GstXContext *xcontext,
|
||||||
GstElement *parent, int width, int height, BufferReturnFunc return_func);
|
GstElement *parent, int width, int height, BufferReturnFunc return_func);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user