annotate sub/spudec.c @ 36814:b33a9dff0b57

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