annotate sub/spudec.c @ 35553:29f2de5e63d6

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