changeset 3166:69ad1e3db38c

Palette support for SPU decoder.
author atmos4
date Tue, 27 Nov 2001 20:16:45 +0000
parents c9f140f5a34e
children b91c24076bca
files mplayer.c spudec.c spudec.h
diffstat 3 files changed, 39 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/mplayer.c	Tue Nov 27 18:36:35 2001 +0000
+++ b/mplayer.c	Tue Nov 27 20:16:45 2001 +0000
@@ -773,18 +773,18 @@
 
     
 
-  current_module="spudec";
-  vo_spudec=spudec_new();
-  if (vo_spudec!=NULL)
-    inited_flags|=INITED_SPUDEC;
-  current_module=NULL;
-
   current_module="open_stream";
   stream=open_stream(filename,vcd_track,&file_format);
   if(!stream) goto goto_next_file;//  exit_player(MSGTR_Exit_error); // error...
   inited_flags|=INITED_STREAM;
   stream->start_pos+=seek_to_byte;
 
+  current_module="spudec";
+  vo_spudec=spudec_new(stream->priv);
+  if (vo_spudec!=NULL)
+    inited_flags|=INITED_SPUDEC;
+  current_module=NULL;
+
   if(stream_cache_size) stream_enable_cache(stream,stream_cache_size*1024);
 
   use_stdin=filename && (!strcmp(filename,"-"));
--- a/spudec.c	Tue Nov 27 18:36:35 2001 +0000
+++ b/spudec.c	Tue Nov 27 20:16:45 2001 +0000
@@ -5,7 +5,7 @@
 
    Kim Minh Kaplan
    implement fragments reassembly, RLE decoding.
-   image rendering needs to be corrected (see mkcolor & mkalpha).
+   read brightness from the IFO.
 
    For information on SPU format see <URL:http://sam.zoy.org/doc/dvd/subtitles/>
 
@@ -17,6 +17,7 @@
 #include "spudec.h"
 
 typedef struct {
+  dvd_priv_t *dvd_info;		/* Info from libmpdemux */
   unsigned char* packet;
   size_t packet_reserve;	/* size of the memory pointed to by packet */
   int packet_offset;		/* end of the currently assembled fragment */
@@ -74,51 +75,35 @@
 
 static inline int mkalpha(int i)
 {
-  /* for VO 0 is transparent
-     127 is quite dark, but still...
-     255 is transparent with color 0, and hum... funny with other colors...
-
-     FIXME, I can't seem to get a good alpha value!
-
-     i is the value read from SPU, from 0 to 15.  The function should
-     return the corresponding alpha value suitable for libvo's
-     draw_alpha.  */
-#if 0
-  return (0xf - (i & 0xf)) << 4;
-#else
-  return (i < 8) ? 127 : 0;
-#endif
-}
-
-static inline int mkcolor(int i)
-{
-  /* FIXME, have to get the colormap's RGB values from the IFO */
-#if 0
+  /* In mplayer's alpha planes, 0 is transparent, then 1 is nearly
+     opaque upto 255 which is transparent */
   switch (i) {
-  case 15: return 0;
-  default: return i << 4;
+  case 0xf:
+    return 1;
+  case 0:
+    return 0;
+  default:
+    return (0xf - i) << 4;
   }
-#else
-  return i << 4;
-#endif
 }
 
 static void spudec_process_data(spudec_handle_t *this)
 {
-  int alpha[4] = {
-    mkalpha(this->alpha[0]),
-    mkalpha(this->alpha[1]),
-    mkalpha(this->alpha[2]),
-    mkalpha(this->alpha[3])
-  };
-  int cmap[4] = {
-    mkcolor(this->palette[0]),
-    mkcolor(this->palette[1]),
-    mkcolor(this->palette[2]),
-    mkcolor(this->palette[3])
-  };
+  int cmap[4], alpha[4];
+  int i;
   int y = 0, x = 0;
 
+  for (i = 0; i < 4; ++i) {
+    alpha[i] = mkalpha(this->alpha[i]);
+    if (alpha[i] == 0)
+      cmap[i] = 0;
+    else {
+      cmap[i] = ((this->dvd_info->vts_file->vts_pgcit->pgci_srp[0].pgc->palette[this->palette[i]] >> 16) & 0xff) - alpha[i];
+      if (cmap[i] < 0)
+	cmap[i] = 0;
+    }
+  }
+
   if (this->image_size < this->width * this->height) {
     if (this->image != NULL)
       free(this->image);
@@ -130,7 +115,8 @@
   }
   if (this->image == NULL)
     return;
-  while (this->current_nibble[0] / 2 < this->control_start
+  i = this->current_nibble[1];
+  while (this->current_nibble[0] < i
 	 && this->current_nibble[1] / 2 < this->control_start
 	 && y < this->height) {
     int len, color;
@@ -147,17 +133,13 @@
 	}
       }
     }
-    color = rle & 0x3;
+    color = 3 - (rle & 0x3);
     len = rle >> 2;
     if (len > this->width - x)
       len = this->width - x;
     /* FIXME have to use palette and alpha map*/
     memset(this->image + y * this->width + x, cmap[color], len);
-    if (alpha[color] < cmap[color]) {
-      memset(this->aimage + y * this->width + x, 1, len);
-    } else {
-      memset(this->aimage + y * this->width + x, alpha[color] - cmap[color], len);
-    }
+    memset(this->aimage + y * this->width + x, alpha[color], len);
     x += len;
     if (x >= this->width) {
       next_line(this);
@@ -229,7 +211,7 @@
 	this->width = this->end_col - this->start_col + 1;
 	this->start_row = b >> 12;
 	this->end_row = b & 0xfff;
-	this->height = this->end_row - this->start_row + 1;
+	this->height = this->end_row - this->start_row /* + 1 */;
 	printf("Coords  col: %d - %d  row: %d - %d  (%dx%d)\n",
 	       this->start_col, this->end_col, this->start_row, this->end_row,
 	       this->width, this->height);
@@ -313,11 +295,11 @@
 		   spu->image, spu->aimage, spu->width);
 }
 
-void *spudec_new()
+void *spudec_new(dvd_priv_t *dvd_info)
 {
   spudec_handle_t *this = calloc(1, sizeof(spudec_handle_t));
   if (this) {
-    ;
+    this->dvd_info = dvd_info;
   }
   else
     perror("FATAL: spudec_init: calloc");
--- a/spudec.h	Tue Nov 27 18:36:35 2001 +0000
+++ b/spudec.h	Tue Nov 27 20:16:45 2001 +0000
@@ -1,10 +1,12 @@
 #ifndef _MPLAYER_SPUDEC_H
 #define _MPLAYER_SPUDEC_H
 
+#include "config.h"
+#include "stream.h"
 void spudec_heartbeat(void *this, int pts100);
 void spudec_assemble(void *this, unsigned char *packet, int len, int pts100);
 void spudec_draw(void *this, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
-void *spudec_new();
+void *spudec_new(dvd_priv_t *dvd_info);
 void spudec_free(void *this);
 
 #endif