FFmpeg  4.4.7
yuv2rgb_template.c
Go to the documentation of this file.
1 /*
2  * software YUV to RGB converter
3  *
4  * Copyright (C) 2001-2007 Michael Niedermayer
5  * (c) 2010 Konstantin Shishkov
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <stdint.h>
25 
26 #include "libavutil/x86/asm.h"
28 
29 #undef EMMS_IF_MMX
30 
31 #if defined(COMPILE_TEMPLATE_MMX) || defined(COMPILE_TEMPLATE_MMXEXT)
32 // Don't use emms_c() directly as it may entail an av_get_cpu_flags() call.
33 #if HAVE_MMX_INLINE
34 # define EMMS_IF_MMX __asm__ volatile ("emms" ::: "memory");
35 #elif HAVE_MM_EMPTY
36 # include <mmintrin.h>
37 # define EMMS_IF_MMX _mm_empty();
38 #else
39 # include "libavutil/x86/emms.h"
40 # define EMMS_IF_MMX emms_c();
41 #endif
42 #else
43 #define EMMS_IF_MMX
44 #endif
45 
46 #define YUV2RGB_LOOP(depth) \
47  h_size = (c->dstW + 7) & ~7; \
48  if (h_size * depth > FFABS(dstStride[0])) \
49  h_size -= 8; \
50  \
51  vshift = c->srcFormat != AV_PIX_FMT_YUV422P; \
52  \
53  for (y = 0; y < srcSliceH; y++) { \
54  uint8_t *image = dst[0] + (y + srcSliceY) * dstStride[0]; \
55  const uint8_t *py = src[0] + y * srcStride[0]; \
56  const uint8_t *pu = src[1] + (y >> vshift) * srcStride[1]; \
57  const uint8_t *pv = src[2] + (y >> vshift) * srcStride[2]; \
58  x86_reg index = -h_size / 2; \
59 
60 extern void RENAME(ff_yuv_420_rgb24)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
61  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
62  const uint8_t *py_2index);
63 extern void RENAME(ff_yuv_420_bgr24)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
64  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
65  const uint8_t *py_2index);
66 
67 #if !COMPILE_TEMPLATE_MMXEXT
68 extern void RENAME(ff_yuv_420_rgb15)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
69  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
70  const uint8_t *py_2index);
71 extern void RENAME(ff_yuv_420_rgb16)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
72  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
73  const uint8_t *py_2index);
74 extern void RENAME(ff_yuv_420_rgb32)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
75  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
76  const uint8_t *py_2index);
77 extern void RENAME(ff_yuv_420_bgr32)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
78  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
79  const uint8_t *py_2index);
80 extern void RENAME(ff_yuva_420_rgb32)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
81  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
82  const uint8_t *py_2index, const uint8_t *pa_2index);
83 extern void RENAME(ff_yuva_420_bgr32)(x86_reg index, uint8_t *image, const uint8_t *pu_index,
84  const uint8_t *pv_index, const uint64_t *pointer_c_dither,
85  const uint8_t *py_2index, const uint8_t *pa_2index);
86 
87 static inline int RENAME(yuv420_rgb15)(SwsContext *c, const uint8_t *src[],
88  int srcStride[],
89  int srcSliceY, int srcSliceH,
90  uint8_t *dst[], int dstStride[])
91 {
92  int y, h_size, vshift;
93 
94  YUV2RGB_LOOP(2)
95 
96 #ifdef DITHER1XBPP
97  c->blueDither = ff_dither8[y & 1];
98  c->greenDither = ff_dither8[y & 1];
99  c->redDither = ff_dither8[(y + 1) & 1];
100 #endif
101 
102  RENAME(ff_yuv_420_rgb15)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
103  }
105  return srcSliceH;
106 }
107 
108 static inline int RENAME(yuv420_rgb16)(SwsContext *c, const uint8_t *src[],
109  int srcStride[],
110  int srcSliceY, int srcSliceH,
111  uint8_t *dst[], int dstStride[])
112 {
113  int y, h_size, vshift;
114 
115  YUV2RGB_LOOP(2)
116 
117 #ifdef DITHER1XBPP
118  c->blueDither = ff_dither8[y & 1];
119  c->greenDither = ff_dither4[y & 1];
120  c->redDither = ff_dither8[(y + 1) & 1];
121 #endif
122 
123  RENAME(ff_yuv_420_rgb16)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
124  }
126  return srcSliceH;
127 }
128 
129 static inline int RENAME(yuv420_rgb32)(SwsContext *c, const uint8_t *src[],
130  int srcStride[],
131  int srcSliceY, int srcSliceH,
132  uint8_t *dst[], int dstStride[])
133 {
134  int y, h_size, vshift;
135 
136  YUV2RGB_LOOP(4)
137 
138  RENAME(ff_yuv_420_rgb32)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
139  }
141  return srcSliceH;
142 }
143 
144 static inline int RENAME(yuv420_bgr32)(SwsContext *c, const uint8_t *src[],
145  int srcStride[],
146  int srcSliceY, int srcSliceH,
147  uint8_t *dst[], int dstStride[])
148 {
149  int y, h_size, vshift;
150 
151  YUV2RGB_LOOP(4)
152 
153  RENAME(ff_yuv_420_bgr32)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
154  }
156  return srcSliceH;
157 }
158 
159 static inline int RENAME(yuva420_rgb32)(SwsContext *c, const uint8_t *src[],
160  int srcStride[],
161  int srcSliceY, int srcSliceH,
162  uint8_t *dst[], int dstStride[])
163 {
164  int y, h_size, vshift;
165  YUV2RGB_LOOP(4)
166 
167  const uint8_t *pa = src[3] + y * srcStride[3];
168  RENAME(ff_yuva_420_rgb32)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index, pa - 2 * index);
169  }
171  return srcSliceH;
172 }
173 
174 static inline int RENAME(yuva420_bgr32)(SwsContext *c, const uint8_t *src[],
175  int srcStride[],
176  int srcSliceY, int srcSliceH,
177  uint8_t *dst[], int dstStride[])
178 {
179  int y, h_size, vshift;
180 
181  YUV2RGB_LOOP(4)
182 
183  const uint8_t *pa = src[3] + y * srcStride[3];
184  RENAME(ff_yuva_420_bgr32)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index, pa - 2 * index);
185  }
187  return srcSliceH;
188 }
189 #endif
190 
191 static inline int RENAME(yuv420_rgb24)(SwsContext *c, const uint8_t *src[],
192  int srcStride[],
193  int srcSliceY, int srcSliceH,
194  uint8_t *dst[], int dstStride[])
195 {
196  int y, h_size, vshift;
197 
198  YUV2RGB_LOOP(3)
199 
200  RENAME(ff_yuv_420_rgb24)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
201  }
203  return srcSliceH;
204 }
205 
206 static inline int RENAME(yuv420_bgr24)(SwsContext *c, const uint8_t *src[],
207  int srcStride[],
208  int srcSliceY, int srcSliceH,
209  uint8_t *dst[], int dstStride[])
210 {
211  int y, h_size, vshift;
212 
213  YUV2RGB_LOOP(3)
214 
215  RENAME(ff_yuv_420_bgr24)(index, image, pu - index, pv - index, &(c->redDither), py - 2 * index);
216  }
218  return srcSliceH;
219 }
uint8_t
#define RENAME(name)
Definition: ffv1.h:197
int index
Definition: gxfenc.c:89
int x86_reg
Definition: asm.h:72
#define pv
Definition: regdef.h:60
const uint64_t ff_dither4[2]
Definition: swscale.c:33
const uint64_t ff_dither8[2]
Definition: swscale.c:37
#define src
Definition: vp8dsp.c:255
static double c[64]
void RENAME() ff_yuv_420_rgb32(x86_reg index, uint8_t *image, const uint8_t *pu_index, const uint8_t *pv_index, const uint64_t *pointer_c_dither, const uint8_t *py_2index)
void RENAME() ff_yuva_420_bgr32(x86_reg index, uint8_t *image, const uint8_t *pu_index, const uint8_t *pv_index, const uint64_t *pointer_c_dither, const uint8_t *py_2index, const uint8_t *pa_2index)
void RENAME() ff_yuva_420_rgb32(x86_reg index, uint8_t *image, const uint8_t *pu_index, const uint8_t *pv_index, const uint64_t *pointer_c_dither, const uint8_t *py_2index, const uint8_t *pa_2index)
static int RENAME() yuva420_bgr32(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
static int RENAME() yuv420_rgb15(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
static int RENAME() yuv420_rgb24(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
#define EMMS_IF_MMX
#define YUV2RGB_LOOP(depth)
static int RENAME() yuv420_bgr24(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
static int RENAME() yuva420_rgb32(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
void RENAME() ff_yuv_420_bgr24(x86_reg index, uint8_t *image, const uint8_t *pu_index, const uint8_t *pv_index, const uint64_t *pointer_c_dither, const uint8_t *py_2index)
static int RENAME() yuv420_rgb32(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
static int RENAME() yuv420_rgb16(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])
void RENAME() ff_yuv_420_rgb24(x86_reg index, uint8_t *image, const uint8_t *pu_index, const uint8_t *pv_index, const uint64_t *pointer_c_dither, const uint8_t *py_2index)
void RENAME() ff_yuv_420_rgb16(x86_reg index, uint8_t *image, const uint8_t *pu_index, const uint8_t *pv_index, const uint64_t *pointer_c_dither, const uint8_t *py_2index)
void RENAME() ff_yuv_420_bgr32(x86_reg index, uint8_t *image, const uint8_t *pu_index, const uint8_t *pv_index, const uint64_t *pointer_c_dither, const uint8_t *py_2index)
void RENAME() ff_yuv_420_rgb15(x86_reg index, uint8_t *image, const uint8_t *pu_index, const uint8_t *pv_index, const uint64_t *pointer_c_dither, const uint8_t *py_2index)
EMMS_IF_MMX return srcSliceH
static int RENAME() yuv420_bgr32(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[])