mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-08 16:35:40 +00:00
omxbufferpool: Copy buffers if the stride does not match and we can't use video meta
https://bugzilla.gnome.org/show_bug.cgi?id=731672
This commit is contained in:
parent
b9238195dd
commit
4593f434a0
3 changed files with 95 additions and 29 deletions
|
@ -380,46 +380,73 @@ gst_omx_buffer_pool_alloc_buffer (GstBufferPool * bpool,
|
|||
GST_VIDEO_INFO_HEIGHT (&pool->video_info));
|
||||
}
|
||||
}
|
||||
|
||||
pool->need_copy = FALSE;
|
||||
} else {
|
||||
GstMemory *mem;
|
||||
const guint nstride = pool->port->port_def.format.video.nStride;
|
||||
const guint nslice = pool->port->port_def.format.video.nSliceHeight;
|
||||
gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
|
||||
gint stride[GST_VIDEO_MAX_PLANES] = { nstride, 0, };
|
||||
|
||||
mem = gst_omx_memory_allocator_alloc (pool->allocator, 0, omx_buf);
|
||||
buf = gst_buffer_new ();
|
||||
gst_buffer_append_memory (buf, mem);
|
||||
g_ptr_array_add (pool->buffers, buf);
|
||||
|
||||
if (pool->add_videometa) {
|
||||
const guint nstride = pool->port->port_def.format.video.nStride;
|
||||
const guint nslice = pool->port->port_def.format.video.nSliceHeight;
|
||||
gsize offset[GST_VIDEO_MAX_PLANES] = { 0, };
|
||||
gint stride[GST_VIDEO_MAX_PLANES] = { nstride, 0, };
|
||||
switch (GST_VIDEO_INFO_FORMAT (&pool->video_info)) {
|
||||
case GST_VIDEO_FORMAT_ABGR:
|
||||
case GST_VIDEO_FORMAT_ARGB:
|
||||
case GST_VIDEO_FORMAT_RGB16:
|
||||
case GST_VIDEO_FORMAT_BGR16:
|
||||
case GST_VIDEO_FORMAT_YUY2:
|
||||
case GST_VIDEO_FORMAT_UYVY:
|
||||
case GST_VIDEO_FORMAT_YVYU:
|
||||
case GST_VIDEO_FORMAT_GRAY8:
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_I420:
|
||||
stride[1] = nstride / 2;
|
||||
offset[1] = offset[0] + stride[0] * nslice;
|
||||
stride[2] = nstride / 2;
|
||||
offset[2] = offset[1] + (stride[1] * nslice / 2);
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_NV12:
|
||||
case GST_VIDEO_FORMAT_NV16:
|
||||
stride[1] = nstride;
|
||||
offset[1] = offset[0] + stride[0] * nslice;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
switch (GST_VIDEO_INFO_FORMAT (&pool->video_info)) {
|
||||
case GST_VIDEO_FORMAT_ABGR:
|
||||
case GST_VIDEO_FORMAT_ARGB:
|
||||
case GST_VIDEO_FORMAT_RGB16:
|
||||
case GST_VIDEO_FORMAT_BGR16:
|
||||
case GST_VIDEO_FORMAT_YUY2:
|
||||
case GST_VIDEO_FORMAT_UYVY:
|
||||
case GST_VIDEO_FORMAT_YVYU:
|
||||
case GST_VIDEO_FORMAT_GRAY8:
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_I420:
|
||||
stride[1] = nstride / 2;
|
||||
offset[1] = offset[0] + stride[0] * nslice;
|
||||
stride[2] = nstride / 2;
|
||||
offset[2] = offset[1] + (stride[1] * nslice / 2);
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_NV12:
|
||||
case GST_VIDEO_FORMAT_NV16:
|
||||
stride[1] = nstride;
|
||||
offset[1] = offset[0] + stride[0] * nslice;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
if (pool->add_videometa) {
|
||||
pool->need_copy = FALSE;
|
||||
} else {
|
||||
GstVideoInfo info;
|
||||
gboolean need_copy = FALSE;
|
||||
gint i;
|
||||
|
||||
gst_video_info_init (&info);
|
||||
gst_video_info_set_format (&info,
|
||||
GST_VIDEO_INFO_FORMAT (&pool->video_info),
|
||||
GST_VIDEO_INFO_WIDTH (&pool->video_info),
|
||||
GST_VIDEO_INFO_HEIGHT (&pool->video_info));
|
||||
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&pool->video_info); i++) {
|
||||
if (info.stride[i] != stride[i] || info.offset[i] != offset[i]) {
|
||||
need_copy = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pool->need_copy = need_copy;
|
||||
}
|
||||
|
||||
if (pool->need_copy || pool->add_videometa) {
|
||||
/* We always add the videometa. It's the job of the user
|
||||
* to copy the buffer if pool->need_copy is TRUE
|
||||
*/
|
||||
gst_buffer_add_video_meta_full (buf, GST_VIDEO_FRAME_FLAG_NONE,
|
||||
GST_VIDEO_INFO_FORMAT (&pool->video_info),
|
||||
GST_VIDEO_INFO_WIDTH (&pool->video_info),
|
||||
|
|
|
@ -51,6 +51,7 @@ struct _GstOMXBufferPool
|
|||
|
||||
GstCaps *caps;
|
||||
gboolean add_videometa;
|
||||
gboolean need_copy;
|
||||
GstVideoInfo video_info;
|
||||
|
||||
/* Owned by element, element has to stop this pool before
|
||||
|
|
|
@ -1214,6 +1214,29 @@ gst_omx_video_dec_clean_older_frames (GstOMXVideoDec * self,
|
|||
g_list_free (frames);
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
copy_frame (const GstVideoInfo * info, GstBuffer * outbuf)
|
||||
{
|
||||
GstVideoInfo out_info, tmp_info;
|
||||
GstBuffer *tmpbuf;
|
||||
GstVideoFrame out_frame, tmp_frame;
|
||||
|
||||
out_info = *info;
|
||||
tmp_info = *info;
|
||||
|
||||
tmpbuf = gst_buffer_new_and_alloc (out_info.size);
|
||||
|
||||
gst_video_frame_map (&out_frame, &out_info, outbuf, GST_MAP_READ);
|
||||
gst_video_frame_map (&tmp_frame, &tmp_info, tmpbuf, GST_MAP_WRITE);
|
||||
gst_video_frame_copy (&tmp_frame, &out_frame);
|
||||
gst_video_frame_unmap (&out_frame);
|
||||
gst_video_frame_unmap (&tmp_frame);
|
||||
|
||||
gst_buffer_unref (outbuf);
|
||||
|
||||
return tmpbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_omx_video_dec_loop (GstOMXVideoDec * self)
|
||||
{
|
||||
|
@ -1392,6 +1415,12 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
|
|||
gst_omx_port_release_buffer (port, buf);
|
||||
goto invalid_buffer;
|
||||
}
|
||||
|
||||
if (GST_OMX_BUFFER_POOL (self->out_port_pool)->need_copy)
|
||||
outbuf =
|
||||
copy_frame (&GST_OMX_BUFFER_POOL (self->out_port_pool)->video_info,
|
||||
outbuf);
|
||||
|
||||
buf = NULL;
|
||||
} else {
|
||||
outbuf =
|
||||
|
@ -1407,6 +1436,7 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
|
|||
} else if (buf->omx_buf->nFilledLen > 0 || buf->eglimage) {
|
||||
if (self->out_port_pool) {
|
||||
gint i, n;
|
||||
GstBuffer *outbuf;
|
||||
GstBufferPoolAcquireParams params = { 0, };
|
||||
|
||||
n = port->buffers->len;
|
||||
|
@ -1421,7 +1451,7 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
|
|||
GST_OMX_BUFFER_POOL (self->out_port_pool)->current_buffer_index = i;
|
||||
flow_ret =
|
||||
gst_buffer_pool_acquire_buffer (self->out_port_pool,
|
||||
&frame->output_buffer, ¶ms);
|
||||
&outbuf, ¶ms);
|
||||
if (flow_ret != GST_FLOW_OK) {
|
||||
flow_ret =
|
||||
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
|
||||
|
@ -1429,6 +1459,14 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
|
|||
gst_omx_port_release_buffer (port, buf);
|
||||
goto invalid_buffer;
|
||||
}
|
||||
|
||||
if (GST_OMX_BUFFER_POOL (self->out_port_pool)->need_copy)
|
||||
outbuf =
|
||||
copy_frame (&GST_OMX_BUFFER_POOL (self->out_port_pool)->video_info,
|
||||
outbuf);
|
||||
|
||||
frame->output_buffer = outbuf;
|
||||
|
||||
flow_ret =
|
||||
gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
|
||||
frame = NULL;
|
||||
|
|
Loading…
Reference in a new issue