diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:13:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:13:14 +0000 |
commit | 60e8a3d404f0640fa5a3f834eae54b4f1fb9127d (patch) | |
tree | 1da89a218d0ecf010c67a87cb2f625c4cb18e7d7 /video/out/opengl/hwdec_rpi.c | |
parent | Adding upstream version 0.37.0. (diff) | |
download | mpv-60e8a3d404f0640fa5a3f834eae54b4f1fb9127d.tar.xz mpv-60e8a3d404f0640fa5a3f834eae54b4f1fb9127d.zip |
Adding upstream version 0.38.0.upstream/0.38.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'video/out/opengl/hwdec_rpi.c')
-rw-r--r-- | video/out/opengl/hwdec_rpi.c | 384 |
1 files changed, 0 insertions, 384 deletions
diff --git a/video/out/opengl/hwdec_rpi.c b/video/out/opengl/hwdec_rpi.c deleted file mode 100644 index 5362832..0000000 --- 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 mp_csp csp) -{ - switch (csp) { - case MP_CSP_BT_601: return MMAL_COLOR_SPACE_ITUR_BT601; - case MP_CSP_BT_709: return MMAL_COLOR_SPACE_ITUR_BT709; - case MP_CSP_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->color.space); - - 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, -}; |