mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 15:48:23 +00:00
eglglessink: Use PAR/DAR to set viewport
This commit is contained in:
parent
c3fb44aef3
commit
eeb3b84d07
2 changed files with 70 additions and 11 deletions
|
@ -1384,6 +1384,7 @@ HANDLE_ERROR_LOCKED:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* XXX: Lock eglgles context? */
|
||||
static gboolean
|
||||
gst_eglglessink_update_surface_dimensions (GstEglGlesSink * eglglessink)
|
||||
{
|
||||
|
@ -1395,6 +1396,29 @@ gst_eglglessink_update_surface_dimensions (GstEglGlesSink * eglglessink)
|
|||
eglQuerySurface (eglglessink->eglglesctx->display,
|
||||
eglglessink->eglglesctx->surface, EGL_HEIGHT, &height);
|
||||
|
||||
/* Save Pixel Aspect Ratio
|
||||
*
|
||||
* PAR is reported as w/h * EGL_DISPLAY_SCALING wich is
|
||||
* a constant with value 10000. This attribute is only
|
||||
* supported if the EGL version is >= 1.2
|
||||
* XXX: Setup this as a property.
|
||||
*/
|
||||
if (eglglessink->eglglesctx->egl_minor > 1) {
|
||||
eglQuerySurface (eglglessink->eglglesctx->display,
|
||||
eglglessink->eglglesctx->surface, EGL_PIXEL_ASPECT_RATIO,
|
||||
&eglglessink->eglglesctx->pixel_aspect_ratio);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (eglglessink, "Can't query PAR. Using default: %dx%d",
|
||||
EGL_DISPLAY_SCALING, EGL_DISPLAY_SCALING);
|
||||
eglglessink->eglglesctx->pixel_aspect_ratio = EGL_DISPLAY_SCALING;
|
||||
}
|
||||
|
||||
if (eglglessink->eglglesctx->pixel_aspect_ratio == EGL_UNKNOWN) {
|
||||
GST_WARNING_OBJECT (eglglessink, "PAR value returned doesn't make sense. "
|
||||
"Will use default: %d/%d", EGL_DISPLAY_SCALING, EGL_DISPLAY_SCALING);
|
||||
eglglessink->eglglesctx->pixel_aspect_ratio = EGL_DISPLAY_SCALING;
|
||||
}
|
||||
|
||||
if (width != eglglessink->eglglesctx->surface_width ||
|
||||
height != eglglessink->eglglesctx->surface_height) {
|
||||
eglglessink->eglglesctx->surface_width = width;
|
||||
|
@ -1694,8 +1718,6 @@ HANDLE_ERROR:
|
|||
static gboolean
|
||||
gst_eglglessink_init_egl_display (GstEglGlesSink * eglglessink)
|
||||
{
|
||||
EGLint egl_major, egl_minor;
|
||||
|
||||
GST_DEBUG_OBJECT (eglglessink, "Enter EGL initial configuration");
|
||||
|
||||
eglglessink->eglglesctx->display = eglGetDisplay (EGL_DEFAULT_DISPLAY);
|
||||
|
@ -1704,21 +1726,25 @@ gst_eglglessink_init_egl_display (GstEglGlesSink * eglglessink)
|
|||
goto HANDLE_ERROR; /* No EGL error is set by eglGetDisplay() */
|
||||
}
|
||||
|
||||
if (!eglInitialize (eglglessink->eglglesctx->display, &egl_major, &egl_minor)) {
|
||||
if (!eglInitialize (eglglessink->eglglesctx->display,
|
||||
&eglglessink->eglglesctx->egl_major, &eglglessink->eglglesctx->egl_minor)) {
|
||||
show_egl_error ("eglInitialize");
|
||||
GST_ERROR_OBJECT (eglglessink, "Could not init EGL display connection");
|
||||
goto HANDLE_EGL_ERROR;
|
||||
}
|
||||
|
||||
/* Check against required EGL version */
|
||||
if (egl_major < GST_EGLGLESSINK_EGL_MIN_VERSION) {
|
||||
GST_ERROR_OBJECT (eglglessink, "EGL v%d\n needed, but you only have v%d.%d",
|
||||
GST_EGLGLESSINK_EGL_MIN_VERSION, egl_major, egl_minor);
|
||||
/* Check against required EGL version
|
||||
* XXX: Need to review the version requirement in terms of the needed API
|
||||
*/
|
||||
if (eglglessink->eglglesctx->egl_major < GST_EGLGLESSINK_EGL_MIN_VERSION) {
|
||||
GST_ERROR_OBJECT (eglglessink, "EGL v%d needed, but you only have v%d.%d",
|
||||
GST_EGLGLESSINK_EGL_MIN_VERSION, eglglessink->eglglesctx->egl_major,
|
||||
eglglessink->eglglesctx->egl_minor);
|
||||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
GST_INFO_OBJECT (eglglessink, "System reports supported EGL version v%d.%d",
|
||||
egl_major, egl_minor);
|
||||
eglglessink->eglglesctx->egl_major, eglglessink->eglglesctx->egl_minor);
|
||||
|
||||
eglBindAPI (EGL_OPENGL_ES_API);
|
||||
|
||||
|
@ -1839,6 +1865,7 @@ gst_eglglessink_render_and_display (GstEglGlesSink * eglglessink,
|
|||
{
|
||||
GstVideoRectangle frame, surface;
|
||||
gint w, h;
|
||||
guint dar_n, dar_d;
|
||||
|
||||
#ifdef EGL_FAST_RENDERING_POSSIBLE
|
||||
EGLImageKHR img = EGL_NO_IMAGE_KHR;
|
||||
|
@ -2032,9 +2059,26 @@ gst_eglglessink_render_and_display (GstEglGlesSink * eglglessink,
|
|||
eglglessink->display_region.h =
|
||||
eglglessink->eglglesctx->surface_height;
|
||||
} else {
|
||||
/* XXX: Proly consider display pixel aspect ratio too? */
|
||||
frame.w = w;
|
||||
frame.h = h;
|
||||
if (!gst_video_calculate_display_ratio (&dar_n, &dar_d, w, h,
|
||||
eglglessink->par_n, eglglessink->par_d,
|
||||
eglglessink->eglglesctx->pixel_aspect_ratio, EGL_DISPLAY_SCALING)) {
|
||||
GST_WARNING_OBJECT (eglglessink, "Could not compute resulting DAR");
|
||||
frame.w = w;
|
||||
frame.h = h;
|
||||
} else {
|
||||
/* Find suitable matching new size acording to dar & par
|
||||
* XXX: Move this to gstutils?
|
||||
*/
|
||||
frame.w = w;
|
||||
frame.h = h;
|
||||
if (!(h % dar_d))
|
||||
frame.w = gst_util_uint64_scale_int (h, dar_n, dar_d);
|
||||
else if (!(w % dar_n))
|
||||
frame.h = gst_util_uint64_scale_int (w, dar_d, dar_n);
|
||||
else /* need aprox */
|
||||
frame.w = gst_util_uint64_scale_int (h, dar_n, dar_d);
|
||||
}
|
||||
|
||||
surface.w = eglglessink->eglglesctx->surface_width;
|
||||
surface.h = eglglessink->eglglesctx->surface_height;
|
||||
gst_video_sink_center_rect (frame, surface,
|
||||
|
@ -2123,6 +2167,7 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
|||
GstEglGlesSink *eglglessink;
|
||||
gboolean ret = TRUE;
|
||||
gint width, height;
|
||||
int par_n, par_d;
|
||||
EGLNativeWindowType window;
|
||||
GstEglGlesImageFmt *format;
|
||||
|
||||
|
@ -2138,6 +2183,12 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
|||
goto HANDLE_ERROR;
|
||||
}
|
||||
|
||||
if (!(ret = gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d))) {
|
||||
par_n = 1;
|
||||
par_d = 1;
|
||||
GST_WARNING_OBJECT (eglglessink, "Can't parse PAR from caps. Using default: 1");
|
||||
}
|
||||
|
||||
format = gst_eglglessink_get_compat_format_from_caps (eglglessink, caps);
|
||||
if (!format) {
|
||||
GST_ERROR_OBJECT (eglglessink,
|
||||
|
@ -2149,6 +2200,8 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
|||
|
||||
g_mutex_lock (eglglessink->flow_lock);
|
||||
eglglessink->selected_fmt = format;
|
||||
eglglessink->par_n = par_n;
|
||||
eglglessink->par_d = par_d;
|
||||
GST_VIDEO_SINK_WIDTH (eglglessink) = width;
|
||||
GST_VIDEO_SINK_HEIGHT (eglglessink) = height;
|
||||
g_mutex_unlock (eglglessink->flow_lock);
|
||||
|
@ -2448,6 +2501,8 @@ gst_eglglessink_init (GstEglGlesSink * eglglessink,
|
|||
eglglessink->force_aspect_ratio = TRUE;
|
||||
eglglessink->using_own_window = FALSE;
|
||||
eglglessink->eglglesctx = g_new0 (GstEglGlesRenderContext, 1);
|
||||
eglglessink->par_n = 1;
|
||||
eglglessink->par_d = 1;
|
||||
eglglessink->flow_lock = g_mutex_new ();
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,8 @@ struct _GstEglGlesRenderContext
|
|||
GLuint texture[3];
|
||||
EGLint surface_width;
|
||||
EGLint surface_height;
|
||||
EGLint pixel_aspect_ratio;
|
||||
EGLint egl_minor, egl_major;
|
||||
gint n_textures;
|
||||
|
||||
/* shader vars */
|
||||
|
@ -147,6 +149,8 @@ struct _GstEglGlesSink
|
|||
GstVideoFormat format;
|
||||
GstCaps *current_caps;
|
||||
|
||||
int par_n, par_d; /* Aspect ratio from caps */
|
||||
|
||||
GstEglGlesRenderContext *eglglesctx;
|
||||
|
||||
GstVideoRectangle display_region;
|
||||
|
|
Loading…
Reference in a new issue