MythTV master
zoom_filter_mmx.cpp
Go to the documentation of this file.
1#include <algorithm>
2#include <cstdint>
3
4#include "zoom_filters.h"
5#include "libmythbase/mythconfig.h"
6
7#if HAVE_MMX
8static constexpr uint8_t BUFFPOINTNB { 16 };
9//static constexpr uint16_t BUFFPOINTMASK { 0xffff };
10//static constexpr uint8_t BUFFINCR { 0xff };
11
12#include "mmx.h"
13
14//static constexpr uint8_t sqrtperte { 16 };
15// faire : a % sqrtperte <=> a & pertemask
16static constexpr uint8_t PERTEMASK { 0xf };
17// faire : a / sqrtperte <=> a >> PERTEDEC
18static constexpr uint8_t PERTEDEC { 4 };
19
20extern "C" {
21#include "libavutil/cpu.h"
22}
23
25 return (av_get_cpu_flags() & AV_CPU_FLAG_MMX);
26}
27
28void zoom_filter_mmx (int prevX, int prevY,
29 const unsigned int *expix1, unsigned int *expix2,//NOLINT(readability-non-const-parameter)
30 const sintvec& brutS,
31 const sintvec& brutD,
32 int buffratio,
34{
35 unsigned int ax = (prevX-1)<<PERTEDEC;
36 unsigned int ay = (prevY-1)<<PERTEDEC;
37
38 int bufsize = prevX * prevY;
39
40 pxor_r2r(mm7,mm7);
41
42 for (int loop=0; loop<bufsize; loop++)
43 {
44 int pos = 0;
45 int coeffs = 0;
46
47 int myPos = loop << 1;
48 int myPos2 = myPos + 1;
49 int brutSmypos = brutS[myPos];
50
51 int px = brutSmypos +
52 (((brutD[myPos] - brutSmypos)*buffratio) >> BUFFPOINTNB);
53
54 brutSmypos = brutS[myPos2];
55 int py = brutSmypos +
56 (((brutD[myPos2] - brutSmypos)*buffratio) >> BUFFPOINTNB);
57
58 px = std::max(px, 0);
59 py = std::max(py, 0);
60
61 if ((py>=(int)ay) || (px>=(int)ax))
62 {
63 pos=coeffs=0;
64 }
65 else {
66 pos = ((px >> PERTEDEC) + (prevX * (py >> PERTEDEC)));
67 /* coef en modulo 15 */
68 coeffs = precalCoef [px & PERTEMASK][py & PERTEMASK];
69 }
70
71 int posplusprevX = pos + prevX;
72
73 movd_m2r(coeffs, mm6);
74
75 /* recuperation des deux premiers pixels dans mm0 et mm1 */
76 movq_m2r(expix1[pos], mm0); /* b1-v1-r1-a1-b2-v2-r2-a2 */
77 movq_r2r(mm0, mm1); /* b1-v1-r1-a1-b2-v2-r2-a2 */
78
79 /* depackage du premier pixel */
80 punpcklbw_r2r(mm7, mm0); /* 00-b2-00-v2-00-r2-00-a2 */
81 movq_r2r(mm6, mm5); /* xx-xx-xx-xx-c4-c3-c2-c1 */
82
83 /* depackage du 2ieme pixel */
84 punpckhbw_r2r(mm7, mm1); /* 00-b1-00-v1-00-r1-00-a1 */
85
86 /* extraction des coefficients... */
87 punpcklbw_r2r(mm5, mm6); /* c4-c4-c3-c3-c2-c2-c1-c1 */
88 movq_r2r(mm6, mm4); /* c4-c4-c3-c3-c2-c2-c1-c1 */
89 movq_r2r(mm6, mm5); /* c4-c4-c3-c3-c2-c2-c1-c1 */
90 punpcklbw_r2r(mm5, mm6); /* c2-c2-c2-c2-c1-c1-c1-c1 */
91 punpckhbw_r2r(mm5, mm4); /* c4-c4-c4-c4-c3-c3-c3-c3 */
92
93 movq_r2r(mm6, mm3); /* c2-c2-c2-c2-c1-c1-c1-c1 */
94 punpcklbw_r2r(mm7, mm6); /* 00-c1-00-c1-00-c1-00-c1 */
95 punpckhbw_r2r(mm7, mm3); /* 00-c2-00-c2-00-c2-00-c2 */
96
97 /* multiplication des pixels par les coefficients */
98 pmullw_r2r(mm6, mm0); /* c1*b2-c1*v2-c1*r2-c1*a2 */
99 pmullw_r2r(mm3, mm1); /* c2*b1-c2*v1-c2*r1-c2*a1 */
100 paddw_r2r(mm1, mm0);
101
102 /* ...extraction des 2 derniers coefficients */
103 movq_r2r(mm4, mm5); /* c4-c4-c4-c4-c3-c3-c3-c3 */
104 punpcklbw_r2r(mm7, mm4); /* 00-c3-00-c3-00-c3-00-c3 */
105 punpckhbw_r2r(mm7, mm5); /* 00-c4-00-c4-00-c4-00-c4 */
106
107 /* ajouter la longueur de ligne a esi */
108 /* recuperation des 2 derniers pixels */
109 movq_m2r(expix1[posplusprevX], mm1);
110 movq_r2r(mm1, mm2);
111
112 /* depackage des pixels */
113 punpcklbw_r2r(mm7, mm1);
114 punpckhbw_r2r(mm7, mm2);
115
116 /* multiplication pas les coeffs */
117 pmullw_r2r(mm4, mm1);
118 pmullw_r2r(mm5, mm2);
119
120 /* ajout des valeurs obtenues de iso8859-15 à la valeur finale */
121 paddw_r2r(mm1, mm0);
122 paddw_r2r(mm2, mm0);
123
124 /* division par 256 = 16+16+16+16, puis repackage du pixel final */
125 psrlw_i2r(8, mm0);
126 packuswb_r2r(mm7, mm0);
127 movd_r2m(mm0,expix2[loop]);
128 }
129 emms();
130}
131
132#else
133
135 return 0;
136}
137
138void zoom_filter_mmx ([[maybe_unused]] int prevX,
139 [[maybe_unused]] int prevY,
140 [[maybe_unused]] const unsigned int *expix1,
141 [[maybe_unused]] unsigned int *expix2,
142 [[maybe_unused]] const sintvec& brutS,
143 [[maybe_unused]] const sintvec& brutD,
144 [[maybe_unused]] int buffratio,
145 [[maybe_unused]] const GoomCoefficients &precalCoef)
146{
147}
148
149#endif
150
151/*
152 * vim:ts=4:sw=4:ai:et:si:sts=4
153 */
154
sintvec brutS
Definition: filters.cpp:82
uint32_t * expix2
Definition: filters.cpp:88
static constexpr int8_t PERTEMASK
Definition: filters.cpp:117
static constexpr uint8_t BUFFPOINTNB
Definition: filters.cpp:111
unsigned int * coeffs
Definition: filters.cpp:80
unsigned int prevY
Definition: filters.cpp:93
unsigned int prevX
Definition: filters.cpp:93
GoomCoefficients precalCoef
modif d'optim by Jeko : precalcul des 4 coefs résultant des 2 pos
Definition: filters.cpp:128
int buffratio
modif by jeko : fixedpoint : buffration = (16:16) (donc 0<=buffration<=2^16)
Definition: filters.cpp:109
static constexpr uint8_t PERTEDEC
Definition: filters.cpp:119
uint32_t * expix1
Definition: filters.cpp:87
sintvec brutD
Definition: filters.cpp:83
#define punpckhbw_r2r(regs, regd)
Definition: mmx.h:203
#define emms()
Definition: mmx.h:82
#define movq_m2r(var, reg)
Definition: mmx.h:94
#define packuswb_r2r(regs, regd)
Definition: mmx.h:106
#define psrlw_i2r(imm, reg)
Definition: mmx.h:181
#define punpcklbw_r2r(regs, regd)
Definition: mmx.h:210
#define pmullw_r2r(regs, regd)
Definition: mmx.h:153
#define movd_r2m(reg, var)
Definition: mmx.h:85
#define movd_m2r(var, reg)
Definition: mmx.h:84
#define movq_r2r(regs, regd)
Definition: mmx.h:97
#define pxor_r2r(regs, regd)
Definition: mmx.h:217
#define paddw_r2r(regs, regd)
Definition: mmx.h:113
int zoom_filter_mmx_supported()
void zoom_filter_mmx(int prevX, int prevY, const unsigned int *expix1, unsigned int *expix2, const sintvec &brutS, const sintvec &brutD, int buffratio, const GoomCoefficients &precalCoef)
std::vector< signed int > sintvec
Definition: zoom_filters.h:4
std::array< std::array< int, 16 >, 16 > GoomCoefficients
Definition: zoom_filters.h:5