annotate sub/spudec.c @ 35833:dbfedb331095

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