Skip to content

Commit 7019d7e

Browse files
committed
Optimize YUV to RGB conversion.
Refs #816.
1 parent 5fd228e commit 7019d7e

File tree

1 file changed

+34
-18
lines changed

1 file changed

+34
-18
lines changed

lib/sequence/sequence.c

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ static bool audiobuf_ready = false; // single 'frame' audio buffer ready for pr
140140
// file handle
141141
static PHYSFS_file* fpInfile = NULL;
142142

143-
static char* RGBAframe = NULL; // texture buffer
143+
static uint32_t* RGBAframe = NULL; // texture buffer
144144

145145
#if !defined(WZ_NOSOUND)
146146
static ogg_int16_t* audiobuf = NULL; // audio buffer
@@ -320,29 +320,45 @@ static void video_write(bool update)
320320

321321
if (update)
322322
{
323+
int rgb_offset = 0;
324+
int y_offset = 0;
325+
int uv_offset = 0;
326+
int half_width = video_width / 2;
327+
323328
theora_decode_YUVout(&videodata.td, &yuv);
324329

325330
// fill the RGBA buffer
326331
for (y = 0; y < video_height; y++)
327332
{
328-
for (x = 0; x < video_width; x++)
333+
y_offset = y * yuv.y_stride;
334+
uv_offset = (y >> 1) * yuv.uv_stride;
335+
336+
for (x = 0; x < half_width; x++)
329337
{
330-
int Y = yuv.y[x + y * yuv.y_stride];
331-
int U = yuv.u[x / 2 + (y / 2) * yuv.uv_stride];
332-
int V = yuv.v[x / 2 + (y / 2) * yuv.uv_stride];
333-
334-
int C = Y - 16;
335-
int D = U - 128;
336-
int E = V - 128;
337-
338-
int R = Vclip((298 * C + 409 * E + 128) >> 8);
339-
int G = Vclip((298 * C - 100 * D - 208 * E + 128) >> 8);
340-
int B = Vclip((298 * C + 516 * D + 128) >> 8);
341-
342-
RGBAframe[x * 4 + y * video_width * 4 + 0] = R;
343-
RGBAframe[x * 4 + y * video_width * 4 + 1] = G;
344-
RGBAframe[x * 4 + y * video_width * 4 + 2] = B;
345-
RGBAframe[x * 4 + y * video_width * 4 + 3] = 0xFF;
338+
int Y = yuv.y[y_offset++] - 16;
339+
const int U = yuv.u[uv_offset] - 128;
340+
const int V = yuv.v[uv_offset++] - 128;
341+
342+
int A = 298 * Y;
343+
const int C = 409 * V;
344+
345+
int R = Vclip((A + C + 128) >> 8);
346+
int G = Vclip((A - 100 * U - (C >> 1) + 128) >> 8);
347+
int B = Vclip((A + 516 * U + 128) >> 8);
348+
349+
RGBAframe[rgb_offset] = (B << 16) | (G << 8) | (R << 0) | (0xFF << 24);
350+
rgb_offset++;
351+
352+
// second pixel, U and V (and thus C) are the same as before.
353+
Y = yuv.y[y_offset++] - 16;
354+
A = 298 * Y;
355+
356+
R = Vclip((A + C + 128) >> 8);
357+
G = Vclip((A - 100 * U - (C >> 1) + 128) >> 8);
358+
B = Vclip((A + 516 * U + 128) >> 8);
359+
360+
RGBAframe[rgb_offset] = (B << 16) | (G << 8) | (R << 0) | (0xFF << 24);
361+
rgb_offset++;
346362
}
347363
}
348364

0 commit comments

Comments
 (0)