diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.c b/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.c index 18588c163c..17140514e4 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/egl/gsteglimage.c @@ -553,6 +553,21 @@ _drm_rgba_fourcc_from_info (const GstVideoInfo * info, int plane, } } +static gint +get_egl_stride (const GstVideoInfo * info, gint plane) +{ + const GstVideoFormatInfo *finfo = info->finfo; + gint stride = info->stride[plane]; + guint ws; + + if (!GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) + return stride; + + gst_video_format_info_get_tile_sizes (finfo, plane, &ws, NULL); + + return GST_VIDEO_TILE_X_TILES (stride) << ws; +} + /** * gst_egl_image_from_dmabuf: * @context: a #GstGLContext (must be an EGL context) @@ -601,7 +616,7 @@ gst_egl_image_from_dmabuf (GstGLContext * context, attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; attribs[atti++] = offset; attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; - attribs[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (in_info, plane); + attribs[atti++] = get_egl_stride (in_info, plane); attribs[atti] = EGL_NONE; g_assert (atti == G_N_ELEMENTS (attribs) - 1); @@ -905,7 +920,7 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context, attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; attribs[atti++] = offset[0]; attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; - attribs[atti++] = in_info->stride[0]; + attribs[atti++] = get_egl_stride (in_info, 0); if (with_modifiers) { attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff; @@ -921,7 +936,7 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context, attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT; attribs[atti++] = offset[1]; attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT; - attribs[atti++] = in_info->stride[1]; + attribs[atti++] = get_egl_stride (in_info, 1); if (with_modifiers) { attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT; attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff; @@ -937,7 +952,7 @@ gst_egl_image_from_dmabuf_direct_target (GstGLContext * context, attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT; attribs[atti++] = offset[2]; attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT; - attribs[atti++] = in_info->stride[2]; + attribs[atti++] = get_egl_stride (in_info, 2); if (with_modifiers) { attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT; attribs[atti++] = DRM_FORMAT_MOD_LINEAR & 0xffffffff; diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglmemory.c b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglmemory.c index 9cb078749b..118f07eff2 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglmemory.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglmemory.c @@ -59,7 +59,7 @@ #define GL_MEM_WIDTH(gl_mem) _get_plane_width (&gl_mem->info, gl_mem->plane) #define GL_MEM_HEIGHT(gl_mem) _get_plane_height (&gl_mem->info, gl_mem->plane) -#define GL_MEM_STRIDE(gl_mem) GST_VIDEO_INFO_PLANE_STRIDE (&gl_mem->info, gl_mem->plane) +#define GL_MEM_STRIDE(gl_mem) _get_mem_stride (gl_mem) static GstAllocator *_gl_memory_allocator; @@ -122,19 +122,43 @@ _get_plane_width (const GstVideoInfo * info, guint plane) static inline guint _get_plane_height (const GstVideoInfo * info, guint plane) { + if (GST_VIDEO_FORMAT_INFO_IS_TILED (info->finfo)) { + guint hs; + gsize stride; + + gst_video_format_info_get_tile_sizes (info->finfo, plane, NULL, &hs); + stride = GST_VIDEO_INFO_PLANE_STRIDE (info, plane); + + return GST_VIDEO_TILE_Y_TILES (stride) << hs; + } + if (GST_VIDEO_INFO_IS_YUV (info)) { gint comp[GST_VIDEO_MAX_COMPONENTS]; gst_video_format_info_component (info->finfo, plane, comp); return GST_VIDEO_INFO_COMP_HEIGHT (info, comp[0]); - } else { - /* RGB, GRAY */ - return GST_VIDEO_INFO_HEIGHT (info); } + + /* RGB, GRAY */ + return GST_VIDEO_INFO_HEIGHT (info); +} + +static guint +_get_mem_stride (GstGLMemory * gl_mem) +{ + const GstVideoFormatInfo *finfo = gl_mem->info.finfo; + guint stride = GST_VIDEO_INFO_PLANE_STRIDE (&gl_mem->info, gl_mem->plane); + + if (!GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) + return stride; + + return + GST_VIDEO_TILE_X_TILES (stride) << GST_VIDEO_FORMAT_INFO_TILE_WS (finfo); } static inline void _calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context) { + GstVideoInfo *info = &gl_mem->info; guint n_gl_bytes; GstGLFormat tex_format; guint tex_type; @@ -142,7 +166,6 @@ _calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context) gl_mem->tex_scaling[0] = 1.0f; gl_mem->tex_scaling[1] = 1.0f; gl_mem->unpack_length = 1; - gl_mem->tex_width = GL_MEM_WIDTH (gl_mem); gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &tex_format, &tex_type); @@ -152,6 +175,13 @@ _calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context) return; } + /* For tiles, we need GL not to clip on the display width, as the would make + * some tile not fully accessible by GLSL. */ + if (GST_VIDEO_FORMAT_INFO_IS_TILED (info->finfo)) + gl_mem->tex_width = GL_MEM_STRIDE (gl_mem) / n_gl_bytes; + else + gl_mem->tex_width = GL_MEM_WIDTH (gl_mem); + if (USING_OPENGL (context) || USING_GLES3 (context) || USING_OPENGL3 (context)) { gl_mem->unpack_length = GL_MEM_STRIDE (gl_mem) / n_gl_bytes; diff --git a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c index cb9e858f92..570d0e1076 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/gl/gstglutils.c @@ -613,6 +613,7 @@ gsize gst_gl_get_plane_data_size (const GstVideoInfo * info, const GstVideoAlignment * align, guint plane) { + const GstVideoFormatInfo *finfo = info->finfo; gint comp[GST_VIDEO_MAX_COMPONENTS]; gint padded_height; gsize plane_size; @@ -627,7 +628,21 @@ gst_gl_get_plane_data_size (const GstVideoInfo * info, padded_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comp[0], padded_height); - plane_size = GST_VIDEO_INFO_PLANE_STRIDE (info, plane) * padded_height; + if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) { + gsize stride; + gint x_tiles, y_tiles; + gint tile_size; + + tile_size = gst_video_format_info_get_tile_sizes (finfo, plane, NULL, NULL); + + stride = GST_VIDEO_INFO_PLANE_STRIDE (info, plane); + x_tiles = GST_VIDEO_TILE_X_TILES (stride); + y_tiles = GST_VIDEO_TILE_Y_TILES (stride); + + plane_size = x_tiles * y_tiles * tile_size; + } else { + plane_size = GST_VIDEO_INFO_PLANE_STRIDE (info, plane) * padded_height; + } return plane_size; }