mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2026-11-06 05:17:42 +00:00
swscale/loongarch: add unscaled NV12/NV21 to 32-bit RGB conversions
Add fast path for NV12/NV21 to RGBA/ARGB/BGRA/ABGR conversions. The LSX implementations are based on the unscaled YUV420P to RGBA/ARGB/ BGRA/ABGR conversions. The difference is that the NV12/NV21 load UV data from src[1], and then use `vshuf` to prepare the U and V data. The C reference implementations work as the runtime fallback when LSX is unavailable, and are mainly used by the checkasm yuv2rgb test to verify the LSX path. The LSX implementations use the fixed-point coefficient math, while the C references use the lookup tables like yuv2rgb_c_32, both differ by at most a couple of LSBs. checkasm --bench on 3A5000 4 cores 2.5GHz: nv21_bgra_8_c: 14.5 nv21_bgra_8_lsx: 7.6 ( 1.88x) nv21_bgra_128_c: 220.1 nv21_bgra_128_lsx: 35.6 ( 6.17x) nv21_bgra_1080_c: 1819.7 nv21_bgra_1080_lsx: 304.0 ( 5.98x) nv21_bgra_1920_c: 3236.6 nv21_bgra_1920_lsx: 510.8 ( 6.33x) Performance with: $ ./ffmpeg -cpuflags lsx -f lavfi -i "smptebars=size=3840x2160:rate=30:duration=100,format=nv12" \ -threads 1 -vf "format=bgra" -f null - before: 14fps after : 114fps
This commit is contained in:
1 parent
c766e0de78
commit
8e940665d0
6 files changed
+401
No files matched your search
@@ -5,6 +5,7 @@ LASX-OBJS-$(CONFIG_SWSCALE) += loongarch/swscale_lasx.o \
|
||||
loongarch/rgb2rgb_lasx.o \
|
||||
loongarch/output_lasx.o
|
||||
LSX-OBJS-$(CONFIG_SWSCALE) += loongarch/swscale.o \
|
||||
loongarch/swscale_unscaled.o \
|
||||
loongarch/swscale_lsx.o \
|
||||
loongarch/input.o \
|
||||
loongarch/output.o \
|
||||
|
||||
@@ -208,4 +208,26 @@ av_cold void ff_sws_init_output_lasx(SwsInternal *c,
|
||||
yuv2anyX_fn *yuv2anyX);
|
||||
#endif // #if HAVE_LASX
|
||||
|
||||
int yuv420_nv12_bgra32_lsx(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
|
||||
int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
|
||||
int yuv420_nv21_bgra32_lsx(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
|
||||
int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
|
||||
int yuv420_nv12_rgba32_lsx(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
|
||||
int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
|
||||
int yuv420_nv21_rgba32_lsx(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
|
||||
int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
|
||||
int yuv420_nv12_argb32_lsx(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
|
||||
int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
|
||||
int yuv420_nv21_argb32_lsx(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
|
||||
int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
|
||||
int yuv420_nv12_abgr32_lsx(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
|
||||
int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
|
||||
int yuv420_nv21_abgr32_lsx(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
|
||||
int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
|
||||
|
||||
int ff_nv12ToRgb32_c(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
|
||||
int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
|
||||
int ff_nv21ToRgb32_c(SwsInternal *c, const uint8_t *const src[], const int srcStride[],
|
||||
int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
|
||||
|
||||
#endif /* SWSCALE_LOONGARCH_SWSCALE_LOONGARCH_H */
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Loongson Technology Co. Ltd.
|
||||
* Contributed by Bo Jin(jinbo@loongson.cn)
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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.
|
||||
*
|
||||
* FFmpeg 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 FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "swscale_loongarch.h"
|
||||
#include "libswscale/swscale_internal.h"
|
||||
#include "libavutil/loongarch/cpu.h"
|
||||
|
||||
/* C reference implementations of the unscaled NV12/NV21 -> 32-bit RGB
|
||||
* conversions (interleaved chroma consumed from src[1]). They work as
|
||||
* the runtime fallback on LoongArch when LSX is unavailable, so they use
|
||||
* the lookup-table math (like yuv2rgb_c_32) rather than the fixed-point
|
||||
* coefficient form; the LSX implementations differ from them by at most
|
||||
* a couple of LSBs, which the checkasm yuv2rgb test tolerates. */
|
||||
#define NVXXRGB32FUNC(func_name, uv_swap) \
|
||||
int func_name(SwsInternal *c, const uint8_t *const src[], \
|
||||
const int srcStride[], int srcSliceY, int srcSliceH, \
|
||||
uint8_t *const dst[], const int dstStride[]) \
|
||||
{ \
|
||||
int y; \
|
||||
\
|
||||
for (y = 0; y < srcSliceH; y++) { \
|
||||
int yd = y + srcSliceY; \
|
||||
uint32_t *dest = (uint32_t *)(dst[0] + yd * dstStride[0]); \
|
||||
const uint8_t *py = src[0] + y * srcStride[0]; \
|
||||
const uint8_t *puv = src[1] + (y >> 1) * srcStride[1]; \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < c->opts.dst_w; i++) { \
|
||||
int Y = py[i]; \
|
||||
int U = puv[(i >> 1) * 2 + uv_swap]; \
|
||||
int V = puv[(i >> 1) * 2 + (uv_swap ^ 1)]; \
|
||||
uint32_t *r = (void *)c->table_rV[V+YUVRGB_TABLE_HEADROOM]; \
|
||||
uint32_t *g = (void *)(c->table_gU[U+YUVRGB_TABLE_HEADROOM] \
|
||||
+ c->table_gV[V+YUVRGB_TABLE_HEADROOM]); \
|
||||
uint32_t *b = (void *)c->table_bU[U+YUVRGB_TABLE_HEADROOM]; \
|
||||
dest[i] = r[Y] + g[Y] + b[Y]; \
|
||||
} \
|
||||
} \
|
||||
return srcSliceH; \
|
||||
}
|
||||
|
||||
NVXXRGB32FUNC(ff_nv12ToRgb32_c, 0)
|
||||
NVXXRGB32FUNC(ff_nv21ToRgb32_c, 1)
|
||||
|
||||
/* Unscaled NV12/NV21 -> packed 32-bit RGB */
|
||||
void ff_get_unscaled_swscale_loongarch(SwsInternal *c)
|
||||
{
|
||||
int cpu_flags = av_get_cpu_flags();
|
||||
int use_lsx = have_lsx(cpu_flags);
|
||||
|
||||
if ((c->opts.dst_w & 1) || (c->opts.dst_h & 1) ||
|
||||
(c->opts.flags & (SWS_ACCURATE_RND | SWS_BITEXACT | SWS_FULL_CHR_H_INT)))
|
||||
return;
|
||||
|
||||
if (c->opts.src_format != AV_PIX_FMT_NV12 &&
|
||||
c->opts.src_format != AV_PIX_FMT_NV21)
|
||||
return;
|
||||
|
||||
switch (c->opts.dst_format) {
|
||||
case AV_PIX_FMT_RGBA:
|
||||
c->convert_unscaled = use_lsx ?
|
||||
(c->opts.src_format == AV_PIX_FMT_NV12 ? yuv420_nv12_rgba32_lsx
|
||||
: yuv420_nv21_rgba32_lsx) :
|
||||
(c->opts.src_format == AV_PIX_FMT_NV12 ? ff_nv12ToRgb32_c
|
||||
: ff_nv21ToRgb32_c);
|
||||
break;
|
||||
case AV_PIX_FMT_ARGB:
|
||||
c->convert_unscaled = use_lsx ?
|
||||
(c->opts.src_format == AV_PIX_FMT_NV12 ? yuv420_nv12_argb32_lsx
|
||||
: yuv420_nv21_argb32_lsx) :
|
||||
(c->opts.src_format == AV_PIX_FMT_NV12 ? ff_nv12ToRgb32_c
|
||||
: ff_nv21ToRgb32_c);
|
||||
break;
|
||||
case AV_PIX_FMT_BGRA:
|
||||
c->convert_unscaled = use_lsx ?
|
||||
(c->opts.src_format == AV_PIX_FMT_NV12 ? yuv420_nv12_bgra32_lsx
|
||||
: yuv420_nv21_bgra32_lsx) :
|
||||
(c->opts.src_format == AV_PIX_FMT_NV12 ? ff_nv12ToRgb32_c
|
||||
: ff_nv21ToRgb32_c);
|
||||
break;
|
||||
case AV_PIX_FMT_ABGR:
|
||||
c->convert_unscaled = use_lsx ?
|
||||
(c->opts.src_format == AV_PIX_FMT_NV12 ? yuv420_nv12_abgr32_lsx
|
||||
: yuv420_nv21_abgr32_lsx) :
|
||||
(c->opts.src_format == AV_PIX_FMT_NV12 ? ff_nv12ToRgb32_c
|
||||
: ff_nv21ToRgb32_c);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
c->dst_slice_align = 2;
|
||||
}
|
||||
@@ -46,6 +46,17 @@
|
||||
DUP2_ARG2(__lsx_vilvh_b, zero, m_y1, zero, m_y2, m_y1_h, m_y2_h); \
|
||||
DUP2_ARG2(__lsx_vilvl_b, zero, m_y1, zero, m_y2, m_y1, m_y2); \
|
||||
|
||||
#define LOAD_YUV_16_NV12 \
|
||||
m_y1 = __lsx_vld(py_1, 0); \
|
||||
m_y2 = __lsx_vld(py_2, 0); \
|
||||
m_uv = __lsx_vld(puv, 0); \
|
||||
m_u = __lsx_vshuf_b(zero, m_uv, shuf_u); \
|
||||
m_u_h = __lsx_vshuf_b(zero, m_uv, shuf_uh); \
|
||||
m_v = __lsx_vshuf_b(zero, m_uv, shuf_v); \
|
||||
m_v_h = __lsx_vshuf_b(zero, m_uv, shuf_vh); \
|
||||
DUP2_ARG2(__lsx_vilvh_b, zero, m_y1, zero, m_y2, m_y1_h, m_y2_h); \
|
||||
DUP2_ARG2(__lsx_vilvl_b, zero, m_y1, zero, m_y2, m_y1, m_y2); \
|
||||
|
||||
/* YUV2RGB method
|
||||
* The conversion method is as follows:
|
||||
* R = Y' * y_coeff + V' * vr_coeff
|
||||
@@ -252,6 +263,83 @@
|
||||
return srcSliceH; \
|
||||
}
|
||||
|
||||
#define SHUF_UV_EVEN {0x1002100210001000, 0x1006100610041004}
|
||||
#define SHUF_UV_EVEN_HI {0x100a100a10081008, 0x100e100e100c100c}
|
||||
#define SHUF_UV_ODD {0x1003100310011001, 0x1007100710051005}
|
||||
#define SHUF_UV_ODD_HI {0x100b100b10091009, 0x100f100f100d100d}
|
||||
|
||||
#define YUV2RGBFUNC32_NV12(func_name, dst_type, alpha, \
|
||||
SHUF_U, SHUF_UH, SHUF_V, SHUF_VH) \
|
||||
int func_name(SwsInternal *c, const uint8_t *const src[], \
|
||||
const int srcStride[], int srcSliceY, int srcSliceH, \
|
||||
uint8_t *const dst[], const int dstStride[]) \
|
||||
{ \
|
||||
int x, y, h_size, vshift, res; \
|
||||
__m128i m_y1, m_y2, m_u, m_v, m_uv; \
|
||||
__m128i m_y1_h, m_y2_h, m_u_h, m_v_h; \
|
||||
__m128i y_1, y_2, u2g, v2g, u2b, v2r, rgb1_l, rgb1_h; \
|
||||
__m128i rgb2_l, rgb2_h, r1, g1, b1, r2, g2, b2; \
|
||||
__m128i a = __lsx_vldi(0xFF); \
|
||||
__m128i zero = __lsx_vldi(0); \
|
||||
__m128i shuf_u = SHUF_U; \
|
||||
__m128i shuf_uh = SHUF_UH; \
|
||||
__m128i shuf_v = SHUF_V; \
|
||||
__m128i shuf_vh = SHUF_VH; \
|
||||
\
|
||||
YUV2RGB_LOAD_COE \
|
||||
\
|
||||
h_size = c->opts.dst_w >> 4; \
|
||||
res = (c->opts.dst_w & 15) >> 1; \
|
||||
vshift = c->opts.src_format != AV_PIX_FMT_YUV422P; \
|
||||
for (y = 0; y < srcSliceH; y += 2) { \
|
||||
int yd = y + srcSliceY; \
|
||||
dst_type av_unused *r, *g, *b; \
|
||||
dst_type *image1 = (dst_type *)(dst[0] + (yd) * dstStride[0]); \
|
||||
dst_type *image2 = (dst_type *)(dst[0] + (yd + 1) * dstStride[0]); \
|
||||
const uint8_t *py_1 = src[0] + y * srcStride[0]; \
|
||||
const uint8_t *py_2 = py_1 + srcStride[0]; \
|
||||
const uint8_t *puv = src[1] + (y >> vshift) * srcStride[1]; \
|
||||
for(x = 0; x < h_size; x++) { \
|
||||
|
||||
#define DEALYUV2RGBREMAIN32_NV12 \
|
||||
py_1 += 16; \
|
||||
py_2 += 16; \
|
||||
puv += 16; \
|
||||
image1 += 16; \
|
||||
image2 += 16; \
|
||||
} \
|
||||
for (x = 0; x < res; x++) { \
|
||||
av_unused int U, V, Y; \
|
||||
U = puv[0]; \
|
||||
V = puv[1]; \
|
||||
r = (void *)c->table_rV[V+YUVRGB_TABLE_HEADROOM]; \
|
||||
g = (void *)(c->table_gU[U+YUVRGB_TABLE_HEADROOM] \
|
||||
+ c->table_gV[V+YUVRGB_TABLE_HEADROOM]); \
|
||||
b = (void *)c->table_bU[U+YUVRGB_TABLE_HEADROOM]; \
|
||||
|
||||
#define DEALYUV2RGBREMAIN32_NV21 \
|
||||
py_1 += 16; \
|
||||
py_2 += 16; \
|
||||
puv += 16; \
|
||||
image1 += 16; \
|
||||
image2 += 16; \
|
||||
} \
|
||||
for (x = 0; x < res; x++) { \
|
||||
av_unused int U, V, Y; \
|
||||
U = puv[1]; \
|
||||
V = puv[0]; \
|
||||
r = (void *)c->table_rV[V+YUVRGB_TABLE_HEADROOM]; \
|
||||
g = (void *)(c->table_gU[U+YUVRGB_TABLE_HEADROOM] \
|
||||
+ c->table_gV[V+YUVRGB_TABLE_HEADROOM]); \
|
||||
b = (void *)c->table_bU[U+YUVRGB_TABLE_HEADROOM]; \
|
||||
|
||||
#define ENDRES32_NV12 \
|
||||
puv += 2; \
|
||||
py_1 += 2; \
|
||||
py_2 += 2; \
|
||||
image1 += 2; \
|
||||
image2 += 2; \
|
||||
|
||||
YUV2RGBFUNC(yuv420_rgb24_lsx, uint8_t, 0)
|
||||
LOAD_YUV_16
|
||||
YUV2RGB(m_y1, m_y2, m_u, m_v, r1, g1, b1, r2, g2, b2);
|
||||
@@ -359,3 +447,179 @@ YUV2RGBFUNC32(yuv420_abgr32_lsx, uint32_t, 0)
|
||||
PUTRGB(image2, py_2);
|
||||
ENDRES32
|
||||
END_FUNC()
|
||||
|
||||
YUV2RGBFUNC32_NV12(yuv420_nv12_bgra32_lsx, uint32_t, 0,
|
||||
SHUF_UV_EVEN,
|
||||
SHUF_UV_EVEN_HI,
|
||||
SHUF_UV_ODD,
|
||||
SHUF_UV_ODD_HI)
|
||||
LOAD_YUV_16_NV12
|
||||
YUV2RGB(m_y1, m_y2, m_u, m_v, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(b1, g1, r1, a, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(b2, g2, r2, a, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2);
|
||||
YUV2RGB(m_y1_h, m_y2_h, m_u_h, m_v_h, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(b1, g1, r1, a, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(b2, g2, r2, a, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1 + 8);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2 + 8);
|
||||
DEALYUV2RGBREMAIN32_NV12
|
||||
PUTRGB(image1, py_1);
|
||||
PUTRGB(image2, py_2);
|
||||
ENDRES32_NV12
|
||||
END_FUNC()
|
||||
|
||||
YUV2RGBFUNC32_NV12(yuv420_nv21_bgra32_lsx, uint32_t, 0,
|
||||
SHUF_UV_ODD,
|
||||
SHUF_UV_ODD_HI,
|
||||
SHUF_UV_EVEN,
|
||||
SHUF_UV_EVEN_HI)
|
||||
LOAD_YUV_16_NV12
|
||||
YUV2RGB(m_y1, m_y2, m_u, m_v, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(b1, g1, r1, a, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(b2, g2, r2, a, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2);
|
||||
YUV2RGB(m_y1_h, m_y2_h, m_u_h, m_v_h, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(b1, g1, r1, a, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(b2, g2, r2, a, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1 + 8);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2 + 8);
|
||||
DEALYUV2RGBREMAIN32_NV21
|
||||
PUTRGB(image1, py_1);
|
||||
PUTRGB(image2, py_2);
|
||||
ENDRES32_NV12
|
||||
END_FUNC()
|
||||
|
||||
YUV2RGBFUNC32_NV12(yuv420_nv12_rgba32_lsx, uint32_t, 0,
|
||||
SHUF_UV_EVEN,
|
||||
SHUF_UV_EVEN_HI,
|
||||
SHUF_UV_ODD,
|
||||
SHUF_UV_ODD_HI)
|
||||
LOAD_YUV_16_NV12
|
||||
YUV2RGB(m_y1, m_y2, m_u, m_v, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(r1, g1, b1, a, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(r2, g2, b2, a, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2);
|
||||
YUV2RGB(m_y1_h, m_y2_h, m_u_h, m_v_h, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(r1, g1, b1, a, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(r2, g2, b2, a, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1 + 8);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2 + 8);
|
||||
DEALYUV2RGBREMAIN32_NV12
|
||||
PUTRGB(image1, py_1);
|
||||
PUTRGB(image2, py_2);
|
||||
ENDRES32_NV12
|
||||
END_FUNC()
|
||||
|
||||
YUV2RGBFUNC32_NV12(yuv420_nv21_rgba32_lsx, uint32_t, 0,
|
||||
SHUF_UV_ODD,
|
||||
SHUF_UV_ODD_HI,
|
||||
SHUF_UV_EVEN,
|
||||
SHUF_UV_EVEN_HI)
|
||||
LOAD_YUV_16_NV12
|
||||
YUV2RGB(m_y1, m_y2, m_u, m_v, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(r1, g1, b1, a, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(r2, g2, b2, a, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2);
|
||||
YUV2RGB(m_y1_h, m_y2_h, m_u_h, m_v_h, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(r1, g1, b1, a, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(r2, g2, b2, a, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1 + 8);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2 + 8);
|
||||
DEALYUV2RGBREMAIN32_NV21
|
||||
PUTRGB(image1, py_1);
|
||||
PUTRGB(image2, py_2);
|
||||
ENDRES32_NV12
|
||||
END_FUNC()
|
||||
|
||||
YUV2RGBFUNC32_NV12(yuv420_nv12_argb32_lsx, uint32_t, 0,
|
||||
SHUF_UV_EVEN,
|
||||
SHUF_UV_EVEN_HI,
|
||||
SHUF_UV_ODD,
|
||||
SHUF_UV_ODD_HI)
|
||||
LOAD_YUV_16_NV12
|
||||
YUV2RGB(m_y1, m_y2, m_u, m_v, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(a, r1, g1, b1, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(a, r2, g2, b2, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2);
|
||||
YUV2RGB(m_y1_h, m_y2_h, m_u_h, m_v_h, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(a, r1, g1, b1, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(a, r2, g2, b2, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1 + 8);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2 + 8);
|
||||
DEALYUV2RGBREMAIN32_NV12
|
||||
PUTRGB(image1, py_1);
|
||||
PUTRGB(image2, py_2);
|
||||
ENDRES32_NV12
|
||||
END_FUNC()
|
||||
|
||||
YUV2RGBFUNC32_NV12(yuv420_nv21_argb32_lsx, uint32_t, 0,
|
||||
SHUF_UV_ODD,
|
||||
SHUF_UV_ODD_HI,
|
||||
SHUF_UV_EVEN,
|
||||
SHUF_UV_EVEN_HI)
|
||||
LOAD_YUV_16_NV12
|
||||
YUV2RGB(m_y1, m_y2, m_u, m_v, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(a, r1, g1, b1, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(a, r2, g2, b2, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2);
|
||||
YUV2RGB(m_y1_h, m_y2_h, m_u_h, m_v_h, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(a, r1, g1, b1, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(a, r2, g2, b2, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1 + 8);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2 + 8);
|
||||
DEALYUV2RGBREMAIN32_NV21
|
||||
PUTRGB(image1, py_1);
|
||||
PUTRGB(image2, py_2);
|
||||
ENDRES32_NV12
|
||||
END_FUNC()
|
||||
|
||||
YUV2RGBFUNC32_NV12(yuv420_nv12_abgr32_lsx, uint32_t, 0,
|
||||
SHUF_UV_EVEN,
|
||||
SHUF_UV_EVEN_HI,
|
||||
SHUF_UV_ODD,
|
||||
SHUF_UV_ODD_HI)
|
||||
LOAD_YUV_16_NV12
|
||||
YUV2RGB(m_y1, m_y2, m_u, m_v, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(a, b1, g1, r1, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(a, b2, g2, r2, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2);
|
||||
YUV2RGB(m_y1_h, m_y2_h, m_u_h, m_v_h, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(a, b1, g1, r1, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(a, b2, g2, r2, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1 + 8);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2 + 8);
|
||||
DEALYUV2RGBREMAIN32_NV12
|
||||
PUTRGB(image1, py_1);
|
||||
PUTRGB(image2, py_2);
|
||||
ENDRES32_NV12
|
||||
END_FUNC()
|
||||
|
||||
YUV2RGBFUNC32_NV12(yuv420_nv21_abgr32_lsx, uint32_t, 0,
|
||||
SHUF_UV_ODD,
|
||||
SHUF_UV_ODD_HI,
|
||||
SHUF_UV_EVEN,
|
||||
SHUF_UV_EVEN_HI)
|
||||
LOAD_YUV_16_NV12
|
||||
YUV2RGB(m_y1, m_y2, m_u, m_v, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(a, b1, g1, r1, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(a, b2, g2, r2, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2);
|
||||
YUV2RGB(m_y1_h, m_y2_h, m_u_h, m_v_h, r1, g1, b1, r2, g2, b2);
|
||||
RGB32_PACK(a, b1, g1, r1, rgb1_l, rgb1_h);
|
||||
RGB32_PACK(a, b2, g2, r2, rgb2_l, rgb2_h);
|
||||
RGB32_STORE(rgb1_l, rgb1_h, image1 + 8);
|
||||
RGB32_STORE(rgb2_l, rgb2_h, image2 + 8);
|
||||
DEALYUV2RGBREMAIN32_NV21
|
||||
PUTRGB(image1, py_1);
|
||||
PUTRGB(image2, py_2);
|
||||
ENDRES32_NV12
|
||||
END_FUNC()
|
||||
@@ -1013,6 +1013,7 @@ void ff_get_unscaled_swscale(SwsInternal *c);
|
||||
void ff_get_unscaled_swscale_ppc(SwsInternal *c);
|
||||
void ff_get_unscaled_swscale_arm(SwsInternal *c);
|
||||
void ff_get_unscaled_swscale_aarch64(SwsInternal *c);
|
||||
void ff_get_unscaled_swscale_loongarch(SwsInternal *c);
|
||||
|
||||
void ff_sws_init_scale(SwsInternal *c);
|
||||
|
||||
|
||||
@@ -2702,6 +2702,8 @@ void ff_get_unscaled_swscale(SwsInternal *c)
|
||||
ff_get_unscaled_swscale_arm(c);
|
||||
#elif ARCH_AARCH64
|
||||
ff_get_unscaled_swscale_aarch64(c);
|
||||
#elif ARCH_LOONGARCH64 && HAVE_LSX
|
||||
ff_get_unscaled_swscale_loongarch(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user