Skip to content

fix mali video player #358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/gl_renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ static ATTR_PURE EGLConfig choose_config_with_pixel_format(EGLDisplay display, c
return EGL_NO_CONFIG_KHR;
}

static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };

struct gl_renderer *gl_renderer_new_from_gbm_device(
struct tracer *tracer,
struct gbm_device *gbm_device,
Expand Down Expand Up @@ -303,8 +305,6 @@ struct gl_renderer *gl_renderer_new_from_gbm_device(
}
}

static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };

root_context = eglCreateContext(egl_display, forced_egl_config, EGL_NO_CONTEXT, context_attribs);
if (root_context == EGL_NO_CONTEXT) {
LOG_EGL_ERROR(eglGetError(), "Could not create EGL context for OpenGL ES. eglCreateContext");
Expand Down Expand Up @@ -556,6 +556,12 @@ void *gl_renderer_get_proc_address(ASSERTED struct gl_renderer *renderer, const
return get_proc_address(name);
}

void *gl_renderer_try_get_proc_address(ASSERTED struct gl_renderer *renderer, const char *name) {
ASSERT_NOT_NULL(renderer);
ASSERT_NOT_NULL(name);
return try_get_proc_address(name);
}

EGLDisplay gl_renderer_get_egl_display(struct gl_renderer *renderer) {
ASSERT_NOT_NULL(renderer);
return renderer->egl_display;
Expand All @@ -567,7 +573,7 @@ EGLContext gl_renderer_create_context(struct gl_renderer *renderer) {
ASSERT_NOT_NULL(renderer);

pthread_mutex_lock(&renderer->root_context_lock);
context = eglCreateContext(renderer->egl_display, renderer->forced_egl_config, renderer->root_context, NULL);
context = eglCreateContext(renderer->egl_display, renderer->forced_egl_config, renderer->root_context, context_attribs);
pthread_mutex_unlock(&renderer->root_context_lock);

return context;
Expand Down Expand Up @@ -602,7 +608,7 @@ int gl_renderer_make_this_a_render_thread(struct gl_renderer *renderer) {
assert(is_render_thread == false);

pthread_mutex_lock(&renderer->root_context_lock);
context = eglCreateContext(renderer->egl_display, renderer->forced_egl_config, renderer->root_context, NULL);
context = eglCreateContext(renderer->egl_display, renderer->forced_egl_config, renderer->root_context, context_attribs);
pthread_mutex_unlock(&renderer->root_context_lock);

if (context == EGL_NO_CONTEXT) {
Expand Down
2 changes: 2 additions & 0 deletions src/gl_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ EGLContext gl_renderer_create_context(struct gl_renderer *renderer);

void *gl_renderer_get_proc_address(struct gl_renderer *renderer, const char *name);

void *gl_renderer_try_get_proc_address(ASSERTED struct gl_renderer *renderer, const char *name);

EGLDisplay gl_renderer_get_egl_display(struct gl_renderer *renderer);

bool gl_renderer_supports_egl_extension(struct gl_renderer *renderer, const char *name);
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/gstreamer_video_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ ATTR_PURE int frame_interface_get_n_formats(struct frame_interface *interface);
ATTR_PURE const struct egl_modified_format *frame_interface_get_format(struct frame_interface *interface, int index);

#define for_each_format_in_frame_interface(index, format, interface) \
for (const struct egl_modified_format *format = frame_interface_get_format((interface), 0), *guard = NULL; guard == NULL; \
for (const struct egl_modified_format *format = frame_interface_get_n_formats(interface) > 0 ? frame_interface_get_format(interface, 0) : NULL, *guard = NULL; guard == NULL; \
guard = (void *) 1) \
for (size_t index = 0; index < frame_interface_get_n_formats(interface); index++, \
format = (index) < frame_interface_get_n_formats(interface) ? frame_interface_get_format((interface), (index)) : NULL)
Expand Down
42 changes: 34 additions & 8 deletions src/plugins/gstreamer_video_player/frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,35 +233,31 @@ struct frame_interface *frame_interface_new(struct gl_renderer *renderer) {

PFNEGLCREATEIMAGEKHRPROC create_image = (PFNEGLCREATEIMAGEKHRPROC) gl_renderer_get_proc_address(renderer, "eglCreateImageKHR");
if (create_image == NULL) {
LOG_ERROR("Could not resolve eglCreateImageKHR EGL procedure.\n");
goto fail_destroy_context;
}

PFNEGLDESTROYIMAGEKHRPROC destroy_image = (PFNEGLDESTROYIMAGEKHRPROC) gl_renderer_get_proc_address(renderer, "eglDestroyImageKHR");
if (destroy_image == NULL) {
LOG_ERROR("Could not resolve eglDestroyImageKHR EGL procedure.\n");
goto fail_destroy_context;
}

PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture2d = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC
) gl_renderer_get_proc_address(renderer, "glEGLImageTargetTexture2DOES");
if (gl_egl_image_target_texture2d == NULL) {
LOG_ERROR("Could not resolve glEGLImageTargetTexture2DOES EGL procedure.\n");
goto fail_destroy_context;
}

// These two are optional.
// Might be useful in the future.
#ifdef EGL_EXT_image_dma_buf_import_modifiers
PFNEGLQUERYDMABUFFORMATSEXTPROC egl_query_dmabuf_formats = (PFNEGLQUERYDMABUFFORMATSEXTPROC
) gl_renderer_get_proc_address(renderer, "eglQueryDmaBufFormatsEXT");
) gl_renderer_try_get_proc_address(renderer, "eglQueryDmaBufFormatsEXT");
if (egl_query_dmabuf_formats == NULL && supports_extended_imports) {
LOG_ERROR("Could not resolve eglQueryDmaBufFormatsEXT egl procedure, even though it is listed as supported.\n");
supports_extended_imports = false;
}

PFNEGLQUERYDMABUFMODIFIERSEXTPROC egl_query_dmabuf_modifiers = (PFNEGLQUERYDMABUFMODIFIERSEXTPROC
) gl_renderer_get_proc_address(renderer, "eglQueryDmaBufModifiersEXT");
) gl_renderer_try_get_proc_address(renderer, "eglQueryDmaBufModifiersEXT");
if (egl_query_dmabuf_modifiers == NULL && supports_extended_imports) {
LOG_ERROR("Could not resolve eglQueryDmaBufModifiersEXT egl procedure, even though it is listed as supported.\n");
supports_extended_imports = false;
Expand All @@ -281,8 +277,38 @@ struct frame_interface *frame_interface_new(struct gl_renderer *renderer) {
UNREACHABLE();
#endif
} else {
n_formats = 0;
formats = NULL;
// If EGL doesn't support querying the supported formats & modifiers for import,
// use a static list of formats that mostly work.
//
// This can happen on ARM Mali for example:
// ===================================
// EGL information:
// version: "1.4 Midgard-"r18p0-01rel0""
// vendor: "ARM"
// client extensions: "EGL_EXT_client_extensions EGL_EXT_platform_base EGL_KHR_client_get_all_proc_addresses EGL_KHR_platform_gbm EGL_MESA_platform_gbm EGL_KHR_platform_wayland EGL_EXT_platform_wayland"
// display extensions: "EGL_WL_bind_wayland_display EGL_KHR_partial_update EGL_KHR_image_pixmap EGL_EXT_image_dma_buf_import EGL_KHR_config_attribs EGL_KHR_image EGL_KHR_image_base EGL_KHR_fence_sync EGL_KHR_wait_sync EGL_KHR_gl_colorspace EGL_KHR_get_all_proc_addresses EGL_IMG_context_priority EGL_ARM_pixmap_multisample_discard EGL_ARM_implicit_external_sync EGL_KHR_gl_texture_2D_image EGL_KHR_gl_renderbuffer_image EGL_KHR_create_context EGL_KHR_surfaceless_context EGL_KHR_gl_texture_cubemap_image EGL_EXT_create_context_robustness"
// ===================================
// OpenGL ES 2.x information:
// version: "OpenGL ES 3.2 v1.r18p0-01rel0.db8fd8841edf74cef96ef24ce665edac"
// shading language version: "OpenGL ES GLSL ES 3.20"
// vendor: "ARM"
// renderer: "Mali-T860"
// ===================================
//
/// TODO: For each format, try creating a GBM bo and importing, to see if it
/// actually works.
static const struct egl_modified_format fallback_formats[] = {
{DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_INVALID, false},
{DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_INVALID, false},
{DRM_FORMAT_YUYV, DRM_FORMAT_MOD_INVALID, false},
{DRM_FORMAT_NV12, DRM_FORMAT_MOD_INVALID, false},
{DRM_FORMAT_YUV420, DRM_FORMAT_MOD_INVALID, false},
{DRM_FORMAT_YUV444, DRM_FORMAT_MOD_INVALID, false},
{DRM_FORMAT_XYUV8888, DRM_FORMAT_MOD_INVALID, false},
};

n_formats = ARRAY_SIZE(fallback_formats);
formats = memdup(fallback_formats, sizeof(fallback_formats));
}

interface->gbm_device = gbm_device;
Expand Down
20 changes: 11 additions & 9 deletions src/plugins/gstreamer_video_player/player.c
Original file line number Diff line number Diff line change
Expand Up @@ -916,17 +916,19 @@ static int init(struct gstplayer *player, bool force_sw_decoders) {

// configure our caps
// we only accept video formats that we can actually upload to EGL
GstCaps *caps = gst_caps_new_empty();
for_each_format_in_frame_interface(i, format, player->frame_interface) {
GstVideoFormat gst_format = gst_video_format_from_drm_format(format->format);
if (gst_format == GST_VIDEO_FORMAT_UNKNOWN) {
continue;
}
if (frame_interface_get_n_formats(player->frame_interface) > 0) {
GstCaps *caps = gst_caps_new_empty();
for_each_format_in_frame_interface(i, format, player->frame_interface) {
GstVideoFormat gst_format = gst_video_format_from_drm_format(format->format);
if (gst_format == GST_VIDEO_FORMAT_UNKNOWN) {
continue;
}

gst_caps_append(caps, gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, gst_video_format_to_string(gst_format), NULL));
gst_caps_append(caps, gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, gst_video_format_to_string(gst_format), NULL));
}
gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
gst_caps_unref(caps);
}
gst_app_sink_set_caps(GST_APP_SINK(sink), caps);
gst_caps_unref(caps);

gst_app_sink_set_callbacks(
GST_APP_SINK(sink),
Expand Down