annotate dvdsubdec.c @ 8043:a591c3736fd8 libavcodec

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