Mercurial > mplayer.hg
comparison spudec.c @ 3166:69ad1e3db38c
Palette support for SPU decoder.
author | atmos4 |
---|---|
date | Tue, 27 Nov 2001 20:16:45 +0000 |
parents | fa8665a91729 |
children | 3538c34117a3 |
comparison
equal
deleted
inserted
replaced
3165:c9f140f5a34e | 3166:69ad1e3db38c |
---|---|
3 Further works: | 3 Further works: |
4 LGB,... (yeah, try to improve it and insert your name here! ;-) | 4 LGB,... (yeah, try to improve it and insert your name here! ;-) |
5 | 5 |
6 Kim Minh Kaplan | 6 Kim Minh Kaplan |
7 implement fragments reassembly, RLE decoding. | 7 implement fragments reassembly, RLE decoding. |
8 image rendering needs to be corrected (see mkcolor & mkalpha). | 8 read brightness from the IFO. |
9 | 9 |
10 For information on SPU format see <URL:http://sam.zoy.org/doc/dvd/subtitles/> | 10 For information on SPU format see <URL:http://sam.zoy.org/doc/dvd/subtitles/> |
11 | 11 |
12 */ | 12 */ |
13 | 13 |
15 #include <stdio.h> | 15 #include <stdio.h> |
16 #include <stdlib.h> | 16 #include <stdlib.h> |
17 #include "spudec.h" | 17 #include "spudec.h" |
18 | 18 |
19 typedef struct { | 19 typedef struct { |
20 dvd_priv_t *dvd_info; /* Info from libmpdemux */ | |
20 unsigned char* packet; | 21 unsigned char* packet; |
21 size_t packet_reserve; /* size of the memory pointed to by packet */ | 22 size_t packet_reserve; /* size of the memory pointed to by packet */ |
22 int packet_offset; /* end of the currently assembled fragment */ | 23 int packet_offset; /* end of the currently assembled fragment */ |
23 int packet_size; /* size of the packet once all fragments are assembled */ | 24 int packet_size; /* size of the packet once all fragments are assembled */ |
24 int control_start; /* index of start of control data */ | 25 int control_start; /* index of start of control data */ |
72 return nib; | 73 return nib; |
73 } | 74 } |
74 | 75 |
75 static inline int mkalpha(int i) | 76 static inline int mkalpha(int i) |
76 { | 77 { |
77 /* for VO 0 is transparent | 78 /* In mplayer's alpha planes, 0 is transparent, then 1 is nearly |
78 127 is quite dark, but still... | 79 opaque upto 255 which is transparent */ |
79 255 is transparent with color 0, and hum... funny with other colors... | |
80 | |
81 FIXME, I can't seem to get a good alpha value! | |
82 | |
83 i is the value read from SPU, from 0 to 15. The function should | |
84 return the corresponding alpha value suitable for libvo's | |
85 draw_alpha. */ | |
86 #if 0 | |
87 return (0xf - (i & 0xf)) << 4; | |
88 #else | |
89 return (i < 8) ? 127 : 0; | |
90 #endif | |
91 } | |
92 | |
93 static inline int mkcolor(int i) | |
94 { | |
95 /* FIXME, have to get the colormap's RGB values from the IFO */ | |
96 #if 0 | |
97 switch (i) { | 80 switch (i) { |
98 case 15: return 0; | 81 case 0xf: |
99 default: return i << 4; | 82 return 1; |
100 } | 83 case 0: |
101 #else | 84 return 0; |
102 return i << 4; | 85 default: |
103 #endif | 86 return (0xf - i) << 4; |
87 } | |
104 } | 88 } |
105 | 89 |
106 static void spudec_process_data(spudec_handle_t *this) | 90 static void spudec_process_data(spudec_handle_t *this) |
107 { | 91 { |
108 int alpha[4] = { | 92 int cmap[4], alpha[4]; |
109 mkalpha(this->alpha[0]), | 93 int i; |
110 mkalpha(this->alpha[1]), | |
111 mkalpha(this->alpha[2]), | |
112 mkalpha(this->alpha[3]) | |
113 }; | |
114 int cmap[4] = { | |
115 mkcolor(this->palette[0]), | |
116 mkcolor(this->palette[1]), | |
117 mkcolor(this->palette[2]), | |
118 mkcolor(this->palette[3]) | |
119 }; | |
120 int y = 0, x = 0; | 94 int y = 0, x = 0; |
95 | |
96 for (i = 0; i < 4; ++i) { | |
97 alpha[i] = mkalpha(this->alpha[i]); | |
98 if (alpha[i] == 0) | |
99 cmap[i] = 0; | |
100 else { | |
101 cmap[i] = ((this->dvd_info->vts_file->vts_pgcit->pgci_srp[0].pgc->palette[this->palette[i]] >> 16) & 0xff) - alpha[i]; | |
102 if (cmap[i] < 0) | |
103 cmap[i] = 0; | |
104 } | |
105 } | |
121 | 106 |
122 if (this->image_size < this->width * this->height) { | 107 if (this->image_size < this->width * this->height) { |
123 if (this->image != NULL) | 108 if (this->image != NULL) |
124 free(this->image); | 109 free(this->image); |
125 this->image = malloc(2 * this->width * this->height); | 110 this->image = malloc(2 * this->width * this->height); |
128 this->aimage = this->image + this->image_size; | 113 this->aimage = this->image + this->image_size; |
129 } | 114 } |
130 } | 115 } |
131 if (this->image == NULL) | 116 if (this->image == NULL) |
132 return; | 117 return; |
133 while (this->current_nibble[0] / 2 < this->control_start | 118 i = this->current_nibble[1]; |
119 while (this->current_nibble[0] < i | |
134 && this->current_nibble[1] / 2 < this->control_start | 120 && this->current_nibble[1] / 2 < this->control_start |
135 && y < this->height) { | 121 && y < this->height) { |
136 int len, color; | 122 int len, color; |
137 unsigned int rle = 0; | 123 unsigned int rle = 0; |
138 rle = get_nibble(this); | 124 rle = get_nibble(this); |
145 if (rle < 0x0004) | 131 if (rle < 0x0004) |
146 rle |= ((this->width - x) << 2); | 132 rle |= ((this->width - x) << 2); |
147 } | 133 } |
148 } | 134 } |
149 } | 135 } |
150 color = rle & 0x3; | 136 color = 3 - (rle & 0x3); |
151 len = rle >> 2; | 137 len = rle >> 2; |
152 if (len > this->width - x) | 138 if (len > this->width - x) |
153 len = this->width - x; | 139 len = this->width - x; |
154 /* FIXME have to use palette and alpha map*/ | 140 /* FIXME have to use palette and alpha map*/ |
155 memset(this->image + y * this->width + x, cmap[color], len); | 141 memset(this->image + y * this->width + x, cmap[color], len); |
156 if (alpha[color] < cmap[color]) { | 142 memset(this->aimage + y * this->width + x, alpha[color], len); |
157 memset(this->aimage + y * this->width + x, 1, len); | |
158 } else { | |
159 memset(this->aimage + y * this->width + x, alpha[color] - cmap[color], len); | |
160 } | |
161 x += len; | 143 x += len; |
162 if (x >= this->width) { | 144 if (x >= this->width) { |
163 next_line(this); | 145 next_line(this); |
164 x = 0; | 146 x = 0; |
165 ++y; | 147 ++y; |
227 this->start_col = a >> 12; | 209 this->start_col = a >> 12; |
228 this->end_col = a & 0xfff; | 210 this->end_col = a & 0xfff; |
229 this->width = this->end_col - this->start_col + 1; | 211 this->width = this->end_col - this->start_col + 1; |
230 this->start_row = b >> 12; | 212 this->start_row = b >> 12; |
231 this->end_row = b & 0xfff; | 213 this->end_row = b & 0xfff; |
232 this->height = this->end_row - this->start_row + 1; | 214 this->height = this->end_row - this->start_row /* + 1 */; |
233 printf("Coords col: %d - %d row: %d - %d (%dx%d)\n", | 215 printf("Coords col: %d - %d row: %d - %d (%dx%d)\n", |
234 this->start_col, this->end_col, this->start_row, this->end_row, | 216 this->start_col, this->end_col, this->start_row, this->end_row, |
235 this->width, this->height); | 217 this->width, this->height); |
236 off+=6; | 218 off+=6; |
237 break; | 219 break; |
311 if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts && spu->image) | 293 if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts && spu->image) |
312 draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height, | 294 draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height, |
313 spu->image, spu->aimage, spu->width); | 295 spu->image, spu->aimage, spu->width); |
314 } | 296 } |
315 | 297 |
316 void *spudec_new() | 298 void *spudec_new(dvd_priv_t *dvd_info) |
317 { | 299 { |
318 spudec_handle_t *this = calloc(1, sizeof(spudec_handle_t)); | 300 spudec_handle_t *this = calloc(1, sizeof(spudec_handle_t)); |
319 if (this) { | 301 if (this) { |
320 ; | 302 this->dvd_info = dvd_info; |
321 } | 303 } |
322 else | 304 else |
323 perror("FATAL: spudec_init: calloc"); | 305 perror("FATAL: spudec_init: calloc"); |
324 return this; | 306 return this; |
325 } | 307 } |