summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Melanson <mike@multimedia.cx>2002-10-04 03:10:43 +0000
committerMike Melanson <mike@multimedia.cx>2002-10-04 03:10:43 +0000
commitb11ce1489f6292ebda9e1e4c309694a465c83f90 (patch)
treebdc759b2d49011439d88d59a332a9077d1386288
parent33cc14cd0a447c0b96765aac39551af3b783d7d5 (diff)
downloadxine-lib-b11ce1489f6292ebda9e1e4c309694a465c83f90.tar.gz
xine-lib-b11ce1489f6292ebda9e1e4c309694a465c83f90.tar.bz2
bring the RoQ video decoder up to snuff (much, much faster; more
accurate, but a few visual bugs remain) CVS patchset: 2779 CVS date: 2002/10/04 03:10:43
-rw-r--r--src/libxinevdec/roqvideo.c121
1 files changed, 78 insertions, 43 deletions
diff --git a/src/libxinevdec/roqvideo.c b/src/libxinevdec/roqvideo.c
index 322b5d741..9841013f5 100644
--- a/src/libxinevdec/roqvideo.c
+++ b/src/libxinevdec/roqvideo.c
@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: roqvideo.c,v 1.9 2002/09/05 22:19:03 mroi Exp $
+ * $Id: roqvideo.c,v 1.10 2002/10/04 03:10:43 tmmm Exp $
*/
/* And this is the header that came with the RoQ video decoder: */
@@ -100,19 +100,33 @@ typedef struct roq_decoder_s {
long *frame_offset;
unsigned long num_frames, num_audio_bytes;
unsigned char *y[2], *u[2], *v[2];
+ int y_size;
+ int c_size;
+
+ unsigned char *cur_y, *cur_u, *cur_v;
+ unsigned char *prev_y, *prev_u, *prev_v;
+
+ /* this is either 0 or 1 indicating the cur_y points to y[0] or y[1],
+ * same for u and v */
+ int current_planes;
+
} roq_decoder_t;
+/**************************************************************************
+ * RoQ video specific decode functions
+ *************************************************************************/
+
static void apply_vector_2x2(roq_decoder_t *ri, int x, int y, roq_cell *cell) {
unsigned char *yptr;
- yptr = ri->y[0] + (y * ri->width) + x;
+ yptr = ri->cur_y + (y * ri->width) + x;
*yptr++ = cell->y0;
*yptr++ = cell->y1;
yptr += (ri->width - 2);
*yptr++ = cell->y2;
*yptr++ = cell->y3;
- ri->u[0][(y/2) * (ri->width/2) + x/2] = cell->u;
- ri->v[0][(y/2) * (ri->width/2) + x/2] = cell->v;
+ ri->cur_u[(y/2) * (ri->width/2) + x/2] = cell->u;
+ ri->cur_v[(y/2) * (ri->width/2) + x/2] = cell->v;
}
static void apply_vector_4x4(roq_decoder_t *ri, int x, int y, roq_cell *cell) {
@@ -120,9 +134,9 @@ static void apply_vector_4x4(roq_decoder_t *ri, int x, int y, roq_cell *cell) {
register unsigned char y0, y1, u, v;
unsigned char *yptr, *uptr, *vptr;
- yptr = ri->y[0] + (y * ri->width) + x;
- uptr = ri->u[0] + (y/2) * (ri->width/2) + x/2;
- vptr = ri->v[0] + (y/2) * (ri->width/2) + x/2;
+ yptr = ri->cur_y + (y * ri->width) + x;
+ uptr = ri->cur_u + (y/2) * (ri->width/2) + x/2;
+ vptr = ri->cur_v + (y/2) * (ri->width/2) + x/2;
row_inc = ri->width - 4;
c_row_inc = (ri->width/2) - 2;
@@ -162,8 +176,8 @@ static void apply_motion_4x4(roq_decoder_t *ri, int x, int y, unsigned char mv,
mx = x + 8 - (mv >> 4) - mean_x;
my = y + 8 - (mv & 0xf) - mean_y;
- pa = ri->y[0] + (y * ri->width) + x;
- pb = ri->y[1] + (my * ri->width) + mx;
+ pa = ri->cur_y + (y * ri->width) + x;
+ pb = ri->prev_y + (my * ri->width) + mx;
for(i = 0; i < 4; i++) {
pa[0] = pb[0];
pa[1] = pb[1];
@@ -173,8 +187,8 @@ static void apply_motion_4x4(roq_decoder_t *ri, int x, int y, unsigned char mv,
pb += ri->width;
}
- pa = ri->u[0] + (y/2) * (ri->width/2) + x/2;
- pb = ri->u[1] + (my/2) * (ri->width/2) + (mx + 1)/2;
+ pa = ri->cur_u + (y/2) * (ri->width/2) + x/2;
+ pb = ri->prev_u + (my/2) * (ri->width/2) + (mx + 1)/2;
for(i = 0; i < 2; i++) {
pa[0] = pb[0];
pa[1] = pb[1];
@@ -182,8 +196,8 @@ static void apply_motion_4x4(roq_decoder_t *ri, int x, int y, unsigned char mv,
pb += ri->width/2;
}
- pa = ri->v[0] + (y/2) * (ri->width/2) + x/2;
- pb = ri->v[1] + (my/2) * (ri->width/2) + (mx + 1)/2;
+ pa = ri->cur_v + (y/2) * (ri->width/2) + x/2;
+ pb = ri->prev_v + (my/2) * (ri->width/2) + (mx + 1)/2;
for(i = 0; i < 2; i++) {
pa[0] = pb[0];
pa[1] = pb[1];
@@ -201,8 +215,8 @@ static void apply_motion_8x8(roq_decoder_t *ri, int x, int y,
mx = x + 8 - (mv >> 4) - mean_x;
my = y + 8 - (mv & 0xf) - mean_y;
- pa = ri->y[0] + (y * ri->width) + x;
- pb = ri->y[1] + (my * ri->width) + mx;
+ pa = ri->cur_y + (y * ri->width) + x;
+ pb = ri->prev_y + (my * ri->width) + mx;
for(i = 0; i < 8; i++) {
pa[0] = pb[0];
pa[1] = pb[1];
@@ -216,8 +230,8 @@ static void apply_motion_8x8(roq_decoder_t *ri, int x, int y,
pb += ri->width;
}
- pa = ri->u[0] + (y/2) * (ri->width/2) + x/2;
- pb = ri->u[1] + (my/2) * (ri->width/2) + (mx + 1)/2;
+ pa = ri->cur_u + (y/2) * (ri->width/2) + x/2;
+ pb = ri->prev_u + (my/2) * (ri->width/2) + (mx + 1)/2;
for(i = 0; i < 4; i++) {
pa[0] = pb[0];
pa[1] = pb[1];
@@ -227,8 +241,8 @@ static void apply_motion_8x8(roq_decoder_t *ri, int x, int y,
pb += ri->width/2;
}
- pa = ri->v[0] + (y/2) * (ri->width/2) + x/2;
- pb = ri->v[1] + (my/2) * (ri->width/2) + (mx + 1)/2;
+ pa = ri->cur_v + (y/2) * (ri->width/2) + x/2;
+ pb = ri->prev_v + (my/2) * (ri->width/2) + (mx + 1)/2;
for(i = 0; i < 4; i++) {
pa[0] = pb[0];
pa[1] = pb[1];
@@ -239,7 +253,7 @@ static void apply_motion_8x8(roq_decoder_t *ri, int x, int y,
}
}
-static void roq_decode_frame(roq_decoder_t *ri, vo_frame_t *img) {
+static void roq_decode_frame(roq_decoder_t *ri) {
unsigned int chunk_id = 0, chunk_arg = 0;
unsigned long chunk_size = 0;
int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1;
@@ -253,7 +267,7 @@ static void roq_decode_frame(roq_decoder_t *ri, vo_frame_t *img) {
chunk_id = get_word(buf);
chunk_size = get_long(buf);
chunk_arg = get_word(buf);
-//printf (" type %X, %lX bytes\n", chunk_id, chunk_size);
+
if(chunk_id == RoQ_QUAD_VQ)
break;
if(chunk_id == RoQ_QUAD_CODEBOOK) {
@@ -352,25 +366,15 @@ static void roq_decode_frame(roq_decoder_t *ri, vo_frame_t *img) {
if(ypos >= ri->height)
break;
}
-
- /* there has to be a more efficient way to do the next 2 copy blocks */
-
- /* preserve the planes for motion compensation in the next frame decode */
- memcpy(ri->y[1], ri->y[0], ri->width * ri->height);
- memcpy(ri->u[1], ri->u[0], (ri->width * ri->height)/4);
- memcpy(ri->v[1], ri->v[0], (ri->width * ri->height)/4);
-
- /* copy the planes to the output planes */
- /* FIXME: use img->pitches[3] */
- memcpy(img->base[0], ri->y[0], ri->width * ri->height);
- memcpy(img->base[1], ri->u[0], (ri->width * ri->height)/4);
- memcpy(img->base[2], ri->v[0], (ri->width * ri->height)/4);
}
+/**************************************************************************
+ * xine video plugin functions
+ *************************************************************************/
+
static void roq_init (video_decoder_t *this_gen, vo_instance_t *video_out) {
roq_decoder_t *this = (roq_decoder_t *) this_gen;
-printf("roq_init\n");
this->video_out = video_out;
this->buf = NULL;
}
@@ -381,7 +385,6 @@ static void roq_decode_data (video_decoder_t *this_gen,
roq_decoder_t *this = (roq_decoder_t *) this_gen;
vo_frame_t *img; /* video out frame */
-//printf("roq_decode_data\n");
if (buf->decoder_flags & BUF_FLAG_PREVIEW)
return;
@@ -398,13 +401,25 @@ static void roq_decode_data (video_decoder_t *this_gen,
this->height = (buf->content[2] << 8) | buf->content[3];
this->skipframes = 0;
this->video_step = buf->decoder_info[1];
+ this->current_planes = 0;
+
+ this->y_size = this->width * this->height;
+ this->c_size = (this->width * this->height) / 4;
- this->y[0] = xine_xmalloc(this->width * this->height);
- this->y[1] = xine_xmalloc(this->width * this->height);
- this->u[0] = xine_xmalloc((this->width * this->height) / 4);
- this->u[1] = xine_xmalloc((this->width * this->height) / 4);
- this->v[0] = xine_xmalloc((this->width * this->height) / 4);
- this->v[1] = xine_xmalloc((this->width * this->height) / 4);
+ this->y[0] = xine_xmalloc(this->y_size);
+ this->y[1] = xine_xmalloc(this->y_size);
+ memset(this->y[0], 0x00, this->y_size);
+ memset(this->y[1], 0x00, this->y_size);
+
+ this->u[0] = xine_xmalloc(this->c_size);
+ this->u[1] = xine_xmalloc(this->c_size);
+ memset(this->u[0], 0x80, this->c_size);
+ memset(this->u[1], 0x80, this->c_size);
+
+ this->v[0] = xine_xmalloc(this->c_size);
+ this->v[1] = xine_xmalloc(this->c_size);
+ memset(this->v[0], 0x80, this->c_size);
+ memset(this->v[1], 0x80, this->c_size);
return;
}
@@ -430,7 +445,27 @@ static void roq_decode_data (video_decoder_t *this_gen,
img->pts = buf->pts;
img->duration = this->video_step;
- roq_decode_frame(this, img);
+ if (this->current_planes == 0) {
+ this->cur_y = this->y[0];
+ this->cur_u = this->u[0];
+ this->cur_v = this->v[0];
+ this->prev_y = this->y[1];
+ this->prev_u = this->u[1];
+ this->prev_v = this->v[1];
+ this->current_planes = 1;
+ } else {
+ this->cur_y = this->y[1];
+ this->cur_u = this->u[1];
+ this->cur_v = this->v[1];
+ this->prev_y = this->y[0];
+ this->prev_u = this->u[0];
+ this->prev_v = this->v[0];
+ this->current_planes = 0;
+ }
+ roq_decode_frame(this);
+ xine_fast_memcpy(img->base[0], this->cur_y, this->y_size);
+ xine_fast_memcpy(img->base[1], this->cur_u, this->c_size);
+ xine_fast_memcpy(img->base[2], this->cur_v, this->c_size);
if (img->copy) {
int height = img->height;