summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2024-02-03 14:27:46 -0600
committerDudemanguy <random342@airmail.cc>2024-02-05 17:41:06 +0000
commit343a5fd345a84572ea5693a805119067d5b0fbc8 (patch)
tree4fbce1c7408194fe9f605d29d194525d30d92927
parent8ecb462a9c2d8003e9972fd20dd2bb713389ed2c (diff)
downloadmpv-343a5fd345a84572ea5693a805119067d5b0fbc8.tar.bz2
mpv-343a5fd345a84572ea5693a805119067d5b0fbc8.tar.xz
player: remove all rpi-specific code
vo_rpi and its related code has pretty much historically been a disaster in mpv. The build regularly gets broken and since nobody uses it, it takes months for anyone to notice. There was also that time where fullscreen was broken for about a year and a half. Also building in waf was entirely broken for about a couple of years or so due to mysterious reasons no one ever figured out (meson magically fixed it). Anyways, once again the build is broken due to rpi being forgotten about again, but instead of pretending to support this crap. Just drop it all. Nowadays, mmal hwdec is a relic since these devices are better off using the v4l2m2m ffmpeg fork instead which actually uses KMS properly. RPI 1 and 2 probably can't do this and will remain broken but oh well blame Broadcom for being special snowflakes and not using standard APIs (my rockpro worked out of the box; just saying). RPI 2 is nearly 10 years old anyways, so I think you can afford a new SBC by now. If we were nicer, there would be a deprecation period, but this is broken in the last major release anyway so too late. Closes #13402.
-rw-r--r--DOCS/interface-changes.rst1
-rw-r--r--DOCS/man/options.rst5
-rw-r--r--DOCS/man/vo.rst24
-rw-r--r--meson.build23
-rw-r--r--meson_options.txt2
-rw-r--r--video/out/gpu/context.c4
-rw-r--r--video/out/gpu/hwdec.c4
-rw-r--r--video/out/opengl/context_rpi.c327
-rw-r--r--video/out/opengl/hwdec_rpi.c384
-rw-r--r--video/out/vo.c4
-rw-r--r--video/out/vo_rpi.c938
11 files changed, 2 insertions, 1714 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 9055ca53a2..827fa79063 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -44,6 +44,7 @@ Interface changes
- change fallback deinterlace to bwdif
- add the command `load-config-file`
- add the command `load-input-conf`
+ - remove `--vo=rpi`, `--gpu-context=rpi`, and `--hwdec=mmal`
--- mpv 0.37.0 ---
- `--save-position-on-quit` and its associated commands now store state files
in %LOCALAPPDATA% instead of %APPDATA% directory by default on Windows.
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index e887e25ba7..e3b49b4087 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -1315,8 +1315,6 @@ Video
:mediacodec: requires ``--vo=gpu --gpu-context=android``
or ``--vo=mediacodec_embed`` (Android only)
:mediacodec-copy: copies video back to system RAM (Android only)
- :mmal: requires ``--vo=gpu`` (Raspberry Pi only - default if available)
- :mmal-copy: copies video back to system RAM (Raspberry Pi only)
:cuda: requires ``--vo=gpu`` (Any platform CUDA is available)
:cuda-copy: copies video back to system RAM (Any platform CUDA is available)
:crystalhd: copies video back to system RAM (Any platform supported by hardware)
@@ -1411,9 +1409,6 @@ Video
affect this additionally. This can give incorrect results even with
completely ordinary video sources.
- ``rpi`` always uses the hardware overlay renderer, even with
- ``--vo=gpu``.
-
``mediacodec`` is not safe. It forces RGB conversion (not with ``-copy``)
and how well it handles non-standard colorspaces is not known.
In the rare cases where 10-bit is supported the bit depth of the output
diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst
index 5ee4eaa14f..2c9390114d 100644
--- a/DOCS/man/vo.rst
+++ b/DOCS/man/vo.rst
@@ -567,30 +567,6 @@ Available video output drivers are:
This also supports many of the options the ``gpu`` VO has, depending on the
backend.
-``rpi`` (Raspberry Pi)
- Native video output on the Raspberry Pi using the MMAL API.
-
- The following global options are supported by this video output:
-
- ``--rpi-display=<number>``
- Select the display number on which the video overlay should be shown
- (default: 0).
-
- ``--rpi-layer=<number>``
- Select the dispmanx layer on which the video overlay should be shown
- (default: -10). Note that mpv will also use the 2 layers above the
- selected layer, to handle the window background and OSD. Actual video
- rendering will happen on the layer above the selected layer.
-
- ``--rpi-background=<yes|no>``
- Whether to render a black background behind the video (default: no).
- Normally it's better to kill the console framebuffer instead, which
- gives better performance.
-
- ``--rpi-osd=<yes|no>``
- Enabled by default. If disabled with ``no``, no OSD layer is created.
- This also means there will be no subtitles rendered.
-
``drm`` (Direct Rendering Manager)
Video output driver using Kernel Mode Setting / Direct Rendering Manager.
Should be used when one doesn't want to install full-blown graphical
diff --git a/meson.build b/meson.build
index 8a96176d85..8c7730f6b8 100644
--- a/meson.build
+++ b/meson.build
@@ -1219,16 +1219,7 @@ if plain_gl.allowed()
features += {'gl': true}
endif
-rpi = dependency('/opt/vc/lib/pkgconfig/brcmegl.pc', 'brcmegl', required: get_option('rpi'))
-features += {'rpi': gl_allowed and rpi.found()}
-if features['rpi']
- dependencies += rpi
- features += {'gl': true}
- sources += files('video/out/opengl/context_rpi.c')
-endif
-
-features += {'egl-helpers': features['egl'] or egl_android.found() or
- egl_angle_win32.allowed() or features['rpi']}
+features += {'egl-helpers': features['egl'] or egl_android.found() or egl_angle_win32.allowed()}
if features['egl-helpers']
sources += files('video/out/opengl/egl_helpers.c')
endif
@@ -1377,18 +1368,6 @@ if features['ios-gl']
sources += files('video/out/hwdec/hwdec_ios_gl.m')
endif
-rpi_mmal_opt = get_option('rpi-mmal').require(
- features['rpi'],
- error_message: 'rpi was not found!',
-)
-rpi_mmal = dependency('/opt/vc/lib/pkgconfig/mmal.pc', 'mmal', required: rpi_mmal_opt)
-features += {'rpi-mmal': rpi_mmal.found()}
-if features['rpi-mmal']
- dependencies += rpi_mmal
- sources += files('video/out/opengl/hwdec_rpi.c',
- 'video/out/vo_rpi.c')
-endif
-
libva = dependency('libva', version: '>= 1.1.0', required: get_option('vaapi'))
vaapi_drm = dependency('libva-drm', version: '>= 1.1.0',
diff --git a/meson_options.txt b/meson_options.txt
index a5454e97ef..cded6a8e61 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -74,7 +74,6 @@ option('gl-dxinterop', type: 'feature', value: 'auto', description: 'OpenGL/Dire
option('gl-win32', type: 'feature', value: 'auto', description: 'OpenGL Win32 Backend')
option('gl-x11', type: 'feature', value: 'disabled', description: 'OpenGL X11/GLX (deprecated/legacy)')
option('jpeg', type: 'feature', value: 'auto', description: 'JPEG support')
-option('rpi', type: 'feature', value: 'disabled', description: 'Raspberry Pi support')
option('sdl2-video', type: 'feature', value: 'auto', description: 'SDL2 video output')
option('shaderc', type: 'feature', value: 'auto', description: 'libshaderc SPIR-V compiler')
option('sixel', type: 'feature', value:'auto', description: 'Sixel')
@@ -100,7 +99,6 @@ option('d3d-hwaccel', type: 'feature', value: 'auto', description: 'D3D11VA hwac
option('d3d9-hwaccel', type: 'feature', value: 'auto', description: 'DXVA2 hwaccel')
option('gl-dxinterop-d3d9', type: 'feature', value: 'auto', description: 'OpenGL/DirectX Interop Backend DXVA2 interop')
option('ios-gl', type: 'feature', value: 'auto', description: 'iOS OpenGL ES hardware decoding interop support')
-option('rpi-mmal', type: 'feature', value: 'auto', description: 'Raspberry Pi MMAL hwaccel')
option('videotoolbox-gl', type: 'feature', value: 'auto', description: 'Videotoolbox with OpenGL')
option('videotoolbox-pl', type: 'feature', value: 'auto', description: 'Videotoolbox with libplacebo')
option('vulkan-interop', type: 'feature', value: 'auto', description: 'Vulkan graphics interop')
diff --git a/video/out/gpu/context.c b/video/out/gpu/context.c
index 41ec2a4107..d842ddda91 100644
--- a/video/out/gpu/context.c
+++ b/video/out/gpu/context.c
@@ -41,7 +41,6 @@ extern const struct ra_ctx_fns ra_ctx_wayland_egl;
extern const struct ra_ctx_fns ra_ctx_wgl;
extern const struct ra_ctx_fns ra_ctx_angle;
extern const struct ra_ctx_fns ra_ctx_dxgl;
-extern const struct ra_ctx_fns ra_ctx_rpi;
extern const struct ra_ctx_fns ra_ctx_android;
/* Vulkan */
@@ -67,9 +66,6 @@ static const struct ra_ctx_fns *contexts[] = {
#if HAVE_EGL_ANDROID
&ra_ctx_android,
#endif
-#if HAVE_RPI
- &ra_ctx_rpi,
-#endif
#if HAVE_EGL_ANGLE_WIN32
&ra_ctx_angle,
#endif
diff --git a/video/out/gpu/hwdec.c b/video/out/gpu/hwdec.c
index c8098f3aad..c7d817c63a 100644
--- a/video/out/gpu/hwdec.c
+++ b/video/out/gpu/hwdec.c
@@ -34,7 +34,6 @@ extern const struct ra_hwdec_driver ra_hwdec_dxva2gldx;
extern const struct ra_hwdec_driver ra_hwdec_d3d11va;
extern const struct ra_hwdec_driver ra_hwdec_dxva2dxgi;
extern const struct ra_hwdec_driver ra_hwdec_cuda;
-extern const struct ra_hwdec_driver ra_hwdec_rpi_overlay;
extern const struct ra_hwdec_driver ra_hwdec_drmprime;
extern const struct ra_hwdec_driver ra_hwdec_drmprime_overlay;
extern const struct ra_hwdec_driver ra_hwdec_aimagereader;
@@ -70,9 +69,6 @@ const struct ra_hwdec_driver *const ra_hwdec_drivers[] = {
#if HAVE_VDPAU_GL_X11
&ra_hwdec_vdpau,
#endif
-#if HAVE_RPI_MMAL
- &ra_hwdec_rpi_overlay,
-#endif
#if HAVE_DRM
&ra_hwdec_drmprime,
&ra_hwdec_drmprime_overlay,
diff --git a/video/out/opengl/context_rpi.c b/video/out/opengl/context_rpi.c
deleted file mode 100644
index 0b6babbd1f..0000000000
--- a/video/out/opengl/context_rpi.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * mpv is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * mpv is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <assert.h>
-#include <stdatomic.h>
-#include <stddef.h>
-
-#include <bcm_host.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include "common/common.h"
-#include "video/out/win_state.h"
-#include "context.h"
-#include "egl_helpers.h"
-
-struct priv {
- struct GL gl;
- DISPMANX_DISPLAY_HANDLE_T display;
- DISPMANX_ELEMENT_HANDLE_T window;
- DISPMANX_UPDATE_HANDLE_T update;
- EGLDisplay egl_display;
- EGLConfig egl_config;
- EGLContext egl_context;
- EGLSurface egl_surface;
- // yep, the API keeps a pointer to it
- EGL_DISPMANX_WINDOW_T egl_window;
- int x, y, w, h;
- double display_fps;
- atomic_int reload_display;
- int win_params[4];
-};
-
-static void tv_callback(void *callback_data, uint32_t reason, uint32_t param1,
- uint32_t param2)
-{
- struct ra_ctx *ctx = callback_data;
- struct priv *p = ctx->priv;
- atomic_store(&p->reload_display, true);
- vo_wakeup(ctx->vo);
-}
-
-static void destroy_dispmanx(struct ra_ctx *ctx)
-{
- struct priv *p = ctx->priv;
-
- if (p->egl_surface) {
- eglMakeCurrent(p->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
- eglDestroySurface(p->egl_display, p->egl_surface);
- p->egl_surface = EGL_NO_SURFACE;
- }
-
- if (p->window)
- vc_dispmanx_element_remove(p->update, p->window);
- p->window = 0;
- if (p->display)
- vc_dispmanx_display_close(p->display);
- p->display = 0;
- if (p->update)
- vc_dispmanx_update_submit_sync(p->update);
- p->update = 0;
-}
-
-static void rpi_uninit(struct ra_ctx *ctx)
-{
- struct priv *p = ctx->priv;
- ra_gl_ctx_uninit(ctx);
-
- vc_tv_unregister_callback_full(tv_callback, ctx);
-
- destroy_dispmanx(ctx);
-
- if (p->egl_context)
- eglDestroyContext(p->egl_display, p->egl_context);
- p->egl_context = EGL_NO_CONTEXT;
- eglReleaseThread();
- p->egl_display = EGL_NO_DISPLAY;
-}
-
-static bool recreate_dispmanx(struct ra_ctx *ctx)
-{
- struct priv *p = ctx->priv;
- int display_nr = 0;
- int layer = 0;
-
- MP_VERBOSE(ctx, "Recreating DISPMANX state...\n");
-
- destroy_dispmanx(ctx);
-
- p->display = vc_dispmanx_display_open(display_nr);
- p->update = vc_dispmanx_update_start(0);
- if (!p->display || !p->update) {
- MP_FATAL(ctx, "Could not get DISPMANX objects.\n");
- goto fail;
- }
-
- uint32_t dispw, disph;
- if (graphics_get_display_size(0, &dispw, &disph) < 0) {
- MP_FATAL(ctx, "Could not get display size.\n");
- goto fail;
- }
- p->w = dispw;
- p->h = disph;
-
- if (ctx->vo->opts->fullscreen) {
- p->x = p->y = 0;
- } else {
- struct vo_win_geometry geo;
- struct mp_rect screenrc = {0, 0, p->w, p->h};
-
- vo_calc_window_geometry(ctx->vo, &screenrc, &geo);
-
- mp_rect_intersection(&geo.win, &screenrc);
-
- p->x = geo.win.x0;
- p->y = geo.win.y0;
- p->w = geo.win.x1 - geo.win.x0;
- p->h = geo.win.y1 - geo.win.y0;
- }
-
- // dispmanx is like a neanderthal version of Wayland - you can add an
- // overlay any place on the screen.
- VC_RECT_T dst = {.x = p->x, .y = p->y, .width = p->w, .height = p->h};
- VC_RECT_T src = {.width = p->w << 16, .height = p->h << 16};
- VC_DISPMANX_ALPHA_T alpha = {
- .flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,
- .opacity = 0xFF,
- };
- p->window = vc_dispmanx_element_add(p->update, p->display, layer, &dst, 0,
- &src, DISPMANX_PROTECTION_NONE, &alpha,
- 0, 0);
- if (!p->window) {
- MP_FATAL(ctx, "Could not add DISPMANX element.\n");
- goto fail;
- }
-
- vc_dispmanx_update_submit_sync(p->update);
- p->update = vc_dispmanx_update_start(0);
-
- p->egl_window = (EGL_DISPMANX_WINDOW_T){
- .element = p->window,
- .width = p->w,
- .height = p->h,
- };
- p->egl_surface = eglCreateWindowSurface(p->egl_display, p->egl_config,
- &p->egl_window, NULL);
-
- if (p->egl_surface == EGL_NO_SURFACE) {
- MP_FATAL(ctx, "Could not create EGL surface!\n");
- goto fail;
- }
-
- if (!eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface,
- p->egl_context))
- {
- MP_FATAL(ctx, "Failed to set context!\n");
- goto fail;
- }
-
- p->display_fps = 0;
- TV_GET_STATE_RESP_T tvstate;
- TV_DISPLAY_STATE_T tvstate_disp;
- if (!vc_tv_get_state(&tvstate) && !vc_tv_get_display_state(&tvstate_disp)) {
- if (tvstate_disp.state & (VC_HDMI_HDMI | VC_HDMI_DVI)) {
- p->display_fps = tvstate_disp.display.hdmi.frame_rate;
-
- HDMI_PROPERTY_PARAM_T param = {
- .property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE,
- };
- if (!vc_tv_hdmi_get_property(&param) &&
- param.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC)
- p->display_fps = p->display_fps / 1.001;
- } else {
- p->display_fps = tvstate_disp.display.sdtv.frame_rate;
- }
- }
-
- p->win_params[0] = display_nr;
- p->win_params[1] = layer;
- p->win_params[2] = p->x;
- p->win_params[3] = p->y;
-
- ctx->vo->dwidth = p->w;
- ctx->vo->dheight = p->h;
- if (ctx->swapchain)
- ra_gl_ctx_resize(ctx->swapchain, p->w, p->h, 0);
-
- ctx->vo->want_redraw = true;
-
- vo_event(ctx->vo, VO_EVENT_WIN_STATE);
- return true;
-
-fail:
- destroy_dispmanx(ctx);
- return false;
-}
-
-static void rpi_swap_buffers(struct ra_ctx *ctx)
-{
- struct priv *p = ctx->priv;
- eglSwapBuffers(p->egl_display, p->egl_surface);
-}
-
-static bool rpi_init(struct ra_ctx *ctx)
-{
- struct priv *p = ctx->priv = talloc_zero(ctx, struct priv);
-
- bcm_host_init();
-
- vc_tv_register_callback(tv_callback, ctx);
-
- p->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (!eglInitialize(p->egl_display, NULL, NULL)) {
- MP_FATAL(ctx, "EGL failed to initialize.\n");
- goto fail;
- }
-
- if (!mpegl_create_context(ctx, p->egl_display, &p->egl_context, &p->egl_config))
- goto fail;
-
- if (!recreate_dispmanx(ctx))
- goto fail;
-
- mpegl_load_functions(&p->gl, ctx->log);
-
- struct ra_gl_ctx_params params = {
- .swap_buffers = rpi_swap_buffers,
- };
-
- if (!ra_gl_ctx_init(ctx, &p->gl, params))
- goto fail;
-
- ra_add_native_resource(ctx->ra, "MPV_RPI_WINDOW", p->win_params);
-
- ra_gl_ctx_resize(ctx->swapchain, ctx->vo->dwidth, ctx->vo->dheight, 0);
- return true;
-
-fail:
- rpi_uninit(ctx);
- return false;
-}
-
-static bool rpi_reconfig(struct ra_ctx *ctx)
-{
- return recreate_dispmanx(ctx);
-}
-
-static struct mp_image *take_screenshot(struct ra_ctx *ctx)
-{
- struct priv *p = ctx->priv;
-
- if (!p->display)
- return NULL;
-
- struct mp_image *img = mp_image_alloc(IMGFMT_BGR0, p->w, p->h);
- if (!img)
- return NULL;
-
- DISPMANX_RESOURCE_HANDLE_T resource =
- vc_dispmanx_resource_create(VC_IMAGE_ARGB8888,
- img->w | ((img->w * 4) << 16), img->h,
- &(int32_t){0});
- if (!resource)
- goto fail;
-
- if (vc_dispmanx_snapshot(p->display, resource, 0))
- goto fail;
-
- VC_RECT_T rc = {.width = img->w, .height = img->h};
- if (vc_dispmanx_resource_read_data(resource, &rc, img->planes[0], img->stride[0]))
- goto fail;
-
- vc_dispmanx_resource_delete(resource);
- return img;
-
-fail:
- vc_dispmanx_resource_delete(resource);
- talloc_free(img);
- return NULL;
-}
-
-static int rpi_control(struct ra_ctx *ctx, int *events, int request, void *arg)
-{
- struct priv *p = ctx->priv;
-
- switch (request) {
- case VOCTRL_SCREENSHOT_WIN:
- *(struct mp_image **)arg = take_screenshot(ctx);
- return VO_TRUE;
- case VOCTRL_CHECK_EVENTS:
- if (atomic_fetch_and(&p->reload_display, 0)) {
- MP_WARN(ctx, "Recovering from display mode switch...\n");
- recreate_dispmanx(ctx);
- }
- return VO_TRUE;
- case VOCTRL_GET_DISPLAY_FPS:
- *(double *)arg = p->display_fps;
- return VO_TRUE;
- }
-
- return VO_NOTIMPL;
-}
-
-const struct ra_ctx_fns ra_ctx_rpi = {
- .type = "opengl",
- .name = "rpi",
- .reconfig = rpi_reconfig,
- .control = rpi_control,
- .init = rpi_init,
- .uninit = rpi_uninit,
-};
diff --git a/video/out/opengl/hwdec_rpi.c b/video/out/opengl/hwdec_rpi.c
deleted file mode 100644
index b90fae571d..0000000000
--- a/video/out/opengl/hwdec_rpi.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * mpv is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * mpv is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <stdbool.h>
-#include <assert.h>
-
-#include <bcm_host.h>
-#include <interface/mmal/mmal.h>
-#include <interface/mmal/util/mmal_util.h>
-#include <interface/mmal/util/mmal_default_components.h>
-#include <interface/mmal/vc/mmal_vc_api.h>
-
-#include <libavutil/rational.h>
-
-#include "common/common.h"
-#include "common/msg.h"
-#include "video/mp_image.h"
-#include "video/out/gpu/hwdec.h"
-
-#include "common.h"
-
-struct priv {
- struct mp_log *log;
-
- struct mp_image_params params;
-
- MMAL_COMPONENT_T *renderer;
- bool renderer_enabled;
-
- // for RAM input
- MMAL_POOL_T *swpool;
-
- struct mp_image *current_frame;
-
- struct mp_rect src, dst;
- int cur_window[4]; // raw user params
-};
-
-// Magic alignments (in pixels) expected by the MMAL internals.
-#define ALIGN_W 32
-#define ALIGN_H 16
-
-// Make mpi point to buffer, assuming MMAL_ENCODING_I420.
-// buffer can be NULL.
-// Return the required buffer space.
-static size_t layout_buffer(struct mp_image *mpi, MMAL_BUFFER_HEADER_T *buffer,
- struct mp_image_params *params)
-{
- assert(params->imgfmt == IMGFMT_420P);
- mp_image_set_params(mpi, params);
- int w = MP_ALIGN_UP(params->w, ALIGN_W);
- int h = MP_ALIGN_UP(params->h, ALIGN_H);
- uint8_t *cur = buffer ? buffer->data : NULL;
- size_t size = 0;
- for (int i = 0; i < 3; i++) {
- int div = i ? 2 : 1;
- mpi->planes[i] = cur;
- mpi->stride[i] = w / div;
- size_t plane_size = h / div * mpi->stride[i];
- if (cur)
- cur += plane_size;
- size += plane_size;
- }
- return size;
-}
-
-static MMAL_FOURCC_T map_csp(enum pl_color_system csp)
-{
- switch (csp) {
- case PL_COLOR_SYSTEM_BT_601: return MMAL_COLOR_SPACE_ITUR_BT601;
- case PL_COLOR_SYSTEM_BT_709: return MMAL_COLOR_SPACE_ITUR_BT709;
- case PL_COLOR_SYSTEM_SMPTE_240M: return MMAL_COLOR_SPACE_SMPTE240M;
- default: return MMAL_COLOR_SPACE_UNKNOWN;
- }
-}
-
-static void control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- mmal_buffer_header_release(buffer);
-}
-
-static void input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
-{
- struct mp_image *mpi = buffer->user_data;
- talloc_free(mpi);
-}
-
-static void disable_renderer(struct ra_hwdec *hw)
-{
- struct priv *p = hw->priv;
-
- if (p->renderer_enabled) {
- mmal_port_disable(p->renderer->control);
- mmal_port_disable(p->renderer->input[0]);
-
- mmal_port_flush(p->renderer->control);
- mmal_port_flush(p->renderer->input[0]);
-
- mmal_component_disable(p->renderer);
- }
- mmal_pool_destroy(p->swpool);
- p->swpool = NULL;
- p->renderer_enabled = false;
-}
-
-// check_window_only: assume params and dst/src rc are unchanged
-static void update_overlay(struct ra_hwdec *hw, bool check_window_only)
-{
- struct priv *p = hw->priv;
- MMAL_PORT_T *input = p->renderer->input[0];
- struct mp_rect src = p->src;
- struct mp_rect dst = p->dst;
-
- int defs[4] = {0, 0, 0, 0};
- int *z = ra_get_native_resource(hw->ra_ctx->ra, "MPV_RPI_WINDOW");
- if (!z)
- z = defs;
-
- // As documented in the libmpv openglcb headers.
- int display = z[0];
- int layer = z[1];
- int x = z[2];
- int y = z[3];
-
- if (check_window_only && memcmp(z, p->cur_window, sizeof(p->cur_window)) == 0)
- return;
-
- memcpy(p->cur_window, z, sizeof(p->cur_window));
-
- int rotate[] = {MMAL_DISPLAY_ROT0,
- MMAL_DISPLAY_ROT90,
- MMAL_DISPLAY_ROT180,
- MMAL_DISPLAY_ROT270};
-
- int src_w = src.x1 - src.x0, src_h = src.y1 - src.y0,
- dst_w = dst.x1 - dst.x0, dst_h = dst.y1 - dst.y0;
- int p_x, p_y;
- av_reduce(&p_x, &p_y, dst_w * src_h, src_w * dst_h, 16000);
- MMAL_DISPLAYREGION_T dr = {
- .hdr = { .id = MMAL_PARAMETER_DISPLAYREGION,
- .size = sizeof(MMAL_DISPLAYREGION_T), },
- .src_rect = { .x = src.x0, .y = src.y0,
- .width = src_w, .height = src_h },
- .dest_rect = { .x = dst.x0 + x, .y = dst.y0 + y,
- .width = dst_w, .height = dst_h },
- .layer = layer - 1, // under the GL layer
- .display_num = display,
- .pixel_x = p_x,
- .pixel_y = p_y,
- .transform = rotate[p->params.rotate / 90],
- .fullscreen = 0,
- .set = MMAL_DISPLAY_SET_SRC_RECT | MMAL_DISPLAY_SET_DEST_RECT |
- MMAL_DISPLAY_SET_LAYER | MMAL_DISPLAY_SET_NUM |
- MMAL_DISPLAY_SET_PIXEL | MMAL_DISPLAY_SET_TRANSFORM |
- MMAL_DISPLAY_SET_FULLSCREEN,
- };
-
- if (p->params.rotate % 180 == 90) {
- MPSWAP(int, dr.src_rect.x, dr.src_rect.y);
- MPSWAP(int, dr.src_rect.width, dr.src_rect.height);
- }
-
- if (mmal_port_parameter_set(input, &dr.hdr))
- MP_WARN(p, "could not set video rectangle\n");
-}
-
-static int enable_renderer(struct ra_hwdec *hw)
-{
- struct priv *p = hw->priv;
- MMAL_PORT_T *input = p->renderer->input[0];
- struct mp_image_params *params = &p->params;
-
- if (p->renderer_enabled)
- return 0;
-
- if (!params->imgfmt)
- return -1;
-
- bool opaque = params->imgfmt == IMGFMT_MMAL;
-
- input->format->encoding = opaque ? MMAL_ENCODING_OPAQUE : MMAL_ENCODING_I420;
- input->format->es->video.width = MP_ALIGN_UP(params->w, ALIGN_W);
- input->format->es->video.height = MP_ALIGN_UP(params->h, ALIGN_H);
- input->format->es->video.crop = (MMAL_RECT_T){0, 0, params->w, params->h};
- input->format->es->video.par = (MMAL_RATIONAL_T){params->p_w, params->p_h};
- input->format->es->video.color_space = map_csp(params->repr.sys);
-
- if (mmal_port_format_commit(input))
- return -1;
-
- input->buffer_num = MPMAX(input->buffer_num_min,
- input->buffer_num_recommended) + 3;
- input->buffer_size = MPMAX(input->buffer_size_min,
- input->buffer_size_recommended);
-
- if (!opaque) {
- size_t size = layout_buffer(&(struct mp_image){0}, NULL, params);
- if (input->buffer_size != size) {
- MP_FATAL(hw, "We disagree with MMAL about buffer sizes.\n");
- return -1;
- }
-
- p->swpool = mmal_pool_create(input->buffer_num, input->buffer_size);
- if (!p->swpool) {
- MP_FATAL(hw, "Could not allocate buffer pool.\n");
- return -1;
- }
- }
-
- update_overlay(hw, false);
-
- p->renderer_enabled = true;
-
- if (mmal_port_enable(p->renderer->control, control_port_cb))
- return -1;
-
- if (mmal_port_enable(input, input_port_cb))
- return -1;
-
- if (mmal_component_enable(p->renderer)) {
- MP_FATAL(hw, "Failed to enable video renderer.\n");
- return -1;
- }
-
- return 0;
-}
-
-static void free_mmal_buffer(void *arg)
-{
- MMAL_BUFFER_HEADER_T *buffer = arg;
- mmal_buffer_header_release(buffer);
-}
-
-static struct mp_image *upload(struct ra_hwdec *hw, struct mp_image *hw_image)
-{
- struct priv *p = hw->priv;
-
- MMAL_BUFFER_HEADER_T *buffer = mmal_queue_wait(p->swpool->queue);
- if (!buffer) {
- MP_ERR(hw, "Can't allocate buffer.\n");
- return NULL;
- }
- mmal_buffer_header_reset(buffer);
-
- struct mp_image *new_ref = mp_image_new_custom_ref(NULL, buffer,
- free_mmal_buffer);
- if (!new_ref) {
- mmal_buffer_header_release(buffer);
- MP_ERR(hw, "Out of memory.\n");
- return NULL;
- }
-
- mp_image_setfmt(new_ref, IMGFMT_MMAL);
- new_ref->planes[3] = (void *)buffer;
-
- struct mp_image dmpi = {0};
- buffer->length = layout_buffer(&dmpi, buffer, &p->params);
- mp_image_copy(&dmpi, hw_image);
-
- return new_ref;
-}
-
-static int overlay_frame(struct ra_hwdec *hw, struct mp_image *hw_image,
- struct mp_rect *src, struct mp_rect *dst, bool newframe)
-{
- struct priv *p = hw->priv;
-
- if (hw_image && !mp_image_params_equal(&p->params, &hw_image->params)) {
- p->params = hw_image->params;
-
- disable_renderer(hw);
- mp_image_unrefp(&p->current_frame);
-
- if (enable_renderer(hw) < 0)
- return -1;
- }
-
- if (hw_image && p->current_frame && !newframe) {
- if (!mp_rect_equals(&p->src, src) ||mp_rect_equals(&p->dst, dst)) {
- p->src = *src;
- p->dst = *dst;
- update_overlay(hw, false);
- }
- return 0; // don't reupload
- }
-
- mp_image_unrefp(&p->current_frame);
-
- if (!hw_image) {
- disable_renderer(hw);
- return 0;
- }
-
- if (enable_renderer(hw) < 0)
- return -1;
-
- update_overlay(hw, true);
-
- struct mp_image *mpi = NULL;
- if (hw_image->imgfmt == IMGFMT_MMAL) {
- mpi = mp_image_new_ref(hw_image);
- } else {
- mpi = upload(hw, hw_image);
- }
-
- if (!mpi) {
- disable_renderer(hw);
- return -1;
- }
-
- MMAL_BUFFER_HEADER_T *ref = (void *)mpi->planes[3];
-
- // Assume this field is free for use by us.
- ref->user_data = mpi;
-
- if (mmal_port_send_buffer(p->renderer->input[0], ref)) {
- MP_ERR(hw, "could not queue picture!\n");
- talloc_free(mpi);
- return -1;
- }
-
- return 0;
-}
-
-static void destroy(struct ra_hwdec *hw)
-{
- struct priv *p = hw->priv;
-
- disable_renderer(hw);
-
- if (p->renderer)
- mmal_component_release(p->renderer);
-
- mmal_vc_deinit();
-}
-
-static int create(struct ra_hwdec *hw)
-{
- struct priv *p = hw->priv;
- p->log = hw->log;
-
- bcm_host_init();
-
- if (mmal_vc_init()) {
- MP_FATAL(hw, "Could not initialize MMAL.\n");
- return -1;
- }
-
- if (mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &p->renderer))
- {
- MP_FATAL(hw, "Could not create MMAL renderer.\n");
- mmal_vc_deinit();
- return -1;
- }
-
- return 0;
-}
-
-const struct ra_hwdec_driver ra_hwdec_rpi_overlay = {
- .name = "rpi-overlay",
- .priv_size = sizeof(struct priv),
- .imgfmts = {IMGFMT_MMAL, IMGFMT_420P, 0},
- .init = create,
- .overlay_frame = overlay_frame,
- .uninit = destroy,
-};
diff --git a/video/out/vo.c b/video/out/vo.c
index ce93c66810..aa98bc8aea 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -63,7 +63,6 @@ extern const struct vo_driver video_out_sdl;
extern const struct vo_driver video_out_vaapi;
extern const struct vo_driver video_out_dmabuf_wayland;
extern const struct vo_driver video_out_wlshm;
-extern const struct vo_driver video_out_rpi;
extern const struct vo_driver video_out_tct;
extern const struct vo_driver video_out_sixel;
extern const struct vo_driver video_out_kitty;
@@ -110,9 +109,6 @@ static const struct vo_driver *const video_out_drivers[] =
#if HAVE_DRM
&video_out_drm,
#endif
-#if HAVE_RPI_MMAL
- &video_out_rpi,
-#endif
#if HAVE_SIXEL
&video_out_sixel,
#endif
diff --git a/video/out/vo_rpi.c b/video/out/vo_rpi.c
deleted file mode 100644
index 7fd65979b0..0000000000
--- a/video/out/vo_rpi.c
+++ /dev/null
@@ -1,938 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * mpv is free software; you can redistribute it and/or
- * modify it unde