plugins: fix for new memory API

This commit is contained in:
Wim Taymans 2011-03-27 17:16:10 +02:00
parent 3b03e23559
commit 5244770775
10 changed files with 138 additions and 108 deletions

View file

@ -400,7 +400,7 @@ gst_cd_paranoia_src_read_sector (GstCddaBaseSrc * cddabasesrc, gint sector)
goto read_failed; goto read_failed;
buf = gst_buffer_new_and_alloc (CD_FRAMESIZE_RAW); buf = gst_buffer_new_and_alloc (CD_FRAMESIZE_RAW);
memcpy (GST_BUFFER_DATA (buf), cdda_buf, CD_FRAMESIZE_RAW); gst_buffer_fill (buf, 0, cdda_buf, CD_FRAMESIZE_RAW);
/* cdda base class will take care of timestamping etc. */ /* cdda base class will take care of timestamping etc. */
++src->next_sector; ++src->next_sector;

View file

@ -267,26 +267,32 @@ gst_gio_base_sink_render (GstBaseSink * base_sink, GstBuffer * buffer)
{ {
GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink); GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);
gssize written; gssize written;
guint8 *data;
gsize size;
gboolean success; gboolean success;
GError *err = NULL; GError *err = NULL;
g_return_val_if_fail (G_IS_OUTPUT_STREAM (sink->stream), GST_FLOW_ERROR); g_return_val_if_fail (G_IS_OUTPUT_STREAM (sink->stream), GST_FLOW_ERROR);
GST_LOG_OBJECT (sink, "writing %u bytes to offset %" G_GUINT64_FORMAT, data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
GST_BUFFER_SIZE (buffer), sink->position);
written = g_output_stream_write (sink->stream, GST_LOG_OBJECT (sink,
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), sink->cancel, &err); "writing %" G_GSIZE_FORMAT " bytes to offset %" G_GUINT64_FORMAT, size,
sink->position);
written =
g_output_stream_write (sink->stream, data, size, sink->cancel, &err);
gst_buffer_unmap (buffer, data, size);
success = (written >= 0); success = (written >= 0);
if (G_UNLIKELY (success && written < GST_BUFFER_SIZE (buffer))) { if (G_UNLIKELY (success && written < size)) {
/* FIXME: Can this happen? Should we handle it gracefully? gnomevfssink /* FIXME: Can this happen? Should we handle it gracefully? gnomevfssink
* doesn't... */ * doesn't... */
GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL), GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
("Could not write to stream: (short write, only %" ("Could not write to stream: (short write, only %"
G_GSSIZE_FORMAT " bytes of %d bytes written)", G_GSSIZE_FORMAT " bytes of %" G_GSIZE_FORMAT " bytes written)",
written, GST_BUFFER_SIZE (buffer))); written, size));
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }

View file

@ -332,9 +332,9 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_OFFSET (buf) = offset;
GST_BUFFER_OFFSET_END (buf) = offset + size; GST_BUFFER_OFFSET_END (buf) = offset + size;
GST_BUFFER_SIZE (buf) = size;
} else { } else {
guint cachesize = MAX (4096, size); guint cachesize = MAX (4096, size);
guint8 *bdata;
gssize read, res; gssize read, res;
gboolean success, eos; gboolean success, eos;
GError *err = NULL; GError *err = NULL;
@ -371,13 +371,14 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
* supports reads up to 64k. So we loop here until we get at * supports reads up to 64k. So we loop here until we get at
* at least the requested amount of bytes or a read returns * at least the requested amount of bytes or a read returns
* nothing. */ * nothing. */
bdata = gst_buffer_map (src->cache, NULL, NULL, GST_MAP_WRITE);
read = 0; read = 0;
while (size - read > 0 && (res = while (size - read > 0 && (res =
g_input_stream_read (G_INPUT_STREAM (src->stream), g_input_stream_read (G_INPUT_STREAM (src->stream),
GST_BUFFER_DATA (src->cache) + read, cachesize - read, bdata + read, cachesize - read, src->cancel, &err)) > 0) {
src->cancel, &err)) > 0) {
read += res; read += res;
} }
gst_buffer_unmap (src->cache, bdata, read);
success = (read >= 0); success = (read >= 0);
eos = (cachesize > 0 && read == 0); eos = (cachesize > 0 && read == 0);
@ -390,7 +391,6 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
if (success && !eos) { if (success && !eos) {
src->position += read; src->position += read;
GST_BUFFER_SIZE (src->cache) = read;
GST_BUFFER_OFFSET (src->cache) = offset; GST_BUFFER_OFFSET (src->cache) = offset;
GST_BUFFER_OFFSET_END (src->cache) = offset + read; GST_BUFFER_OFFSET_END (src->cache) = offset + read;
@ -404,7 +404,6 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
GST_BUFFER_OFFSET (buf) = offset; GST_BUFFER_OFFSET (buf) = offset;
GST_BUFFER_OFFSET_END (buf) = offset + MIN (size, read); GST_BUFFER_OFFSET_END (buf) = offset + MIN (size, read);
GST_BUFFER_SIZE (buf) = MIN (size, read);
} else { } else {
GST_DEBUG_OBJECT (src, "Read not successful"); GST_DEBUG_OBJECT (src, "Read not successful");
gst_buffer_unref (src->cache); gst_buffer_unref (src->cache);

View file

@ -523,6 +523,8 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
GstGnomeVFSSink *sink; GstGnomeVFSSink *sink;
GnomeVFSResult result; GnomeVFSResult result;
GstFlowReturn ret; GstFlowReturn ret;
guint8 *data;
gsize size;
sink = GST_GNOME_VFS_SINK (basesink); sink = GST_GNOME_VFS_SINK (basesink);
@ -531,22 +533,22 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
sink->current_pos = cur_pos; sink->current_pos = cur_pos;
} }
result = gnome_vfs_write (sink->handle, GST_BUFFER_DATA (buf), data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
GST_BUFFER_SIZE (buf), &written); result = gnome_vfs_write (sink->handle, data, size, &written);
gst_buffer_unmap (buf, data, size);
switch (result) { switch (result) {
case GNOME_VFS_OK:{ case GNOME_VFS_OK:{
GST_DEBUG_OBJECT (sink, "wrote %" G_GINT64_FORMAT " bytes at %" GST_DEBUG_OBJECT (sink, "wrote %" G_GINT64_FORMAT " bytes at %"
G_GINT64_FORMAT, (gint64) written, (gint64) cur_pos); G_GINT64_FORMAT, (gint64) written, (gint64) cur_pos);
if (written < GST_BUFFER_SIZE (buf)) { if (written < size) {
/* FIXME: what to do here? (tpm) */ /* FIXME: what to do here? (tpm) */
g_warning ("%s: %d bytes should be written, only %" g_warning ("%s: %" G_GSIZE_FORMAT " bytes should be written, only %"
G_GUINT64_FORMAT " bytes written", G_STRLOC, G_GUINT64_FORMAT " bytes written", G_STRLOC, size, written);
GST_BUFFER_SIZE (buf), written);
} }
sink->current_pos += GST_BUFFER_SIZE (buf); sink->current_pos += size;
ret = GST_FLOW_OK; ret = GST_FLOW_OK;
break; break;
} }
@ -554,7 +556,7 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
/* TODO: emit signal/send msg on out-of-diskspace and /* TODO: emit signal/send msg on out-of-diskspace and
* handle this gracefully (see open bug) (tpm) */ * handle this gracefully (see open bug) (tpm) */
GST_ELEMENT_ERROR (sink, RESOURCE, NO_SPACE_LEFT, (NULL), GST_ELEMENT_ERROR (sink, RESOURCE, NO_SPACE_LEFT, (NULL),
("bufsize=%u, written=%u", GST_BUFFER_SIZE (buf), (guint) written)); ("bufsize=%u, written=%u", size, (guint) written));
ret = GST_FLOW_ERROR; ret = GST_FLOW_ERROR;
break; break;
} }
@ -565,7 +567,7 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
(_("Error while writing to file \"%s\"."), filename), (_("Error while writing to file \"%s\"."), filename),
("%s, bufsize=%u, written=%u", gnome_vfs_result_to_string (result), ("%s, bufsize=%u, written=%u", gnome_vfs_result_to_string (result),
GST_BUFFER_SIZE (buf), (guint) written)); size, (guint) written));
g_free (filename); g_free (filename);
ret = GST_FLOW_ERROR; ret = GST_FLOW_ERROR;

View file

@ -601,8 +601,8 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
GnomeVFSResult res; GnomeVFSResult res;
GstBuffer *buf; GstBuffer *buf;
GnomeVFSFileSize readbytes; GnomeVFSFileSize readbytes;
guint8 *data; guint8 *data, *ptr;
guint todo; gsize todo;
GstGnomeVFSSrc *src; GstGnomeVFSSrc *src;
src = GST_GNOME_VFS_SRC (basesrc); src = GST_GNOME_VFS_SRC (basesrc);
@ -630,12 +630,13 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
data = GST_BUFFER_DATA (buf); data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
ptr = data;
todo = size; todo = size;
while (todo > 0) { while (todo > 0) {
/* this can return less that we ask for */ /* this can return less that we ask for */
res = gnome_vfs_read (src->handle, data, todo, &readbytes); res = gnome_vfs_read (src->handle, ptr, todo, &readbytes);
if (G_UNLIKELY (res == GNOME_VFS_ERROR_EOF || (res == GNOME_VFS_OK if (G_UNLIKELY (res == GNOME_VFS_ERROR_EOF || (res == GNOME_VFS_OK
&& readbytes == 0))) && readbytes == 0)))
@ -645,13 +646,15 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
goto read_failed; goto read_failed;
if (readbytes < todo) { if (readbytes < todo) {
data = &data[readbytes]; ptr += readbytes;
todo -= readbytes; todo -= readbytes;
} else { } else {
todo = 0; todo = 0;
} }
GST_LOG (" got size %" G_GUINT64_FORMAT, readbytes); GST_LOG (" got size %" G_GUINT64_FORMAT, readbytes);
} }
gst_buffer_unmap (buf, data, size);
GST_BUFFER_OFFSET (buf) = src->curoffset; GST_BUFFER_OFFSET (buf) = src->curoffset;
src->curoffset += size; src->curoffset += size;
@ -676,6 +679,7 @@ cannot_seek:
} }
read_failed: read_failed:
{ {
gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf); gst_buffer_unref (buf);
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
("Failed to read data: %s", gnome_vfs_result_to_string (res))); ("Failed to read data: %s", gnome_vfs_result_to_string (res)));
@ -683,6 +687,7 @@ read_failed:
} }
eos: eos:
{ {
gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf); gst_buffer_unref (buf);
GST_DEBUG_OBJECT (src, "Reading data gave EOS"); GST_DEBUG_OBJECT (src, "Reading data gave EOS");
return GST_FLOW_UNEXPECTED; return GST_FLOW_UNEXPECTED;

View file

@ -642,7 +642,8 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
GST_DEBUG_OBJECT (visual, GST_DEBUG_OBJECT (visual,
"Input buffer has %d samples, time=%" G_GUINT64_FORMAT, "Input buffer has %d samples, time=%" G_GUINT64_FORMAT,
GST_BUFFER_SIZE (buffer) / visual->bps, GST_BUFFER_TIMESTAMP (buffer)); gst_buffer_get_size (buffer) / visual->bps,
GST_BUFFER_TIMESTAMP (buffer));
gst_adapter_push (visual->adapter, buffer); gst_adapter_push (visual->adapter, buffer);
@ -828,8 +829,8 @@ gst_visual_change_state (GstElement * element, GstStateChange transition)
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY: case GST_STATE_CHANGE_NULL_TO_READY:
visual->actor = visual->actor =
visual_actor_new (GST_VISUAL_GET_CLASS (visual)->plugin->info-> visual_actor_new (GST_VISUAL_GET_CLASS (visual)->plugin->
plugname); info->plugname);
visual->video = visual_video_new (); visual->video = visual_video_new ();
visual->audio = visual_audio_new (); visual->audio = visual_audio_new ();
/* can't have a play without actors */ /* can't have a play without actors */

View file

@ -657,6 +657,7 @@ gst_meta_v4lsrc_get_info (void)
sizeof (GstMetaV4lSrc), sizeof (GstMetaV4lSrc),
(GstMetaInitFunction) NULL, (GstMetaInitFunction) NULL,
(GstMetaFreeFunction) meta_v4lsrc_free, (GstMetaFreeFunction) meta_v4lsrc_free,
(GstMetaCopyFunction) NULL,
(GstMetaTransformFunction) NULL, (GstMetaTransformFunction) NULL,
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL); (GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
} }
@ -686,9 +687,11 @@ gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num)
meta->num = num; meta->num = num;
meta->v4lsrc = gst_object_ref (v4lsrc); meta->v4lsrc = gst_object_ref (v4lsrc);
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY); gst_buffer_take_memory (buf,
GST_BUFFER_DATA (buf) = gst_v4lsrc_get_buffer (v4lsrc, num); gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
GST_BUFFER_SIZE (buf) = v4lsrc->buffer_size; gst_v4lsrc_get_buffer (v4lsrc, num), NULL, v4lsrc->buffer_size,
0, v4lsrc->buffer_size));
GST_BUFFER_OFFSET (buf) = v4lsrc->offset++; GST_BUFFER_OFFSET (buf) = v4lsrc->offset++;
GST_BUFFER_OFFSET_END (buf) = v4lsrc->offset; GST_BUFFER_OFFSET_END (buf) = v4lsrc->offset;

View file

@ -43,6 +43,7 @@ gst_meta_ximage_get_info (void)
sizeof (GstMetaXImage), sizeof (GstMetaXImage),
(GstMetaInitFunction) NULL, (GstMetaInitFunction) NULL,
(GstMetaFreeFunction) gst_meta_ximage_free, (GstMetaFreeFunction) gst_meta_ximage_free,
(GstMetaCopyFunction) NULL,
(GstMetaTransformFunction) NULL, (GstMetaTransformFunction) NULL,
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL); (GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
} }
@ -173,8 +174,9 @@ gst_buffer_add_meta_ximage (GstBuffer * buffer, GstXImageSink * ximagesink,
error_caught = FALSE; error_caught = FALSE;
XSetErrorHandler (handler); XSetErrorHandler (handler);
GST_BUFFER_DATA (buffer) = (guchar *) meta->ximage->data; gst_buffer_take_memory (buffer,
GST_BUFFER_SIZE (buffer) = meta->size; gst_memory_new_wrapped (0, meta->ximage->data, NULL,
meta->size, 0, meta->size));
g_mutex_unlock (ximagesink->x_lock); g_mutex_unlock (ximagesink->x_lock);

View file

@ -1219,6 +1219,8 @@ gst_ximagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
res = GST_FLOW_OK; res = GST_FLOW_OK;
} else { } else {
GstBuffer *temp; GstBuffer *temp;
guint8 *data;
gsize size;
/* Else we have to copy the data into our private image, */ /* Else we have to copy the data into our private image, */
/* if we have one... */ /* if we have one... */
@ -1233,11 +1235,12 @@ gst_ximagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
if (res != GST_FLOW_OK) if (res != GST_FLOW_OK)
goto no_buffer; goto no_buffer;
if (GST_BUFFER_SIZE (temp) < GST_BUFFER_SIZE (buf)) if (gst_buffer_get_size (temp) < gst_buffer_get_size (buf))
goto wrong_size; goto wrong_size;
memcpy (GST_BUFFER_DATA (temp), GST_BUFFER_DATA (buf), data = gst_buffer_map (temp, &size, NULL, GST_MAP_WRITE);
MIN (GST_BUFFER_SIZE (temp), GST_BUFFER_SIZE (buf))); gst_buffer_extract (buf, 0, data, size);
gst_buffer_unmap (temp, data, size);
buf = temp; buf = temp;
} }

View file

@ -208,6 +208,7 @@ gst_meta_xvimage_get_info (void)
sizeof (GstMetaXvImage), sizeof (GstMetaXvImage),
(GstMetaInitFunction) NULL, (GstMetaInitFunction) NULL,
(GstMetaFreeFunction) NULL, (GstMetaFreeFunction) NULL,
(GstMetaCopyFunction) NULL,
(GstMetaTransformFunction) NULL, (GstMetaTransformFunction) NULL,
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL); (GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
} }
@ -401,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;
GstMetaXvImage *data = NULL; GstMetaXvImage *meta = NULL;
GstStructure *structure = NULL; GstStructure *structure = NULL;
gboolean succeeded = FALSE; gboolean succeeded = FALSE;
int (*handler) (Display *, XErrorEvent *); int (*handler) (Display *, XErrorEvent *);
@ -416,31 +417,31 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
GST_MINI_OBJECT_CAST (buffer)->dispose = GST_MINI_OBJECT_CAST (buffer)->dispose =
(GstMiniObjectDisposeFunction) gst_xvimage_buffer_dispose; (GstMiniObjectDisposeFunction) gst_xvimage_buffer_dispose;
data = GST_META_XVIMAGE_ADD (buffer); meta = GST_META_XVIMAGE_ADD (buffer);
#ifdef HAVE_XSHM #ifdef HAVE_XSHM
data->SHMInfo.shmaddr = ((void *) -1); meta->SHMInfo.shmaddr = ((void *) -1);
data->SHMInfo.shmid = -1; meta->SHMInfo.shmid = -1;
#endif #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_LOG_OBJECT (xvimagesink, "creating %dx%d", data->width, data->height); GST_LOG_OBJECT (xvimagesink, "creating %dx%d", meta->width, meta->height);
data->im_format = gst_xvimagesink_get_format_from_caps (xvimagesink, caps); meta->im_format = gst_xvimagesink_get_format_from_caps (xvimagesink, caps);
if (data->im_format == -1) { if (meta->im_format == -1) {
GST_WARNING_OBJECT (xvimagesink, "failed to get format from caps %" GST_WARNING_OBJECT (xvimagesink, "failed to get format from caps %"
GST_PTR_FORMAT, caps); GST_PTR_FORMAT, caps);
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",
data->width, data->height), ("Invalid input caps")); meta->width, meta->height), ("Invalid input caps"));
goto beach_unlocked; goto beach_unlocked;
} }
data->xvimagesink = gst_object_ref (xvimagesink); meta->xvimagesink = gst_object_ref (xvimagesink);
g_mutex_lock (xvimagesink->x_lock); g_mutex_lock (xvimagesink->x_lock);
@ -452,10 +453,10 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
if (xvimagesink->xcontext->use_xshm) { if (xvimagesink->xcontext->use_xshm) {
int expected_size; int expected_size;
data->xvimage = XvShmCreateImage (xvimagesink->xcontext->disp, meta->xvimage = XvShmCreateImage (xvimagesink->xcontext->disp,
xvimagesink->xcontext->xv_port_id, xvimagesink->xcontext->xv_port_id,
data->im_format, NULL, data->width, data->height, &data->SHMInfo); meta->im_format, NULL, meta->width, meta->height, &meta->SHMInfo);
if (!data->xvimage || error_caught) { if (!meta->xvimage || error_caught) {
g_mutex_unlock (xvimagesink->x_lock); g_mutex_unlock (xvimagesink->x_lock);
/* Reset error handler */ /* Reset error handler */
error_caught = FALSE; error_caught = FALSE;
@ -463,20 +464,20 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
/* Push an error */ /* Push an error */
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",
data->width, data->height), meta->width, meta->height),
("could not XvShmCreateImage a %dx%d image", ("could not XvShmCreateImage a %dx%d image",
data->width, data->height)); meta->width, meta->height));
goto beach_unlocked; goto beach_unlocked;
} }
/* we have to use the returned data_size for our shm size */ /* we have to use the returned data_size for our shm size */
data->size = data->xvimage->data_size; meta->size = meta->xvimage->data_size;
GST_LOG_OBJECT (xvimagesink, "XShm image size is %" G_GSIZE_FORMAT, GST_LOG_OBJECT (xvimagesink, "XShm image size is %" G_GSIZE_FORMAT,
data->size); meta->size);
/* calculate the expected size. This is only for sanity checking the /* calculate the expected size. This is only for sanity checking the
* number we get from X. */ * number we get from X. */
switch (data->im_format) { switch (meta->im_format) {
case GST_MAKE_FOURCC ('I', '4', '2', '0'): case GST_MAKE_FOURCC ('I', '4', '2', '0'):
case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
{ {
@ -485,17 +486,17 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
guint plane; guint plane;
offsets[0] = 0; offsets[0] = 0;
pitches[0] = GST_ROUND_UP_4 (data->width); pitches[0] = GST_ROUND_UP_4 (meta->width);
offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (data->height); offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (meta->height);
pitches[1] = GST_ROUND_UP_8 (data->width) / 2; pitches[1] = GST_ROUND_UP_8 (meta->width) / 2;
offsets[2] = offsets[2] =
offsets[1] + pitches[1] * GST_ROUND_UP_2 (data->height) / 2; offsets[1] + pitches[1] * GST_ROUND_UP_2 (meta->height) / 2;
pitches[2] = GST_ROUND_UP_8 (pitches[0]) / 2; pitches[2] = GST_ROUND_UP_8 (pitches[0]) / 2;
expected_size = expected_size =
offsets[2] + pitches[2] * GST_ROUND_UP_2 (data->height) / 2; offsets[2] + pitches[2] * GST_ROUND_UP_2 (meta->height) / 2;
for (plane = 0; plane < data->xvimage->num_planes; plane++) { for (plane = 0; plane < meta->xvimage->num_planes; plane++) {
GST_DEBUG_OBJECT (xvimagesink, GST_DEBUG_OBJECT (xvimagesink,
"Plane %u has a expected pitch of %d bytes, " "offset of %d", "Plane %u has a expected pitch of %d bytes, " "offset of %d",
plane, pitches[plane], offsets[plane]); plane, pitches[plane], offsets[plane]);
@ -504,63 +505,63 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
} }
case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'): case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
expected_size = data->height * GST_ROUND_UP_4 (data->width * 2); expected_size = meta->height * GST_ROUND_UP_4 (meta->width * 2);
break; break;
default: default:
expected_size = 0; expected_size = 0;
break; break;
} }
if (expected_size != 0 && data->size != expected_size) { if (expected_size != 0 && meta->size != expected_size) {
GST_WARNING_OBJECT (xvimagesink, GST_WARNING_OBJECT (xvimagesink,
"unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)", "unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)",
data->size, expected_size); meta->size, expected_size);
} }
/* Be verbose about our XvImage stride */ /* Be verbose about our XvImage stride */
{ {
guint plane; guint plane;
for (plane = 0; plane < data->xvimage->num_planes; plane++) { for (plane = 0; plane < meta->xvimage->num_planes; plane++) {
GST_DEBUG_OBJECT (xvimagesink, "Plane %u has a pitch of %d bytes, " GST_DEBUG_OBJECT (xvimagesink, "Plane %u has a pitch of %d bytes, "
"offset of %d", plane, data->xvimage->pitches[plane], "offset of %d", plane, meta->xvimage->pitches[plane],
data->xvimage->offsets[plane]); meta->xvimage->offsets[plane]);
} }
} }
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 (xvimagesink->x_lock); g_mutex_unlock (xvimagesink->x_lock);
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",
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_unlocked; goto beach_unlocked;
} }
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 (xvimagesink->x_lock); g_mutex_unlock (xvimagesink->x_lock);
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",
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_unlocked; goto beach_unlocked;
} }
data->xvimage->data = data->SHMInfo.shmaddr; meta->xvimage->data = meta->SHMInfo.shmaddr;
data->SHMInfo.readOnly = FALSE; meta->SHMInfo.readOnly = FALSE;
if (XShmAttach (xvimagesink->xcontext->disp, &data->SHMInfo) == 0) { if (XShmAttach (xvimagesink->xcontext->disp, &meta->SHMInfo) == 0) {
/* 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);
g_mutex_unlock (xvimagesink->x_lock); g_mutex_unlock (xvimagesink->x_lock);
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",
data->width, data->height), ("Failed to XShmAttach")); meta->width, meta->height), ("Failed to XShmAttach"));
goto beach_unlocked; goto beach_unlocked;
} }
@ -569,17 +570,17 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
/* Delete the shared memory segment as soon as we everyone is attached. /* Delete the shared memory segment as soon as we everyone is attached.
* 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);
GST_DEBUG_OBJECT (xvimagesink, "XServer ShmAttached to 0x%x, id 0x%lx", GST_DEBUG_OBJECT (xvimagesink, "XServer ShmAttached to 0x%x, id 0x%lx",
data->SHMInfo.shmid, data->SHMInfo.shmseg); meta->SHMInfo.shmid, meta->SHMInfo.shmseg);
} else } else
#endif /* HAVE_XSHM */ #endif /* HAVE_XSHM */
{ {
data->xvimage = XvCreateImage (xvimagesink->xcontext->disp, meta->xvimage = XvCreateImage (xvimagesink->xcontext->disp,
xvimagesink->xcontext->xv_port_id, xvimagesink->xcontext->xv_port_id,
data->im_format, NULL, data->width, data->height); meta->im_format, NULL, meta->width, meta->height);
if (!data->xvimage || error_caught) { if (!meta->xvimage || error_caught) {
g_mutex_unlock (xvimagesink->x_lock); g_mutex_unlock (xvimagesink->x_lock);
/* Reset error handler */ /* Reset error handler */
error_caught = FALSE; error_caught = FALSE;
@ -587,14 +588,14 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
/* Push an error */ /* Push an error */
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE, GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
("Failed to create outputimage buffer of %dx%d pixels", ("Failed to create outputimage buffer of %dx%d pixels",
data->width, data->height), meta->width, meta->height),
("could not XvCreateImage a %dx%d image", data->width, data->height)); ("could not XvCreateImage a %dx%d image", meta->width, meta->height));
goto beach_unlocked; goto beach_unlocked;
} }
/* we have to use the returned data_size for our image size */ /* we have to use the returned data_size for our image size */
data->size = data->xvimage->data_size; meta->size = meta->xvimage->data_size;
data->xvimage->data = g_malloc (data->size); meta->xvimage->data = g_malloc (meta->size);
XSync (xvimagesink->xcontext->disp, FALSE); XSync (xvimagesink->xcontext->disp, FALSE);
} }
@ -605,8 +606,9 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
succeeded = TRUE; succeeded = TRUE;
GST_BUFFER_DATA (buffer) = (guchar *) data->xvimage->data; gst_buffer_take_memory (buffer,
GST_BUFFER_SIZE (buffer) = data->size; gst_memory_new_wrapped (0, meta->xvimage->data, NULL,
meta->size, 0, meta->size));
g_mutex_unlock (xvimagesink->x_lock); g_mutex_unlock (xvimagesink->x_lock);
@ -2345,6 +2347,9 @@ gst_xvimagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
if (!gst_xvimagesink_xvimage_put (xvimagesink, buf)) if (!gst_xvimagesink_xvimage_put (xvimagesink, buf))
goto no_window; goto no_window;
} else { } else {
guint8 *data;
gsize size;
GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, xvimagesink, GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, xvimagesink,
"slow copy into bufferpool buffer %p", buf); "slow copy into bufferpool buffer %p", buf);
/* Else we have to copy the data into our private image, */ /* Else we have to copy the data into our private image, */
@ -2359,23 +2364,14 @@ gst_xvimagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
/* The create method should have posted an informative error */ /* The create method should have posted an informative error */
goto no_image; goto no_image;
if (GST_BUFFER_SIZE (xvimagesink->xvimage) < GST_BUFFER_SIZE (buf)) { if (gst_buffer_get_size (xvimagesink->xvimage) <
meta = GST_META_XVIMAGE_GET (xvimagesink->xvimage); gst_buffer_get_size (buf))
goto wrong_size;
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
("Failed to create output image buffer of %dx%d pixels",
meta->width, meta->height),
("XServer allocated buffer size did not match input buffer"));
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimagesink->xvimage);
xvimagesink->xvimage = NULL;
goto no_image;
}
} }
memcpy (GST_BUFFER_DATA (xvimagesink->xvimage), data = gst_buffer_map (xvimagesink->xvimage, &size, NULL, GST_MAP_WRITE);
GST_BUFFER_DATA (buf), gst_buffer_extract (buf, 0, data, size);
MIN (GST_BUFFER_SIZE (buf), GST_BUFFER_SIZE (xvimagesink->xvimage))); gst_buffer_unmap (xvimagesink->xvimage, data, size);
if (!gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage)) if (!gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage))
goto no_window; goto no_window;
@ -2396,6 +2392,19 @@ no_window:
GST_WARNING_OBJECT (xvimagesink, "could not output image - no window"); GST_WARNING_OBJECT (xvimagesink, "could not output image - no window");
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
wrong_size:
{
meta = GST_META_XVIMAGE_GET (xvimagesink->xvimage);
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
("Failed to create output image buffer of %dx%d pixels",
meta->width, meta->height),
("XServer allocated buffer size did not match input buffer"));
gst_xvimagesink_xvimage_destroy (xvimagesink, xvimagesink->xvimage);
xvimagesink->xvimage = NULL;
goto no_image;
}
} }
static gboolean static gboolean