From 253696dd196f031463ae67b292804a8b073de646 Mon Sep 17 00:00:00 2001 From: Arnaud de Turckheim Date: Wed, 4 Jun 2025 16:22:19 +0200 Subject: [PATCH] upipe_audio_graph: support nv12 format --- lib/upipe-filters/upipe_audio_graph.c | 62 ++++++++++++++++----------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/lib/upipe-filters/upipe_audio_graph.c b/lib/upipe-filters/upipe_audio_graph.c index ec62bb3b9..6ad2d19b5 100644 --- a/lib/upipe-filters/upipe_audio_graph.c +++ b/lib/upipe-filters/upipe_audio_graph.c @@ -1,6 +1,8 @@ /* * Copyright (C) 2016 Open Broadcast Systems Ltd * Copyright (C) 2016 OpenHeadend S.A.R.L. + * Copyright (C) 2025 EasyTools + * * * Authors: Rafaël Carré * Christophe Massiot @@ -215,12 +217,23 @@ static void copy_color(uint8_t **dst, size_t *strides, uint8_t *hsubs, uint8_t *vsubs, const uint8_t *color, unsigned row, unsigned col, unsigned w) { - memset(&dst[0][(row / vsubs[0]) * strides[0] + col / hsubs[0]], - color[0], w / hsubs[0]); // y8 - memset(&dst[1][(row / vsubs[1]) * strides[1] + col / hsubs[1]], - color[1], w / hsubs[1]); // u8 - memset(&dst[2][(row / vsubs[2]) * strides[2] + col / hsubs[2]], - color[2], w / hsubs[2]); // v8 + if (dst[0] != NULL) + memset(&dst[0][(row / vsubs[0]) * strides[0] + col / hsubs[0]], + color[0], w / hsubs[0]); // y8 + if (dst[1] != NULL) + memset(&dst[1][(row / vsubs[1]) * strides[1] + col / hsubs[1]], + color[1], w / hsubs[1]); // u8 + if (dst[2] != NULL) + memset(&dst[2][(row / vsubs[2]) * strides[2] + col / hsubs[2]], + color[2], w / hsubs[2]); // v8 + if (dst[3] != NULL) { // u8v8 + uint8_t *p = + &dst[3][(row / vsubs[3]) * strides[3] + 2 * col / hsubs[3]]; + for (int i = 0; i < w / hsubs[3]; i++) { + p[i * 2] = color[1]; + p[i * 2 + 1] = color[2]; + } + } } /** @internal @This handles data. @@ -262,19 +275,19 @@ static bool upipe_agraph_handle(struct upipe *upipe, struct uref *uref, upipe_agraph->vsize); uref_attach_ubuf(uref, ubuf); - uint8_t *dst[4]; - size_t strides[4]; - uint8_t hsubs[4]; - uint8_t vsubs[4]; - static const char *chroma[3] = { "y8", "u8", "v8" }; - for (int i = 0; i < 3; i++) { - if (unlikely(!ubase_check(uref_pic_plane_write(uref, chroma[i], - 0, 0, -1, -1, &dst[i])) || - !ubase_check(uref_pic_plane_size(uref, chroma[i], - &strides[i], &hsubs[i], &vsubs[i], NULL)))) { - upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); - uref_free(uref); - return true; + static const char *chroma[4] = { "y8", "u8", "v8", "u8v8" }; +#define NR_CHROMA UBASE_ARRAY_SIZE(chroma) + uint8_t *dst[NR_CHROMA]; + size_t strides[NR_CHROMA]; + uint8_t hsubs[NR_CHROMA]; + uint8_t vsubs[NR_CHROMA]; + for (int i = 0; i < NR_CHROMA; i++) { + if (unlikely( + !ubase_check(uref_pic_plane_size(uref, chroma[i], &strides[i], + &hsubs[i], &vsubs[i], NULL)) || + !ubase_check(uref_pic_plane_write(uref, chroma[i], 0, 0, -1, -1, + &dst[i])))) { + dst[i] = NULL; } } @@ -366,8 +379,10 @@ static bool upipe_agraph_handle(struct upipe *upipe, struct uref *uref, upipe_agraph->hsize); } - for (int i = 0; i < 3; i++) - ubuf_pic_plane_unmap(ubuf, chroma[i], 0, 0, -1, -1); + for (int i = 0; i < NR_CHROMA; i++) + if (dst[i]) + ubuf_pic_plane_unmap(ubuf, chroma[i], 0, 0, -1, -1); + uref_pic_set_progressive(uref); upipe_agraph_output(upipe, uref, upump_p); return true; @@ -403,11 +418,8 @@ static void upipe_agraph_input(struct upipe *upipe, struct uref *uref, static int upipe_agraph_check_flow_format(struct upipe *upipe, struct uref *flow_format) { - if (flow_format != NULL) { - if (unlikely(!ubase_check(uref_pic_flow_check_yuv420p(flow_format)))) - uref_pic_flow_set_yuv420p(flow_format); + if (flow_format != NULL) upipe_agraph_require_ubuf_mgr(upipe, flow_format); - } return UBASE_ERR_NONE; }