17 int left,
int top,
int right,
int bottom)
19 static bool s_bReported;
31 if (c_aligned && !s_bReported)
34 LOG(VB_GENERAL, LOG_WARNING, QString(
35 "OSD image size is odd; performance will suffer.\n" 36 "\t\t\tVideo window position and size must be a multiple of %1x%2.")
50 LOG(VB_GENERAL, LOG_WARNING, QString(
51 "Unable to display the OSD.\n" 52 "\t\t\tVideo window position and size must be a multiple of %1x%2.")
58 #define ASM(code) __asm__ __volatile__(code); 60 int left,
int top,
int right,
int bottom)
62 unsigned char *src1, *src2, *y1, *y2, *u, *v;
63 int y_wrap, src_wrap, u_wrap, v_wrap, width, height;
66 height = bottom - top;
67 src1 = osd_image->scanLine(top) + (left << 2);
68 src2 = src1 + osd_image->bytesPerLine();
69 src_wrap = (osd_image->bytesPerLine() << 1)- (width << 2);
74 (frame->
pitches[1] * (top >> 1)) + (left >> 1);
76 (frame->
pitches[2] * (top >> 1)) + (left >> 1);
77 y_wrap = (frame->
pitches[0] << 1) - width;
78 u_wrap = frame->
pitches[1] - (width >> 1);
79 v_wrap = frame->
pitches[2] - (width >> 1);
81 static long long MMX_MAX = 0xFFFFFFFFFFFFFFFFLL;
82 static long long MMX_MIN = 0x0000000000000000LL;
83 static long long MMX_255 = 0x00FF00FF00FF00FFLL;
84 static long long tmp_u, tmp_v, tmp_a;
86 for (
int row = 0; row < height; row += 2)
88 for (
int col = 0; col < (width >> 3); col++)
92 ASM(
"movq %0, %%mm1"::
"m"(src1[0]))
93 ASM(
"movq %mm1, %mm2")
94 ASM(
"punpckhbw %0, %%mm1"::
"m"(src1[8]))
95 ASM(
"punpcklbw %0, %%mm2"::
"m"(src1[8]))
96 ASM(
"movq %mm2, %mm0")
97 ASM(
"punpckhbw %mm1, %mm2")
98 ASM(
"punpcklbw %mm1, %mm0")
99 ASM(
"movq %0, %%mm3"::
"m"(src1[16]))
100 ASM(
"movq %mm3, %mm4")
101 ASM(
"punpckhbw %0, %%mm3"::
"m"(src1[24]))
102 ASM(
"punpcklbw %0, %%mm4"::
"m"(src1[24]))
103 ASM(
"movq %mm4, %mm1")
104 ASM(
"punpckhbw %mm3, %mm1")
105 ASM(
"punpcklbw %mm3, %mm4")
106 ASM(
"movq %mm2, %mm3")
107 ASM(
"punpckldq %mm1, %mm3")
108 ASM(
"punpckhdq %mm1, %mm2")
109 ASM(
"movq %0, %%mm7"::
"m"(MMX_MAX))
110 ASM(
"psubusb %mm2, %mm7")
111 ASM(
"movq %mm7, %mm6")
112 ASM(
"movq %mm7, %mm2")
113 ASM(
"punpckhbw %0, %%mm7"::
"m"(MMX_MIN))
114 ASM(
"punpcklbw %0, %%mm6"::
"m"(MMX_MIN))
115 ASM(
"movq %0, %%mm5"::
"m"(*y1))
116 ASM(
"movq %mm5, %mm1")
117 ASM(
"punpckhbw %0, %%mm5"::
"m"(MMX_MIN))
118 ASM(
"punpcklbw %0, %%mm1"::
"m"(MMX_MIN))
119 ASM(
"pmullw %mm7, %mm5")
120 ASM(
"pmullw %mm6, %mm1")
121 ASM(
"psrlw $8, %mm5")
122 ASM(
"psrlw $8, %mm1")
123 ASM(
"packuswb %mm5, %mm1")
124 ASM(
"paddusb %mm1, %mm3")
125 ASM(
"movq %%mm3, %0":
"=m"(*y1):)
126 ASM(
"movq %mm0, %mm1")
127 ASM(
"punpckhdq %mm4, %mm0")
128 ASM(
"punpckldq %mm4, %mm1")
130 ASM(
"movq %%mm0, %0":
"=m"(tmp_u):)
131 ASM(
"movq %%mm1, %0":
"=m"(tmp_v):)
132 ASM(
"movq %%mm2, %0":
"=m"(tmp_a):)
134 ASM(
"movq %0, %%mm1"::
"m"(src2[0]))
135 ASM(
"movq %mm1, %mm2")
136 ASM(
"punpckhbw %0, %%mm1"::
"m"(src2[8]))
137 ASM(
"punpcklbw %0, %%mm2"::
"m"(src2[8]))
138 ASM(
"movq %mm2, %mm0")
139 ASM(
"punpckhbw %mm1, %mm2")
140 ASM(
"punpcklbw %mm1, %mm0")
141 ASM(
"movq %0, %%mm3"::
"m"(src2[16]))
142 ASM(
"movq %mm3, %mm4")
143 ASM(
"punpckhbw %0, %%mm3"::
"m"(src2[24]))
144 ASM(
"punpcklbw %0, %%mm4"::
"m"(src2[24]))
145 ASM(
"movq %mm4, %mm1")
146 ASM(
"punpckhbw %mm3, %mm1")
147 ASM(
"punpcklbw %mm3, %mm4")
148 ASM(
"movq %mm2, %mm3")
149 ASM(
"punpckldq %mm1, %mm3")
150 ASM(
"punpckhdq %mm1, %mm2")
151 ASM(
"movq %0, %%mm7"::
"m"(MMX_MAX))
152 ASM(
"psubusb %mm2, %mm7")
153 ASM(
"movq %mm7, %mm6")
154 ASM(
"movq %mm7, %mm2")
155 ASM(
"punpckhbw %0, %%mm7"::
"m"(MMX_MIN))
156 ASM(
"punpcklbw %0, %%mm6"::
"m"(MMX_MIN))
157 ASM(
"movq %0, %%mm5"::
"m"(*y2))
158 ASM(
"movq %mm5, %mm1")
159 ASM(
"punpckhbw %0, %%mm5"::
"m"(MMX_MIN))
160 ASM(
"punpcklbw %0, %%mm1"::
"m"(MMX_MIN))
161 ASM(
"pmullw %mm7, %mm5")
162 ASM(
"pmullw %mm6, %mm1")
163 ASM(
"psrlw $8, %mm5")
164 ASM(
"psrlw $8, %mm1")
165 ASM(
"packuswb %mm5, %mm1")
166 ASM(
"paddusb %mm1, %mm3")
167 ASM(
"movq %%mm3, %0":
"=m"(*y2):)
168 ASM(
"movq %mm0, %mm1")
169 ASM(
"punpckhdq %mm4, %mm0")
170 ASM(
"punpckldq %mm4, %mm1")
172 ASM(
"movq %mm2, %mm3")
173 ASM(
"movq %0, %%mm4"::
"m"(tmp_a))
174 ASM(
"movq %mm4, %mm5")
175 ASM(
"psrlw $8, %mm2")
176 ASM(
"pand %0, %%mm3"::
"m"(MMX_255))
177 ASM(
"psrlw $8, %mm4")
178 ASM(
"pand %0, %%mm5"::
"m"(MMX_255))
179 ASM(
"paddusw %mm5, %mm4")
180 ASM(
"paddusw %mm4, %mm3")
181 ASM(
"paddusw %mm3, %mm2")
182 ASM(
"psrlw $2, %mm2")
183 ASM(
"pand %0, %%mm2"::
"m"(MMX_255))
185 ASM(
"movq %mm0, %mm3")
186 ASM(
"movq %0, %%mm4"::
"m"(tmp_u))
187 ASM(
"movq %mm4, %mm5")
188 ASM(
"psrlw $8, %mm0")
189 ASM(
"pand %0, %%mm3"::
"m"(MMX_255))
190 ASM(
"psrlw $8, %mm4")
191 ASM(
"pand %0, %%mm5"::
"m"(MMX_255))
192 ASM(
"paddusw %mm5, %mm4")
193 ASM(
"paddusw %mm4, %mm3")
194 ASM(
"paddusw %mm3, %mm0")
195 ASM(
"psrlw $2, %mm0")
196 ASM(
"pand %0, %%mm0"::
"m"(MMX_255))
198 ASM(
"movd %0, %%mm3"::
"m"(*u))
199 ASM(
"punpcklbw %0, %%mm3"::
"m"(MMX_MIN))
200 ASM(
"pmullw %mm2, %mm3")
201 ASM(
"psrlw $8, %mm3")
202 ASM(
"paddusb %mm3, %mm0")
203 ASM(
"packuswb %mm1, %mm0")
204 ASM(
"movd %%mm0, %0":
"=m"(*u):)
206 ASM(
"movq %mm1, %mm3")
207 ASM(
"movq %0, %%mm4"::
"m"(tmp_v))
208 ASM(
"movq %mm4, %mm5")
209 ASM(
"psrlw $8, %mm1")
210 ASM(
"pand %0, %%mm3"::
"m"(MMX_255))
211 ASM(
"psrlw $8, %mm4")
212 ASM(
"pand %0, %%mm5"::
"m"(MMX_255))
213 ASM(
"paddusw %mm5, %mm4")
214 ASM(
"paddusw %mm4, %mm3")
215 ASM(
"paddusw %mm3, %mm1")
216 ASM(
"psrlw $2, %mm1")
217 ASM(
"pand %0, %%mm1"::
"m"(MMX_255))
219 ASM(
"movd %0, %%mm3"::
"m"(*v))
220 ASM(
"punpcklbw %0, %%mm3"::
"m"(MMX_MIN))
221 ASM(
"pmullw %mm2, %mm3")
222 ASM(
"psrlw $8, %mm3")
223 ASM(
"paddusb %mm3, %mm1")
224 ASM(
"packuswb %mm2, %mm1")
225 ASM(
"movd %%mm1, %0":
"=m"(*v):)
227 src1 += 32; src2 += 32; y1 += 8; y2 += 8; u += 4; v += 4;
229 y1 += y_wrap; y2 += y_wrap; u+= u_wrap; v += v_wrap;
230 src1 += src_wrap; src2 += src_wrap;
237 int left,
int top,
int right,
int bottom)
239 const int width = right - left;
240 const int height = bottom - top;
242 unsigned char *udest = frame->
buf + frame->
offsets[1];
243 unsigned char *vdest = frame->
buf + frame->
offsets[2];
244 udest += frame->
pitches[1] * (top >> 1) + (left >> 1);
245 vdest += frame->
pitches[2] * (top >> 1) + (left >> 1);
247 unsigned char *y1 = frame->
buf + frame->
offsets[0]
248 + frame->
pitches[0] * top + left;
249 unsigned char *y3 = y1 + frame->
pitches[0];
250 const int y_wrap = (frame->
pitches[0] << 1) - width;
252 const unsigned char *src = osd_image->scanLine(top) + left *
sizeof(QRgb);
253 const int bpl = osd_image->bytesPerLine();
255 for (
int row = 0; row < height; row += 2)
257 const QRgb *
p1 = reinterpret_cast<const QRgb* >(src);
258 const QRgb *p3 = reinterpret_cast<const QRgb* >(src + bpl);
260 for (
int col = 0, maxcol = width / 2; col < maxcol; ++col)
262 QRgb rgb1 =
p1[0], rgb2 =
p1[1], rgb3 = p3[0], rgb4 = p3[1];
263 int alpha1 = 255 - qAlpha(rgb1);
264 int alpha2 = 255 - qAlpha(rgb2);
265 int alpha3 = 255 - qAlpha(rgb3);
266 int alpha4 = 255 - qAlpha(rgb4);
267 int alphaUV = (alpha1 + alpha2 + alpha3 + alpha4) >> 2;
281 udest[col] = (qGreen(rgb1) + qGreen(rgb2) + qGreen(rgb3) + qGreen(rgb4)) >> 2;
282 vdest[col] = (qBlue(rgb1) + qBlue(rgb2) + qBlue(rgb3) + qBlue(rgb4)) >> 2;
284 else if (alphaUV < 255)
290 y1[0] = ((y1[0] * alpha1) >> 8) + qRed(rgb1);
291 y1[1] = ((y1[1] * alpha2) >> 8) + qRed(rgb2);
292 y3[0] = ((y3[0] * alpha3) >> 8) + qRed(rgb3);
293 y3[1] = ((y3[1] * alpha4) >> 8) + qRed(rgb4);
295 int u = (qGreen(rgb1) + qGreen(rgb2) + qGreen(rgb3) + qGreen(rgb4)) >> 2;
296 udest[col] = ((udest[col] * alphaUV) >> 8) + u;
298 int v = (qBlue(rgb1) + qBlue(rgb2) + qBlue(rgb3) + qBlue(rgb4)) >> 2;
299 vdest[col] = ((vdest[col] * alphaUV) >> 8) + v;
305 y1 += y_wrap, y3 += y_wrap;
313 int left,
int top,
int right,
int bottom,
bool ifirst)
315 int width, ashift, amask, ishift, imask, src_wrap, dst_wrap;
316 unsigned char *src, *alpha, *dst;
318 width = right - left;
319 ashift = ifirst ? 0 : 4;
320 amask = ifirst ? 0x0f : 0xf0;
321 ishift = ifirst ? 4 : 0;
322 imask = ifirst ? 0xf0 : 0x0f;
324 src = osd_image->scanLine(top) + (left << 2) +
R_OI;
325 alpha = osd_image->scanLine(top) + (left << 2) +
A_OI;
326 dst =
dest + dst_size.width() * top + left;
327 dst_wrap = dst_size.width() - width;
328 src_wrap = osd_image->bytesPerLine() - (width << 2);
330 for (
int row = top; row < bottom; row++)
332 const unsigned char *dmp =
DM[row & (
DM_HEIGHT - 1)];
333 for (
int col = left; col < right; col++)
337 grey = *src + ((dmp[col & (
DM_WIDTH - 1)] << 2) >> 4);
338 grey = (grey - (grey >> 4)) >> 4;
340 *dst = (((*alpha >> 4) << ashift) & amask) |
341 (((grey) << ishift) & imask);
int pitches[3]
Y, U, & V pitches.
void c_yuv888_to_yv12(VideoFrame *frame, MythImage *osd_image, int left, int top, int right, int bottom)
int offsets[3]
Y, U, & V offsets.
static const unsigned char DM[128][128]
void yuv888_to_i44(unsigned char *dest, MythImage *osd_image, QSize dst_size, int left, int top, int right, int bottom, bool ifirst)
void mmx_yuv888_to_yv12(VideoFrame *frame, MythImage *osd_image, int left, int top, int right, int bottom)
void yuv888_to_yv12(VideoFrame *frame, MythImage *osd_image, int left, int top, int right, int bottom)
#define LOG(_MASK_, _LEVEL_, _STRING_)