annotate sub/spudec.c @ 35031:135b1ef31668

Clamp bitmap subtitles into visible areas. This avoids subtitles disappearing completely if we detect the original resolution the subtitles were created for incorrectly.
author reimar
date Mon, 27 Aug 2012 20:46:06 +0000
parents a0b10e46f7e6
children b7ec2526b402
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1 /*
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
2 * Skeleton of function spudec_process_controll() is from xine sources.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
3 * Further works:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
4 * LGB,... (yeah, try to improve it and insert your name here! ;-)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
5 *
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
6 * Kim Minh Kaplan
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
7 * implement fragments reassembly, RLE decoding.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
8 * read brightness from the IFO.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
9 *
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
10 * For information on SPU format see <URL:http://sam.zoy.org/doc/dvd/subtitles/>
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
11 * and <URL:http://members.aol.com/mpucoder/DVD/spu.html>
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
12 *
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
13 * This file is part of MPlayer.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
14 *
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
15 * MPlayer is free software; you can redistribute it and/or modify
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
16 * it under the terms of the GNU General Public License as published by
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
17 * the Free Software Foundation; either version 2 of the License, or
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
18 * (at your option) any later version.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
19 *
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
20 * MPlayer is distributed in the hope that it will be useful,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
23 * GNU General Public License for more details.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
24 *
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
25 * You should have received a copy of the GNU General Public License along
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
26 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
28 */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
29
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
30 #include "config.h"
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
31 #include "mp_msg.h"
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
32
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
33 #include <errno.h>
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
34 #include <limits.h>
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
35 #include <stdio.h>
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
36 #include <stdlib.h>
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
37 #include <unistd.h>
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
38 #include <string.h>
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
39 #include <math.h>
32467
fbe5c829c69b Move libvo/sub.[ch] from libvo to sub.
cigaes
parents: 32464
diff changeset
40 #include "sub.h"
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
41 #include "libvo/video_out.h"
32464
22888a8cb312 Do not use a path for including files in the same directory.
reimar
parents: 32459
diff changeset
42 #include "spudec.h"
22888a8cb312 Do not use a path for including files in the same directory.
reimar
parents: 32459
diff changeset
43 #include "vobsub.h"
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
44 #include "libavutil/avutil.h"
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
45 #include "libavutil/intreadwrite.h"
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
46 #include "libswscale/swscale.h"
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
47
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
48 /* Valid values for spu_aamode:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
49 0: none (fastest, most ugly)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
50 1: approximate
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
51 2: full (slowest)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
52 3: bilinear (similiar to vobsub, fast and not too bad)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
53 4: uses swscaler gaussian (this is the only one that looks good)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
54 */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
55
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
56 int spu_aamode = 3;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
57 int spu_alignment = -1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
58 float spu_gaussvar = 1.0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
59
34784
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
60 typedef struct spu_packet_t packet_t;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
61 struct spu_packet_t {
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
62 int is_decoded;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
63 unsigned char *packet;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
64 int data_len;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
65 unsigned int palette[4];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
66 unsigned int alpha[4];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
67 unsigned int control_start; /* index of start of control data */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
68 unsigned int current_nibble[2]; /* next data nibble (4 bits) to be
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
69 processed (for RLE decoding) for
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
70 even and odd lines */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
71 int deinterlace_oddness; /* 0 or 1, index into current_nibble */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
72 unsigned int start_col;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
73 unsigned int start_row;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
74 unsigned int width, height, stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
75 unsigned int start_pts, end_pts;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
76 packet_t *next;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
77 };
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
78
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
79 struct palette_crop_cache {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
80 int valid;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
81 uint32_t palette;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
82 int sx, sy, ex, ey;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
83 int result;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
84 };
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
85
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
86 typedef struct {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
87 packet_t *queue_head;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
88 packet_t *queue_tail;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
89 unsigned int global_palette[16];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
90 unsigned int orig_frame_width, orig_frame_height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
91 unsigned char* packet;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
92 size_t packet_reserve; /* size of the memory pointed to by packet */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
93 unsigned int packet_offset; /* end of the currently assembled fragment */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
94 unsigned int packet_size; /* size of the packet once all fragments are assembled */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
95 int packet_pts; /* PTS for this packet */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
96 unsigned int palette[4];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
97 unsigned int alpha[4];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
98 unsigned int cuspal[4];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
99 unsigned int custom;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
100 unsigned int now_pts;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
101 unsigned int start_pts, end_pts;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
102 unsigned int start_col;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
103 unsigned int start_row;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
104 unsigned int width, height, stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
105 size_t image_size; /* Size of the image buffer */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
106 unsigned char *image; /* Grayscale value */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
107 unsigned char *aimage; /* Alpha value */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
108 unsigned int pal_start_col, pal_start_row;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
109 unsigned int pal_width, pal_height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
110 unsigned char *pal_image; /* palette entry value */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
111 unsigned int scaled_frame_width, scaled_frame_height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
112 unsigned int scaled_start_col, scaled_start_row;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
113 unsigned int scaled_width, scaled_height, scaled_stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
114 size_t scaled_image_size;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
115 unsigned char *scaled_image;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
116 unsigned char *scaled_aimage;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
117 int auto_palette; /* 1 if we lack a palette and must use an heuristic. */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
118 int font_start_level; /* Darkest value used for the computed font */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
119 const vo_functions_t *hw_spu;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
120 int spu_changed;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
121 unsigned int forced_subs_only; /* flag: 0=display all subtitle, !0 display only forced subtitles */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
122 unsigned int is_forced_sub; /* true if current subtitle is a forced subtitle */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
123
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
124 struct palette_crop_cache palette_crop_cache;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
125 } spudec_handle_t;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
126
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
127 static void spudec_queue_packet(spudec_handle_t *this, packet_t *packet)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
128 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
129 if (this->queue_head == NULL)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
130 this->queue_head = packet;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
131 else
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
132 this->queue_tail->next = packet;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
133 this->queue_tail = packet;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
134 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
135
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
136 static packet_t *spudec_dequeue_packet(spudec_handle_t *this)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
137 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
138 packet_t *retval = this->queue_head;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
139
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
140 this->queue_head = retval->next;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
141 if (this->queue_head == NULL)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
142 this->queue_tail = NULL;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
143
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
144 return retval;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
145 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
146
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
147 static void spudec_free_packet(packet_t *packet)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
148 {
32511
b39155e98ac3 Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents: 32467
diff changeset
149 free(packet->packet);
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
150 free(packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
151 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
152
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
153 static inline unsigned int get_be16(const unsigned char *p)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
154 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
155 return (p[0] << 8) + p[1];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
156 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
157
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
158 static inline unsigned int get_be24(const unsigned char *p)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
159 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
160 return (get_be16(p) << 8) + p[2];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
161 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
162
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
163 static void next_line(packet_t *packet)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
164 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
165 if (packet->current_nibble[packet->deinterlace_oddness] % 2)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
166 packet->current_nibble[packet->deinterlace_oddness]++;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
167 packet->deinterlace_oddness = (packet->deinterlace_oddness + 1) % 2;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
168 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
169
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
170 static inline unsigned char get_nibble(packet_t *packet)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
171 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
172 unsigned char nib;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
173 unsigned int *nibblep = packet->current_nibble + packet->deinterlace_oddness;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
174 if (*nibblep / 2 >= packet->control_start) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
175 mp_msg(MSGT_SPUDEC,MSGL_WARN, "SPUdec: ERROR: get_nibble past end of packet\n");
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
176 return 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
177 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
178 nib = packet->packet[*nibblep / 2];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
179 if (*nibblep % 2)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
180 nib &= 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
181 else
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
182 nib >>= 4;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
183 ++*nibblep;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
184 return nib;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
185 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
186
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
187 /* Cut the sub to visible part */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
188 static inline void spudec_cut_image(spudec_handle_t *this)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
189 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
190 unsigned int fy, ly;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
191 unsigned int first_y, last_y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
192
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
193 if (this->stride == 0 || this->height == 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
194 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
195 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
196
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
197 for (fy = 0; fy < this->image_size && !this->aimage[fy]; fy++);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
198 for (ly = this->stride * this->height-1; ly && !this->aimage[ly]; ly--);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
199 first_y = fy / this->stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
200 last_y = ly / this->stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
201 //printf("first_y: %d, last_y: %d\n", first_y, last_y);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
202 this->start_row += first_y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
203
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
204 // Some subtitles trigger this condition
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
205 if (last_y + 1 > first_y ) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
206 this->height = last_y - first_y +1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
207 } else {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
208 this->height = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
209 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
210 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
211
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
212 // printf("new h %d new start %d (sz %d st %d)---\n\n", this->height, this->start_row, this->image_size, this->stride);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
213
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
214 if (first_y > 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
215 memmove(this->image, this->image + this->stride * first_y, this->stride * this->height);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
216 memmove(this->aimage, this->aimage + this->stride * first_y, this->stride * this->height);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
217 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
218 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
219
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
220
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
221 static int spudec_alloc_image(spudec_handle_t *this, int stride, int height)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
222 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
223 if (this->width > stride) // just a safeguard
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
224 this->width = stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
225 this->stride = stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
226 this->height = height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
227 if (this->image_size < this->stride * this->height) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
228 if (this->image != NULL) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
229 free(this->image);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
230 free(this->pal_image);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
231 this->image_size = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
232 this->pal_width = this->pal_height = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
233 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
234 this->image = malloc(2 * this->stride * this->height);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
235 if (this->image) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
236 this->image_size = this->stride * this->height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
237 this->aimage = this->image + this->image_size;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
238 // use stride here as well to simplify reallocation checks
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
239 this->pal_image = malloc(this->stride * this->height);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
240 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
241 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
242 return this->image != NULL;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
243 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
244
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
245 /**
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
246 * \param pal palette in MPlayer-style gray-alpha values, i.e.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
247 * alpha == 0 means transparent, 1 fully opaque,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
248 * gray value <= 256 - alpha.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
249 */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
250 static void pal2gray_alpha(const uint16_t *pal,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
251 const uint8_t *src, int src_stride,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
252 uint8_t *dst, uint8_t *dsta,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
253 int dst_stride, int w, int h)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
254 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
255 int x, y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
256 for (y = 0; y < h; y++) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
257 for (x = 0; x < w; x++) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
258 uint16_t pixel = pal[src[x]];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
259 *dst++ = pixel;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
260 *dsta++ = pixel >> 8;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
261 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
262 for (; x < dst_stride; x++)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
263 *dsta++ = *dst++ = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
264 src += src_stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
265 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
266 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
267
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
268 static int apply_palette_crop(spudec_handle_t *this,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
269 unsigned crop_x, unsigned crop_y,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
270 unsigned crop_w, unsigned crop_h)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
271 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
272 int i;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
273 uint8_t *src;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
274 uint16_t pal[4];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
275 unsigned stride = (crop_w + 7) & ~7;
34778
48310248f892 Ensure that the highlight disappears when switching
reimar
parents: 33143
diff changeset
276 int ret = 1;
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
277 if (crop_x > this->pal_width || crop_y > this->pal_height ||
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
278 crop_w > this->pal_width - crop_x || crop_h > this->pal_width - crop_y ||
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
279 crop_w > 0x8000 || crop_h > 0x8000 ||
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
280 stride * crop_h > this->image_size) {
34778
48310248f892 Ensure that the highlight disappears when switching
reimar
parents: 33143
diff changeset
281 // this might be an actual error or just signal that
48310248f892 Ensure that the highlight disappears when switching
reimar
parents: 33143
diff changeset
282 // the highlight should be removed.
48310248f892 Ensure that the highlight disappears when switching
reimar
parents: 33143
diff changeset
283 this->width = 0;
48310248f892 Ensure that the highlight disappears when switching
reimar
parents: 33143
diff changeset
284 this->height = 0;
48310248f892 Ensure that the highlight disappears when switching
reimar
parents: 33143
diff changeset
285 ret = 0;
48310248f892 Ensure that the highlight disappears when switching
reimar
parents: 33143
diff changeset
286 goto out;
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
287 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
288 for (i = 0; i < 4; ++i) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
289 int color;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
290 int alpha = this->alpha[i];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
291 // extend 4 -> 8 bit
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
292 alpha |= alpha << 4;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
293 if (this->custom && (this->cuspal[i] >> 31) != 0)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
294 alpha = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
295 color = this->custom ? this->cuspal[i] :
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
296 this->global_palette[this->palette[i]];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
297 color = (color >> 16) & 0xff;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
298 // convert to MPlayer-style gray/alpha palette
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
299 color = FFMIN(color, alpha);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
300 pal[i] = (-alpha << 8) | color;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
301 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
302 src = this->pal_image + crop_y * this->pal_width + crop_x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
303 pal2gray_alpha(pal, src, this->pal_width,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
304 this->image, this->aimage, stride,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
305 crop_w, crop_h);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
306 this->width = crop_w;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
307 this->height = crop_h;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
308 this->stride = stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
309 this->start_col = this->pal_start_col + crop_x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
310 this->start_row = this->pal_start_row + crop_y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
311 spudec_cut_image(this);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
312
34778
48310248f892 Ensure that the highlight disappears when switching
reimar
parents: 33143
diff changeset
313 out:
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
314 // reset scaled image
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
315 this->scaled_frame_width = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
316 this->scaled_frame_height = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
317 this->palette_crop_cache.valid = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
318 return 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
319 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
320
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
321 int spudec_apply_palette_crop(void *this, uint32_t palette,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
322 int sx, int sy, int ex, int ey)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
323 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
324 spudec_handle_t *spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
325 struct palette_crop_cache *c = &spu->palette_crop_cache;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
326 if (c->valid && c->palette == palette &&
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
327 c->sx == sx && c->sy == sy && c->ex == ex && c->ey == ey)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
328 return c->result;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
329 spu->palette[0] = (palette >> 28) & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
330 spu->palette[1] = (palette >> 24) & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
331 spu->palette[2] = (palette >> 20) & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
332 spu->palette[3] = (palette >> 16) & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
333 spu->alpha[0] = (palette >> 12) & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
334 spu->alpha[1] = (palette >> 8) & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
335 spu->alpha[2] = (palette >> 4) & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
336 spu->alpha[3] = palette & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
337 spu->spu_changed = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
338 c->result = apply_palette_crop(spu,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
339 sx - spu->pal_start_col, sy - spu->pal_start_row,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
340 ex - sx, ey - sy);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
341 c->palette = palette;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
342 c->sx = sx; c->sy = sy;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
343 c->ex = ex; c->ey = ey;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
344 c->valid = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
345 return c->result;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
346 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
347
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
348 static void spudec_process_data(spudec_handle_t *this, packet_t *packet)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
349 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
350 unsigned int i, x, y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
351 uint8_t *dst;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
352
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
353 if (!spudec_alloc_image(this, packet->stride, packet->height))
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
354 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
355
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
356 this->pal_start_col = packet->start_col;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
357 this->pal_start_row = packet->start_row;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
358 this->pal_height = packet->height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
359 this->pal_width = packet->width;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
360 this->stride = packet->stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
361 memcpy(this->palette, packet->palette, sizeof(this->palette));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
362 memcpy(this->alpha, packet->alpha, sizeof(this->alpha));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
363
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
364 i = packet->current_nibble[1];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
365 x = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
366 y = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
367 dst = this->pal_image;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
368 while (packet->current_nibble[0] < i
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
369 && packet->current_nibble[1] / 2 < packet->control_start
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
370 && y < this->pal_height) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
371 unsigned int len, color;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
372 unsigned int rle = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
373 rle = get_nibble(packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
374 if (rle < 0x04) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
375 if (rle == 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
376 rle = (rle << 4) | get_nibble(packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
377 if (rle < 0x04)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
378 rle = (rle << 4) | get_nibble(packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
379 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
380 rle = (rle << 4) | get_nibble(packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
381 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
382 color = 3 - (rle & 0x3);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
383 len = rle >> 2;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
384 x += len;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
385 if (len == 0 || x >= this->pal_width) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
386 len += this->pal_width - x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
387 next_line(packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
388 x = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
389 ++y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
390 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
391 memset(dst, color, len);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
392 dst += len;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
393 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
394 apply_palette_crop(this, 0, 0, this->pal_width, this->pal_height);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
395 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
396
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
397
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
398 /*
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
399 This function tries to create a usable palette.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
400 It determines how many non-transparent colors are used, and assigns different
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
401 gray scale values to each color.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
402 I tested it with four streams and even got something readable. Half of the
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
403 times I got black characters with white around and half the reverse.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
404 */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
405 static void compute_palette(spudec_handle_t *this, packet_t *packet)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
406 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
407 int used[16],i,cused,start,step,color;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
408
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
409 memset(used, 0, sizeof(used));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
410 for (i=0; i<4; i++)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
411 if (packet->alpha[i]) /* !Transparent? */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
412 used[packet->palette[i]] = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
413 for (cused=0, i=0; i<16; i++)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
414 if (used[i]) cused++;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
415 if (!cused) return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
416 if (cused == 1) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
417 start = 0x80;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
418 step = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
419 } else {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
420 start = this->font_start_level;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
421 step = (0xF0-this->font_start_level)/(cused-1);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
422 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
423 memset(used, 0, sizeof(used));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
424 for (i=0; i<4; i++) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
425 color = packet->palette[i];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
426 if (packet->alpha[i] && !used[color]) { /* not assigned? */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
427 used[color] = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
428 this->global_palette[color] = start<<16;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
429 start += step;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
430 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
431 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
432 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
433
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
434 static void spudec_process_control(spudec_handle_t *this, int pts100)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
435 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
436 int a,b,c,d; /* Temporary vars */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
437 unsigned int date, type;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
438 unsigned int off;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
439 unsigned int start_off = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
440 unsigned int next_off;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
441 unsigned int start_pts = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
442 unsigned int end_pts = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
443 unsigned int current_nibble[2] = {0, 0};
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
444 unsigned int control_start;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
445 unsigned int display = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
446 unsigned int start_col = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
447 unsigned int end_col = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
448 unsigned int start_row = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
449 unsigned int end_row = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
450 unsigned int width = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
451 unsigned int height = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
452 unsigned int stride = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
453
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
454 control_start = get_be16(this->packet + 2);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
455 next_off = control_start;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
456 while (start_off != next_off) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
457 start_off = next_off;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
458 date = get_be16(this->packet + start_off) * 1024;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
459 next_off = get_be16(this->packet + start_off + 2);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
460 mp_msg(MSGT_SPUDEC,MSGL_DBG2, "date=%d\n", date);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
461 off = start_off + 4;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
462 for (type = this->packet[off++]; type != 0xff; type = this->packet[off++]) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
463 mp_msg(MSGT_SPUDEC,MSGL_DBG2, "cmd=%d ",type);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
464 switch(type) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
465 case 0x00:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
466 /* Menu ID, 1 byte */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
467 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Menu ID\n");
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
468 /* shouldn't a Menu ID type force display start? */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
469 start_pts = pts100 < 0 && -pts100 >= date ? 0 : pts100 + date;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
470 end_pts = UINT_MAX;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
471 display = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
472 this->is_forced_sub=~0; // current subtitle is forced
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
473 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
474 case 0x01:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
475 /* Start display */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
476 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Start display!\n");
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
477 start_pts = pts100 < 0 && -pts100 >= date ? 0 : pts100 + date;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
478 end_pts = UINT_MAX;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
479 display = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
480 this->is_forced_sub=0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
481 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
482 case 0x02:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
483 /* Stop display */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
484 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Stop display!\n");
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
485 end_pts = pts100 < 0 && -pts100 >= date ? 0 : pts100 + date;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
486 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
487 case 0x03:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
488 /* Palette */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
489 this->palette[0] = this->packet[off] >> 4;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
490 this->palette[1] = this->packet[off] & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
491 this->palette[2] = this->packet[off + 1] >> 4;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
492 this->palette[3] = this->packet[off + 1] & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
493 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Palette %d, %d, %d, %d\n",
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
494 this->palette[0], this->palette[1], this->palette[2], this->palette[3]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
495 off+=2;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
496 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
497 case 0x04:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
498 /* Alpha */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
499 a = this->packet[off] >> 4;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
500 b = this->packet[off] & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
501 c = this->packet[off + 1] >> 4;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
502 d = this->packet[off + 1] & 0xf;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
503 // Note: some DVDs change these values to create a fade-in/fade-out effect
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
504 // We can not handle this, so just keep the highest value during the display time.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
505 if (display) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
506 a = FFMAX(a, this->alpha[0]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
507 b = FFMAX(b, this->alpha[1]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
508 c = FFMAX(c, this->alpha[2]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
509 d = FFMAX(d, this->alpha[3]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
510 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
511 this->alpha[0] = a;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
512 this->alpha[1] = b;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
513 this->alpha[2] = c;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
514 this->alpha[3] = d;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
515 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Alpha %d, %d, %d, %d\n",
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
516 this->alpha[0], this->alpha[1], this->alpha[2], this->alpha[3]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
517 off+=2;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
518 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
519 case 0x05:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
520 /* Co-ords */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
521 a = get_be24(this->packet + off);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
522 b = get_be24(this->packet + off + 3);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
523 start_col = a >> 12;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
524 end_col = a & 0xfff;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
525 width = (end_col < start_col) ? 0 : end_col - start_col + 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
526 stride = (width + 7) & ~7; /* Kludge: draw_alpha needs width multiple of 8 */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
527 start_row = b >> 12;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
528 end_row = b & 0xfff;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
529 height = (end_row < start_row) ? 0 : end_row - start_row /* + 1 */;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
530 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Coords col: %d - %d row: %d - %d (%dx%d)\n",
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
531 start_col, end_col, start_row, end_row,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
532 width, height);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
533 off+=6;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
534 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
535 case 0x06:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
536 /* Graphic lines */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
537 current_nibble[0] = 2 * get_be16(this->packet + off);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
538 current_nibble[1] = 2 * get_be16(this->packet + off + 2);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
539 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Graphic offset 1: %d offset 2: %d\n",
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
540 current_nibble[0] / 2, current_nibble[1] / 2);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
541 off+=4;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
542 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
543 case 0xff:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
544 /* All done, bye-bye */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
545 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"Done!\n");
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
546 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
547 // break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
548 default:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
549 mp_msg(MSGT_SPUDEC,MSGL_WARN,"spudec: Error determining control type 0x%02x. Skipping %d bytes.\n",
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
550 type, next_off - off);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
551 goto next_control;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
552 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
553 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
554 next_control:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
555 if (!display)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
556 continue;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
557 if (end_pts == UINT_MAX && start_off != next_off) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
558 end_pts = get_be16(this->packet + next_off) * 1024;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
559 end_pts = 1 - pts100 >= end_pts ? 0 : pts100 + end_pts - 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
560 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
561 if (end_pts > 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
562 packet_t *packet = calloc(1, sizeof(packet_t));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
563 int i;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
564 packet->start_pts = start_pts;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
565 packet->end_pts = end_pts;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
566 packet->current_nibble[0] = current_nibble[0];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
567 packet->current_nibble[1] = current_nibble[1];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
568 packet->start_row = start_row;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
569 packet->start_col = start_col;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
570 packet->width = width;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
571 packet->height = height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
572 packet->stride = stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
573 packet->control_start = control_start;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
574 for (i=0; i<4; i++) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
575 packet->alpha[i] = this->alpha[i];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
576 packet->palette[i] = this->palette[i];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
577 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
578 packet->packet = malloc(this->packet_size);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
579 memcpy(packet->packet, this->packet, this->packet_size);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
580 spudec_queue_packet(this, packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
581 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
582 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
583 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
584
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
585 static void spudec_decode(spudec_handle_t *this, int pts100)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
586 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
587 if (!this->hw_spu)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
588 spudec_process_control(this, pts100);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
589 else if (pts100 >= 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
590 static vo_mpegpes_t packet = { NULL, 0, 0x20, 0 };
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
591 static vo_mpegpes_t *pkg=&packet;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
592 packet.data = this->packet;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
593 packet.size = this->packet_size;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
594 packet.timestamp = pts100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
595 this->hw_spu->draw_frame((uint8_t**)&pkg);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
596 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
597 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
598
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
599 int spudec_changed(void * this)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
600 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
601 spudec_handle_t * spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
602 return spu->spu_changed || spu->now_pts > spu->end_pts;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
603 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
604
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
605 void spudec_assemble(void *this, unsigned char *packet, unsigned int len, int pts100)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
606 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
607 spudec_handle_t *spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
608 // spudec_heartbeat(this, pts100);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
609 if (len < 2) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
610 mp_msg(MSGT_SPUDEC,MSGL_WARN,"SPUasm: packet too short\n");
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
611 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
612 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
613 spu->packet_pts = pts100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
614 if (spu->packet_offset == 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
615 unsigned int len2 = get_be16(packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
616 // Start new fragment
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
617 if (spu->packet_reserve < len2) {
32511
b39155e98ac3 Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents: 32467
diff changeset
618 free(spu->packet);
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
619 spu->packet = malloc(len2);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
620 spu->packet_reserve = spu->packet != NULL ? len2 : 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
621 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
622 if (spu->packet != NULL) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
623 spu->packet_size = len2;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
624 if (len > len2) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
625 mp_msg(MSGT_SPUDEC,MSGL_WARN,"SPUasm: invalid frag len / len2: %d / %d \n", len, len2);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
626 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
627 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
628 memcpy(spu->packet, packet, len);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
629 spu->packet_offset = len;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
630 spu->packet_pts = pts100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
631 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
632 } else {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
633 // Continue current fragment
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
634 if (spu->packet_size < spu->packet_offset + len){
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
635 mp_msg(MSGT_SPUDEC,MSGL_WARN,"SPUasm: invalid fragment\n");
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
636 spu->packet_size = spu->packet_offset = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
637 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
638 } else {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
639 memcpy(spu->packet + spu->packet_offset, packet, len);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
640 spu->packet_offset += len;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
641 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
642 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
643 #if 1
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
644 // check if we have a complete packet (unfortunatelly packet_size is bad
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
645 // for some disks)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
646 // [cb] packet_size is padded to be even -> may be one byte too long
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
647 if ((spu->packet_offset == spu->packet_size) ||
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
648 ((spu->packet_offset + 1) == spu->packet_size)){
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
649 unsigned int x=0,y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
650 while(x+4<=spu->packet_offset){
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
651 y=get_be16(spu->packet+x+2); // next control pointer
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
652 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"SPUtest: x=%d y=%d off=%d size=%d\n",x,y,spu->packet_offset,spu->packet_size);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
653 if(x>=4 && x==y){ // if it points to self - we're done!
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
654 // we got it!
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
655 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"SPUgot: off=%d size=%d \n",spu->packet_offset,spu->packet_size);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
656 spudec_decode(spu, pts100);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
657 spu->packet_offset = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
658 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
659 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
660 if(y<=x || y>=spu->packet_size){ // invalid?
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
661 mp_msg(MSGT_SPUDEC,MSGL_WARN,"SPUtest: broken packet!!!!! y=%d < x=%d\n",y,x);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
662 spu->packet_size = spu->packet_offset = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
663 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
664 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
665 x=y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
666 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
667 // [cb] packet is done; start new packet
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
668 spu->packet_offset = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
669 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
670 #else
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
671 if (spu->packet_offset == spu->packet_size) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
672 spudec_decode(spu, pts100);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
673 spu->packet_offset = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
674 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
675 #endif
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
676 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
677
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
678 void spudec_reset(void *this) // called after seek
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
679 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
680 spudec_handle_t *spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
681 while (spu->queue_head)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
682 spudec_free_packet(spudec_dequeue_packet(spu));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
683 spu->now_pts = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
684 spu->end_pts = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
685 spu->packet_size = spu->packet_offset = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
686 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
687
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
688 void spudec_heartbeat(void *this, unsigned int pts100)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
689 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
690 spudec_handle_t *spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
691 spu->now_pts = pts100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
692
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
693 // TODO: detect and handle broken timestamps (e.g. due to wrapping)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
694 while (spu->queue_head != NULL && pts100 >= spu->queue_head->start_pts) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
695 packet_t *packet = spudec_dequeue_packet(spu);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
696 spu->start_pts = packet->start_pts;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
697 spu->end_pts = packet->end_pts;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
698 if (packet->is_decoded) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
699 free(spu->image);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
700 spu->image_size = packet->data_len;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
701 spu->image = packet->packet;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
702 spu->aimage = packet->packet + packet->stride * packet->height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
703 packet->packet = NULL;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
704 spu->width = packet->width;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
705 spu->height = packet->height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
706 spu->stride = packet->stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
707 spu->start_col = packet->start_col;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
708 spu->start_row = packet->start_row;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
709
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
710 // reset scaled image
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
711 spu->scaled_frame_width = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
712 spu->scaled_frame_height = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
713 } else {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
714 if (spu->auto_palette)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
715 compute_palette(spu, packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
716 spudec_process_data(spu, packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
717 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
718 spudec_free_packet(packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
719 spu->spu_changed = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
720 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
721 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
722
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
723 int spudec_visible(void *this){
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
724 spudec_handle_t *spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
725 int ret=(spu->start_pts <= spu->now_pts &&
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
726 spu->now_pts < spu->end_pts &&
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
727 spu->height > 0);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
728 // printf("spu visible: %d \n",ret);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
729 return ret;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
730 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
731
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
732 void spudec_set_forced_subs_only(void * const this, const unsigned int flag)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
733 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
734 if(this){
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
735 ((spudec_handle_t *)this)->forced_subs_only=flag;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
736 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"SPU: Display only forced subs now %s\n", flag ? "enabled": "disabled");
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
737 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
738 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
739
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
740 void spudec_draw(void *this, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride))
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
741 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
742 spudec_handle_t *spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
743 if (spudec_visible(spu))
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
744 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
745 draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
746 spu->image, spu->aimage, spu->stride);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
747 spu->spu_changed = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
748 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
749 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
750
35031
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
751 static void validate_dimensions(spudec_handle_t *spu, unsigned dxs, unsigned dys)
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
752 {
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
753 if (spu->orig_frame_width == 0 || spu->orig_frame_height == 0) {
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
754 spu->width = FFMIN(spu->width, dxs);
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
755 spu->height = FFMIN(spu->height, dys);
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
756 spu->start_col = FFMIN(spu->start_col, dxs - spu->width);
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
757 spu->start_row = FFMIN(spu->start_row, dys - spu->height);
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
758 return;
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
759 }
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
760 spu->orig_frame_width = FFMAX(spu->orig_frame_width, spu->start_col + spu->width);
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
761 spu->orig_frame_height = FFMAX(spu->orig_frame_height, spu->start_row + spu->height);
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
762 }
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
763
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
764 /* calc the bbox for spudec subs */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
765 void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
766 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
767 spudec_handle_t *spu = me;
35031
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
768 validate_dimensions(spu, dxs, dys);
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
769 if (spu->orig_frame_width == 0 || spu->orig_frame_height == 0
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
770 || (spu->orig_frame_width == dxs && spu->orig_frame_height == dys)) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
771 // unscaled
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
772 bbox[0] = spu->start_col;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
773 bbox[1] = spu->start_col + spu->width;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
774 bbox[2] = spu->start_row;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
775 bbox[3] = spu->start_row + spu->height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
776 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
777 else {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
778 // scaled
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
779 unsigned int scalex = 0x100 * dxs / spu->orig_frame_width;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
780 unsigned int scaley = 0x100 * dys / spu->orig_frame_height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
781 bbox[0] = spu->start_col * scalex / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
782 bbox[1] = spu->start_col * scalex / 0x100 + spu->width * scalex / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
783 switch (spu_alignment) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
784 case 0:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
785 bbox[3] = dys*sub_pos/100 + spu->height * scaley / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
786 if (bbox[3] > dys) bbox[3] = dys;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
787 bbox[2] = bbox[3] - spu->height * scaley / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
788 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
789 case 1:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
790 if (sub_pos < 50) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
791 bbox[2] = dys*sub_pos/100 - spu->height * scaley / 0x200;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
792 bbox[3] = bbox[2] + spu->height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
793 } else {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
794 bbox[3] = dys*sub_pos/100 + spu->height * scaley / 0x200;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
795 if (bbox[3] > dys) bbox[3] = dys;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
796 bbox[2] = bbox[3] - spu->height * scaley / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
797 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
798 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
799 case 2:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
800 bbox[2] = dys*sub_pos/100 - spu->height * scaley / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
801 bbox[3] = bbox[2] + spu->height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
802 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
803 default: /* -1 */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
804 bbox[2] = spu->start_row * scaley / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
805 bbox[3] = spu->start_row * scaley / 0x100 + spu->height * scaley / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
806 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
807 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
808 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
809 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
810 /* transform mplayer's alpha value into an opacity value that is linear */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
811 static inline int canon_alpha(int alpha)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
812 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
813 return (uint8_t)-alpha;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
814 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
815
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
816 typedef struct {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
817 unsigned position;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
818 unsigned left_up;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
819 unsigned right_down;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
820 }scale_pixel;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
821
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
822
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
823 static void scale_table(unsigned int start_src, unsigned int start_tar, unsigned int end_src, unsigned int end_tar, scale_pixel * table)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
824 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
825 unsigned int t;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
826 unsigned int delta_src = end_src - start_src;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
827 unsigned int delta_tar = end_tar - start_tar;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
828 int src = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
829 int src_step;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
830 if (delta_src == 0 || delta_tar == 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
831 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
832 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
833 src_step = (delta_src << 16) / delta_tar >>1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
834 for (t = 0; t<=delta_tar; src += (src_step << 1), t++){
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
835 table[t].position= FFMIN(src >> 16, end_src - 1);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
836 table[t].right_down = src & 0xffff;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
837 table[t].left_up = 0x10000 - table[t].right_down;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
838 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
839 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
840
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
841 /* bilinear scale, similar to vobsub's code */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
842 static void scale_image(int x, int y, scale_pixel* table_x, scale_pixel* table_y, spudec_handle_t * spu)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
843 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
844 int alpha[4];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
845 int color[4];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
846 unsigned int scale[4];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
847 int base = table_y[y].position * spu->stride + table_x[x].position;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
848 int scaled = y * spu->scaled_stride + x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
849 alpha[0] = canon_alpha(spu->aimage[base]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
850 alpha[1] = canon_alpha(spu->aimage[base + 1]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
851 alpha[2] = canon_alpha(spu->aimage[base + spu->stride]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
852 alpha[3] = canon_alpha(spu->aimage[base + spu->stride + 1]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
853 color[0] = spu->image[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
854 color[1] = spu->image[base + 1];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
855 color[2] = spu->image[base + spu->stride];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
856 color[3] = spu->image[base + spu->stride + 1];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
857 scale[0] = (table_x[x].left_up * table_y[y].left_up >> 16) * alpha[0];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
858 if (table_y[y].left_up == 0x10000) // necessary to avoid overflow-case
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
859 scale[0] = table_x[x].left_up * alpha[0];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
860 scale[1] = (table_x[x].right_down * table_y[y].left_up >>16) * alpha[1];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
861 scale[2] = (table_x[x].left_up * table_y[y].right_down >> 16) * alpha[2];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
862 scale[3] = (table_x[x].right_down * table_y[y].right_down >> 16) * alpha[3];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
863 spu->scaled_image[scaled] = (color[0] * scale[0] + color[1] * scale[1] + color[2] * scale[2] + color[3] * scale[3])>>24;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
864 spu->scaled_aimage[scaled] = (scale[0] + scale[1] + scale[2] + scale[3]) >> 16;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
865 if (spu->scaled_aimage[scaled]){
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
866 // ensure that MPlayer's simplified alpha-blending can not overflow
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
867 spu->scaled_image[scaled] = FFMIN(spu->scaled_image[scaled], spu->scaled_aimage[scaled]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
868 // convert to MPlayer-style alpha
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
869 spu->scaled_aimage[scaled] = -spu->scaled_aimage[scaled];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
870 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
871 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
872
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
873 static void sws_spu_image(unsigned char *d1, unsigned char *d2, int dw, int dh,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
874 int ds, const unsigned char* s1, unsigned char* s2,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
875 int sw, int sh, int ss)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
876 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
877 struct SwsContext *ctx;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
878 static SwsFilter filter;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
879 static int firsttime = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
880 static float oldvar;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
881 int i;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
882
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
883 if (!firsttime && oldvar != spu_gaussvar) sws_freeVec(filter.lumH);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
884 if (firsttime) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
885 filter.lumH = filter.lumV =
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
886 filter.chrH = filter.chrV = sws_getGaussianVec(spu_gaussvar, 3.0);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
887 sws_normalizeVec(filter.lumH, 1.0);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
888 firsttime = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
889 oldvar = spu_gaussvar;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
890 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
891
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
892 ctx=sws_getContext(sw, sh, PIX_FMT_GRAY8, dw, dh, PIX_FMT_GRAY8, SWS_GAUSS, &filter, NULL, NULL);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
893 sws_scale(ctx,&s1,&ss,0,sh,&d1,&ds);
34786
a0b10e46f7e6 Use more precise alpha handling for -spuaa 4.
reimar
parents: 34784
diff changeset
894 for (i=ss*sh-1; i>=0; i--) s2[i] = -s2[i];
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
895 sws_scale(ctx,&s2,&ss,0,sh,&d2,&ds);
34786
a0b10e46f7e6 Use more precise alpha handling for -spuaa 4.
reimar
parents: 34784
diff changeset
896 for (i=ds*dh-1; i>=0; i--) d2[i] = -d2[i];
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
897 sws_freeContext(ctx);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
898 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
899
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
900 void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride))
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
901 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
902 spudec_handle_t *spu = me;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
903 scale_pixel *table_x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
904 scale_pixel *table_y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
905
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
906 if (spudec_visible(spu)) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
907
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
908 // check if only forced subtitles are requested
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
909 if( (spu->forced_subs_only) && !(spu->is_forced_sub) ){
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
910 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
911 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
912
35031
135b1ef31668 Clamp bitmap subtitles into visible areas.
reimar
parents: 34786
diff changeset
913 validate_dimensions(spu, dxs, dys);
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
914 if (!(spu_aamode&16) && (spu->orig_frame_width == 0 || spu->orig_frame_height == 0
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
915 || (spu->orig_frame_width == dxs && spu->orig_frame_height == dys))) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
916 spudec_draw(spu, draw_alpha);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
917 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
918 else {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
919 if (spu->scaled_frame_width != dxs || spu->scaled_frame_height != dys) { /* Resizing is needed */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
920 /* scaled_x = scalex * x / 0x100
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
921 scaled_y = scaley * y / 0x100
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
922 order of operations is important because of rounding. */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
923 unsigned int scalex = 0x100 * dxs / spu->orig_frame_width;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
924 unsigned int scaley = 0x100 * dys / spu->orig_frame_height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
925 spu->scaled_start_col = spu->start_col * scalex / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
926 spu->scaled_start_row = spu->start_row * scaley / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
927 spu->scaled_width = spu->width * scalex / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
928 spu->scaled_height = spu->height * scaley / 0x100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
929 /* Kludge: draw_alpha needs width multiple of 8 */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
930 spu->scaled_stride = (spu->scaled_width + 7) & ~7;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
931 if (spu->scaled_image_size < spu->scaled_stride * spu->scaled_height) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
932 if (spu->scaled_image) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
933 free(spu->scaled_image);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
934 spu->scaled_image_size = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
935 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
936 spu->scaled_image = malloc(2 * spu->scaled_stride * spu->scaled_height);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
937 if (spu->scaled_image) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
938 spu->scaled_image_size = spu->scaled_stride * spu->scaled_height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
939 spu->scaled_aimage = spu->scaled_image + spu->scaled_image_size;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
940 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
941 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
942 if (spu->scaled_image) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
943 unsigned int x, y;
33143
1cad23803d94 Fix artefacts at right border of scaled bitmap subtitles by clearing the
reimar
parents: 32511
diff changeset
944 // needs to be 0-initialized because draw_alpha draws always a
1cad23803d94 Fix artefacts at right border of scaled bitmap subtitles by clearing the
reimar
parents: 32511
diff changeset
945 // multiple of 8 pixels. TODO: optimize
1cad23803d94 Fix artefacts at right border of scaled bitmap subtitles by clearing the
reimar
parents: 32511
diff changeset
946 if (spu->scaled_width & 7)
1cad23803d94 Fix artefacts at right border of scaled bitmap subtitles by clearing the
reimar
parents: 32511
diff changeset
947 memset(spu->scaled_image, 0, 2 * spu->scaled_image_size);
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
948 if (spu->scaled_width <= 1 || spu->scaled_height <= 1) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
949 goto nothing_to_do;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
950 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
951 switch(spu_aamode&15) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
952 case 4:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
953 sws_spu_image(spu->scaled_image, spu->scaled_aimage,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
954 spu->scaled_width, spu->scaled_height, spu->scaled_stride,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
955 spu->image, spu->aimage, spu->width, spu->height, spu->stride);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
956 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
957 case 3:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
958 table_x = calloc(spu->scaled_width, sizeof(scale_pixel));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
959 table_y = calloc(spu->scaled_height, sizeof(scale_pixel));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
960 if (!table_x || !table_y) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
961 mp_msg(MSGT_SPUDEC, MSGL_FATAL, "Fatal: spudec_draw_scaled: calloc failed\n");
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
962 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
963 scale_table(0, 0, spu->width - 1, spu->scaled_width - 1, table_x);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
964 scale_table(0, 0, spu->height - 1, spu->scaled_height - 1, table_y);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
965 for (y = 0; y < spu->scaled_height; y++)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
966 for (x = 0; x < spu->scaled_width; x++)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
967 scale_image(x, y, table_x, table_y, spu);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
968 free(table_x);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
969 free(table_y);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
970 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
971 case 0:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
972 /* no antialiasing */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
973 for (y = 0; y < spu->scaled_height; ++y) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
974 int unscaled_y = y * 0x100 / scaley;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
975 int strides = spu->stride * unscaled_y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
976 int scaled_strides = spu->scaled_stride * y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
977 for (x = 0; x < spu->scaled_width; ++x) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
978 int unscaled_x = x * 0x100 / scalex;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
979 spu->scaled_image[scaled_strides + x] = spu->image[strides + unscaled_x];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
980 spu->scaled_aimage[scaled_strides + x] = spu->aimage[strides + unscaled_x];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
981 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
982 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
983 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
984 case 1:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
985 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
986 /* Intermediate antialiasing. */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
987 for (y = 0; y < spu->scaled_height; ++y) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
988 const unsigned int unscaled_top = y * spu->orig_frame_height / dys;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
989 unsigned int unscaled_bottom = (y + 1) * spu->orig_frame_height / dys;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
990 if (unscaled_bottom >= spu->height)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
991 unscaled_bottom = spu->height - 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
992 for (x = 0; x < spu->scaled_width; ++x) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
993 const unsigned int unscaled_left = x * spu->orig_frame_width / dxs;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
994 unsigned int unscaled_right = (x + 1) * spu->orig_frame_width / dxs;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
995 unsigned int color = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
996 unsigned int alpha = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
997 unsigned int walkx, walky;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
998 unsigned int base, tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
999 if (unscaled_right >= spu->width)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1000 unscaled_right = spu->width - 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1001 for (walky = unscaled_top; walky <= unscaled_bottom; ++walky)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1002 for (walkx = unscaled_left; walkx <= unscaled_right; ++walkx) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1003 base = walky * spu->stride + walkx;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1004 tmp = canon_alpha(spu->aimage[base]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1005 alpha += tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1006 color += tmp * spu->image[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1007 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1008 base = y * spu->scaled_stride + x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1009 spu->scaled_image[base] = alpha ? color / alpha : 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1010 spu->scaled_aimage[base] =
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1011 alpha * (1 + unscaled_bottom - unscaled_top) * (1 + unscaled_right - unscaled_left);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1012 /* spu->scaled_aimage[base] =
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1013 alpha * dxs * dys / spu->orig_frame_width / spu->orig_frame_height; */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1014 if (spu->scaled_aimage[base]) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1015 spu->scaled_aimage[base] = 256 - spu->scaled_aimage[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1016 if (spu->scaled_aimage[base] + spu->scaled_image[base] > 255)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1017 spu->scaled_image[base] = 256 - spu->scaled_aimage[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1018 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1019 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1020 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1021 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1022 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1023 case 2:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1024 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1025 /* Best antialiasing. Very slow. */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1026 /* Any pixel (x, y) represents pixels from the original
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1027 rectangular region comprised between the columns
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1028 unscaled_y and unscaled_y + 0x100 / scaley and the rows
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1029 unscaled_x and unscaled_x + 0x100 / scalex
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1030
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1031 The original rectangular region that the scaled pixel
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1032 represents is cut in 9 rectangular areas like this:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1033
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1034 +---+-----------------+---+
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1035 | 1 | 2 | 3 |
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1036 +---+-----------------+---+
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1037 | | | |
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1038 | 4 | 5 | 6 |
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1039 | | | |
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1040 +---+-----------------+---+
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1041 | 7 | 8 | 9 |
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1042 +---+-----------------+---+
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1043
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1044 The width of the left column is at most one pixel and
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1045 it is never null and its right column is at a pixel
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1046 boundary. The height of the top row is at most one
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1047 pixel it is never null and its bottom row is at a
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1048 pixel boundary. The width and height of region 5 are
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1049 integral values. The width of the right column is
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1050 what remains and is less than one pixel. The height
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1051 of the bottom row is what remains and is less than
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1052 one pixel.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1053
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1054 The row above 1, 2, 3 is unscaled_y. The row between
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1055 1, 2, 3 and 4, 5, 6 is top_low_row. The row between 4,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1056 5, 6 and 7, 8, 9 is (unsigned int)unscaled_y_bottom.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1057 The row beneath 7, 8, 9 is unscaled_y_bottom.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1058
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1059 The column left of 1, 4, 7 is unscaled_x. The column
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1060 between 1, 4, 7 and 2, 5, 8 is left_right_column. The
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1061 column between 2, 5, 8 and 3, 6, 9 is (unsigned
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1062 int)unscaled_x_right. The column right of 3, 6, 9 is
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1063 unscaled_x_right. */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1064 const double inv_scalex = (double) 0x100 / scalex;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1065 const double inv_scaley = (double) 0x100 / scaley;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1066 for (y = 0; y < spu->scaled_height; ++y) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1067 const double unscaled_y = y * inv_scaley;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1068 const double unscaled_y_bottom = unscaled_y + inv_scaley;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1069 const unsigned int top_low_row = FFMIN(unscaled_y_bottom, unscaled_y + 1.0);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1070 const double top = top_low_row - unscaled_y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1071 const unsigned int height = unscaled_y_bottom > top_low_row
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1072 ? (unsigned int) unscaled_y_bottom - top_low_row
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1073 : 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1074 const double bottom = unscaled_y_bottom > top_low_row
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1075 ? unscaled_y_bottom - floor(unscaled_y_bottom)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1076 : 0.0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1077 for (x = 0; x < spu->scaled_width; ++x) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1078 const double unscaled_x = x * inv_scalex;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1079 const double unscaled_x_right = unscaled_x + inv_scalex;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1080 const unsigned int left_right_column = FFMIN(unscaled_x_right, unscaled_x + 1.0);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1081 const double left = left_right_column - unscaled_x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1082 const unsigned int width = unscaled_x_right > left_right_column
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1083 ? (unsigned int) unscaled_x_right - left_right_column
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1084 : 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1085 const double right = unscaled_x_right > left_right_column
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1086 ? unscaled_x_right - floor(unscaled_x_right)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1087 : 0.0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1088 double color = 0.0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1089 double alpha = 0.0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1090 double tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1091 unsigned int base;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1092 /* Now use these informations to compute a good alpha,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1093 and lightness. The sum is on each of the 9
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1094 region's surface and alpha and lightness.
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1095
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1096 transformed alpha = sum(surface * alpha) / sum(surface)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1097 transformed color = sum(surface * alpha * color) / sum(surface * alpha)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1098 */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1099 /* 1: top left part */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1100 base = spu->stride * (unsigned int) unscaled_y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1101 tmp = left * top * canon_alpha(spu->aimage[base + (unsigned int) unscaled_x]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1102 alpha += tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1103 color += tmp * spu->image[base + (unsigned int) unscaled_x];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1104 /* 2: top center part */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1105 if (width > 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1106 unsigned int walkx;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1107 for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1108 base = spu->stride * (unsigned int) unscaled_y + walkx;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1109 tmp = /* 1.0 * */ top * canon_alpha(spu->aimage[base]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1110 alpha += tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1111 color += tmp * spu->image[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1112 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1113 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1114 /* 3: top right part */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1115 if (right > 0.0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1116 base = spu->stride * (unsigned int) unscaled_y + (unsigned int) unscaled_x_right;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1117 tmp = right * top * canon_alpha(spu->aimage[base]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1118 alpha += tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1119 color += tmp * spu->image[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1120 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1121 /* 4: center left part */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1122 if (height > 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1123 unsigned int walky;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1124 for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1125 base = spu->stride * walky + (unsigned int) unscaled_x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1126 tmp = left /* * 1.0 */ * canon_alpha(spu->aimage[base]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1127 alpha += tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1128 color += tmp * spu->image[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1129 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1130 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1131 /* 5: center part */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1132 if (width > 0 && height > 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1133 unsigned int walky;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1134 for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1135 unsigned int walkx;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1136 base = spu->stride * walky;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1137 for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1138 tmp = /* 1.0 * 1.0 * */ canon_alpha(spu->aimage[base + walkx]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1139 alpha += tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1140 color += tmp * spu->image[base + walkx];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1141 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1142 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1143 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1144 /* 6: center right part */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1145 if (right > 0.0 && height > 0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1146 unsigned int walky;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1147 for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1148 base = spu->stride * walky + (unsigned int) unscaled_x_right;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1149 tmp = right /* * 1.0 */ * canon_alpha(spu->aimage[base]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1150 alpha += tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1151 color += tmp * spu->image[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1152 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1153 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1154 /* 7: bottom left part */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1155 if (bottom > 0.0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1156 base = spu->stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1157 tmp = left * bottom * canon_alpha(spu->aimage[base]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1158 alpha += tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1159 color += tmp * spu->image[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1160 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1161 /* 8: bottom center part */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1162 if (width > 0 && bottom > 0.0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1163 unsigned int walkx;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1164 base = spu->stride * (unsigned int) unscaled_y_bottom;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1165 for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1166 tmp = /* 1.0 * */ bottom * canon_alpha(spu->aimage[base + walkx]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1167 alpha += tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1168 color += tmp * spu->image[base + walkx];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1169 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1170 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1171 /* 9: bottom right part */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1172 if (right > 0.0 && bottom > 0.0) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1173 base = spu->stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x_right;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1174 tmp = right * bottom * canon_alpha(spu->aimage[base]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1175 alpha += tmp;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1176 color += tmp * spu->image[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1177 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1178 /* Finally mix these transparency and brightness information suitably */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1179 base = spu->scaled_stride * y + x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1180 spu->scaled_image[base] = alpha > 0 ? color / alpha : 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1181 spu->scaled_aimage[base] = alpha * scalex * scaley / 0x10000;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1182 if (spu->scaled_aimage[base]) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1183 spu->scaled_aimage[base] = 256 - spu->scaled_aimage[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1184 if (spu->scaled_aimage[base] + spu->scaled_image[base] > 255)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1185 spu->scaled_image[base] = 256 - spu->scaled_aimage[base];
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1186 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1187 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1188 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1189 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1190 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1191 nothing_to_do:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1192 /* Kludge: draw_alpha needs width multiple of 8. */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1193 if (spu->scaled_width < spu->scaled_stride)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1194 for (y = 0; y < spu->scaled_height; ++y) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1195 memset(spu->scaled_aimage + y * spu->scaled_stride + spu->scaled_width, 0,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1196 spu->scaled_stride - spu->scaled_width);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1197 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1198 spu->scaled_frame_width = dxs;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1199 spu->scaled_frame_height = dys;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1200 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1201 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1202 if (spu->scaled_image){
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1203 switch (spu_alignment) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1204 case 0:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1205 spu->scaled_start_row = dys*sub_pos/100;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1206 if (spu->scaled_start_row + spu->scaled_height > dys)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1207 spu->scaled_start_row = dys - spu->scaled_height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1208 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1209 case 1:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1210 spu->scaled_start_row = dys*sub_pos/100 - spu->scaled_height/2;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1211 if (sub_pos >= 50 && spu->scaled_start_row + spu->scaled_height > dys)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1212 spu->scaled_start_row = dys - spu->scaled_height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1213 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1214 case 2:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1215 spu->scaled_start_row = dys*sub_pos/100 - spu->scaled_height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1216 break;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1217 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1218 draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1219 spu->scaled_image, spu->scaled_aimage, spu->scaled_stride);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1220 spu->spu_changed = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1221 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1222 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1223 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1224 else
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1225 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1226 mp_msg(MSGT_SPUDEC,MSGL_DBG2,"SPU not displayed: start_pts=%d end_pts=%d now_pts=%d\n",
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1227 spu->start_pts, spu->end_pts, spu->now_pts);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1228 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1229 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1230
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1231 void spudec_update_palette(void * this, unsigned int *palette)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1232 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1233 spudec_handle_t *spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1234 if (spu && palette) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1235 memcpy(spu->global_palette, palette, sizeof(spu->global_palette));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1236 if(spu->hw_spu)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1237 spu->hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1238 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1239 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1240
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1241 void spudec_set_font_factor(void * this, double factor)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1242 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1243 spudec_handle_t *spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1244 spu->font_start_level = (int)(0xF0-(0xE0*factor));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1245 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1246
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1247 static void spudec_parse_extradata(spudec_handle_t *this,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1248 uint8_t *extradata, int extradata_len)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1249 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1250 uint8_t *buffer, *ptr;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1251 unsigned int *pal = this->global_palette, *cuspal = this->cuspal;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1252 unsigned int tridx;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1253 int i;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1254
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1255 if (extradata_len == 16*4) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1256 for (i=0; i<16; i++)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1257 pal[i] = AV_RB32(extradata + i*4);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1258 this->auto_palette = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1259 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1260 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1261
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1262 if (!(ptr = buffer = malloc(extradata_len+1)))
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1263 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1264 memcpy(buffer, extradata, extradata_len);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1265 buffer[extradata_len] = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1266
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1267 do {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1268 if (*ptr == '#')
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1269 continue;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1270 if (!strncmp(ptr, "size: ", 6))
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1271 sscanf(ptr + 6, "%dx%d", &this->orig_frame_width, &this->orig_frame_height);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1272 if (!strncmp(ptr, "palette: ", 9) &&
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1273 sscanf(ptr + 9, "%x, %x, %x, %x, %x, %x, %x, %x, "
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1274 "%x, %x, %x, %x, %x, %x, %x, %x",
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1275 &pal[ 0], &pal[ 1], &pal[ 2], &pal[ 3],
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1276 &pal[ 4], &pal[ 5], &pal[ 6], &pal[ 7],
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1277 &pal[ 8], &pal[ 9], &pal[10], &pal[11],
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1278 &pal[12], &pal[13], &pal[14], &pal[15]) == 16) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1279 for (i=0; i<16; i++)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1280 pal[i] = vobsub_palette_to_yuv(pal[i]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1281 this->auto_palette = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1282 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1283 if (!strncasecmp(ptr, "forced subs: on", 15))
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1284 this->forced_subs_only = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1285 if (!strncmp(ptr, "custom colors: ON, tridx: ", 26) &&
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1286 sscanf(ptr + 26, "%x, colors: %x, %x, %x, %x",
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1287 &tridx, cuspal+0, cuspal+1, cuspal+2, cuspal+3) == 5) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1288 for (i=0; i<4; i++) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1289 cuspal[i] = vobsub_rgb_to_yuv(cuspal[i]);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1290 if (tridx & (1 << (12-4*i)))
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1291 cuspal[i] |= 1 << 31;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1292 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1293 this->custom = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1294 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1295 } while ((ptr=strchr(ptr,'\n')) && *++ptr);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1296
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1297 free(buffer);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1298 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1299
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1300 void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigned int frame_height, uint8_t *extradata, int extradata_len)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1301 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1302 spudec_handle_t *this = calloc(1, sizeof(spudec_handle_t));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1303 if (this){
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1304 this->orig_frame_height = frame_height;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1305 this->orig_frame_width = frame_width;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1306 // set up palette:
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1307 if (palette)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1308 memcpy(this->global_palette, palette, sizeof(this->global_palette));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1309 else
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1310 this->auto_palette = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1311 if (extradata)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1312 spudec_parse_extradata(this, extradata, extradata_len);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1313 /* XXX Although the video frame is some size, the SPU frame is
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1314 always maximum size i.e. 720 wide and 576 or 480 high */
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1315 // For HD files in MKV the VobSub resolution can be higher though,
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1316 // see largeres_vobsub.mkv
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1317 if (this->orig_frame_width <= 720 && this->orig_frame_height <= 576) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1318 this->orig_frame_width = 720;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1319 if (this->orig_frame_height == 480 || this->orig_frame_height == 240)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1320 this->orig_frame_height = 480;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1321 else
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1322 this->orig_frame_height = 576;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1323 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1324 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1325 else
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1326 mp_msg(MSGT_SPUDEC,MSGL_FATAL, "FATAL: spudec_init: calloc");
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1327 return this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1328 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1329
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1330 void *spudec_new(unsigned int *palette)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1331 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1332 return spudec_new_scaled(palette, 0, 0, NULL, 0);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1333 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1334
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1335 void spudec_free(void *this)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1336 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1337 spudec_handle_t *spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1338 if (spu) {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1339 while (spu->queue_head)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1340 spudec_free_packet(spudec_dequeue_packet(spu));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1341 free(spu->packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1342 spu->packet = NULL;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1343 free(spu->scaled_image);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1344 spu->scaled_image = NULL;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1345 free(spu->image);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1346 spu->image = NULL;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1347 spu->aimage = NULL;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1348 free(spu->pal_image);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1349 spu->pal_image = NULL;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1350 spu->image_size = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1351 spu->pal_width = spu->pal_height = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1352 free(spu);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1353 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1354 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1355
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1356 void spudec_set_hw_spu(void *this, const vo_functions_t *hw_spu)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1357 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1358 spudec_handle_t *spu = this;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1359 if (!spu)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1360 return;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1361 spu->hw_spu = hw_spu;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1362 hw_spu->control(VOCTRL_SET_SPU_PALETTE,spu->global_palette);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1363 }
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1364
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1365 #define MP_NOPTS_VALUE (-1LL<<63) //both int64_t and double should be able to represent this exactly
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1366
34784
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1367 packet_t *spudec_packet_create(int x, int y, int w, int h)
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1368 {
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1369 packet_t *packet;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1370 int stride = (w + 7) & ~7;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1371 if ((unsigned)w >= 0x8000 || (unsigned)h > 0x4000)
34784
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1372 return NULL;
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1373 packet = calloc(1, sizeof(packet_t));
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1374 packet->is_decoded = 1;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1375 packet->width = w;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1376 packet->height = h;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1377 packet->stride = stride;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1378 packet->start_col = x;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1379 packet->start_row = y;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1380 packet->data_len = 2 * stride * h;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1381 if (packet->data_len) { // size 0 is a special "clear" packet
34784
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1382 packet->packet = malloc(packet->data_len);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1383 if (!packet->packet) {
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1384 free(packet);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1385 packet = NULL;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1386 }
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1387 }
34784
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1388 return packet;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1389 }
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1390
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1391 void spudec_packet_clear(packet_t *packet)
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1392 {
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1393 /* clear alpha and value, as value is premultiplied */
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1394 memset(packet->packet, 0, packet->data_len);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1395 }
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1396
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1397 void spudec_packet_fill(packet_t *packet,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1398 const uint8_t *pal_img, int pal_stride,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1399 const void *palette,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1400 int x, int y, int w, int h)
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1401 {
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1402 const uint32_t *pal = palette;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1403 uint8_t *img = packet->packet + x + y * packet->stride;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1404 uint8_t *aimg = img + packet->stride * packet->height;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1405 int i;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1406 uint16_t g8a8_pal[256];
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1407
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1408 for (i = 0; i < 256; i++) {
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1409 uint32_t pixel = pal[i];
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1410 int alpha = pixel >> 24;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1411 int gray = (((pixel & 0x000000ff) >> 0) +
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1412 ((pixel & 0x0000ff00) >> 7) +
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1413 ((pixel & 0x00ff0000) >> 16)) >> 2;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1414 gray = FFMIN(gray, alpha);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1415 g8a8_pal[i] = (-alpha << 8) | gray;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1416 }
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1417 pal2gray_alpha(g8a8_pal, pal_img, pal_stride,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1418 img, aimg, packet->stride, w, h);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1419 }
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1420
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1421 void spudec_packet_send(void *spu, packet_t *packet, double pts, double endpts)
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1422 {
32456
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1423 packet->start_pts = 0;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1424 packet->end_pts = 0x7fffffff;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1425 if (pts != MP_NOPTS_VALUE)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1426 packet->start_pts = pts * 90000;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1427 if (endpts != MP_NOPTS_VALUE)
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1428 packet->end_pts = endpts * 90000;
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1429 spudec_queue_packet(spu, packet);
728bd5c2aea7 Move spudec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1430 }
34784
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1431
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1432 /**
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1433 * palette must contain at least 256 32-bit entries, otherwise crashes
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1434 * are possible
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1435 */
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1436 void spudec_set_paletted(void *spu, const uint8_t *pal_img, int pal_stride,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1437 const void *palette,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1438 int x, int y, int w, int h,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1439 double pts, double endpts)
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1440 {
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1441 packet_t *packet = spudec_packet_create(x, y, w, h);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1442 if (!packet)
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1443 return;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1444 if (packet->data_len) // size 0 is a special "clear" packet
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1445 spudec_packet_fill(packet, pal_img, pal_stride, palette, 0, 0, w, h);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1446 spudec_packet_send(spu, packet, pts, endpts);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34778
diff changeset
1447 }