Mercurial > libavcodec.hg
annotate dvdsubdec.c @ 12266:48d6738904a9 libavcodec
Fix SPLATB_REG mess. Used to be a if/elseif/elseif/elseif spaghetti, so this
splits it into small optimization-specific macros which are selected for each
DSP function. The advantage of this approach is that the sse4 functions now
use the ssse3 codepath also without needing an explicit sse4 codepath.
author | rbultje |
---|---|
date | Sat, 24 Jul 2010 19:33:05 +0000 |
parents | d5705b52b76e |
children | de55a539a2e1 |
rev | line source |
---|---|
4091 | 1 /* |
2 * DVD subtitle decoding for ffmpeg | |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8516
diff
changeset
|
3 * Copyright (c) 2005 Fabrice Bellard |
4091 | 4 * |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 #include "avcodec.h" | |
9428 | 22 #include "get_bits.h" |
5397 | 23 #include "dsputil.h" |
12039 | 24 #include "libavutil/colorspace.h" |
4091 | 25 |
26 //#define DEBUG | |
27 | |
5397 | 28 static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values) |
29 { | |
30 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; | |
31 uint8_t r, g, b; | |
32 int i, y, cb, cr; | |
33 int r_add, g_add, b_add; | |
34 | |
35 for (i = num_values; i > 0; i--) { | |
36 y = *ycbcr++; | |
37 cb = *ycbcr++; | |
38 cr = *ycbcr++; | |
39 YUV_TO_RGB1_CCIR(cb, cr); | |
40 YUV_TO_RGB2_CCIR(r, g, b, y); | |
41 *rgba++ = (*alpha++ << 24) | (r << 16) | (g << 8) | b; | |
42 } | |
43 } | |
44 | |
45 static int decode_run_2bit(GetBitContext *gb, int *color) | |
46 { | |
47 unsigned int v, t; | |
48 | |
49 v = 0; | |
50 for (t = 1; v < t && t <= 0x40; t <<= 2) | |
51 v = (v << 4) | get_bits(gb, 4); | |
52 *color = v & 3; | |
53 if (v < 4) { /* Code for fill rest of line */ | |
54 return INT_MAX; | |
55 } | |
56 return v >> 2; | |
57 } | |
58 | |
59 static int decode_run_8bit(GetBitContext *gb, int *color) | |
4091 | 60 { |
5397 | 61 int len; |
62 int has_run = get_bits1(gb); | |
63 if (get_bits1(gb)) | |
64 *color = get_bits(gb, 8); | |
65 else | |
66 *color = get_bits(gb, 2); | |
67 if (has_run) { | |
68 if (get_bits1(gb)) { | |
69 len = get_bits(gb, 7); | |
70 if (len == 0) | |
71 len = INT_MAX; | |
72 else | |
73 len += 9; | |
74 } else | |
75 len = get_bits(gb, 3) + 2; | |
76 } else | |
77 len = 1; | |
78 return len; | |
4091 | 79 } |
80 | |
81 static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, | |
5397 | 82 const uint8_t *buf, int start, int buf_size, int is_8bit) |
4091 | 83 { |
5397 | 84 GetBitContext gb; |
85 int bit_len; | |
86 int x, y, len, color; | |
4091 | 87 uint8_t *d; |
88 | |
5397 | 89 bit_len = (buf_size - start) * 8; |
90 init_get_bits(&gb, buf + start, bit_len); | |
91 | |
4091 | 92 x = 0; |
93 y = 0; | |
94 d = bitmap; | |
95 for(;;) { | |
5397 | 96 if (get_bits_count(&gb) > bit_len) |
4091 | 97 return -1; |
5397 | 98 if (is_8bit) |
99 len = decode_run_8bit(&gb, &color); | |
100 else | |
101 len = decode_run_2bit(&gb, &color); | |
102 len = FFMIN(len, w - x); | |
4091 | 103 memset(d + x, color, len); |
104 x += len; | |
105 if (x >= w) { | |
106 y++; | |
107 if (y >= h) | |
108 break; | |
109 d += linesize; | |
110 x = 0; | |
111 /* byte align */ | |
5397 | 112 align_get_bits(&gb); |
4091 | 113 } |
114 } | |
115 return 0; | |
116 } | |
117 | |
118 static void guess_palette(uint32_t *rgba_palette, | |
5396
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
119 uint8_t *colormap, |
4091 | 120 uint8_t *alpha, |
121 uint32_t subtitle_color) | |
122 { | |
123 uint8_t color_used[16]; | |
124 int nb_opaque_colors, i, level, j, r, g, b; | |
125 | |
126 for(i = 0; i < 4; i++) | |
127 rgba_palette[i] = 0; | |
128 | |
129 memset(color_used, 0, 16); | |
130 nb_opaque_colors = 0; | |
131 for(i = 0; i < 4; i++) { | |
5396
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
132 if (alpha[i] != 0 && !color_used[colormap[i]]) { |
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
133 color_used[colormap[i]] = 1; |
4091 | 134 nb_opaque_colors++; |
135 } | |
136 } | |
137 | |
138 if (nb_opaque_colors == 0) | |
139 return; | |
140 | |
141 j = nb_opaque_colors; | |
142 memset(color_used, 0, 16); | |
143 for(i = 0; i < 4; i++) { | |
144 if (alpha[i] != 0) { | |
5396
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
145 if (!color_used[colormap[i]]) { |
4091 | 146 level = (0xff * j) / nb_opaque_colors; |
147 r = (((subtitle_color >> 16) & 0xff) * level) >> 8; | |
148 g = (((subtitle_color >> 8) & 0xff) * level) >> 8; | |
149 b = (((subtitle_color >> 0) & 0xff) * level) >> 8; | |
150 rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17) << 24); | |
5396
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
151 color_used[colormap[i]] = (i + 1); |
4091 | 152 j--; |
153 } else { | |
5396
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
154 rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) | |
4091 | 155 ((alpha[i] * 17) << 24); |
156 } | |
157 } | |
158 } | |
159 } | |
160 | |
5397 | 161 #define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a)) |
162 | |
4091 | 163 static int decode_dvd_subtitles(AVSubtitle *sub_header, |
164 const uint8_t *buf, int buf_size) | |
165 { | |
166 int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos; | |
5397 | 167 int big_offsets, offset_size, is_8bit = 0; |
168 const uint8_t *yuv_palette = 0; | |
169 uint8_t colormap[4], alpha[256]; | |
4091 | 170 int date; |
171 int i; | |
172 int is_menu = 0; | |
173 | |
5397 | 174 if (buf_size < 10) |
4091 | 175 return -1; |
10051
e73c688ca84c
Simplify initialization of AVSubtitle by using memset.
reimar
parents:
10049
diff
changeset
|
176 memset(sub_header, 0, sizeof(*sub_header)); |
4091 | 177 |
5397 | 178 if (AV_RB16(buf) == 0) { /* HD subpicture with 4-byte offsets */ |
179 big_offsets = 1; | |
180 offset_size = 4; | |
181 cmd_pos = 6; | |
182 } else { | |
183 big_offsets = 0; | |
184 offset_size = 2; | |
185 cmd_pos = 2; | |
186 } | |
187 | |
188 cmd_pos = READ_OFFSET(buf + cmd_pos); | |
189 | |
10049
a1b42791b13d
Fix cmd_pos bounds check to avoid the overflow case.
reimar
parents:
9999
diff
changeset
|
190 while (cmd_pos > 0 && cmd_pos < buf_size - 2 - offset_size) { |
4438
fe3179006730
Remove the getbe16 functions and use the AV_RB16 macro instead. Patch by Ian
takis
parents:
4437
diff
changeset
|
191 date = AV_RB16(buf + cmd_pos); |
5397 | 192 next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2); |
9999
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
193 dprintf(NULL, "cmd_pos=0x%04x next=0x%04x date=%d\n", |
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
194 cmd_pos, next_cmd_pos, date); |
5397 | 195 pos = cmd_pos + 2 + offset_size; |
4091 | 196 offset1 = -1; |
197 offset2 = -1; | |
198 x1 = y1 = x2 = y2 = 0; | |
199 while (pos < buf_size) { | |
200 cmd = buf[pos++]; | |
9999
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
201 dprintf(NULL, "cmd=%02x\n", cmd); |
4091 | 202 switch(cmd) { |
203 case 0x00: | |
204 /* menu subpicture */ | |
205 is_menu = 1; | |
206 break; | |
207 case 0x01: | |
208 /* set start date */ | |
209 sub_header->start_display_time = (date << 10) / 90; | |
210 break; | |
211 case 0x02: | |
212 /* set end date */ | |
213 sub_header->end_display_time = (date << 10) / 90; | |
214 break; | |
215 case 0x03: | |
5396
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
216 /* set colormap */ |
4091 | 217 if ((buf_size - pos) < 2) |
218 goto fail; | |
5396
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
219 colormap[3] = buf[pos] >> 4; |
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
220 colormap[2] = buf[pos] & 0x0f; |
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
221 colormap[1] = buf[pos + 1] >> 4; |
9f0f022ca8e7
Rename "palette" to "colormap" when it's referring to the mapping from a 2-bit
takis
parents:
4924
diff
changeset
|
222 colormap[0] = buf[pos + 1] & 0x0f; |
4091 | 223 pos += 2; |
224 break; | |
225 case 0x04: | |
226 /* set alpha */ | |
227 if ((buf_size - pos) < 2) | |
228 goto fail; | |
229 alpha[3] = buf[pos] >> 4; | |
230 alpha[2] = buf[pos] & 0x0f; | |
231 alpha[1] = buf[pos + 1] >> 4; | |
232 alpha[0] = buf[pos + 1] & 0x0f; | |
233 pos += 2; | |
9999
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
234 dprintf(NULL, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]); |
4091 | 235 break; |
236 case 0x05: | |
5397 | 237 case 0x85: |
4091 | 238 if ((buf_size - pos) < 6) |
239 goto fail; | |
240 x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4); | |
241 x2 = ((buf[pos + 1] & 0x0f) << 8) | buf[pos + 2]; | |
242 y1 = (buf[pos + 3] << 4) | (buf[pos + 4] >> 4); | |
243 y2 = ((buf[pos + 4] & 0x0f) << 8) | buf[pos + 5]; | |
5397 | 244 if (cmd & 0x80) |
245 is_8bit = 1; | |
9999
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
246 dprintf(NULL, "x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2); |
4091 | 247 pos += 6; |
248 break; | |
249 case 0x06: | |
250 if ((buf_size - pos) < 4) | |
251 goto fail; | |
4438
fe3179006730
Remove the getbe16 functions and use the AV_RB16 macro instead. Patch by Ian
takis
parents:
4437
diff
changeset
|
252 offset1 = AV_RB16(buf + pos); |
fe3179006730
Remove the getbe16 functions and use the AV_RB16 macro instead. Patch by Ian
takis
parents:
4437
diff
changeset
|
253 offset2 = AV_RB16(buf + pos + 2); |
9999
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
254 dprintf(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); |
4091 | 255 pos += 4; |
256 break; | |
5397 | 257 case 0x86: |
258 if ((buf_size - pos) < 8) | |
259 goto fail; | |
260 offset1 = AV_RB32(buf + pos); | |
261 offset2 = AV_RB32(buf + pos + 4); | |
9999
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
262 dprintf(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); |
5397 | 263 pos += 8; |
264 break; | |
265 | |
266 case 0x83: | |
267 /* HD set palette */ | |
268 if ((buf_size - pos) < 768) | |
269 goto fail; | |
270 yuv_palette = buf + pos; | |
271 pos += 768; | |
272 break; | |
273 case 0x84: | |
274 /* HD set contrast (alpha) */ | |
275 if ((buf_size - pos) < 256) | |
276 goto fail; | |
277 for (i = 0; i < 256; i++) | |
278 alpha[i] = 0xFF - buf[pos+i]; | |
279 pos += 256; | |
280 break; | |
281 | |
4091 | 282 case 0xff: |
5397 | 283 goto the_end; |
4091 | 284 default: |
9999
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
285 dprintf(NULL, "unrecognised subpicture command 0x%x\n", cmd); |
4091 | 286 goto the_end; |
287 } | |
288 } | |
289 the_end: | |
290 if (offset1 >= 0) { | |
291 int w, h; | |
292 uint8_t *bitmap; | |
293 | |
294 /* decode the bitmap */ | |
295 w = x2 - x1 + 1; | |
296 if (w < 0) | |
297 w = 0; | |
298 h = y2 - y1; | |
299 if (h < 0) | |
300 h = 0; | |
301 if (w > 0 && h > 0) { | |
302 if (sub_header->rects != NULL) { | |
303 for (i = 0; i < sub_header->num_rects; i++) { | |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
304 av_freep(&sub_header->rects[i]->pict.data[0]); |
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
305 av_freep(&sub_header->rects[i]->pict.data[1]); |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
306 av_freep(&sub_header->rects[i]); |
4091 | 307 } |
308 av_freep(&sub_header->rects); | |
309 sub_header->num_rects = 0; | |
310 } | |
311 | |
312 bitmap = av_malloc(w * h); | |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
313 sub_header->rects = av_mallocz(sizeof(*sub_header->rects)); |
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
314 sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect)); |
4091 | 315 sub_header->num_rects = 1; |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
316 sub_header->rects[0]->pict.data[0] = bitmap; |
4437
42ad7d63fb5d
Fix a bug in the DVD subtitle decoder where subtitles with odd heights would not
takis
parents:
4091
diff
changeset
|
317 decode_rle(bitmap, w * 2, w, (h + 1) / 2, |
5397 | 318 buf, offset1, buf_size, is_8bit); |
4091 | 319 decode_rle(bitmap + w, w * 2, w, h / 2, |
5397 | 320 buf, offset2, buf_size, is_8bit); |
10069
8ac9bc10b485
Always allocate a buffer of AVPALETTE_SIZE for palette in the subtitle
reimar
parents:
10051
diff
changeset
|
321 sub_header->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); |
5397 | 322 if (is_8bit) { |
323 if (yuv_palette == 0) | |
324 goto fail; | |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
325 sub_header->rects[0]->nb_colors = 256; |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
326 yuv_a_to_rgba(yuv_palette, alpha, (uint32_t*)sub_header->rects[0]->pict.data[1], 256); |
5397 | 327 } else { |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
328 sub_header->rects[0]->nb_colors = 4; |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
329 guess_palette((uint32_t*)sub_header->rects[0]->pict.data[1], |
5398 | 330 colormap, alpha, 0xffff00); |
5397 | 331 } |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
332 sub_header->rects[0]->x = x1; |
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
333 sub_header->rects[0]->y = y1; |
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
334 sub_header->rects[0]->w = w; |
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
335 sub_header->rects[0]->h = h; |
9988
b8a9cfe64488
Set subtitle type in DVD and XSUB subtitle decoders.
stefano
parents:
9428
diff
changeset
|
336 sub_header->rects[0]->type = SUBTITLE_BITMAP; |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
337 sub_header->rects[0]->pict.linesize[0] = w; |
4091 | 338 } |
339 } | |
340 if (next_cmd_pos == cmd_pos) | |
341 break; | |
342 cmd_pos = next_cmd_pos; | |
343 } | |
344 if (sub_header->num_rects > 0) | |
345 return is_menu; | |
346 fail: | |
5397 | 347 if (sub_header->rects != NULL) { |
348 for (i = 0; i < sub_header->num_rects; i++) { | |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
349 av_freep(&sub_header->rects[i]->pict.data[0]); |
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
350 av_freep(&sub_header->rects[i]->pict.data[1]); |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
351 av_freep(&sub_header->rects[i]); |
5397 | 352 } |
353 av_freep(&sub_header->rects); | |
354 sub_header->num_rects = 0; | |
355 } | |
4091 | 356 return -1; |
357 } | |
358 | |
359 static int is_transp(const uint8_t *buf, int pitch, int n, | |
360 const uint8_t *transp_color) | |
361 { | |
362 int i; | |
363 for(i = 0; i < n; i++) { | |
364 if (!transp_color[*buf]) | |
365 return 0; | |
366 buf += pitch; | |
367 } | |
368 return 1; | |
369 } | |
370 | |
371 /* return 0 if empty rectangle, 1 if non empty */ | |
372 static int find_smallest_bounding_rectangle(AVSubtitle *s) | |
373 { | |
374 uint8_t transp_color[256]; | |
375 int y1, y2, x1, x2, y, w, h, i; | |
376 uint8_t *bitmap; | |
377 | |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
378 if (s->num_rects == 0 || s->rects == NULL || s->rects[0]->w <= 0 || s->rects[0]->h <= 0) |
4091 | 379 return 0; |
380 | |
381 memset(transp_color, 0, 256); | |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
382 for(i = 0; i < s->rects[0]->nb_colors; i++) { |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
383 if ((((uint32_t*)s->rects[0]->pict.data[1])[i] >> 24) == 0) |
4091 | 384 transp_color[i] = 1; |
385 } | |
386 y1 = 0; | |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
387 while (y1 < s->rects[0]->h && is_transp(s->rects[0]->pict.data[0] + y1 * s->rects[0]->pict.linesize[0], |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
388 1, s->rects[0]->w, transp_color)) |
4091 | 389 y1++; |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
390 if (y1 == s->rects[0]->h) { |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
391 av_freep(&s->rects[0]->pict.data[0]); |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
392 s->rects[0]->w = s->rects[0]->h = 0; |
4091 | 393 return 0; |
394 } | |
395 | |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
396 y2 = s->rects[0]->h - 1; |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
397 while (y2 > 0 && is_transp(s->rects[0]->pict.data[0] + y2 * s->rects[0]->pict.linesize[0], 1, |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
398 s->rects[0]->w, transp_color)) |
4091 | 399 y2--; |
400 x1 = 0; | |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
401 while (x1 < (s->rects[0]->w - 1) && is_transp(s->rects[0]->pict.data[0] + x1, s->rects[0]->pict.linesize[0], |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
402 s->rects[0]->h, transp_color)) |
4091 | 403 x1++; |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
404 x2 = s->rects[0]->w - 1; |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
405 while (x2 > 0 && is_transp(s->rects[0]->pict.data[0] + x2, s->rects[0]->pict.linesize[0], s->rects[0]->h, |
4091 | 406 transp_color)) |
407 x2--; | |
408 w = x2 - x1 + 1; | |
409 h = y2 - y1 + 1; | |
410 bitmap = av_malloc(w * h); | |
411 if (!bitmap) | |
412 return 1; | |
413 for(y = 0; y < h; y++) { | |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
414 memcpy(bitmap + w * y, s->rects[0]->pict.data[0] + x1 + (y1 + y) * s->rects[0]->pict.linesize[0], w); |
4091 | 415 } |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
416 av_freep(&s->rects[0]->pict.data[0]); |
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
417 s->rects[0]->pict.data[0] = bitmap; |
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
418 s->rects[0]->pict.linesize[0] = w; |
8514
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
419 s->rects[0]->w = w; |
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
420 s->rects[0]->h = h; |
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
421 s->rects[0]->x += x1; |
b866cb2a5330
Forgot to update (I likely missed it due to its similar name to dvb...)
michael
parents:
7264
diff
changeset
|
422 s->rects[0]->y += y1; |
4091 | 423 return 1; |
424 } | |
425 | |
426 #ifdef DEBUG | |
427 #undef fprintf | |
7264 | 428 #undef perror |
429 #undef exit | |
4091 | 430 static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h, |
431 uint32_t *rgba_palette) | |
432 { | |
433 int x, y, v; | |
434 FILE *f; | |
435 | |
436 f = fopen(filename, "w"); | |
437 if (!f) { | |
438 perror(filename); | |
439 exit(1); | |
440 } | |
441 fprintf(f, "P6\n" | |
442 "%d %d\n" | |
443 "%d\n", | |
444 w, h, 255); | |
445 for(y = 0; y < h; y++) { | |
446 for(x = 0; x < w; x++) { | |
447 v = rgba_palette[bitmap[y * w + x]]; | |
448 putc((v >> 16) & 0xff, f); | |
449 putc((v >> 8) & 0xff, f); | |
450 putc((v >> 0) & 0xff, f); | |
451 } | |
452 } | |
453 fclose(f); | |
454 } | |
455 #endif | |
456 | |
457 static int dvdsub_decode(AVCodecContext *avctx, | |
458 void *data, int *data_size, | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8810
diff
changeset
|
459 AVPacket *avpkt) |
4091 | 460 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8810
diff
changeset
|
461 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8810
diff
changeset
|
462 int buf_size = avpkt->size; |
4091 | 463 AVSubtitle *sub = (void *)data; |
464 int is_menu; | |
465 | |
466 is_menu = decode_dvd_subtitles(sub, buf, buf_size); | |
467 | |
468 if (is_menu < 0) { | |
469 no_subtitle: | |
470 *data_size = 0; | |
471 | |
472 return buf_size; | |
473 } | |
474 if (!is_menu && find_smallest_bounding_rectangle(sub) == 0) | |
475 goto no_subtitle; | |
476 | |
477 #if defined(DEBUG) | |
9999
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
478 dprintf(NULL, "start=%d ms end =%d ms\n", |
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
479 sub->start_display_time, |
c78fd9154378
Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents:
9988
diff
changeset
|
480 sub->end_display_time); |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
481 ppm_save("/tmp/a.ppm", sub->rects[0]->pict.data[0], |
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8514
diff
changeset
|
482 sub->rects[0]->w, sub->rects[0]->h, sub->rects[0]->pict.data[1]); |
4091 | 483 #endif |
484 | |
485 *data_size = 1; | |
486 return buf_size; | |
487 } | |
488 | |
489 AVCodec dvdsub_decoder = { | |
490 "dvdsub", | |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
10069
diff
changeset
|
491 AVMEDIA_TYPE_SUBTITLE, |
4091 | 492 CODEC_ID_DVD_SUBTITLE, |
493 0, | |
5941 | 494 NULL, |
4091 | 495 NULL, |
5941 | 496 NULL, |
4091 | 497 dvdsub_decode, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
498 .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), |
4091 | 499 }; |