Skip to content

Commit

Permalink
RoQ decoder: Work on RGBA-data interenally instead of YUV420-data (ft…
Browse files Browse the repository at this point in the history
…e-team#250)

* RoQ decoder: Work on RGBA-data interenally instead of YUV420-data

This fixes color-smearing artifacts on movement (caused by uneven motion vectors not being correctly applicable on half-resolution UV-buffers) and makes RoQ-video directly uploadable as texture.

YUV-to-RGB-conversion is now done only when receiving new codebooks in the RoQ stream, which is a lot less data to be RGB-converted per-frame.

* RoQ decoder: C89-compliant variable declarations

* RoQ decoder: more consistent indentation
  • Loading branch information
RandomBrushes authored Apr 6, 2024
1 parent b7963e6 commit 0630ea5
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 217 deletions.
55 changes: 1 addition & 54 deletions engine/client/m_mp3.c
Original file line number Diff line number Diff line change
Expand Up @@ -2211,64 +2211,12 @@ static qboolean Media_Roq_DecodeFrame (cin_t *cin, qboolean nosound, qboolean fo

if (doupdate)
{
//#define LIMIT(x) ((x)<0xFFFF)?(x)>>16:0xFF;
#define LIMIT(x) ((((x) > 0xffffff) ? 0xff0000 : (((x) <= 0xffff) ? 0 : (x) & 0xff0000)) >> 16)
unsigned char *pa=cin->roq.roqfilm->y[0];
unsigned char *pb=cin->roq.roqfilm->u[0];
unsigned char *pc=cin->roq.roqfilm->v[0];
int pix=0;
int num_columns=(cin->roq.roqfilm->width)>>1;
int num_rows=cin->roq.roqfilm->height;
int y;
int x;

qbyte *framedata;

if (cin->roq.roqfilm->num_frames)
cin->filmpercentage = cin->roq.roqfilm->frame_num / cin->roq.roqfilm->num_frames;
else
cin->filmpercentage = 0;

{
framedata = cin->framedata;

for(y = 0; y < num_rows; ++y) //roq playing doesn't give nice data. It's still fairly raw.
{ //convert it properly.
for(x = 0; x < num_columns; ++x)
{

int r, g, b, y1, y2, u, v, t;
y1 = *(pa++); y2 = *(pa++);
u = pb[x] - 128;
v = pc[x] - 128;

y1 <<= 16;
y2 <<= 16;
r = 91881 * v;
g = -22554 * u + -46802 * v;
b = 116130 * u;

t=r+y1;
framedata[pix] =(unsigned char) LIMIT(t);
t=g+y1;
framedata[pix+1] =(unsigned char) LIMIT(t);
t=b+y1;
framedata[pix+2] =(unsigned char) LIMIT(t);

t=r+y2;
framedata[pix+4] =(unsigned char) LIMIT(t);
t=g+y2;
framedata[pix+5] =(unsigned char) LIMIT(t);
t=b+y2;
framedata[pix+6] =(unsigned char) LIMIT(t);
pix+=8;

}
if(y & 0x01) { pb += num_columns; pc += num_columns; }
}
}

uploadtexture(ctx, TF_RGBX32, cin->roq.roqfilm->width, cin->roq.roqfilm->height, cin->framedata, NULL);
uploadtexture(ctx, TF_RGBX32, cin->roq.roqfilm->width, cin->roq.roqfilm->height, cin->roq.roqfilm->rgba[0], NULL);

if (!nosound)
{
Expand Down Expand Up @@ -2308,7 +2256,6 @@ static cin_t *Media_RoQ_TryLoad(char *name)

cin->roq.roqfilm = roqfilm;

cin->framedata = BZ_Malloc(roqfilm->width*roqfilm->height*4);
return cin;
}
return NULL;
Expand Down
7 changes: 6 additions & 1 deletion engine/client/roq.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ typedef struct {
unsigned char y0, y1, y2, y3, u, v;
} roq_cell;

typedef struct {
char p[16];
} roq_cell_rgba;

typedef struct {
int idx[4];
} roq_qcell;
Expand All @@ -26,13 +30,14 @@ typedef struct roq_info_s {
int buf_size;
unsigned char *buf;
roq_cell cells[256];
roq_cell_rgba cells_rgba[256];
roq_qcell qcells[256];
short snd_sqr_arr[256];
qofs_t roq_start, aud_pos, vid_pos;
long *frame_offset;
unsigned long num_frames, num_audio_bytes;
int width, height, frame_num, audio_channels;
unsigned char *y[2], *u[2], *v[2];
byte_vec4_t *rgba[2];
long stream_length;
int audio_buf_size, audio_size;
unsigned char *audio;
Expand Down
Loading

0 comments on commit 0630ea5

Please sign in to comment.