mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
plugins: fix for new memory API
This commit is contained in:
parent
3b03e23559
commit
5244770775
10 changed files with 138 additions and 108 deletions
|
@ -400,7 +400,7 @@ gst_cd_paranoia_src_read_sector (GstCddaBaseSrc * cddabasesrc, gint sector)
|
|||
goto read_failed;
|
||||
|
||||
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. */
|
||||
++src->next_sector;
|
||||
|
|
|
@ -267,26 +267,32 @@ gst_gio_base_sink_render (GstBaseSink * base_sink, GstBuffer * buffer)
|
|||
{
|
||||
GstGioBaseSink *sink = GST_GIO_BASE_SINK (base_sink);
|
||||
gssize written;
|
||||
guint8 *data;
|
||||
gsize size;
|
||||
gboolean success;
|
||||
GError *err = NULL;
|
||||
|
||||
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,
|
||||
GST_BUFFER_SIZE (buffer), sink->position);
|
||||
data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
|
||||
|
||||
written = g_output_stream_write (sink->stream,
|
||||
GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), sink->cancel, &err);
|
||||
GST_LOG_OBJECT (sink,
|
||||
"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);
|
||||
|
||||
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
|
||||
* doesn't... */
|
||||
GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
|
||||
("Could not write to stream: (short write, only %"
|
||||
G_GSSIZE_FORMAT " bytes of %d bytes written)",
|
||||
written, GST_BUFFER_SIZE (buffer)));
|
||||
G_GSSIZE_FORMAT " bytes of %" G_GSIZE_FORMAT " bytes written)",
|
||||
written, size));
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -332,9 +332,9 @@ gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
|
|||
|
||||
GST_BUFFER_OFFSET (buf) = offset;
|
||||
GST_BUFFER_OFFSET_END (buf) = offset + size;
|
||||
GST_BUFFER_SIZE (buf) = size;
|
||||
} else {
|
||||
guint cachesize = MAX (4096, size);
|
||||
guint8 *bdata;
|
||||
gssize read, res;
|
||||
gboolean success, eos;
|
||||
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
|
||||
* at least the requested amount of bytes or a read returns
|
||||
* nothing. */
|
||||
bdata = gst_buffer_map (src->cache, NULL, NULL, GST_MAP_WRITE);
|
||||
read = 0;
|
||||
while (size - read > 0 && (res =
|
||||
g_input_stream_read (G_INPUT_STREAM (src->stream),
|
||||
GST_BUFFER_DATA (src->cache) + read, cachesize - read,
|
||||
src->cancel, &err)) > 0) {
|
||||
bdata + read, cachesize - read, src->cancel, &err)) > 0) {
|
||||
read += res;
|
||||
}
|
||||
gst_buffer_unmap (src->cache, bdata, read);
|
||||
|
||||
success = (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) {
|
||||
src->position += read;
|
||||
GST_BUFFER_SIZE (src->cache) = read;
|
||||
|
||||
GST_BUFFER_OFFSET (src->cache) = offset;
|
||||
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_END (buf) = offset + MIN (size, read);
|
||||
GST_BUFFER_SIZE (buf) = MIN (size, read);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (src, "Read not successful");
|
||||
gst_buffer_unref (src->cache);
|
||||
|
|
|
@ -523,6 +523,8 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
|
|||
GstGnomeVFSSink *sink;
|
||||
GnomeVFSResult result;
|
||||
GstFlowReturn ret;
|
||||
guint8 *data;
|
||||
gsize size;
|
||||
|
||||
sink = GST_GNOME_VFS_SINK (basesink);
|
||||
|
||||
|
@ -531,22 +533,22 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
|
|||
sink->current_pos = cur_pos;
|
||||
}
|
||||
|
||||
result = gnome_vfs_write (sink->handle, GST_BUFFER_DATA (buf),
|
||||
GST_BUFFER_SIZE (buf), &written);
|
||||
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||
result = gnome_vfs_write (sink->handle, data, size, &written);
|
||||
gst_buffer_unmap (buf, data, size);
|
||||
|
||||
switch (result) {
|
||||
case GNOME_VFS_OK:{
|
||||
GST_DEBUG_OBJECT (sink, "wrote %" G_GINT64_FORMAT " bytes at %"
|
||||
G_GINT64_FORMAT, (gint64) written, (gint64) cur_pos);
|
||||
|
||||
if (written < GST_BUFFER_SIZE (buf)) {
|
||||
if (written < size) {
|
||||
/* FIXME: what to do here? (tpm) */
|
||||
g_warning ("%s: %d bytes should be written, only %"
|
||||
G_GUINT64_FORMAT " bytes written", G_STRLOC,
|
||||
GST_BUFFER_SIZE (buf), written);
|
||||
g_warning ("%s: %" G_GSIZE_FORMAT " bytes should be written, only %"
|
||||
G_GUINT64_FORMAT " bytes written", G_STRLOC, size, written);
|
||||
}
|
||||
|
||||
sink->current_pos += GST_BUFFER_SIZE (buf);
|
||||
sink->current_pos += size;
|
||||
ret = GST_FLOW_OK;
|
||||
break;
|
||||
}
|
||||
|
@ -554,7 +556,7 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
|
|||
/* TODO: emit signal/send msg on out-of-diskspace and
|
||||
* handle this gracefully (see open bug) (tpm) */
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -565,7 +567,7 @@ gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
|
|||
GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
|
||||
(_("Error while writing to file \"%s\"."), filename),
|
||||
("%s, bufsize=%u, written=%u", gnome_vfs_result_to_string (result),
|
||||
GST_BUFFER_SIZE (buf), (guint) written));
|
||||
size, (guint) written));
|
||||
|
||||
g_free (filename);
|
||||
ret = GST_FLOW_ERROR;
|
||||
|
|
|
@ -601,8 +601,8 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
|
|||
GnomeVFSResult res;
|
||||
GstBuffer *buf;
|
||||
GnomeVFSFileSize readbytes;
|
||||
guint8 *data;
|
||||
guint todo;
|
||||
guint8 *data, *ptr;
|
||||
gsize todo;
|
||||
GstGnomeVFSSrc *src;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
data = GST_BUFFER_DATA (buf);
|
||||
data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
|
||||
|
||||
ptr = data;
|
||||
todo = size;
|
||||
while (todo > 0) {
|
||||
/* 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
|
||||
&& readbytes == 0)))
|
||||
|
@ -645,13 +646,15 @@ gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
|
|||
goto read_failed;
|
||||
|
||||
if (readbytes < todo) {
|
||||
data = &data[readbytes];
|
||||
ptr += readbytes;
|
||||
todo -= readbytes;
|
||||
} else {
|
||||
todo = 0;
|
||||
}
|
||||
GST_LOG (" got size %" G_GUINT64_FORMAT, readbytes);
|
||||
}
|
||||
gst_buffer_unmap (buf, data, size);
|
||||
|
||||
GST_BUFFER_OFFSET (buf) = src->curoffset;
|
||||
src->curoffset += size;
|
||||
|
||||
|
@ -676,6 +679,7 @@ cannot_seek:
|
|||
}
|
||||
read_failed:
|
||||
{
|
||||
gst_buffer_unmap (buf, data, size);
|
||||
gst_buffer_unref (buf);
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
|
||||
("Failed to read data: %s", gnome_vfs_result_to_string (res)));
|
||||
|
@ -683,6 +687,7 @@ read_failed:
|
|||
}
|
||||
eos:
|
||||
{
|
||||
gst_buffer_unmap (buf, data, size);
|
||||
gst_buffer_unref (buf);
|
||||
GST_DEBUG_OBJECT (src, "Reading data gave EOS");
|
||||
return GST_FLOW_UNEXPECTED;
|
||||
|
|
|
@ -642,7 +642,8 @@ gst_visual_chain (GstPad * pad, GstBuffer * buffer)
|
|||
|
||||
GST_DEBUG_OBJECT (visual,
|
||||
"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);
|
||||
|
||||
|
@ -828,8 +829,8 @@ gst_visual_change_state (GstElement * element, GstStateChange transition)
|
|||
switch (transition) {
|
||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
visual->actor =
|
||||
visual_actor_new (GST_VISUAL_GET_CLASS (visual)->plugin->info->
|
||||
plugname);
|
||||
visual_actor_new (GST_VISUAL_GET_CLASS (visual)->plugin->
|
||||
info->plugname);
|
||||
visual->video = visual_video_new ();
|
||||
visual->audio = visual_audio_new ();
|
||||
/* can't have a play without actors */
|
||||
|
|
|
@ -657,6 +657,7 @@ gst_meta_v4lsrc_get_info (void)
|
|||
sizeof (GstMetaV4lSrc),
|
||||
(GstMetaInitFunction) NULL,
|
||||
(GstMetaFreeFunction) meta_v4lsrc_free,
|
||||
(GstMetaCopyFunction) NULL,
|
||||
(GstMetaTransformFunction) NULL,
|
||||
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
||||
}
|
||||
|
@ -686,9 +687,11 @@ gst_v4lsrc_buffer_new (GstV4lSrc * v4lsrc, gint num)
|
|||
meta->num = num;
|
||||
meta->v4lsrc = gst_object_ref (v4lsrc);
|
||||
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
|
||||
GST_BUFFER_DATA (buf) = gst_v4lsrc_get_buffer (v4lsrc, num);
|
||||
GST_BUFFER_SIZE (buf) = v4lsrc->buffer_size;
|
||||
gst_buffer_take_memory (buf,
|
||||
gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
|
||||
gst_v4lsrc_get_buffer (v4lsrc, num), NULL, v4lsrc->buffer_size,
|
||||
0, v4lsrc->buffer_size));
|
||||
|
||||
GST_BUFFER_OFFSET (buf) = v4lsrc->offset++;
|
||||
GST_BUFFER_OFFSET_END (buf) = v4lsrc->offset;
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ gst_meta_ximage_get_info (void)
|
|||
sizeof (GstMetaXImage),
|
||||
(GstMetaInitFunction) NULL,
|
||||
(GstMetaFreeFunction) gst_meta_ximage_free,
|
||||
(GstMetaCopyFunction) NULL,
|
||||
(GstMetaTransformFunction) NULL,
|
||||
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
||||
}
|
||||
|
@ -173,8 +174,9 @@ gst_buffer_add_meta_ximage (GstBuffer * buffer, GstXImageSink * ximagesink,
|
|||
error_caught = FALSE;
|
||||
XSetErrorHandler (handler);
|
||||
|
||||
GST_BUFFER_DATA (buffer) = (guchar *) meta->ximage->data;
|
||||
GST_BUFFER_SIZE (buffer) = meta->size;
|
||||
gst_buffer_take_memory (buffer,
|
||||
gst_memory_new_wrapped (0, meta->ximage->data, NULL,
|
||||
meta->size, 0, meta->size));
|
||||
|
||||
g_mutex_unlock (ximagesink->x_lock);
|
||||
|
||||
|
|
|
@ -1219,6 +1219,8 @@ gst_ximagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
|||
res = GST_FLOW_OK;
|
||||
} else {
|
||||
GstBuffer *temp;
|
||||
guint8 *data;
|
||||
gsize size;
|
||||
|
||||
/* Else we have to copy the data into our private image, */
|
||||
/* if we have one... */
|
||||
|
@ -1233,11 +1235,12 @@ gst_ximagesink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
|||
if (res != GST_FLOW_OK)
|
||||
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;
|
||||
|
||||
memcpy (GST_BUFFER_DATA (temp), GST_BUFFER_DATA (buf),
|
||||
MIN (GST_BUFFER_SIZE (temp), GST_BUFFER_SIZE (buf)));
|
||||
data = gst_buffer_map (temp, &size, NULL, GST_MAP_WRITE);
|
||||
gst_buffer_extract (buf, 0, data, size);
|
||||
gst_buffer_unmap (temp, data, size);
|
||||
|
||||
buf = temp;
|
||||
}
|
||||
|
|
|
@ -208,6 +208,7 @@ gst_meta_xvimage_get_info (void)
|
|||
sizeof (GstMetaXvImage),
|
||||
(GstMetaInitFunction) NULL,
|
||||
(GstMetaFreeFunction) NULL,
|
||||
(GstMetaCopyFunction) NULL,
|
||||
(GstMetaTransformFunction) NULL,
|
||||
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
||||
}
|
||||
|
@ -401,7 +402,7 @@ static GstBuffer *
|
|||
gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
||||
{
|
||||
GstBuffer *buffer = NULL;
|
||||
GstMetaXvImage *data = NULL;
|
||||
GstMetaXvImage *meta = NULL;
|
||||
GstStructure *structure = NULL;
|
||||
gboolean succeeded = FALSE;
|
||||
int (*handler) (Display *, XErrorEvent *);
|
||||
|
@ -416,31 +417,31 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
|||
GST_MINI_OBJECT_CAST (buffer)->dispose =
|
||||
(GstMiniObjectDisposeFunction) gst_xvimage_buffer_dispose;
|
||||
|
||||
data = GST_META_XVIMAGE_ADD (buffer);
|
||||
meta = GST_META_XVIMAGE_ADD (buffer);
|
||||
#ifdef HAVE_XSHM
|
||||
data->SHMInfo.shmaddr = ((void *) -1);
|
||||
data->SHMInfo.shmid = -1;
|
||||
meta->SHMInfo.shmaddr = ((void *) -1);
|
||||
meta->SHMInfo.shmid = -1;
|
||||
#endif
|
||||
|
||||
structure = gst_caps_get_structure (caps, 0);
|
||||
|
||||
if (!gst_structure_get_int (structure, "width", &data->width) ||
|
||||
!gst_structure_get_int (structure, "height", &data->height)) {
|
||||
if (!gst_structure_get_int (structure, "width", &meta->width) ||
|
||||
!gst_structure_get_int (structure, "height", &meta->height)) {
|
||||
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);
|
||||
if (data->im_format == -1) {
|
||||
meta->im_format = gst_xvimagesink_get_format_from_caps (xvimagesink, caps);
|
||||
if (meta->im_format == -1) {
|
||||
GST_WARNING_OBJECT (xvimagesink, "failed to get format from caps %"
|
||||
GST_PTR_FORMAT, caps);
|
||||
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
|
||||
("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;
|
||||
}
|
||||
data->xvimagesink = gst_object_ref (xvimagesink);
|
||||
meta->xvimagesink = gst_object_ref (xvimagesink);
|
||||
|
||||
g_mutex_lock (xvimagesink->x_lock);
|
||||
|
||||
|
@ -452,10 +453,10 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
|||
if (xvimagesink->xcontext->use_xshm) {
|
||||
int expected_size;
|
||||
|
||||
data->xvimage = XvShmCreateImage (xvimagesink->xcontext->disp,
|
||||
meta->xvimage = XvShmCreateImage (xvimagesink->xcontext->disp,
|
||||
xvimagesink->xcontext->xv_port_id,
|
||||
data->im_format, NULL, data->width, data->height, &data->SHMInfo);
|
||||
if (!data->xvimage || error_caught) {
|
||||
meta->im_format, NULL, meta->width, meta->height, &meta->SHMInfo);
|
||||
if (!meta->xvimage || error_caught) {
|
||||
g_mutex_unlock (xvimagesink->x_lock);
|
||||
/* Reset error handler */
|
||||
error_caught = FALSE;
|
||||
|
@ -463,20 +464,20 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
|||
/* Push an error */
|
||||
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
|
||||
("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",
|
||||
data->width, data->height));
|
||||
meta->width, meta->height));
|
||||
goto beach_unlocked;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
data->size);
|
||||
meta->size);
|
||||
|
||||
/* calculate the expected size. This is only for sanity checking the
|
||||
* 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 ('Y', 'V', '1', '2'):
|
||||
{
|
||||
|
@ -485,17 +486,17 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
|||
guint plane;
|
||||
|
||||
offsets[0] = 0;
|
||||
pitches[0] = GST_ROUND_UP_4 (data->width);
|
||||
offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (data->height);
|
||||
pitches[1] = GST_ROUND_UP_8 (data->width) / 2;
|
||||
pitches[0] = GST_ROUND_UP_4 (meta->width);
|
||||
offsets[1] = offsets[0] + pitches[0] * GST_ROUND_UP_2 (meta->height);
|
||||
pitches[1] = GST_ROUND_UP_8 (meta->width) / 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;
|
||||
|
||||
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,
|
||||
"Plane %u has a expected pitch of %d bytes, " "offset of %d",
|
||||
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 ('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;
|
||||
default:
|
||||
expected_size = 0;
|
||||
break;
|
||||
}
|
||||
if (expected_size != 0 && data->size != expected_size) {
|
||||
if (expected_size != 0 && meta->size != expected_size) {
|
||||
GST_WARNING_OBJECT (xvimagesink,
|
||||
"unexpected XShm image size (got %" G_GSIZE_FORMAT ", expected %d)",
|
||||
data->size, expected_size);
|
||||
meta->size, expected_size);
|
||||
}
|
||||
|
||||
/* Be verbose about our XvImage stride */
|
||||
{
|
||||
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, "
|
||||
"offset of %d", plane, data->xvimage->pitches[plane],
|
||||
data->xvimage->offsets[plane]);
|
||||
"offset of %d", plane, meta->xvimage->pitches[plane],
|
||||
meta->xvimage->offsets[plane]);
|
||||
}
|
||||
}
|
||||
|
||||
data->SHMInfo.shmid = shmget (IPC_PRIVATE, data->size, IPC_CREAT | 0777);
|
||||
if (data->SHMInfo.shmid == -1) {
|
||||
meta->SHMInfo.shmid = shmget (IPC_PRIVATE, meta->size, IPC_CREAT | 0777);
|
||||
if (meta->SHMInfo.shmid == -1) {
|
||||
g_mutex_unlock (xvimagesink->x_lock);
|
||||
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
|
||||
("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",
|
||||
data->size));
|
||||
meta->size));
|
||||
goto beach_unlocked;
|
||||
}
|
||||
|
||||
data->SHMInfo.shmaddr = shmat (data->SHMInfo.shmid, NULL, 0);
|
||||
if (data->SHMInfo.shmaddr == ((void *) -1)) {
|
||||
meta->SHMInfo.shmaddr = shmat (meta->SHMInfo.shmid, NULL, 0);
|
||||
if (meta->SHMInfo.shmaddr == ((void *) -1)) {
|
||||
g_mutex_unlock (xvimagesink->x_lock);
|
||||
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
|
||||
("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)));
|
||||
/* Clean up the shared memory segment */
|
||||
shmctl (data->SHMInfo.shmid, IPC_RMID, NULL);
|
||||
shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
|
||||
goto beach_unlocked;
|
||||
}
|
||||
|
||||
data->xvimage->data = data->SHMInfo.shmaddr;
|
||||
data->SHMInfo.readOnly = FALSE;
|
||||
meta->xvimage->data = meta->SHMInfo.shmaddr;
|
||||
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 */
|
||||
shmctl (data->SHMInfo.shmid, IPC_RMID, NULL);
|
||||
shmctl (meta->SHMInfo.shmid, IPC_RMID, NULL);
|
||||
|
||||
g_mutex_unlock (xvimagesink->x_lock);
|
||||
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
|
||||
("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;
|
||||
}
|
||||
|
||||
|
@ -569,17 +570,17 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
|||
/* 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
|
||||
* 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",
|
||||
data->SHMInfo.shmid, data->SHMInfo.shmseg);
|
||||
meta->SHMInfo.shmid, meta->SHMInfo.shmseg);
|
||||
} else
|
||||
#endif /* HAVE_XSHM */
|
||||
{
|
||||
data->xvimage = XvCreateImage (xvimagesink->xcontext->disp,
|
||||
meta->xvimage = XvCreateImage (xvimagesink->xcontext->disp,
|
||||
xvimagesink->xcontext->xv_port_id,
|
||||
data->im_format, NULL, data->width, data->height);
|
||||
if (!data->xvimage || error_caught) {
|
||||
meta->im_format, NULL, meta->width, meta->height);
|
||||
if (!meta->xvimage || error_caught) {
|
||||
g_mutex_unlock (xvimagesink->x_lock);
|
||||
/* Reset error handler */
|
||||
error_caught = FALSE;
|
||||
|
@ -587,14 +588,14 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
|||
/* Push an error */
|
||||
GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
|
||||
("Failed to create outputimage buffer of %dx%d pixels",
|
||||
data->width, data->height),
|
||||
("could not XvCreateImage a %dx%d image", data->width, data->height));
|
||||
meta->width, meta->height),
|
||||
("could not XvCreateImage a %dx%d image", meta->width, meta->height));
|
||||
goto beach_unlocked;
|
||||
}
|
||||
|
||||
/* we have to use the returned data_size for our image size */
|
||||
data->size = data->xvimage->data_size;
|
||||
data->xvimage->data = g_malloc (data->size);
|
||||
meta->size = meta->xvimage->data_size;
|
||||
meta->xvimage->data = g_malloc (meta->size);
|
||||
|
||||
XSync (xvimagesink->xcontext->disp, FALSE);
|
||||
}
|
||||
|
@ -605,8 +606,9 @@ gst_xvimagesink_xvimage_new (GstXvImageSink * xvimagesink, GstCaps * caps)
|
|||
|
||||
succeeded = TRUE;
|
||||
|
||||
GST_BUFFER_DATA (buffer) = (guchar *) data->xvimage->data;
|
||||
GST_BUFFER_SIZE (buffer) = data->size;
|
||||
gst_buffer_take_memory (buffer,
|
||||
gst_memory_new_wrapped (0, meta->xvimage->data, NULL,
|
||||
meta->size, 0, meta->size));
|
||||
|
||||
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))
|
||||
goto no_window;
|
||||
} else {
|
||||
guint8 *data;
|
||||
gsize size;
|
||||
|
||||
GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, xvimagesink,
|
||||
"slow copy into bufferpool buffer %p", buf);
|
||||
/* 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 */
|
||||
goto no_image;
|
||||
|
||||
if (GST_BUFFER_SIZE (xvimagesink->xvimage) < GST_BUFFER_SIZE (buf)) {
|
||||
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;
|
||||
}
|
||||
if (gst_buffer_get_size (xvimagesink->xvimage) <
|
||||
gst_buffer_get_size (buf))
|
||||
goto wrong_size;
|
||||
}
|
||||
|
||||
memcpy (GST_BUFFER_DATA (xvimagesink->xvimage),
|
||||
GST_BUFFER_DATA (buf),
|
||||
MIN (GST_BUFFER_SIZE (buf), GST_BUFFER_SIZE (xvimagesink->xvimage)));
|
||||
data = gst_buffer_map (xvimagesink->xvimage, &size, NULL, GST_MAP_WRITE);
|
||||
gst_buffer_extract (buf, 0, data, size);
|
||||
gst_buffer_unmap (xvimagesink->xvimage, data, size);
|
||||
|
||||
if (!gst_xvimagesink_xvimage_put (xvimagesink, xvimagesink->xvimage))
|
||||
goto no_window;
|
||||
|
@ -2396,6 +2392,19 @@ no_window:
|
|||
GST_WARNING_OBJECT (xvimagesink, "could not output image - no window");
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue