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 ();
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;
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)) {
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]);
/* 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;
#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,
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
{
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);
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;
}
}
* @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
*/
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);
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;
}
}
- 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);
}
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];
((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;
+}
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
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_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);
+ 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);
+ }
return TRUE;
}
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
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))
{
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;
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))
_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);
gboolean result;
GstVideoGLTextureUploadMeta *meta;
- guint texture_ids[GST_VIDEO_MAX_PLANES];
+ guint texture_ids[GST_GL_UPLOAD_MAX_PLANES];
};
static gpointer
{
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");
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;
}
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);
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]);
_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);
}
*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]);
}