FFmpeg
Loading...
Searching...
No Matches
swscale_unscaled.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 Loongson Technology Co. Ltd.
3 * Contributed by Bo Jin(jinbo@loongson.cn)
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include "swscale_loongarch.h"
25
26/* C reference implementations of the unscaled NV12/NV21 -> 32-bit RGB
27 * conversions (interleaved chroma consumed from src[1]). They work as
28 * the runtime fallback on LoongArch when LSX is unavailable, so they use
29 * the lookup-table math (like yuv2rgb_c_32) rather than the fixed-point
30 * coefficient form; the LSX implementations differ from them by at most
31 * a couple of LSBs, which the checkasm yuv2rgb test tolerates. */
32#define NVXXRGB32FUNC(func_name, uv_swap) \
33int func_name(SwsInternal *c, const uint8_t *const src[], \
34 const int srcStride[], int srcSliceY, int srcSliceH, \
35 uint8_t *const dst[], const int dstStride[]) \
36{ \
37 int y; \
38 \
39 for (y = 0; y < srcSliceH; y++) { \
40 int yd = y + srcSliceY; \
41 uint32_t *dest = (uint32_t *)(dst[0] + yd * dstStride[0]); \
42 const uint8_t *py = src[0] + y * srcStride[0]; \
43 const uint8_t *puv = src[1] + (y >> 1) * srcStride[1]; \
44 int i; \
45 \
46 for (i = 0; i < c->opts.dst_w; i++) { \
47 int Y = py[i]; \
48 int U = puv[(i >> 1) * 2 + uv_swap]; \
49 int V = puv[(i >> 1) * 2 + (uv_swap ^ 1)]; \
50 uint32_t *r = (void *)c->table_rV[V+YUVRGB_TABLE_HEADROOM]; \
51 uint32_t *g = (void *)(c->table_gU[U+YUVRGB_TABLE_HEADROOM] \
52 + c->table_gV[V+YUVRGB_TABLE_HEADROOM]); \
53 uint32_t *b = (void *)c->table_bU[U+YUVRGB_TABLE_HEADROOM]; \
54 dest[i] = r[Y] + g[Y] + b[Y]; \
55 } \
56 } \
57 return srcSliceH; \
58}
59
62
63/* Unscaled NV12/NV21 -> packed 32-bit RGB */
65{
67 int use_lsx = have_lsx(cpu_flags);
68
69 if ((c->opts.dst_w & 1) || (c->opts.dst_h & 1) ||
71 return;
72
73 if (c->opts.src_format != AV_PIX_FMT_NV12 &&
74 c->opts.src_format != AV_PIX_FMT_NV21)
75 return;
76
77 switch (c->opts.dst_format) {
78 case AV_PIX_FMT_RGBA:
79 c->convert_unscaled = use_lsx ?
80 (c->opts.src_format == AV_PIX_FMT_NV12 ? yuv420_nv12_rgba32_lsx
82 (c->opts.src_format == AV_PIX_FMT_NV12 ? ff_nv12ToRgb32_c
84 break;
85 case AV_PIX_FMT_ARGB:
86 c->convert_unscaled = use_lsx ?
87 (c->opts.src_format == AV_PIX_FMT_NV12 ? yuv420_nv12_argb32_lsx
89 (c->opts.src_format == AV_PIX_FMT_NV12 ? ff_nv12ToRgb32_c
91 break;
92 case AV_PIX_FMT_BGRA:
93 c->convert_unscaled = use_lsx ?
94 (c->opts.src_format == AV_PIX_FMT_NV12 ? yuv420_nv12_bgra32_lsx
96 (c->opts.src_format == AV_PIX_FMT_NV12 ? ff_nv12ToRgb32_c
98 break;
99 case AV_PIX_FMT_ABGR:
100 c->convert_unscaled = use_lsx ?
101 (c->opts.src_format == AV_PIX_FMT_NV12 ? yuv420_nv12_abgr32_lsx
103 (c->opts.src_format == AV_PIX_FMT_NV12 ? ff_nv12ToRgb32_c
105 break;
106 default:
107 return;
108 }
109
110 c->dst_slice_align = 2;
111}
@ SWS_BITEXACT
Definition swscale.h:178
@ SWS_ACCURATE_RND
Force bit-exact output.
Definition swscale.h:177
@ SWS_FULL_CHR_H_INT
Perform full chroma upsampling when upscaling to RGB.
Definition swscale.h:154
static atomic_int cpu_flags
Definition cpu.c:56
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition cpu.c:109
#define have_lsx(flags)
Definition cpu.h:28
void ff_get_unscaled_swscale_loongarch(SwsInternal *c)
#define NVXXRGB32FUNC(func_name, uv_swap)
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition pixfmt.h:96
@ AV_PIX_FMT_NV21
as above, but U and V bytes are swapped
Definition pixfmt.h:97
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition pixfmt.h:99
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition pixfmt.h:102
@ AV_PIX_FMT_ABGR
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
Definition pixfmt.h:101
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition pixfmt.h:100
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_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_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_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_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 ff_nv21ToRgb32_c(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 ff_nv12ToRgb32_c(SwsInternal *c, const uint8_t *const src[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
static double c[64]