mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
metadata: implement extra buffer data with metadata
Use buffer metadata to attach arbitrary extra data to buffers.
This commit is contained in:
parent
5e6339b055
commit
55c9ca592f
5 changed files with 185 additions and 132 deletions
|
@ -616,23 +616,24 @@ gst_v4lsrc_get_fps_list (GstV4lSrc * v4lsrc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_V4LSRC_DATA(buf) ((GstV4lSrcData *) (GST_BUFFER_CAST(buf)->owner_priv))
|
typedef struct _GstMetaV4lSrc
|
||||||
|
|
||||||
typedef struct _GstV4lSrcData
|
|
||||||
{
|
{
|
||||||
|
GstMeta meta;
|
||||||
|
|
||||||
GstV4lSrc *v4lsrc;
|
GstV4lSrc *v4lsrc;
|
||||||
gint num;
|
gint num;
|
||||||
} GstV4lSrcData;
|
} GstMetaV4lSrc;
|
||||||
|
|
||||||
|
#define GST_META_V4LSRC_GET(buf,create) ((GstMetaV4lSrc *)gst_buffer_get_meta(buf,gst_meta_v4lsrc_get_info(),create));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_v4lsrc_buffer_dispose (GstBuffer * buffer)
|
meta_v4lsrc_free (GstMetaV4lSrc * meta, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstV4lSrcData *data = GET_V4LSRC_DATA (buffer);
|
|
||||||
GstV4lSrc *v4lsrc;
|
GstV4lSrc *v4lsrc;
|
||||||
gint num;
|
gint num;
|
||||||
|
|
||||||
v4lsrc = data->v4lsrc;
|
v4lsrc = meta->v4lsrc;
|
||||||
num = data->num;
|
num = meta->num;
|
||||||
|
|
||||||
GST_LOG_OBJECT (v4lsrc, "freeing buffer %p for frame %d", buffer, num);
|
GST_LOG_OBJECT (v4lsrc, "freeing buffer %p for frame %d", buffer, num);
|
||||||
|
|
||||||
|
@ -642,17 +643,32 @@ gst_v4lsrc_buffer_dispose (GstBuffer * buffer)
|
||||||
gst_v4lsrc_requeue_frame (v4lsrc, num);
|
gst_v4lsrc_requeue_frame (v4lsrc, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free data */
|
|
||||||
gst_object_unref (v4lsrc);
|
gst_object_unref (v4lsrc);
|
||||||
g_slice_free (GstV4lSrcData, data);
|
|
||||||
buffer->owner_priv = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const GstMetaInfo *
|
||||||
|
gst_meta_v4lsrc_get_info (void)
|
||||||
|
{
|
||||||
|
static const GstMetaInfo *meta_v4lsrc_info = NULL;
|
||||||
|
|
||||||
|
if (meta_v4lsrc_info == NULL) {
|
||||||
|
meta_v4lsrc_info = gst_meta_register ("GstMetaV4lSrc", "GstMetaV4lSrc",
|
||||||
|
sizeof (GstMetaV4lSrc),
|
||||||
|
(GstMetaInitFunction) NULL,
|
||||||
|
(GstMetaFreeFunction) meta_v4lsrc_free,
|
||||||
|
(GstMetaCopyFunction) NULL,
|
||||||
|
(GstMetaSubFunction) NULL,
|
||||||
|
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
||||||
|
}
|
||||||
|
return meta_v4lsrc_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create a V4lSrc buffer from our mmap'd data area */
|
/* Create a V4lSrc buffer from our mmap'd data area */
|
||||||
GstBuffer *
|
GstBuffer *
|
||||||
gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num)
|
gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num)
|
||||||
{
|
{
|
||||||
GstV4lSrcData *data;
|
GstMetaV4lSrc *meta;
|
||||||
GstClockTime duration, timestamp, latency;
|
GstClockTime duration, timestamp, latency;
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
GstClock *clock;
|
GstClock *clock;
|
||||||
|
@ -664,13 +680,11 @@ gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
buf = gst_buffer_new ();
|
buf = gst_buffer_new ();
|
||||||
data = g_slice_new (GstV4lSrcData);
|
|
||||||
buf->owner_priv = data;
|
|
||||||
GST_MINI_OBJECT_CAST (buf)->dispose =
|
|
||||||
(GstMiniObjectDisposeFunction) gst_v4lsrc_buffer_dispose;
|
|
||||||
|
|
||||||
data->num = num;
|
/* attach private metadata with the frame num and v4lsrc element */
|
||||||
data->v4lsrc = gst_object_ref (v4lsrc);
|
meta = GST_META_V4LSRC_GET (buf, TRUE);
|
||||||
|
meta->num = num;
|
||||||
|
meta->v4lsrc = gst_object_ref (v4lsrc);
|
||||||
|
|
||||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
|
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
|
||||||
GST_BUFFER_DATA (buf) = gst_v4lsrc_get_buffer (v4lsrc, num);
|
GST_BUFFER_DATA (buf) = gst_v4lsrc_get_buffer (v4lsrc, num);
|
||||||
|
|
|
@ -165,20 +165,35 @@ static GstVideoSinkClass *parent_class = NULL;
|
||||||
/* ============================================================= */
|
/* ============================================================= */
|
||||||
|
|
||||||
/* ximage buffers */
|
/* ximage buffers */
|
||||||
#define GET_XDATA(buf) ((GstXImageData *) (GST_BUFFER_CAST(buf)->owner_priv))
|
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 ("GstMetaXImage", "GstMetaXImage",
|
||||||
|
sizeof (GstMetaXImage),
|
||||||
|
(GstMetaInitFunction) NULL,
|
||||||
|
(GstMetaFreeFunction) NULL,
|
||||||
|
(GstMetaCopyFunction) NULL,
|
||||||
|
(GstMetaSubFunction) NULL,
|
||||||
|
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
||||||
|
}
|
||||||
|
return meta_ximage_info;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_ximage_buffer_dispose (GstBuffer * ximage)
|
gst_ximage_buffer_dispose (GstBuffer * ximage)
|
||||||
{
|
{
|
||||||
GstXImageData *data = NULL;
|
GstMetaXImage *meta = NULL;
|
||||||
GstXImageSink *ximagesink = NULL;
|
GstXImageSink *ximagesink = NULL;
|
||||||
gboolean recycled = FALSE;
|
gboolean recycled = FALSE;
|
||||||
gboolean running;
|
gboolean running;
|
||||||
|
|
||||||
data = GET_XDATA (ximage);
|
meta = GST_META_XIMAGE_GET (ximage, FALSE);
|
||||||
g_return_if_fail (data != NULL);
|
g_return_if_fail (meta != NULL);
|
||||||
|
|
||||||
ximagesink = data->ximagesink;
|
ximagesink = meta->ximagesink;
|
||||||
if (G_UNLIKELY (ximagesink == NULL))
|
if (G_UNLIKELY (ximagesink == NULL))
|
||||||
goto no_sink;
|
goto no_sink;
|
||||||
|
|
||||||
|
@ -193,12 +208,12 @@ gst_ximage_buffer_dispose (GstBuffer * ximage)
|
||||||
GST_DEBUG_OBJECT (ximagesink,
|
GST_DEBUG_OBJECT (ximagesink,
|
||||||
"destroy image %p because the sink is shutting down", ximage);
|
"destroy image %p because the sink is shutting down", ximage);
|
||||||
gst_ximagesink_ximage_destroy (ximagesink, ximage);
|
gst_ximagesink_ximage_destroy (ximagesink, ximage);
|
||||||
} else if ((data->width != GST_VIDEO_SINK_WIDTH (ximagesink)) ||
|
} else if ((meta->width != GST_VIDEO_SINK_WIDTH (ximagesink)) ||
|
||||||
(data->height != GST_VIDEO_SINK_HEIGHT (ximagesink))) {
|
(meta->height != GST_VIDEO_SINK_HEIGHT (ximagesink))) {
|
||||||
/* If our geometry changed we can't reuse that image. */
|
/* If our geometry changed we can't reuse that image. */
|
||||||
GST_DEBUG_OBJECT (ximagesink,
|
GST_DEBUG_OBJECT (ximagesink,
|
||||||
"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,
|
ximage, meta->width, meta->height,
|
||||||
GST_VIDEO_SINK_WIDTH (ximagesink), GST_VIDEO_SINK_HEIGHT (ximagesink));
|
GST_VIDEO_SINK_WIDTH (ximagesink), GST_VIDEO_SINK_HEIGHT (ximagesink));
|
||||||
gst_ximagesink_ximage_destroy (ximagesink, ximage);
|
gst_ximagesink_ximage_destroy (ximagesink, ximage);
|
||||||
} else {
|
} else {
|
||||||
|
@ -223,13 +238,12 @@ no_sink:
|
||||||
static void
|
static void
|
||||||
gst_ximage_buffer_free (GstBuffer * ximage)
|
gst_ximage_buffer_free (GstBuffer * ximage)
|
||||||
{
|
{
|
||||||
GstXImageData *data = GET_XDATA (ximage);
|
GstMetaXImage *meta = GST_META_XIMAGE_GET (ximage, FALSE);
|
||||||
|
g_return_if_fail (meta != NULL);
|
||||||
g_return_if_fail (data != NULL);
|
|
||||||
|
|
||||||
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,33 +364,32 @@ static GstBuffer *
|
||||||
gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps)
|
gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstBuffer *buffer = NULL;
|
GstBuffer *buffer = NULL;
|
||||||
GstXImageData *data = NULL;
|
GstMetaXImage *meta = NULL;
|
||||||
GstStructure *structure = NULL;
|
GstStructure *structure = NULL;
|
||||||
gboolean succeeded = FALSE;
|
gboolean succeeded = FALSE;
|
||||||
int (*handler) (Display *, XErrorEvent *);
|
int (*handler) (Display *, XErrorEvent *);
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_XIMAGESINK (ximagesink), NULL);
|
g_return_val_if_fail (GST_IS_XIMAGESINK (ximagesink), NULL);
|
||||||
|
|
||||||
data = g_slice_new0 (GstXImageData);
|
|
||||||
#ifdef HAVE_XSHM
|
|
||||||
data->SHMInfo.shmaddr = ((void *) -1);
|
|
||||||
data->SHMInfo.shmid = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
buffer = gst_buffer_new ();
|
buffer = gst_buffer_new ();
|
||||||
GST_MINI_OBJECT_CAST (buffer)->dispose =
|
GST_MINI_OBJECT_CAST (buffer)->dispose =
|
||||||
(GstMiniObjectDisposeFunction) gst_ximage_buffer_dispose;
|
(GstMiniObjectDisposeFunction) gst_ximage_buffer_dispose;
|
||||||
buffer->owner_priv = data;
|
meta = GST_META_XIMAGE_GET (buffer, TRUE);
|
||||||
|
#ifdef HAVE_XSHM
|
||||||
|
meta->SHMInfo.shmaddr = ((void *) -1);
|
||||||
|
meta->SHMInfo.shmid = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
if (!gst_structure_get_int (structure, "width", &data->width) ||
|
if (!gst_structure_get_int (structure, "width", &meta->width) ||
|
||||||
!gst_structure_get_int (structure, "height", &data->height)) {
|
!gst_structure_get_int (structure, "height", &meta->height)) {
|
||||||
GST_WARNING ("failed getting geometry from caps %" GST_PTR_FORMAT, caps);
|
GST_WARNING ("failed getting geometry from caps %" GST_PTR_FORMAT, caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ximagesink, "creating image %p (%dx%d)", data,
|
GST_DEBUG_OBJECT (ximagesink, "creating image %p (%dx%d)", buffer,
|
||||||
data->width, data->height);
|
meta->width, meta->height);
|
||||||
|
|
||||||
g_mutex_lock (ximagesink->x_lock);
|
g_mutex_lock (ximagesink->x_lock);
|
||||||
|
|
||||||
|
@ -386,11 +399,11 @@ gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps)
|
||||||
|
|
||||||
#ifdef HAVE_XSHM
|
#ifdef HAVE_XSHM
|
||||||
if (ximagesink->xcontext->use_xshm) {
|
if (ximagesink->xcontext->use_xshm) {
|
||||||
data->ximage = XShmCreateImage (ximagesink->xcontext->disp,
|
meta->ximage = XShmCreateImage (ximagesink->xcontext->disp,
|
||||||
ximagesink->xcontext->visual,
|
ximagesink->xcontext->visual,
|
||||||
ximagesink->xcontext->depth,
|
ximagesink->xcontext->depth,
|
||||||
ZPixmap, NULL, &data->SHMInfo, data->width, data->height);
|
ZPixmap, NULL, &meta->SHMInfo, meta->width, meta->height);
|
||||||
if (!data->ximage || error_caught) {
|
if (!meta->ximage || error_caught) {
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
/* Reset error handler */
|
/* Reset error handler */
|
||||||
error_caught = FALSE;
|
error_caught = FALSE;
|
||||||
|
@ -398,52 +411,52 @@ gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps)
|
||||||
/* Push an error */
|
/* Push an error */
|
||||||
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
||||||
("Failed to create output image buffer of %dx%d pixels",
|
("Failed to create output image buffer of %dx%d pixels",
|
||||||
data->width, data->height),
|
meta->width, meta->height),
|
||||||
("could not XShmCreateImage a %dx%d image",
|
("could not XShmCreateImage a %dx%d image",
|
||||||
data->width, data->height));
|
meta->width, meta->height));
|
||||||
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;
|
||||||
GST_LOG_OBJECT (ximagesink,
|
GST_LOG_OBJECT (ximagesink,
|
||||||
"XShm image size is %" G_GSIZE_FORMAT ", width %d, stride %d",
|
"XShm image size is %" G_GSIZE_FORMAT ", width %d, stride %d",
|
||||||
data->size, data->width, data->ximage->bytes_per_line);
|
meta->size, meta->width, meta->ximage->bytes_per_line);
|
||||||
|
|
||||||
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) {
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
||||||
("Failed to create output image buffer of %dx%d pixels",
|
("Failed to create output image buffer of %dx%d pixels",
|
||||||
data->width, data->height),
|
meta->width, meta->height),
|
||||||
("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
|
("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
|
||||||
data->size));
|
meta->size));
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->SHMInfo.shmaddr = shmat (data->SHMInfo.shmid, NULL, 0);
|
meta->SHMInfo.shmaddr = shmat (meta->SHMInfo.shmid, NULL, 0);
|
||||||
if (data->SHMInfo.shmaddr == ((void *) -1)) {
|
if (meta->SHMInfo.shmaddr == ((void *) -1)) {
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
||||||
("Failed to create output image buffer of %dx%d pixels",
|
("Failed to create output image buffer of %dx%d pixels",
|
||||||
data->width, data->height),
|
meta->width, meta->height),
|
||||||
("Failed to shmat: %s", g_strerror (errno)));
|
("Failed to shmat: %s", g_strerror (errno)));
|
||||||
/* Clean up the shared memory segment */
|
/* Clean up the shared memory segment */
|
||||||
shmctl (data->SHMInfo.shmid, IPC_RMID, NULL);
|
shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->ximage->data = data->SHMInfo.shmaddr;
|
meta->ximage->data = meta->SHMInfo.shmaddr;
|
||||||
data->SHMInfo.readOnly = FALSE;
|
meta->SHMInfo.readOnly = FALSE;
|
||||||
|
|
||||||
if (XShmAttach (ximagesink->xcontext->disp, &data->SHMInfo) == 0) {
|
if (XShmAttach (ximagesink->xcontext->disp, &meta->SHMInfo) == 0) {
|
||||||
/* Clean up shm seg */
|
/* Clean up shm seg */
|
||||||
shmctl (data->SHMInfo.shmid, IPC_RMID, NULL);
|
shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
|
||||||
|
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
||||||
("Failed to create output image buffer of %dx%d pixels",
|
("Failed to create output image buffer of %dx%d pixels",
|
||||||
data->width, data->height), ("Failed to XShmAttach"));
|
meta->width, meta->height), ("Failed to XShmAttach"));
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,19 +465,19 @@ gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps)
|
||||||
/* Now that everyone has attached, we can delete the shared memory segment.
|
/* Now that everyone has attached, we can delete the shared memory segment.
|
||||||
* This way, it will be deleted as soon as we detach later, and not
|
* This way, it will be deleted as soon as we detach later, and not
|
||||||
* leaked if we crash. */
|
* leaked if we crash. */
|
||||||
shmctl (data->SHMInfo.shmid, IPC_RMID, NULL);
|
shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_XSHM */
|
#endif /* HAVE_XSHM */
|
||||||
{
|
{
|
||||||
guint allocsize;
|
guint allocsize;
|
||||||
|
|
||||||
data->ximage = XCreateImage (ximagesink->xcontext->disp,
|
meta->ximage = XCreateImage (ximagesink->xcontext->disp,
|
||||||
ximagesink->xcontext->visual,
|
ximagesink->xcontext->visual,
|
||||||
ximagesink->xcontext->depth,
|
ximagesink->xcontext->depth,
|
||||||
ZPixmap, 0, NULL,
|
ZPixmap, 0, NULL,
|
||||||
data->width, data->height, ximagesink->xcontext->bpp, 0);
|
meta->width, meta->height, ximagesink->xcontext->bpp, 0);
|
||||||
if (!data->ximage || error_caught) {
|
if (!meta->ximage || error_caught) {
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
/* Reset error handler */
|
/* Reset error handler */
|
||||||
error_caught = FALSE;
|
error_caught = FALSE;
|
||||||
|
@ -472,31 +485,31 @@ gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps)
|
||||||
/* Push an error */
|
/* Push an error */
|
||||||
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
||||||
("Failed to create output image buffer of %dx%d pixels",
|
("Failed to create output image buffer of %dx%d pixels",
|
||||||
data->width, data->height),
|
meta->width, meta->height),
|
||||||
("could not XCreateImage a %dx%d image", data->width, data->height));
|
("could not XCreateImage a %dx%d image", meta->width, meta->height));
|
||||||
goto beach;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* upstream will assume that rowstrides are multiples of 4, but this
|
/* upstream will assume that rowstrides are multiples of 4, but this
|
||||||
* doesn't always seem to be the case with XCreateImage() */
|
* doesn't always seem to be the case with XCreateImage() */
|
||||||
if ((data->ximage->bytes_per_line % 4) != 0) {
|
if ((meta->ximage->bytes_per_line % 4) != 0) {
|
||||||
GST_WARNING_OBJECT (ximagesink, "returned stride not a multiple of 4 as "
|
GST_WARNING_OBJECT (ximagesink, "returned stride not a multiple of 4 as "
|
||||||
"usually assumed");
|
"usually assumed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
/* alloc a bit more for unexpected strides to avoid crashes upstream.
|
/* alloc a bit more for unexpected strides to avoid crashes upstream.
|
||||||
* FIXME: if we get an unrounded stride, the image will be displayed
|
* FIXME: if we get an unrounded stride, the image will be displayed
|
||||||
* distorted, since all upstream elements assume a rounded stride */
|
* distorted, since all upstream elements assume a rounded stride */
|
||||||
allocsize =
|
allocsize =
|
||||||
GST_ROUND_UP_4 (data->ximage->bytes_per_line) * data->ximage->height;
|
GST_ROUND_UP_4 (meta->ximage->bytes_per_line) * meta->ximage->height;
|
||||||
data->ximage->data = g_malloc (allocsize);
|
meta->ximage->data = g_malloc (allocsize);
|
||||||
GST_LOG_OBJECT (ximagesink,
|
GST_LOG_OBJECT (ximagesink,
|
||||||
"non-XShm image size is %" G_GSIZE_FORMAT " (alloced: %u), width %d, "
|
"non-XShm image size is %" G_GSIZE_FORMAT " (alloced: %u), width %d, "
|
||||||
"stride %d", data->size, allocsize, data->width,
|
"stride %d", meta->size, allocsize, meta->width,
|
||||||
data->ximage->bytes_per_line);
|
meta->ximage->bytes_per_line);
|
||||||
|
|
||||||
XSync (ximagesink->xcontext->disp, FALSE);
|
XSync (ximagesink->xcontext->disp, FALSE);
|
||||||
}
|
}
|
||||||
|
@ -508,10 +521,10 @@ gst_ximagesink_ximage_new (GstXImageSink * ximagesink, GstCaps * caps)
|
||||||
succeeded = TRUE;
|
succeeded = TRUE;
|
||||||
|
|
||||||
/* Keep a ref to our sink */
|
/* Keep a ref to our sink */
|
||||||
data->ximagesink = gst_object_ref (ximagesink);
|
meta->ximagesink = gst_object_ref (ximagesink);
|
||||||
|
|
||||||
GST_BUFFER_DATA (buffer) = (guchar *) data->ximage->data;
|
GST_BUFFER_DATA (buffer) = (guchar *) meta->ximage->data;
|
||||||
GST_BUFFER_SIZE (buffer) = data->size;
|
GST_BUFFER_SIZE (buffer) = meta->size;
|
||||||
|
|
||||||
g_mutex_unlock (ximagesink->x_lock);
|
g_mutex_unlock (ximagesink->x_lock);
|
||||||
|
|
||||||
|
@ -528,13 +541,13 @@ beach:
|
||||||
static void
|
static void
|
||||||
gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink, GstBuffer * ximage)
|
gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
{
|
{
|
||||||
GstXImageData *data;
|
GstMetaXImage *meta;
|
||||||
|
|
||||||
g_return_if_fail (ximage != NULL);
|
g_return_if_fail (ximage != NULL);
|
||||||
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
|
g_return_if_fail (GST_IS_XIMAGESINK (ximagesink));
|
||||||
|
|
||||||
data = GET_XDATA (ximage);
|
meta = GST_META_XIMAGE_GET (ximage, FALSE);
|
||||||
g_return_if_fail (data != NULL);
|
g_return_if_fail (meta != NULL);
|
||||||
|
|
||||||
/* Hold the object lock to ensure the XContext doesn't disappear */
|
/* Hold the object lock to ensure the XContext doesn't disappear */
|
||||||
GST_OBJECT_LOCK (ximagesink);
|
GST_OBJECT_LOCK (ximagesink);
|
||||||
|
@ -548,8 +561,8 @@ gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
if (!ximagesink->xcontext) {
|
if (!ximagesink->xcontext) {
|
||||||
GST_DEBUG_OBJECT (ximagesink, "Destroying XImage after XContext");
|
GST_DEBUG_OBJECT (ximagesink, "Destroying XImage after XContext");
|
||||||
#ifdef HAVE_XSHM
|
#ifdef HAVE_XSHM
|
||||||
if (data->SHMInfo.shmaddr != ((void *) -1)) {
|
if (meta->SHMInfo.shmaddr != ((void *) -1)) {
|
||||||
shmdt (data->SHMInfo.shmaddr);
|
shmdt (meta->SHMInfo.shmaddr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
goto beach;
|
goto beach;
|
||||||
|
@ -559,19 +572,19 @@ gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
|
|
||||||
#ifdef HAVE_XSHM
|
#ifdef HAVE_XSHM
|
||||||
if (ximagesink->xcontext->use_xshm) {
|
if (ximagesink->xcontext->use_xshm) {
|
||||||
if (data->SHMInfo.shmaddr != ((void *) -1)) {
|
if (meta->SHMInfo.shmaddr != ((void *) -1)) {
|
||||||
XShmDetach (ximagesink->xcontext->disp, &data->SHMInfo);
|
XShmDetach (ximagesink->xcontext->disp, &meta->SHMInfo);
|
||||||
XSync (ximagesink->xcontext->disp, 0);
|
XSync (ximagesink->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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,13 +595,11 @@ gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
beach:
|
beach:
|
||||||
GST_OBJECT_UNLOCK (ximagesink);
|
GST_OBJECT_UNLOCK (ximagesink);
|
||||||
|
|
||||||
if (data->ximagesink) {
|
if (meta->ximagesink) {
|
||||||
/* Release the ref to our sink */
|
/* Release the ref to our sink */
|
||||||
data->ximagesink = NULL;
|
meta->ximagesink = NULL;
|
||||||
gst_object_unref (ximagesink);
|
gst_object_unref (ximagesink);
|
||||||
}
|
}
|
||||||
g_slice_free (GstXImageData, data);
|
|
||||||
ximage->owner_priv = NULL;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -633,7 +644,7 @@ gst_ximagesink_xwindow_draw_borders (GstXImageSink * ximagesink,
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
|
gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
{
|
{
|
||||||
GstXImageData *data;
|
GstMetaXImage *meta;
|
||||||
GstVideoRectangle src, dst, result;
|
GstVideoRectangle src, dst, result;
|
||||||
gboolean draw_border = FALSE;
|
gboolean draw_border = FALSE;
|
||||||
|
|
||||||
|
@ -675,9 +686,9 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data = GET_XDATA (ximage);
|
meta = GST_META_XIMAGE_GET (ximage, FALSE);
|
||||||
src.w = data->width;
|
src.w = meta->width;
|
||||||
src.h = data->height;
|
src.h = meta->height;
|
||||||
dst.w = ximagesink->xwindow->width;
|
dst.w = ximagesink->xwindow->width;
|
||||||
dst.h = ximagesink->xwindow->height;
|
dst.h = ximagesink->xwindow->height;
|
||||||
|
|
||||||
|
@ -697,7 +708,7 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
ximage, 0, 0, result.x, result.y, result.w, result.h,
|
ximage, 0, 0, result.x, result.y, result.w, result.h,
|
||||||
ximagesink->xwindow->width, ximagesink->xwindow->height);
|
ximagesink->xwindow->width, ximagesink->xwindow->height);
|
||||||
XShmPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
|
XShmPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
|
||||||
ximagesink->xwindow->gc, data->ximage, 0, 0, result.x, result.y,
|
ximagesink->xwindow->gc, meta->ximage, 0, 0, result.x, result.y,
|
||||||
result.w, result.h, FALSE);
|
result.w, result.h, FALSE);
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_XSHM */
|
#endif /* HAVE_XSHM */
|
||||||
|
@ -707,7 +718,7 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
ximage, 0, 0, result.x, result.y, result.w, result.h,
|
ximage, 0, 0, result.x, result.y, result.w, result.h,
|
||||||
ximagesink->xwindow->width, ximagesink->xwindow->height);
|
ximagesink->xwindow->width, ximagesink->xwindow->height);
|
||||||
XPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
|
XPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
|
||||||
ximagesink->xwindow->gc, data->ximage, 0, 0, result.x, result.y,
|
ximagesink->xwindow->gc, meta->ximage, 0, 0, result.x, result.y,
|
||||||
result.w, result.h);
|
result.w, result.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,10 +1515,10 @@ gst_ximagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
/* If our ximage has changed we destroy it, next chain iteration will create
|
/* If our ximage has changed we destroy it, next chain iteration will create
|
||||||
a new one */
|
a new one */
|
||||||
if ((ximagesink->ximage)) {
|
if ((ximagesink->ximage)) {
|
||||||
GstXImageData *data = GET_XDATA (ximagesink->ximage);
|
GstMetaXImage *meta = GST_META_XIMAGE_GET (ximagesink->ximage, FALSE);
|
||||||
|
|
||||||
if (((GST_VIDEO_SINK_WIDTH (ximagesink) != data->width) ||
|
if (((GST_VIDEO_SINK_WIDTH (ximagesink) != meta->width) ||
|
||||||
(GST_VIDEO_SINK_HEIGHT (ximagesink) != data->height))) {
|
(GST_VIDEO_SINK_HEIGHT (ximagesink) != meta->height))) {
|
||||||
GST_DEBUG_OBJECT (ximagesink, "our image is not usable anymore, unref %p",
|
GST_DEBUG_OBJECT (ximagesink, "our image is not usable anymore, unref %p",
|
||||||
ximagesink->ximage);
|
ximagesink->ximage);
|
||||||
gst_buffer_unref (ximagesink->ximage);
|
gst_buffer_unref (ximagesink->ximage);
|
||||||
|
@ -1655,10 +1666,11 @@ gst_ximagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
||||||
goto no_ximage;
|
goto no_ximage;
|
||||||
|
|
||||||
if (GST_BUFFER_SIZE (ximagesink->ximage) < GST_BUFFER_SIZE (buf)) {
|
if (GST_BUFFER_SIZE (ximagesink->ximage) < GST_BUFFER_SIZE (buf)) {
|
||||||
|
GstMetaXImage *meta = GST_META_XIMAGE_GET (ximagesink->ximage, FALSE);
|
||||||
|
|
||||||
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
|
||||||
("Failed to create output image buffer of %dx%d pixels",
|
("Failed to create output image buffer of %dx%d pixels",
|
||||||
GET_XDATA (ximagesink->ximage)->width,
|
meta->width, meta->height),
|
||||||
GET_XDATA (ximagesink->ximage)->height),
|
|
||||||
("XServer allocated buffer size did not match input buffer"));
|
("XServer allocated buffer size did not match input buffer"));
|
||||||
|
|
||||||
gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage);
|
gst_ximagesink_ximage_destroy (ximagesink, ximagesink->ximage);
|
||||||
|
|
|
@ -52,7 +52,7 @@ G_BEGIN_DECLS
|
||||||
typedef struct _GstXContext GstXContext;
|
typedef struct _GstXContext GstXContext;
|
||||||
typedef struct _GstXWindow GstXWindow;
|
typedef struct _GstXWindow GstXWindow;
|
||||||
|
|
||||||
typedef struct _GstXImageData GstXImageData;
|
typedef struct _GstMetaXImage GstMetaXImage;
|
||||||
|
|
||||||
typedef struct _GstXImageSink GstXImageSink;
|
typedef struct _GstXImageSink GstXImageSink;
|
||||||
typedef struct _GstXImageSinkClass GstXImageSinkClass;
|
typedef struct _GstXImageSinkClass GstXImageSinkClass;
|
||||||
|
@ -130,7 +130,7 @@ struct _GstXWindow
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstXImageData:
|
* GstMetaXImage:
|
||||||
* @ximagesink: a reference to our #GstXImageSink
|
* @ximagesink: a reference to our #GstXImageSink
|
||||||
* @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
|
||||||
|
@ -139,8 +139,10 @@ struct _GstXWindow
|
||||||
*
|
*
|
||||||
* Structure with additional information about an XImage.
|
* Structure with additional information about an XImage.
|
||||||
*/
|
*/
|
||||||
struct _GstXImageData
|
struct _GstMetaXImage
|
||||||
{
|
{
|
||||||
|
GstMeta meta;
|
||||||
|
|
||||||
/* Reference to the ximagesink we belong to */
|
/* Reference to the ximagesink we belong to */
|
||||||
GstXImageSink *ximagesink;
|
GstXImageSink *ximagesink;
|
||||||
|
|
||||||
|
@ -154,6 +156,10 @@ struct _GstXImageData
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstXImageSink:
|
* GstXImageSink:
|
||||||
* @display_name: the name of the Display we want to render to
|
* @display_name: the name of the Display we want to render to
|
||||||
|
|
|
@ -198,16 +198,31 @@ static GstVideoSinkClass *parent_class = NULL;
|
||||||
/* ============================================================= */
|
/* ============================================================= */
|
||||||
|
|
||||||
/* xvimage buffers */
|
/* xvimage buffers */
|
||||||
#define GET_XVDATA(buf) ((GstXvImageData *) (GST_BUFFER_CAST(buf)->owner_priv))
|
const GstMetaInfo *
|
||||||
|
gst_meta_xvimage_get_info (void)
|
||||||
|
{
|
||||||
|
static const GstMetaInfo *meta_xvimage_info = NULL;
|
||||||
|
|
||||||
|
if (meta_xvimage_info == NULL) {
|
||||||
|
meta_xvimage_info = gst_meta_register ("GstMetaXvImage", "GstMetaXvImage",
|
||||||
|
sizeof (GstMetaXvImage),
|
||||||
|
(GstMetaInitFunction) NULL,
|
||||||
|
(GstMetaFreeFunction) NULL,
|
||||||
|
(GstMetaCopyFunction) NULL,
|
||||||
|
(GstMetaSubFunction) NULL,
|
||||||
|
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
||||||
|
}
|
||||||
|
return meta_xvimage_info;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_xvimage_buffer_dispose (GstBuffer * xvimage)
|
gst_xvimage_buffer_dispose (GstBuffer * xvimage)
|
||||||
{
|
{
|
||||||
GstXvImageData *data = NULL;
|
GstMetaXvImage *data = NULL;
|
||||||
GstXvImageSink *xvimagesink;
|
GstXvImageSink *xvimagesink;
|
||||||
gboolean running;
|
gboolean running;
|
||||||
|
|
||||||
data = GET_XVDATA (xvimage);
|
data = GST_META_XVIMAGE_GET (xvimage, FALSE);
|
||||||
g_return_if_fail (data != NULL);
|
g_return_if_fail (data != NULL);
|
||||||
|
|
||||||
xvimagesink = data->xvimagesink;
|
xvimagesink = data->xvimagesink;
|
||||||
|
@ -253,7 +268,7 @@ no_sink:
|
||||||
static void
|
static void
|
||||||
gst_xvimage_buffer_free (GstBuffer * xvimage)
|
gst_xvimage_buffer_free (GstBuffer * xvimage)
|
||||||
{
|
{
|
||||||
GstXvImageData *data = GET_XVDATA (xvimage);
|
GstMetaXvImage *data = GST_META_XVIMAGE_GET (xvimage, FALSE);
|
||||||
|
|
||||||
g_return_if_fail (data != NULL);
|
g_return_if_fail (data != NULL);
|
||||||
|
|
||||||
|
@ -387,7 +402,7 @@ static GstBuffer *
|
||||||
gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstBuffer *buffer = NULL;
|
GstBuffer *buffer = NULL;
|
||||||
GstXvImageData *data = NULL;
|
GstMetaXvImage *data = NULL;
|
||||||
GstStructure *structure = NULL;
|
GstStructure *structure = NULL;
|
||||||
gboolean succeeded = FALSE;
|
gboolean succeeded = FALSE;
|
||||||
int (*handler) (Display *, XErrorEvent *);
|
int (*handler) (Display *, XErrorEvent *);
|
||||||
|
@ -397,17 +412,16 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
||||||
if (caps == NULL)
|
if (caps == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
data = g_slice_new0 (GstXvImageData);
|
|
||||||
#ifdef HAVE_XSHM
|
|
||||||
data->SHMInfo.shmaddr = ((void *) -1);
|
|
||||||
data->SHMInfo.shmid = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
buffer = gst_buffer_new ();
|
buffer = gst_buffer_new ();
|
||||||
GST_DEBUG_OBJECT (xvimagesink, "Creating new XvImageBuffer");
|
GST_DEBUG_OBJECT (xvimagesink, "Creating new XvImageBuffer");
|
||||||
GST_MINI_OBJECT_CAST (buffer)->dispose =
|
GST_MINI_OBJECT_CAST (buffer)->dispose =
|
||||||
(GstMiniObjectDisposeFunction) gst_xvimage_buffer_dispose;
|
(GstMiniObjectDisposeFunction) gst_xvimage_buffer_dispose;
|
||||||
buffer->owner_priv = data;
|
|
||||||
|
data = GST_META_XVIMAGE_GET (buffer, TRUE);
|
||||||
|
#ifdef HAVE_XSHM
|
||||||
|
data->SHMInfo.shmaddr = ((void *) -1);
|
||||||
|
data->SHMInfo.shmid = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
|
@ -611,14 +625,14 @@ static void
|
||||||
gst_xvimagesink_xvimage_destroy (GstXvImageSink * xvimagesink,
|
gst_xvimagesink_xvimage_destroy (GstXvImageSink * xvimagesink,
|
||||||
GstBuffer * xvimage)
|
GstBuffer * xvimage)
|
||||||
{
|
{
|
||||||
GstXvImageData *data = NULL;
|
GstMetaXvImage *data = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (xvimage, "Destroying buffer");
|
GST_DEBUG_OBJECT (xvimage, "Destroying buffer");
|
||||||
|
|
||||||
g_return_if_fail (xvimage != NULL);
|
g_return_if_fail (xvimage != NULL);
|
||||||
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
|
g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink));
|
||||||
|
|
||||||
data = GET_XVDATA (xvimage);
|
data = GST_META_XVIMAGE_GET (xvimage, FALSE);
|
||||||
g_return_if_fail (data != NULL);
|
g_return_if_fail (data != NULL);
|
||||||
|
|
||||||
GST_OBJECT_LOCK (xvimagesink);
|
GST_OBJECT_LOCK (xvimagesink);
|
||||||
|
@ -675,9 +689,6 @@ beach:
|
||||||
data->xvimagesink = NULL;
|
data->xvimagesink = NULL;
|
||||||
gst_object_unref (xvimagesink);
|
gst_object_unref (xvimagesink);
|
||||||
|
|
||||||
g_slice_free (GstXvImageData, data);
|
|
||||||
xvimage->owner_priv = NULL;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,7 +741,7 @@ gst_xvimagesink_xwindow_draw_borders (GstXvImageSink * xvimagesink,
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
|
gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
|
||||||
{
|
{
|
||||||
GstXvImageData *data;
|
GstMetaXvImage *data;
|
||||||
GstVideoRectangle result;
|
GstVideoRectangle result;
|
||||||
gboolean draw_border = FALSE;
|
gboolean draw_border = FALSE;
|
||||||
|
|
||||||
|
@ -795,7 +806,8 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
|
||||||
xvimagesink->redraw_border = FALSE;
|
xvimagesink->redraw_border = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = GET_XVDATA (xvimage);
|
data = GST_META_XVIMAGE_GET (xvimage, FALSE);
|
||||||
|
g_assert (data != NULL);
|
||||||
|
|
||||||
/* We scale to the window's geometry */
|
/* We scale to the window's geometry */
|
||||||
#ifdef HAVE_XSHM
|
#ifdef HAVE_XSHM
|
||||||
|
@ -2174,7 +2186,7 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
/* We renew our xvimage only if size or format changed;
|
/* We renew our xvimage only if size or format changed;
|
||||||
* the xvimage is the same size as the video pixel size */
|
* the xvimage is the same size as the video pixel size */
|
||||||
if ((xvimagesink->xvimage)) {
|
if ((xvimagesink->xvimage)) {
|
||||||
GstXvImageData *data = GET_XVDATA (xvimagesink->xvimage);
|
GstMetaXvImage *data = GST_META_XVIMAGE_GET (xvimagesink->xvimage, FALSE);
|
||||||
|
|
||||||
if (((im_format != data->im_format) ||
|
if (((im_format != data->im_format) ||
|
||||||
(video_width != data->width) || (video_height != data->height))) {
|
(video_width != data->width) || (video_height != data->height))) {
|
||||||
|
@ -2350,10 +2362,12 @@ gst_xvimagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
||||||
goto no_image;
|
goto no_image;
|
||||||
|
|
||||||
if (GST_BUFFER_SIZE (xvimagesink->xvimage) < GST_BUFFER_SIZE (buf)) {
|
if (GST_BUFFER_SIZE (xvimagesink->xvimage) < GST_BUFFER_SIZE (buf)) {
|
||||||
|
GstMetaXvImage *meta =
|
||||||
|
GST_META_XVIMAGE_GET (xvimagesink->xvimage, FALSE);
|
||||||
|
|
||||||
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
|
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
|
||||||
("Failed to create output image buffer of %dx%d pixels",
|
("Failed to create output image buffer of %dx%d pixels",
|
||||||
GET_XVDATA (xvimagesink->xvimage)->width,
|
meta->width, meta->height),
|
||||||
GET_XVDATA (xvimagesink->xvimage)->height),
|
|
||||||
("XServer allocated buffer size did not match input buffer"));
|
("XServer allocated buffer size did not match input buffer"));
|
||||||
|
|
||||||
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimagesink->xvimage);
|
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimagesink->xvimage);
|
||||||
|
@ -2475,7 +2489,7 @@ gst_xvimagesink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
|
||||||
{
|
{
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstXvImageSink *xvimagesink;
|
GstXvImageSink *xvimagesink;
|
||||||
GstXvImageData *xvimage = NULL;
|
GstMetaXvImage *xvimage = NULL;
|
||||||
GstCaps *intersection = NULL;
|
GstCaps *intersection = NULL;
|
||||||
GstStructure *structure = NULL;
|
GstStructure *structure = NULL;
|
||||||
gint width, height, image_format;
|
gint width, height, image_format;
|
||||||
|
|
|
@ -58,7 +58,7 @@ G_BEGIN_DECLS
|
||||||
typedef struct _GstXContext GstXContext;
|
typedef struct _GstXContext GstXContext;
|
||||||
typedef struct _GstXWindow GstXWindow;
|
typedef struct _GstXWindow GstXWindow;
|
||||||
typedef struct _GstXvImageFormat GstXvImageFormat;
|
typedef struct _GstXvImageFormat GstXvImageFormat;
|
||||||
typedef struct _GstXvImageData GstXvImageData;
|
typedef struct _GstMetaXvImage GstMetaXvImage;
|
||||||
|
|
||||||
typedef struct _GstXvImageSink GstXvImageSink;
|
typedef struct _GstXvImageSink GstXvImageSink;
|
||||||
typedef struct _GstXvImageSinkClass GstXvImageSinkClass;
|
typedef struct _GstXvImageSinkClass GstXvImageSinkClass;
|
||||||
|
@ -172,7 +172,9 @@ struct _GstXvImageFormat {
|
||||||
*
|
*
|
||||||
* Structure with additional information about an XvImage.
|
* Structure with additional information about an XvImage.
|
||||||
*/
|
*/
|
||||||
struct _GstXvImageData {
|
struct _GstMetaXvImage {
|
||||||
|
GstMeta meta;
|
||||||
|
|
||||||
/* Reference to the xvimagesink we belong to */
|
/* Reference to the xvimagesink we belong to */
|
||||||
GstXvImageSink *xvimagesink;
|
GstXvImageSink *xvimagesink;
|
||||||
|
|
||||||
|
@ -186,6 +188,11 @@ struct _GstXvImageData {
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const GstMetaInfo * gst_meta_xvimage_get_info (void);
|
||||||
|
|
||||||
|
#define GST_META_XVIMAGE_GET(buf,create) ((GstMetaXvImage *)gst_buffer_get_meta(buf,gst_meta_xvimage_get_info(),create));
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstXvImageSink:
|
* GstXvImageSink:
|
||||||
* @display_name: the name of the Display we want to render to
|
* @display_name: the name of the Display we want to render to
|
||||||
|
|
Loading…
Reference in a new issue