diff options
-rw-r--r-- | src/libspudec/spudec_old.c | 612 |
1 files changed, 0 insertions, 612 deletions
diff --git a/src/libspudec/spudec_old.c b/src/libspudec/spudec_old.c deleted file mode 100644 index 9b61d0e01..000000000 --- a/src/libspudec/spudec_old.c +++ /dev/null @@ -1,612 +0,0 @@ - -static spudec_globals gSpudec; - -clut_t *palette[4] = { - NULL, NULL, NULL, NULL -}; - -uint8_t alpha[4] = { - 0xff, 0x00, 0x00, 0x00 -}; - -static clut_t* default_clut = (clut_t*) default_palette; - -/* Maximum packets we can keep in the queue. Should be fine */ -#define MAX_PACKETS 200 - -typedef struct { - unsigned char *packet; /* The actual packet of data */ - uint32_t pts; /* The PTS of the packet */ - uint16_t size; /* The packet size */ -} spudec_packet; - -/* Implement the SPU packet queue as a ring queuefer */ -spudec_packet* spudec_packet_queue[MAX_PACKETS]; -int16_t spudec_queue_size = 0; /* Queue length (items) */ -int16_t spudec_queue_pos = 0; /* Start of queue position */ - -/* Forward declarations */ -void spudec_process_packet(unsigned char *packet, int size); - -/* Pushes a packet on the end of the queue */ -void spudec_queue_packet(spudec_packet *packet) { - if(spudec_queue_size + 1 > MAX_PACKETS) { - /* Too many packets */ - printf("spudec: Too many packets.\n"); - return; - } - - spudec_packet_queue[(spudec_queue_pos + spudec_queue_size) % MAX_PACKETS] = packet; - spudec_queue_size++; -} - -/* Gets the next packet but does /not/ remove it */ -spudec_packet* spudec_peek_next_packet() { - if(spudec_queue_size <= 0) { - /* No packet in queue */ - printf("spudec: No more packets.\n"); - return NULL; - } - - return spudec_packet_queue[spudec_queue_pos]; -} - -/* Like peek_next but removes the packet from the queue */ -spudec_packet* spudec_get_next_packet() { - spudec_packet *packet; - - if((packet = spudec_peek_next_packet()) != NULL) { - spudec_queue_pos = (spudec_queue_pos + 1) % MAX_PACKETS; - spudec_queue_size --; - } - - return packet; -} - -#if 0 -void spudec_init(clut_t *clut) { - gSpudec.bInitialised = 1; - - spudec_reset(); - - if(clut == NULL) { - gSpudec.clut = default_clut; - } else { - gSpudec.clut = clut; - } - - palette[0] = palette[1] = palette[2] = palette[3] = &(gSpudec.clut[0]); -} -#endif - -void spudec_tick() -{ - uint32_t pts; - if(!gSpudec.bInitialised) - return; - - pts = metronom_got_spu_packet(0); - - /* See if we have any SPUs queued */ - if(spudec_queue_size != 0) { - spudec_packet *p; - - p = spudec_peek_next_packet(); - if(pts >= p->pts) { - /* Process */ - p = spudec_get_next_packet(); - - spudec_process_packet(p->packet, p->size); - /* Assume it was displayed correctly */ - gSpudec.displayPTS = p->pts; - - free(p->packet); - free(p); - } - } - - if((gSpudec.geom.bIsVisible) && (pts - gSpudec.lifetime >= gSpudec.displayPTS)) { - gSpudec.geom.bIsVisible = 0; - gSpudec.lifetime = 0; - gSpudec.lastPTS = pts; - return; - } - - if(pts < gSpudec.lastPTS) { - /* Something screwey. */ - gSpudec.lastPTS = pts; - return; - } - - gSpudec.lastPTS = pts; -} - -spudec_geometry* spudec_get_geometry() -{ - return &(gSpudec.geom); -} - -int spudec_set_images(vo_image_buffer_t* overlay, - vo_image_buffer_t* mask, - int width, int height, - int format) -{ - if(format != IMGFMT_YV12) { - printf("Error, SPUDEC only supports YV12 overlays.\n"); - gSpudec.bInitialised = 0; - - return 0; - } - - gSpudec.overlay = overlay; - gSpudec.mask = mask; - gSpudec.width = width; - gSpudec.height = height; - gSpudec.format = format; - gSpudec.geom.bIsVisible = 0; - - /* Clear images initially */ - if(gSpudec.format == IMGFMT_YV12) { - /* Set initial image to empty & clear mask */ - memset(mask->mem[0], 0xff, (gSpudec.width*gSpudec.height)); - memset(overlay->mem[0], 0x00, (gSpudec.width*gSpudec.height)); - memset(mask->mem[1], 0xff, (gSpudec.width*gSpudec.height) >> 2); - memset(overlay->mem[1], 0x00, (gSpudec.width >> 1)*(gSpudec.height >> 1)); - memset(mask->mem[2], 0xff, (gSpudec.width >> 1)*(gSpudec.height >> 1)); - memset(overlay->mem[2], 0x00, (gSpudec.width >> 1)*(gSpudec.height >> 1)); - } - - gSpudec.geom.start_col = 0; - gSpudec.geom.end_col = gSpudec.width-1; - gSpudec.geom.start_row = 0; - gSpudec.geom.end_row = gSpudec.height-1; - - return gSpudec.bInitialised = 1; -} - -#define nibble(data, index) ((index & 1) ? data[index >> 1] & 0xf : (data[index >> 1] >> 4) & 0xf) - -void spudec_process_data(unsigned char *data, int size, int d1, int d2) -{ - /* This does the 'hard' work of processing the image data */ - - long off,line_base, line_base2,y,na,nb; - int n; /* The code word */ - - na = d1<<1; - nb = d2<<1; - - /* Align on even row */ - if (gSpudec.geom.start_row & 1) { - gSpudec.geom.start_row--; - gSpudec.geom.end_row--; - } - if (gSpudec.geom.start_col & 1) { - gSpudec.geom.start_col--; - gSpudec.geom.end_col--; - } - y = gSpudec.geom.start_row; - - while(y <= gSpudec.geom.end_row) { - line_base = gSpudec.width * y + gSpudec.geom.start_col; - line_base2 = (gSpudec.width>>1) * (y>>1) + (gSpudec.geom.start_col >> 1); - - off = 0; - do { - int num; - clut_t *col; - - n = nibble(data, na); - na++; - if(n < 0x4) { - n = (n<<4) | nibble(data, na); - na++; - if(n < 0x10) { - n = (n<<4) | nibble(data, na); - na++; - if(n < 0x40) { - n = (n<<4) | nibble(data, na); - na++; - if(n < 0x100) - n = 0; /* Carriage return */ - } - } - } - // printf("Code: 0x%04x\n",n); - - num = n >> 2; col = palette[n & 0x3]; - if(col == NULL) { - printf("Error in palette\n"); - } - - if(num != 0) { - if(alpha[n & 0x3] & 0x80) { - memset(&(gSpudec.mask->mem[0][line_base + off]), 0x00, num); - memset(&(gSpudec.overlay->mem[0][line_base + off]), col->y, num); - memset(&(gSpudec.mask->mem[1][line_base2 + (off>>1)]), 0x00, num>>1); - memset(&(gSpudec.overlay->mem[1][line_base2 + (off>>1)]), col->cr, num>>1); - memset(&(gSpudec.mask->mem[2][line_base2 + (off>>1)]), 0x00, num>>1); - memset(&(gSpudec.overlay->mem[2][line_base2 + (off>>1)]), col->cb, num>>1); - } else { - memset(&(gSpudec.mask->mem[0][line_base + off]), 0xff, num); - memset(&(gSpudec.overlay->mem[0][line_base + off]), 0x00, num); - memset(&(gSpudec.mask->mem[1][line_base2 + (off>>1)]), 0xff, num>>1); - memset(&(gSpudec.overlay->mem[1][line_base2 + (off>>1)]), 0x00, num>>1); - memset(&(gSpudec.mask->mem[2][line_base2 + (off>>1)]), 0xff, num>>1); - memset(&(gSpudec.overlay->mem[2][line_base2 + (off>>1)]), 0x00, num>>1); - } - } - off+=num; - } while((n != 0) && (off <= gSpudec.geom.end_col - gSpudec.geom.start_col)); - - if((n == 0) && (off <= gSpudec.geom.end_col - gSpudec.geom.start_col)) { - /* Clear to end of line if carriage return */ - int len = gSpudec.geom.start_col + gSpudec.geom.end_col - off; - memset(&(gSpudec.mask->mem[0][line_base + off]), 0xff, len); - memset(&(gSpudec.overlay->mem[0][line_base + off]), 0x00, len); - memset(&(gSpudec.mask->mem[0][line_base + off]) + gSpudec.width, 0xff, len); - memset(&(gSpudec.overlay->mem[0][line_base + off]) + gSpudec.width, 0x00, len); - memset(&(gSpudec.mask->mem[1][line_base2 + (off>>1)]), 0xff, len>>1); - memset(&(gSpudec.overlay->mem[1][line_base2 + (off>>1)]), 0x00, len>>1); - memset(&(gSpudec.mask->mem[2][line_base2 + (off>>1)]), 0xff, len>>1); - memset(&(gSpudec.overlay->mem[2][line_base2 + (off>>1)]), 0x00, len>>1); - } - - if((na & 1)) - na ++; /* Re-align */ - - line_base += gSpudec.width; - y++; - if (y > gSpudec.geom.end_row) - break; - - off = 0; - do { - int num; - clut_t *col; - - n = nibble(data, nb); - nb++; - if(n < 0x4) { - n = (n<<4) | nibble(data, nb); - nb++; - if(n < 0x10) { - n = (n<<4) | nibble(data, nb); - nb++; - if(n < 0x40) { - n = (n<<4) | nibble(data, nb); - nb++; - if(n < 0x100) - n = 0; /* Carriage return */ - } - } - } - // printf("Code: 0x%04x\n",n); - - num = n >> 2; col = palette[n & 0x3]; - if(col == NULL) { - printf("Error in palette\n"); - } - - if(num != 0) { - if(alpha[n & 0x3] & 0x80) { - memset(&(gSpudec.mask->mem[0][line_base + off]), 0x00, num); - memset(&(gSpudec.overlay->mem[0][line_base + off]), col->y, num); - } else { - memset(&(gSpudec.mask->mem[0][line_base + off]), 0xff, num); - memset(&(gSpudec.overlay->mem[0][line_base + off]), 0x00, num); - } - } - off+=num; - } while((n != 0) && (off <= gSpudec.geom.end_col - gSpudec.geom.start_col)); - - if((n == 0) && (off <= gSpudec.geom.end_col - gSpudec.geom.start_col)) { - /* Clear to end of line if carriage return */ - int len = gSpudec.geom.start_col + gSpudec.geom.end_col - off; - memset(&(gSpudec.mask->mem[0][line_base + off]), 0xff, len); - memset(&(gSpudec.overlay->mem[0][line_base + off]), 0x00, len); - } - - if((nb & 1)) - nb ++; /* Re-align */ - - y++; - } -} - -void spudec_process_control(unsigned char *control, int size, int* d1, int* d2) -{ - int off = 2; - int a,b; /* Temporary vars */ - - do { - int type = control[off]; - off++; - - switch(type) { - case 0x00: - /* Menu ID, 1 byte */ - break; - case 0x01: - /* Start display */ - gSpudec.geom.bIsVisible = 1; - break; - case 0x03: - /* Palette */ - palette[3] = &(gSpudec.clut[(control[off] >> 4)]); - palette[2] = &(gSpudec.clut[control[off] & 0xf]); - palette[1] = &(gSpudec.clut[(control[off+1] >> 4)]); - palette[0] = &(gSpudec.clut[control[off+1] & 0xf]); - off+=2; - break; - case 0x04: - /* Alpha */ - alpha[3] = control[off] & 0xf0; - alpha[2] = (control[off] & 0xf) << 4; - alpha[1] = control[off+1] & 0xf0; - alpha[0] = (control[off+1] & 0xf) << 4; - off+=2; - break; - case 0x05: - /* Co-ords */ - a = (control[off] << 16) + (control[off+1] << 8) + control[off+2]; - b = (control[off+3] << 16) + (control[off+4] << 8) + control[off+5]; - - gSpudec.geom.start_col = a >> 12; - gSpudec.geom.end_col = a & 0xfff; - gSpudec.geom.start_row = b >> 12; - gSpudec.geom.end_row = b & 0xfff; - - off+=6; - break; - case 0x06: - /* Graphic lines */ - *(d1) = (control[off] << 8) + control[off+1]; - *(d2) = (control[off+2] << 8) + control[off+3]; - off+=4; - break; - case 0xff: - /* All done, bye-bye */ - return; - break; - default: - printf("spudec: Error determining control type 0x%02x.\n",type); - return; - break; - } - - /* printf("spudec: Processsed control type 0x%02x.\n",type); */ - } while(off < size); -} - -void spudec_process_packet(unsigned char *packet, int size) -{ - int x0, x1; - int d1, d2; - - /* Check packet */ - if((packet[0] << 8) + packet[1] != size) { - printf("Packet size mismatch:\n"); - printf("Packet reports size 0x%04x\n", (packet[0] << 8) + packet[1]); - printf("I reckon 0x%04x\n", size); - return; - } - - x0 = (packet[2] << 8) + packet[3]; - x1 = (packet[x0+2] << 8) + packet[x0+3]; - - /* /Another/ sanity check. */ - if((packet[x1+2]<<8) + packet[x1+3] != x1) { - printf("spudec: Incorrect packet.\n"); - return; - } - - /* End sequence, FIXME: why do we need the division by 2? */ - gSpudec.lifetime = (metronom_get_video_rate() >> 1)* ((packet[x1]<<8) + packet[x1+1]); - - d1 = d2 = -1; - spudec_process_control(packet + x0 + 2, x1-x0-2, &d1, &d2); - - if((d1 != -1) && (d2 != -1)) { - spudec_process_data(packet, x0, d1, d2); - } -} - -void spudec_decode(unsigned char *data, int size, uint32_t pts) { - if(!gSpudec.bInitialised) - return; - - if(gSpudec.packet == NULL) { - if(pts != 0) { - /* Allocate a packet buffer */ - gSpudec.packet = xmalloc((data[0] << 8) + data[1]); - gSpudec.pts = pts; - - if(gSpudec.packet == NULL) { - printf("Error allocating packet buffer.\n"); - return; - } - - gSpudec.packet_size = 0; - } else { - printf("spudec: Error, we are half way through a packet I don't know\n"); - } - } - - /* Prevent buffer overruns */ - if(gSpudec.packet_size >= 2) { /* If the /packet/ knows how big it is */ - if((gSpudec.packet_size + size) > - (gSpudec.packet[0]<<8) + gSpudec.packet[1]) { - printf("spudec: Mismatched buffer size (0x%04x to big), truncating.\n", - (gSpudec.packet_size + size) - - ((gSpudec.packet[0]<<8) + gSpudec.packet[1])); - size = (gSpudec.packet[0]<<8) + gSpudec.packet[1] - gSpudec.packet_size; - } - } - - - memcpy(gSpudec.packet + gSpudec.packet_size, data, size); - gSpudec.packet_size += size; - - if(gSpudec.packet_size >= (gSpudec.packet[0]<<8) + gSpudec.packet[1]) { - /* If packet complete then queue */ - spudec_packet *p; - - p = xmalloc(sizeof(spudec_packet)); - p->packet = gSpudec.packet; - p->size = gSpudec.packet_size; - p->pts = gSpudec.pts; - - spudec_queue_packet(p); - - gSpudec.packet = NULL; - gSpudec.packet_size = -1; - gSpudec.pts = 0; - } -} - -void spudec_reset() { - /* Clear any packet being assembled */ - if(gSpudec.packet != NULL) { - gSpudec.packet_size = 0; - free(gSpudec.packet); - gSpudec.packet = NULL; - gSpudec.pts = 0; - } - - /* Remove any current subtitle */ - gSpudec.geom.bIsVisible = 0; - gSpudec.lifetime = 0; - - /* Clear packet queue */ - while(spudec_queue_size > 0) { - spudec_packet *p = spudec_get_next_packet(); - - free(p->packet); - free(p); - } -} - -void spudec_overlay_yuv (uint8_t *y, uint8_t *u, uint8_t *v) { - - /* - * Mix in SPU - */ - - /* Tick SPUdec */ - spudec_tick(); - - if(gVO.bOverlayImage) { - /* This code is pretty nasty but quite quick which is important here! */ - /* APPROACH: Since 32bit processors hande data, well 32bits at a time, - * we overlay the image word by word rather than byte by byte and then - * tidy up the odd bytes at the end. This effectively cuts the number of - * loop itterations by a factor of 4. */ - - /* FIXME: Optimise for 64bit machines as well? */ - - if((gVO.spu_geom->bIsVisible) && - (gVO.format == IMGFMT_YV12)) { - /* Overlay the image. */ - long i, off; - uint8_t *img_l_8, *ovl_l_8, *msk_l_8; - uint32_t *img_l_32, *ovl_l_32, *msk_l_32; - uint8_t *img_y_8, *ovl_y_8, *msk_y_8; - uint32_t *img_y_32, *ovl_y_32, *msk_y_32; - uint8_t *img_v_8, *ovl_v_8, *msk_v_8; - uint32_t *img_v_32, *ovl_v_32, *msk_v_32; - - img_l_8 = img->mem[0]; - ovl_l_8 = gVO.overlay_image->mem[0]; - msk_l_8 = gVO.mask_image->mem[0]; - img_l_32 = ((uint32_t*)img->mem[0]); - ovl_l_32 = ((uint32_t*)gVO.overlay_image->mem[0]); - msk_l_32 = ((uint32_t*)gVO.mask_image->mem[0]); - img_y_8 = img->mem[1]; - ovl_y_8 = gVO.overlay_image->mem[1]; - msk_y_8 = gVO.mask_image->mem[1]; - img_y_32 = ((uint32_t*)img->mem[1]); - ovl_y_32 = ((uint32_t*)gVO.overlay_image->mem[1]); - msk_y_32 = ((uint32_t*)gVO.mask_image->mem[1]); - img_v_8 = img->mem[2]; - ovl_v_8 = gVO.overlay_image->mem[2]; - msk_v_8 = gVO.mask_image->mem[2]; - img_v_32 = ((uint32_t*)img->mem[2]); - ovl_v_32 = ((uint32_t*)gVO.overlay_image->mem[2]); - msk_v_32 = ((uint32_t*)gVO.mask_image->mem[2]); - - /* luminance */ - for(i=gVO.width*gVO.spu_geom->start_row; - i<=gVO.width*gVO.spu_geom->end_row; i+=gVO.width) { - /* i is address of begining of line. */ - - /* Firstly, draw the start odd bytes. */ - for(off = i+gVO.spu_geom->start_col; (off & 3) != 0; off++) { - if(msk_l_8[off] != 0xff) { - img_l_8[off] &= msk_l_8[off]; - img_l_8[off] |= ovl_l_8[off]; - } - } - - /* Now words */ - for(; off<=i+gVO.spu_geom->end_col-3; off+=4) { - if(msk_l_32[off>>2] != 0xffffffff) { - img_l_32[off>>2] &= msk_l_32[off>>2]; - img_l_32[off>>2] |= ovl_l_32[off>>2]; - } - } - off -= 4; - - /* Now end odd bytes */ - for(; off<=i+gVO.spu_geom->end_col; off++) { - if(msk_l_8[off] != 0xff) { - img_l_8[off] &= msk_l_8[off]; - img_l_8[off] |= ovl_l_8[off]; - } - } - } - /* colour */ - for(i=(gVO.width>>1)*(gVO.spu_geom->start_row>>1); - i<=(gVO.width>>1)*(gVO.spu_geom->end_row>>1); i+=(gVO.width)>>1) { - /* i is address of begining of line. */ - - /* Firstly, draw the start odd bytes. */ - for(off = i+((gVO.spu_geom->start_col)>>1); (off & 3) != 0; off++) { - if(msk_y_8[off] != 0xff) { - img_y_8[off] &= msk_y_8[off]; - img_y_8[off] |= ovl_y_8[off]; - } - if(msk_v_8[off] != 0xff) { - img_v_8[off] &= msk_v_8[off]; - img_v_8[off] |= ovl_v_8[off]; - } - } - - /* Now words */ - for(; off<=i+((gVO.spu_geom->end_col)>>1)-3; off+=4) { - if(msk_y_32[off>>2] != 0xffffffff) { - img_y_32[off>>2] &= msk_y_32[off>>2]; - img_y_32[off>>2] |= ovl_y_32[off>>2]; - } - if(msk_v_32[off>>2] != 0xffffffff) { - img_v_32[off>>2] &= msk_v_32[off>>2]; - img_v_32[off>>2] |= ovl_v_32[off>>2]; - } - } - off -= 4; - - /* Final end odd bytes */ - for(; off<=i+((gVO.spu_geom->end_col)>>1); off++) { - if(msk_y_8[off] != 0xff) { - img_y_8[off] &= msk_y_8[off]; - img_y_8[off] |= ovl_y_8[off]; - } - if(msk_v_8[off] != 0xff) { - img_v_8[off] &= msk_v_8[off]; - img_v_8[off] |= ovl_v_8[off]; - } - } - } - } - } -} |