mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
gl: Add support for multiple views in upload, colour convert and download
Support multiple attached views on input/output buffers by processing each one, not just the first.
This commit is contained in:
parent
1f7025c585
commit
8a1fc4ab4e
5 changed files with 276 additions and 102 deletions
|
@ -614,6 +614,9 @@ _gst_gl_color_convert_set_caps_unlocked (GstGLColorConvert * convert,
|
|||
g_return_val_if_fail (in_caps, FALSE);
|
||||
g_return_val_if_fail (out_caps, FALSE);
|
||||
|
||||
GST_LOG_OBJECT (convert, "Setting caps in %" GST_PTR_FORMAT
|
||||
" out %" GST_PTR_FORMAT, in_caps, out_caps);
|
||||
|
||||
if (!gst_video_info_from_caps (&in_info, in_caps))
|
||||
g_assert_not_reached ();
|
||||
|
||||
|
@ -1507,38 +1510,27 @@ _init_convert_fbo (GstGLColorConvert * convert)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Called by the idle function in the gl thread */
|
||||
void
|
||||
_do_convert (GstGLContext * context, GstGLColorConvert * convert)
|
||||
static gboolean
|
||||
_do_convert_one_view (GstGLContext * context, GstGLColorConvert * convert,
|
||||
guint view_num)
|
||||
{
|
||||
guint in_width, in_height, out_width, out_height;
|
||||
struct ConvertInfo *c_info = &convert->priv->convert_info;
|
||||
GstMapInfo out_info[GST_VIDEO_MAX_PLANES], in_info[GST_VIDEO_MAX_PLANES];
|
||||
gboolean res = TRUE;
|
||||
gint i, j = 0;
|
||||
const gint in_plane_offset = view_num * c_info->in_n_textures;
|
||||
const gint out_plane_offset = view_num * c_info->out_n_textures;
|
||||
|
||||
out_width = GST_VIDEO_INFO_WIDTH (&convert->out_info);
|
||||
out_height = GST_VIDEO_INFO_HEIGHT (&convert->out_info);
|
||||
in_width = GST_VIDEO_INFO_WIDTH (&convert->in_info);
|
||||
in_height = GST_VIDEO_INFO_HEIGHT (&convert->in_info);
|
||||
|
||||
convert->outbuf = NULL;
|
||||
|
||||
if (!_init_convert (convert)) {
|
||||
convert->priv->result = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
convert->outbuf = gst_buffer_new ();
|
||||
if (!gst_gl_memory_setup_buffer (convert->context, NULL, &convert->out_info,
|
||||
NULL, convert->outbuf)) {
|
||||
convert->priv->result = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < c_info->in_n_textures; i++) {
|
||||
convert->priv->in_tex[i] =
|
||||
(GstGLMemory *) gst_buffer_peek_memory (convert->inbuf, i);
|
||||
(GstGLMemory *) gst_buffer_peek_memory (convert->inbuf,
|
||||
i + in_plane_offset);
|
||||
if (!gst_is_gl_memory ((GstMemory *) convert->priv->in_tex[i])) {
|
||||
GST_ERROR_OBJECT (convert, "input must be GstGLMemory");
|
||||
res = FALSE;
|
||||
|
@ -1555,7 +1547,8 @@ _do_convert (GstGLContext * context, GstGLColorConvert * convert)
|
|||
|
||||
for (j = 0; j < c_info->out_n_textures; j++) {
|
||||
GstGLMemory *out_tex =
|
||||
(GstGLMemory *) gst_buffer_peek_memory (convert->outbuf, j);
|
||||
(GstGLMemory *) gst_buffer_peek_memory (convert->outbuf,
|
||||
j + out_plane_offset);
|
||||
gint mem_width, mem_height;
|
||||
|
||||
if (!gst_is_gl_memory ((GstMemory *) out_tex)) {
|
||||
|
@ -1608,7 +1601,8 @@ _do_convert (GstGLContext * context, GstGLColorConvert * convert)
|
|||
out:
|
||||
for (j--; j >= 0; j--) {
|
||||
GstGLMemory *out_tex =
|
||||
(GstGLMemory *) gst_buffer_peek_memory (convert->outbuf, j);
|
||||
(GstGLMemory *) gst_buffer_peek_memory (convert->outbuf,
|
||||
j + out_plane_offset);
|
||||
gint mem_width, mem_height;
|
||||
|
||||
gst_memory_unmap ((GstMemory *) convert->priv->out_tex[j], &out_info[j]);
|
||||
|
@ -1647,17 +1641,54 @@ out:
|
|||
|
||||
/* YV12 the same as I420 except planes 1+2 swapped */
|
||||
if (GST_VIDEO_INFO_FORMAT (&convert->out_info) == GST_VIDEO_FORMAT_YV12) {
|
||||
GstMemory *mem1 = gst_buffer_get_memory (convert->outbuf, 1);
|
||||
GstMemory *mem2 = gst_buffer_get_memory (convert->outbuf, 2);
|
||||
GstMemory *mem1 =
|
||||
gst_buffer_get_memory (convert->outbuf, 1 + out_plane_offset);
|
||||
GstMemory *mem2 =
|
||||
gst_buffer_get_memory (convert->outbuf, 2 + out_plane_offset);
|
||||
|
||||
gst_buffer_replace_memory (convert->outbuf, 1, mem2);
|
||||
gst_buffer_replace_memory (convert->outbuf, 2, mem1);
|
||||
gst_buffer_replace_memory (convert->outbuf, 1 + out_plane_offset, mem2);
|
||||
gst_buffer_replace_memory (convert->outbuf, 2 + out_plane_offset, mem1);
|
||||
}
|
||||
|
||||
for (i--; i >= 0; i--) {
|
||||
gst_memory_unmap ((GstMemory *) convert->priv->in_tex[i], &in_info[i]);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Called by the idle function in the gl thread */
|
||||
void
|
||||
_do_convert (GstGLContext * context, GstGLColorConvert * convert)
|
||||
{
|
||||
GstVideoInfo *in_info = &convert->in_info;
|
||||
gboolean res = TRUE;
|
||||
gint views, v;
|
||||
|
||||
convert->outbuf = NULL;
|
||||
|
||||
if (!_init_convert (convert)) {
|
||||
convert->priv->result = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
convert->outbuf = gst_buffer_new ();
|
||||
if (!gst_gl_memory_setup_buffer (convert->context, NULL, &convert->out_info,
|
||||
NULL, convert->outbuf)) {
|
||||
convert->priv->result = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (GST_VIDEO_INFO_MULTIVIEW_MODE (in_info) ==
|
||||
GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
|
||||
views = GST_VIDEO_INFO_VIEWS (in_info);
|
||||
else
|
||||
views = 1;
|
||||
|
||||
/* Handle all views on input and output one at a time */
|
||||
for (v = 0; res && v < views; v++)
|
||||
res = _do_convert_one_view (context, convert, v);
|
||||
|
||||
if (!res) {
|
||||
gst_buffer_unref (convert->outbuf);
|
||||
convert->outbuf = NULL;
|
||||
|
|
|
@ -43,8 +43,7 @@
|
|||
#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
|
||||
#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
|
||||
|
||||
static gboolean _do_download (GstGLDownload * download, guint texture_id,
|
||||
gpointer data[GST_VIDEO_MAX_PLANES]);
|
||||
static gboolean _do_download (GstGLDownload * download, GstBuffer * inbuf);
|
||||
static gboolean _init_download (GstGLDownload * download);
|
||||
static gboolean _gst_gl_download_perform_with_data_unlocked (GstGLDownload *
|
||||
download, GLuint texture_id, GLuint texture_target,
|
||||
|
@ -52,6 +51,9 @@ static gboolean _gst_gl_download_perform_with_data_unlocked (GstGLDownload *
|
|||
static void gst_gl_download_reset (GstGLDownload * download);
|
||||
|
||||
/* *INDENT-ON* */
|
||||
/* Define the maximum number of planes we can handle - max 2 views per buffer */
|
||||
#define GST_GL_DOWNLOAD_MAX_VIEWS 2
|
||||
#define GST_GL_DOWNLOAD_MAX_PLANES (GST_VIDEO_MAX_PLANES * GST_GL_DOWNLOAD_MAX_VIEWS)
|
||||
|
||||
struct _GstGLDownloadPrivate
|
||||
{
|
||||
|
@ -61,7 +63,12 @@ struct _GstGLDownloadPrivate
|
|||
const gchar *ARGB;
|
||||
const gchar *vert_shader;
|
||||
|
||||
GstGLMemory *in_tex[GST_VIDEO_MAX_PLANES];
|
||||
GstBuffer *inbuf;
|
||||
/* Temporary wrapped texture for perform_with_data download */
|
||||
GstGLMemory *in_tex;
|
||||
|
||||
/* Output data planes */
|
||||
gpointer out_data[GST_GL_DOWNLOAD_MAX_PLANES];
|
||||
};
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gst_gl_download_debug);
|
||||
|
@ -138,13 +145,9 @@ gst_gl_download_finalize (GObject * object)
|
|||
static void
|
||||
gst_gl_download_reset (GstGLDownload * download)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
|
||||
if (download->priv->in_tex[i]) {
|
||||
gst_memory_unref ((GstMemory *) download->priv->in_tex[i]);
|
||||
download->priv->in_tex[i] = NULL;
|
||||
}
|
||||
if (download->priv->in_tex) {
|
||||
gst_memory_unref ((GstMemory *) download->priv->in_tex);
|
||||
download->priv->in_tex = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,7 +253,9 @@ gst_gl_download_transform_caps (GstGLContext * context,
|
|||
* @data: (out): where the downloaded data should go
|
||||
*
|
||||
* Downloads @texture_id into @data. @data size and format is specified by
|
||||
* the #GstVideoFormat passed to gst_gl_download_set_format()
|
||||
* the #GstVideoFormat passed to gst_gl_download_set_format()
|
||||
*
|
||||
* This method can only be used for download a single view.
|
||||
*
|
||||
* Returns: whether the download was successful
|
||||
*/
|
||||
|
@ -272,12 +277,16 @@ gst_gl_download_perform_with_data (GstGLDownload * download,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* This method only supports one input texture */
|
||||
static gboolean
|
||||
_gst_gl_download_perform_with_data_unlocked (GstGLDownload * download,
|
||||
GLuint texture_id, GLuint texture_target,
|
||||
gpointer data[GST_VIDEO_MAX_PLANES])
|
||||
{
|
||||
guint i;
|
||||
gboolean res;
|
||||
GstBuffer *inbuf;
|
||||
guint out_width, out_height;
|
||||
|
||||
g_return_val_if_fail (download != NULL, FALSE);
|
||||
g_return_val_if_fail (texture_id > 0, FALSE);
|
||||
|
@ -290,36 +299,54 @@ _gst_gl_download_perform_with_data_unlocked (GstGLDownload * download,
|
|||
g_return_val_if_fail (data[i] != NULL, FALSE);
|
||||
}
|
||||
|
||||
if (!download->priv->in_tex[0]) {
|
||||
if (!download->priv->in_tex) {
|
||||
GstVideoInfo temp_info;
|
||||
|
||||
gst_video_info_set_format (&temp_info, GST_VIDEO_FORMAT_RGBA,
|
||||
GST_VIDEO_INFO_WIDTH (&download->info),
|
||||
GST_VIDEO_INFO_HEIGHT (&download->info));
|
||||
|
||||
download->priv->in_tex[0] =
|
||||
download->priv->in_tex =
|
||||
gst_gl_memory_wrapped_texture (download->context,
|
||||
texture_id, texture_target, &temp_info, 0, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
download->priv->in_tex[0]->tex_id = texture_id;
|
||||
|
||||
return _do_download (download, texture_id, data);
|
||||
out_width = GST_VIDEO_INFO_WIDTH (&download->info);
|
||||
out_height = GST_VIDEO_INFO_HEIGHT (&download->info);
|
||||
|
||||
GST_TRACE ("doing download of texture:%u (%ux%u)",
|
||||
download->priv->in_tex->tex_id, out_width, out_height);
|
||||
|
||||
download->priv->in_tex->tex_id = texture_id;
|
||||
|
||||
inbuf = gst_buffer_new ();
|
||||
gst_buffer_append_memory (inbuf,
|
||||
gst_memory_ref ((GstMemory *) download->priv->in_tex));
|
||||
|
||||
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++)
|
||||
download->priv->out_data[i] = data[i];
|
||||
/* Clear remaining planes for safety */
|
||||
while (i < GST_GL_DOWNLOAD_MAX_PLANES)
|
||||
download->priv->out_data[i++] = NULL;
|
||||
|
||||
res = _do_download (download, inbuf);
|
||||
|
||||
download->priv->inbuf = NULL;
|
||||
gst_buffer_unref (inbuf);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_init_download (GstGLDownload * download)
|
||||
{
|
||||
GstVideoFormat v_format;
|
||||
guint out_width, out_height;
|
||||
GstVideoInfo in_info;
|
||||
GstCaps *in_caps, *out_caps;
|
||||
GstCapsFeatures *in_gl_features, *out_gl_features;
|
||||
GstCapsFeatures *out_gl_features;
|
||||
gboolean res;
|
||||
|
||||
v_format = GST_VIDEO_INFO_FORMAT (&download->info);
|
||||
out_width = GST_VIDEO_INFO_WIDTH (&download->info);
|
||||
out_height = GST_VIDEO_INFO_HEIGHT (&download->info);
|
||||
|
||||
if (download->initted)
|
||||
return TRUE;
|
||||
|
@ -336,18 +363,14 @@ _init_download (GstGLDownload * download)
|
|||
}
|
||||
}
|
||||
|
||||
in_gl_features =
|
||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||
gst_video_info_set_format (&in_info, GST_VIDEO_FORMAT_RGBA, out_width,
|
||||
out_height);
|
||||
in_caps = gst_video_info_to_caps (&in_info);
|
||||
gst_caps_set_features (in_caps, 0, in_gl_features);
|
||||
|
||||
out_gl_features =
|
||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||
out_caps = gst_video_info_to_caps (&download->info);
|
||||
gst_caps_set_features (out_caps, 0, out_gl_features);
|
||||
|
||||
in_caps = gst_caps_copy (out_caps);
|
||||
gst_caps_set_simple (in_caps, "format", G_TYPE_STRING, "RGBA", NULL);
|
||||
|
||||
res = gst_gl_color_convert_set_caps (download->convert, in_caps, out_caps);
|
||||
|
||||
gst_caps_unref (in_caps);
|
||||
|
@ -357,35 +380,38 @@ _init_download (GstGLDownload * download)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
_do_download (GstGLDownload * download, guint texture_id,
|
||||
gpointer data[GST_VIDEO_MAX_PLANES])
|
||||
_do_download (GstGLDownload * download, GstBuffer * inbuf)
|
||||
{
|
||||
guint out_width, out_height;
|
||||
GstBuffer *inbuf, *outbuf;
|
||||
GstBuffer *outbuf;
|
||||
GstMapInfo map_info;
|
||||
gboolean ret = TRUE;
|
||||
gint i;
|
||||
|
||||
out_width = GST_VIDEO_INFO_WIDTH (&download->info);
|
||||
out_height = GST_VIDEO_INFO_HEIGHT (&download->info);
|
||||
GstVideoInfo *info;
|
||||
guint views, out_planes;
|
||||
gpointer *data = download->priv->out_data;
|
||||
|
||||
if (!download->initted) {
|
||||
if (!_init_download (download))
|
||||
if (!_init_download (download)) {
|
||||
GST_DEBUG_OBJECT (download, "Failed to initialise");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
GST_TRACE ("doing download of texture:%u (%ux%u)",
|
||||
download->priv->in_tex[0]->tex_id, out_width, out_height);
|
||||
|
||||
inbuf = gst_buffer_new ();
|
||||
gst_buffer_append_memory (inbuf,
|
||||
gst_memory_ref ((GstMemory *) download->priv->in_tex[0]));
|
||||
|
||||
outbuf = gst_gl_color_convert_perform (download->convert, inbuf);
|
||||
if (!outbuf)
|
||||
if (!outbuf) {
|
||||
GST_DEBUG_OBJECT (download, "Failed to colour convert for output");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&download->info); i++) {
|
||||
info = &download->info;
|
||||
if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) ==
|
||||
GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
|
||||
views = GST_VIDEO_INFO_VIEWS (info);
|
||||
else
|
||||
views = 1;
|
||||
out_planes = GST_VIDEO_INFO_N_PLANES (info) * views;
|
||||
|
||||
for (i = 0; i < out_planes; i++) {
|
||||
GstMemory *out_mem = gst_buffer_peek_memory (outbuf, i);
|
||||
gpointer temp_data = ((GstGLMemory *) out_mem)->data;
|
||||
((GstGLMemory *) out_mem)->data = data[i];
|
||||
|
@ -400,8 +426,80 @@ _do_download (GstGLDownload * download, guint texture_id,
|
|||
((GstGLMemory *) out_mem)->data = temp_data;
|
||||
}
|
||||
|
||||
gst_buffer_unref (inbuf);
|
||||
gst_buffer_unref (outbuf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gst_gl_download_perform_unlocked (GstGLDownload * download,
|
||||
GstBuffer * inbuf, GstBuffer * outbuf)
|
||||
{
|
||||
guint i;
|
||||
gboolean res = FALSE;
|
||||
guint out_width, out_height;
|
||||
GstVideoFrame out_frame;
|
||||
|
||||
g_return_val_if_fail (download != NULL, FALSE);
|
||||
g_return_val_if_fail (GST_VIDEO_INFO_FORMAT (&download->info) !=
|
||||
GST_VIDEO_FORMAT_UNKNOWN
|
||||
&& GST_VIDEO_INFO_FORMAT (&download->info) != GST_VIDEO_FORMAT_ENCODED,
|
||||
FALSE);
|
||||
|
||||
out_width = GST_VIDEO_INFO_WIDTH (&download->info);
|
||||
out_height = GST_VIDEO_INFO_HEIGHT (&download->info);
|
||||
|
||||
GST_TRACE_OBJECT (download, "doing download of buffer %" GST_PTR_FORMAT
|
||||
" (%ux%u)", inbuf, out_width, out_height);
|
||||
|
||||
/* FIXME: Map multiple views */
|
||||
if (!gst_video_frame_map (&out_frame, &download->info, outbuf, GST_MAP_WRITE))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&download->info); i++) {
|
||||
if (out_frame.data[i] == NULL)
|
||||
goto fail;
|
||||
download->priv->out_data[i] = out_frame.data[i];
|
||||
}
|
||||
while (i < GST_GL_DOWNLOAD_MAX_PLANES)
|
||||
download->priv->out_data[i++] = NULL;
|
||||
|
||||
res = _do_download (download, inbuf);
|
||||
|
||||
fail:
|
||||
gst_video_frame_unmap (&out_frame);
|
||||
download->priv->inbuf = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_gl_download_perform:
|
||||
* @download: a #GstGLDownload
|
||||
* @inbuf: (transfer none): a #GstBuffer input buffer
|
||||
* @outbuf: (transfer none) (out): a #GstBuffer output buffer
|
||||
*
|
||||
* Downloads the contents of @inbuf into @outbuf.
|
||||
*
|
||||
* The output buffer contents must match the #GstVideoFormat passed
|
||||
* to gst_gl_download_set_format(), and the input buffer must
|
||||
* contain #GstGLMemory memory items.
|
||||
*
|
||||
* This method supports downloading multiple views.
|
||||
*
|
||||
* Returns: whether the download was successful
|
||||
*/
|
||||
gboolean
|
||||
gst_gl_download_perform (GstGLDownload * download,
|
||||
GstBuffer * inbuf, GstBuffer * outbuf)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
g_return_val_if_fail (download != NULL, FALSE);
|
||||
|
||||
GST_OBJECT_LOCK (download);
|
||||
ret = _gst_gl_download_perform_unlocked (download, inbuf, outbuf);
|
||||
GST_OBJECT_UNLOCK (download);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,8 @@ GstCaps * gst_gl_download_transform_caps (GstGLContext * convert,
|
|||
gboolean gst_gl_download_perform_with_data (GstGLDownload * download,
|
||||
GLuint texture_id, GLuint texture_target,
|
||||
gpointer data[GST_VIDEO_MAX_PLANES]);
|
||||
gboolean gst_gl_download_perform (GstGLDownload * download,
|
||||
GstBuffer *inbuf, GstBuffer *outbuf);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -1422,23 +1422,32 @@ gst_gl_memory_setup_buffer (GstGLContext * context,
|
|||
GstVideoAlignment * valign, GstBuffer * buffer)
|
||||
{
|
||||
GstGLMemory *gl_mem[GST_VIDEO_MAX_PLANES] = { NULL, };
|
||||
guint n_mem, i;
|
||||
guint n_mem, i, v, views;
|
||||
|
||||
n_mem = GST_VIDEO_INFO_N_PLANES (info);
|
||||
|
||||
for (i = 0; i < n_mem; i++) {
|
||||
gl_mem[i] =
|
||||
(GstGLMemory *) gst_gl_memory_alloc (context, params, info, i, valign);
|
||||
if (gl_mem[i] == NULL)
|
||||
return FALSE;
|
||||
if (GST_VIDEO_INFO_MULTIVIEW_MODE (info) ==
|
||||
GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
|
||||
views = info->views;
|
||||
else
|
||||
views = 1;
|
||||
|
||||
gst_buffer_append_memory (buffer, (GstMemory *) gl_mem[i]);
|
||||
for (v = 0; v < views; v++) {
|
||||
for (i = 0; i < n_mem; i++) {
|
||||
gl_mem[i] =
|
||||
(GstGLMemory *) gst_gl_memory_alloc (context, params, info, i,
|
||||
valign);
|
||||
if (gl_mem[i] == NULL)
|
||||
return FALSE;
|
||||
|
||||
gst_buffer_append_memory (buffer, (GstMemory *) gl_mem[i]);
|
||||
}
|
||||
|
||||
gst_buffer_add_video_meta_full (buffer, v,
|
||||
GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
|
||||
GST_VIDEO_INFO_HEIGHT (info), n_mem, info->offset, info->stride);
|
||||
}
|
||||
|
||||
gst_buffer_add_video_meta_full (buffer, 0,
|
||||
GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
|
||||
GST_VIDEO_INFO_HEIGHT (info), n_mem, info->offset, info->stride);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
GST_DEBUG_CATEGORY_STATIC (gst_gl_upload_debug);
|
||||
#define GST_CAT_DEFAULT gst_gl_upload_debug
|
||||
|
||||
/* Define the maximum number of planes we can upload - handle 2 views per buffer */
|
||||
#define GST_GL_UPLOAD_MAX_PLANES (GST_VIDEO_MAX_PLANES * 2)
|
||||
|
||||
typedef struct _UploadMethod UploadMethod;
|
||||
|
||||
struct _GstGLUploadPrivate
|
||||
|
@ -162,12 +165,18 @@ _gl_memory_upload_accept (gpointer impl, GstBuffer * buffer, GstCaps * in_caps,
|
|||
return FALSE;
|
||||
|
||||
if (buffer) {
|
||||
if (gst_buffer_n_memory (buffer) !=
|
||||
GST_VIDEO_INFO_N_PLANES (&upload->upload->priv->in_info))
|
||||
GstVideoInfo *in_info = &upload->upload->priv->in_info;
|
||||
guint expected_memories = GST_VIDEO_INFO_N_PLANES (in_info);
|
||||
|
||||
/* Support stereo views for separated multiview mode */
|
||||
if (GST_VIDEO_INFO_MULTIVIEW_MODE (in_info) ==
|
||||
GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
|
||||
expected_memories *= GST_VIDEO_INFO_VIEWS (in_info);
|
||||
|
||||
if (gst_buffer_n_memory (buffer) != expected_memories)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->upload->priv->in_info);
|
||||
i++) {
|
||||
for (i = 0; i < expected_memories; i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (buffer, i);
|
||||
|
||||
if (!gst_is_gl_memory (mem))
|
||||
|
@ -250,9 +259,10 @@ _gl_memory_upload_perform (gpointer impl, GstBuffer * buffer,
|
|||
{
|
||||
struct GLMemoryUpload *upload = impl;
|
||||
GstGLMemory *gl_mem;
|
||||
int i;
|
||||
int i, n;
|
||||
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->upload->priv->in_info); i++) {
|
||||
n = gst_buffer_n_memory (buffer);
|
||||
for (i = 0; i < n; i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (buffer, i);
|
||||
|
||||
gl_mem = (GstGLMemory *) mem;
|
||||
|
@ -357,12 +367,18 @@ _egl_image_upload_accept (gpointer impl, GstBuffer * buffer, GstCaps * in_caps,
|
|||
return FALSE;
|
||||
|
||||
if (buffer) {
|
||||
if (gst_buffer_n_memory (buffer) !=
|
||||
GST_VIDEO_INFO_N_PLANES (&image->upload->priv->in_info))
|
||||
GstVideoInfo *in_info = &image->upload->priv->in_info;
|
||||
guint expected_memories = GST_VIDEO_INFO_N_PLANES (in_info);
|
||||
|
||||
/* Support stereo views for separated multiview mode */
|
||||
if (GST_VIDEO_INFO_MULTIVIEW_MODE (in_info) ==
|
||||
GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
|
||||
expected_memories *= GST_VIDEO_INFO_VIEWS (in_info);
|
||||
|
||||
if (gst_buffer_n_memory (buffer) != expected_memories)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&image->upload->priv->in_info);
|
||||
i++) {
|
||||
for (i = 0; i < expected_memories; i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (buffer, i);
|
||||
|
||||
if (!gst_is_egl_image_memory (mem))
|
||||
|
@ -395,14 +411,15 @@ static void
|
|||
_egl_image_upload_perform_gl_thread (GstGLContext * context,
|
||||
struct EGLImageUpload *image)
|
||||
{
|
||||
guint i;
|
||||
guint i, n;
|
||||
|
||||
/* FIXME: buffer pool */
|
||||
*image->outbuf = gst_buffer_new ();
|
||||
gst_gl_memory_setup_buffer (image->upload->context,
|
||||
NULL, &image->upload->priv->out_info, NULL, *image->outbuf);
|
||||
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&image->upload->priv->in_info); i++) {
|
||||
n = gst_buffer_n_memory (image->buffer);
|
||||
for (i = 0; i < n; i++) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (image->buffer, i);
|
||||
GstGLMemory *out_gl_mem =
|
||||
(GstGLMemory *) gst_buffer_peek_memory (*image->outbuf, i);
|
||||
|
@ -474,7 +491,7 @@ struct GLUploadMeta
|
|||
|
||||
gboolean result;
|
||||
GstVideoGLTextureUploadMeta *meta;
|
||||
guint texture_ids[GST_VIDEO_MAX_PLANES];
|
||||
guint texture_ids[GST_GL_UPLOAD_MAX_PLANES];
|
||||
};
|
||||
|
||||
static gpointer
|
||||
|
@ -606,6 +623,13 @@ _upload_meta_upload_perform (gpointer impl, GstBuffer * buffer,
|
|||
{
|
||||
struct GLUploadMeta *upload = impl;
|
||||
int i;
|
||||
GstVideoInfo *in_info = &upload->upload->priv->in_info;
|
||||
guint max_planes = GST_VIDEO_INFO_N_PLANES (in_info);
|
||||
|
||||
/* Support stereo views for separated multiview mode */
|
||||
if (GST_VIDEO_INFO_MULTIVIEW_MODE (in_info) ==
|
||||
GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
|
||||
max_planes *= GST_VIDEO_INFO_VIEWS (in_info);
|
||||
|
||||
GST_LOG_OBJECT (upload, "Attempting upload with GstVideoGLTextureUploadMeta");
|
||||
|
||||
|
@ -616,10 +640,10 @@ _upload_meta_upload_perform (gpointer impl, GstBuffer * buffer,
|
|||
gst_gl_memory_setup_buffer (upload->upload->context,
|
||||
NULL, &upload->upload->priv->in_info, NULL, *outbuf);
|
||||
|
||||
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
|
||||
for (i = 0; i < GST_GL_UPLOAD_MAX_PLANES; i++) {
|
||||
guint tex_id = 0;
|
||||
|
||||
if (i < GST_VIDEO_INFO_N_PLANES (&upload->upload->priv->in_info)) {
|
||||
if (i < max_planes) {
|
||||
GstMemory *mem = gst_buffer_peek_memory (*outbuf, i);
|
||||
tex_id = ((GstGLMemory *) mem)->tex_id;
|
||||
}
|
||||
|
@ -627,9 +651,12 @@ _upload_meta_upload_perform (gpointer impl, GstBuffer * buffer,
|
|||
upload->texture_ids[i] = tex_id;
|
||||
}
|
||||
|
||||
GST_LOG ("Uploading with GLTextureUploadMeta with textures %i,%i,%i,%i",
|
||||
upload->texture_ids[0], upload->texture_ids[1], upload->texture_ids[2],
|
||||
upload->texture_ids[3]);
|
||||
GST_LOG ("Uploading with GLTextureUploadMeta with textures "
|
||||
"%i,%i,%i,%i / %i,%i,%i,%i",
|
||||
upload->texture_ids[0], upload->texture_ids[1],
|
||||
upload->texture_ids[2], upload->texture_ids[3],
|
||||
upload->texture_ids[4], upload->texture_ids[5],
|
||||
upload->texture_ids[6], upload->texture_ids[7]);
|
||||
|
||||
gst_gl_context_thread_add (upload->upload->context,
|
||||
(GstGLContextThreadFunc) _do_upload_with_meta, upload);
|
||||
|
@ -653,7 +680,7 @@ _upload_meta_upload_free (gpointer impl)
|
|||
|
||||
g_return_if_fail (impl != NULL);
|
||||
|
||||
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
|
||||
for (i = 0; i < GST_GL_UPLOAD_MAX_PLANES; i++) {
|
||||
if (upload->texture_ids[i])
|
||||
gst_gl_context_del_texture (upload->upload->context,
|
||||
&upload->texture_ids[i]);
|
||||
|
@ -750,14 +777,21 @@ static GstGLUploadReturn
|
|||
_raw_data_upload_perform (gpointer impl, GstBuffer * buffer,
|
||||
GstBuffer ** outbuf)
|
||||
{
|
||||
GstGLMemory *in_tex[GST_VIDEO_MAX_PLANES] = { 0, };
|
||||
GstGLMemory *in_tex[GST_GL_UPLOAD_MAX_PLANES] = { 0, };
|
||||
struct RawUpload *raw = impl;
|
||||
int i;
|
||||
GstVideoInfo *in_info = &raw->upload->priv->in_info;
|
||||
guint max_planes = GST_VIDEO_INFO_N_PLANES (in_info);
|
||||
|
||||
/* Support stereo views for separated multiview mode */
|
||||
if (GST_VIDEO_INFO_MULTIVIEW_MODE (in_info) ==
|
||||
GST_VIDEO_MULTIVIEW_MODE_SEPARATED)
|
||||
max_planes *= GST_VIDEO_INFO_VIEWS (in_info);
|
||||
|
||||
gst_gl_memory_setup_wrapped (raw->upload->context,
|
||||
&raw->upload->priv->in_info, NULL, raw->in_frame.data, in_tex);
|
||||
|
||||
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
|
||||
for (i = 0; i < GST_GL_UPLOAD_MAX_PLANES; i++) {
|
||||
if (in_tex[i]) {
|
||||
in_tex[i]->data = raw->in_frame.data[i];
|
||||
GST_GL_MEMORY_FLAG_SET (in_tex[i], GST_GL_MEMORY_FLAG_NEED_UPLOAD);
|
||||
|
@ -765,7 +799,7 @@ _raw_data_upload_perform (gpointer impl, GstBuffer * buffer,
|
|||
}
|
||||
|
||||
*outbuf = gst_buffer_new ();
|
||||
for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&raw->upload->priv->in_info); i++) {
|
||||
for (i = 0; i < max_planes; i++) {
|
||||
gst_buffer_append_memory (*outbuf, (GstMemory *) in_tex[i]);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue