Mercurial > libavcodec.hg
annotate dvbsub.c @ 10381:9262948fd649 libavcodec
Hack: set the coded frame PTS to the incoming PTS.
This is not correct, but libtheora does not seem to provide a way
to get the correct value, and this is necessary to make encoding
produce sensible time stamps when encoded content is variable
FPS or the time base is simply different from FPS.
Somewhat fixes issue 1197.
author | reimar |
---|---|
date | Sat, 10 Oct 2009 14:43:31 +0000 |
parents | 04423b2f6e0b |
children | 8a4984c5cacc |
rev | line source |
---|---|
2756 | 1 /* |
2 * DVB subtitle encoding for ffmpeg | |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8516
diff
changeset
|
3 * Copyright (c) 2005 Fabrice Bellard |
2756 | 4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
2756 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
2756 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
2756 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
2756 | 20 */ |
21 #include "avcodec.h" | |
5067 | 22 #include "bytestream.h" |
5354 | 23 #include "colorspace.h" |
2756 | 24 |
25 typedef struct DVBSubtitleContext { | |
26 int hide_state; | |
27 int object_version; | |
28 } DVBSubtitleContext; | |
29 | |
30 #define PUTBITS2(val)\ | |
31 {\ | |
32 bitbuf |= (val) << bitcnt;\ | |
33 bitcnt -= 2;\ | |
34 if (bitcnt < 0) {\ | |
35 bitcnt = 6;\ | |
36 *q++ = bitbuf;\ | |
37 bitbuf = 0;\ | |
38 }\ | |
39 } | |
40 | |
41 static void dvb_encode_rle2(uint8_t **pq, | |
42 const uint8_t *bitmap, int linesize, | |
43 int w, int h) | |
44 { | |
45 uint8_t *q; | |
46 unsigned int bitbuf; | |
47 int bitcnt; | |
48 int x, y, len, x1, v, color; | |
49 | |
50 q = *pq; | |
2967 | 51 |
2756 | 52 for(y = 0; y < h; y++) { |
53 *q++ = 0x10; | |
54 bitbuf = 0; | |
55 bitcnt = 6; | |
2967 | 56 |
2756 | 57 x = 0; |
58 while (x < w) { | |
59 x1 = x; | |
60 color = bitmap[x1++]; | |
61 while (x1 < w && bitmap[x1] == color) | |
62 x1++; | |
63 len = x1 - x; | |
64 if (color == 0 && len == 2) { | |
65 PUTBITS2(0); | |
66 PUTBITS2(0); | |
67 PUTBITS2(1); | |
68 } else if (len >= 3 && len <= 10) { | |
69 v = len - 3; | |
70 PUTBITS2(0); | |
71 PUTBITS2((v >> 2) | 2); | |
72 PUTBITS2(v & 3); | |
73 PUTBITS2(color); | |
74 } else if (len >= 12 && len <= 27) { | |
75 v = len - 12; | |
76 PUTBITS2(0); | |
77 PUTBITS2(0); | |
78 PUTBITS2(2); | |
79 PUTBITS2(v >> 2); | |
80 PUTBITS2(v & 3); | |
81 PUTBITS2(color); | |
82 } else if (len >= 29) { | |
83 /* length = 29 ... 284 */ | |
84 if (len > 284) | |
85 len = 284; | |
86 v = len - 29; | |
87 PUTBITS2(0); | |
88 PUTBITS2(0); | |
89 PUTBITS2(3); | |
90 PUTBITS2((v >> 6)); | |
91 PUTBITS2((v >> 4) & 3); | |
92 PUTBITS2((v >> 2) & 3); | |
93 PUTBITS2(v & 3); | |
94 PUTBITS2(color); | |
95 } else { | |
96 PUTBITS2(color); | |
97 if (color == 0) { | |
98 PUTBITS2(1); | |
99 } | |
100 len = 1; | |
101 } | |
102 x += len; | |
103 } | |
104 /* end of line */ | |
105 PUTBITS2(0); | |
106 PUTBITS2(0); | |
107 PUTBITS2(0); | |
108 if (bitcnt != 6) { | |
109 *q++ = bitbuf; | |
110 } | |
111 *q++ = 0xf0; | |
112 bitmap += linesize; | |
113 } | |
114 *pq = q; | |
115 } | |
116 | |
117 #define PUTBITS4(val)\ | |
118 {\ | |
119 bitbuf |= (val) << bitcnt;\ | |
120 bitcnt -= 4;\ | |
121 if (bitcnt < 0) {\ | |
122 bitcnt = 4;\ | |
123 *q++ = bitbuf;\ | |
124 bitbuf = 0;\ | |
125 }\ | |
126 } | |
127 | |
128 /* some DVB decoders only implement 4 bits/pixel */ | |
129 static void dvb_encode_rle4(uint8_t **pq, | |
130 const uint8_t *bitmap, int linesize, | |
131 int w, int h) | |
132 { | |
133 uint8_t *q; | |
134 unsigned int bitbuf; | |
135 int bitcnt; | |
136 int x, y, len, x1, v, color; | |
137 | |
138 q = *pq; | |
2967 | 139 |
2756 | 140 for(y = 0; y < h; y++) { |
141 *q++ = 0x11; | |
142 bitbuf = 0; | |
143 bitcnt = 4; | |
2967 | 144 |
2756 | 145 x = 0; |
146 while (x < w) { | |
147 x1 = x; | |
148 color = bitmap[x1++]; | |
149 while (x1 < w && bitmap[x1] == color) | |
150 x1++; | |
151 len = x1 - x; | |
152 if (color == 0 && len == 2) { | |
153 PUTBITS4(0); | |
154 PUTBITS4(0xd); | |
155 } else if (color == 0 && (len >= 3 && len <= 9)) { | |
156 PUTBITS4(0); | |
157 PUTBITS4(len - 2); | |
158 } else if (len >= 4 && len <= 7) { | |
159 PUTBITS4(0); | |
160 PUTBITS4(8 + len - 4); | |
161 PUTBITS4(color); | |
162 } else if (len >= 9 && len <= 24) { | |
163 PUTBITS4(0); | |
164 PUTBITS4(0xe); | |
165 PUTBITS4(len - 9); | |
166 PUTBITS4(color); | |
167 } else if (len >= 25) { | |
168 if (len > 280) | |
169 len = 280; | |
170 v = len - 25; | |
171 PUTBITS4(0); | |
172 PUTBITS4(0xf); | |
173 PUTBITS4(v >> 4); | |
174 PUTBITS4(v & 0xf); | |
175 PUTBITS4(color); | |
176 } else { | |
177 PUTBITS4(color); | |
178 if (color == 0) { | |
179 PUTBITS4(0xc); | |
180 } | |
181 len = 1; | |
182 } | |
183 x += len; | |
184 } | |
185 /* end of line */ | |
186 PUTBITS4(0); | |
187 PUTBITS4(0); | |
188 if (bitcnt != 4) { | |
189 *q++ = bitbuf; | |
190 } | |
191 *q++ = 0xf0; | |
192 bitmap += linesize; | |
193 } | |
194 *pq = q; | |
195 } | |
196 | |
2967 | 197 static int encode_dvb_subtitles(DVBSubtitleContext *s, |
2756 | 198 uint8_t *outbuf, AVSubtitle *h) |
199 { | |
200 uint8_t *q, *pseg_len; | |
201 int page_id, region_id, clut_id, object_id, i, bpp_index, page_state; | |
202 | |
203 | |
204 q = outbuf; | |
205 | |
206 page_id = 1; | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
207 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
208 if (h->num_rects == 0 || h->rects == NULL) |
2756 | 209 return -1; |
210 | |
211 *q++ = 0x00; /* subtitle_stream_id */ | |
212 | |
213 /* page composition segment */ | |
214 | |
215 *q++ = 0x0f; /* sync_byte */ | |
216 *q++ = 0x10; /* segment_type */ | |
5067 | 217 bytestream_put_be16(&q, page_id); |
2756 | 218 pseg_len = q; |
219 q += 2; /* segment length */ | |
220 *q++ = 30; /* page_timeout (seconds) */ | |
221 if (s->hide_state) | |
222 page_state = 0; /* normal case */ | |
223 else | |
224 page_state = 2; /* mode change */ | |
225 /* page_version = 0 + page_state */ | |
2967 | 226 *q++ = s->object_version | (page_state << 2) | 3; |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
227 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
228 for (region_id = 0; region_id < h->num_rects; region_id++) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
229 *q++ = region_id; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
230 *q++ = 0xff; /* reserved */ |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
231 bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */ |
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
232 bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */ |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
233 } |
2756 | 234 |
5067 | 235 bytestream_put_be16(&pseg_len, q - pseg_len - 2); |
2756 | 236 |
237 if (!s->hide_state) { | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
238 for (clut_id = 0; clut_id < h->num_rects; clut_id++) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
239 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
240 /* CLUT segment */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
241 |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
242 if (h->rects[clut_id]->nb_colors <= 4) { |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
243 /* 2 bpp, some decoders do not support it correctly */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
244 bpp_index = 0; |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
245 } else if (h->rects[clut_id]->nb_colors <= 16) { |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
246 /* 4 bpp, standard encoding */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
247 bpp_index = 1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
248 } else { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
249 return -1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
250 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
251 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
252 *q++ = 0x0f; /* sync byte */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
253 *q++ = 0x12; /* CLUT definition segment */ |
5067 | 254 bytestream_put_be16(&q, page_id); |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
255 pseg_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
256 q += 2; /* segment length */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
257 *q++ = clut_id; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
258 *q++ = (0 << 4) | 0xf; /* version = 0 */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
259 |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
260 for(i = 0; i < h->rects[clut_id]->nb_colors; i++) { |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
261 *q++ = i; /* clut_entry_id */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
262 *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
263 { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
264 int a, r, g, b; |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8512
diff
changeset
|
265 uint32_t x= ((uint32_t*)h->rects[clut_id]->pict.data[1])[i]; |
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8512
diff
changeset
|
266 a = (x >> 24) & 0xff; |
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8512
diff
changeset
|
267 r = (x >> 16) & 0xff; |
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8512
diff
changeset
|
268 g = (x >> 8) & 0xff; |
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8512
diff
changeset
|
269 b = (x >> 0) & 0xff; |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
270 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
271 *q++ = RGB_TO_Y_CCIR(r, g, b); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
272 *q++ = RGB_TO_V_CCIR(r, g, b, 0); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
273 *q++ = RGB_TO_U_CCIR(r, g, b, 0); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
274 *q++ = 255 - a; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
275 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
276 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
277 |
5067 | 278 bytestream_put_be16(&pseg_len, q - pseg_len - 2); |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
279 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
280 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
281 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
282 for (region_id = 0; region_id < h->num_rects; region_id++) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
283 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
284 /* region composition segment */ |
2967 | 285 |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
286 if (h->rects[region_id]->nb_colors <= 4) { |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
287 /* 2 bpp, some decoders do not support it correctly */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
288 bpp_index = 0; |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
289 } else if (h->rects[region_id]->nb_colors <= 16) { |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
290 /* 4 bpp, standard encoding */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
291 bpp_index = 1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
292 } else { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
293 return -1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
294 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
295 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
296 *q++ = 0x0f; /* sync_byte */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
297 *q++ = 0x11; /* segment_type */ |
5067 | 298 bytestream_put_be16(&q, page_id); |
2756 | 299 pseg_len = q; |
300 q += 2; /* segment length */ | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
301 *q++ = region_id; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
302 *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */ |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
303 bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */ |
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
304 bytestream_put_be16(&q, h->rects[region_id]->h); /* region height */ |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
305 *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
306 *q++ = region_id; /* clut_id == region_id */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
307 *q++ = 0; /* 8 bit fill colors */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
308 *q++ = 0x03; /* 4 bit and 2 bit fill colors */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
309 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
310 if (!s->hide_state) { |
5067 | 311 bytestream_put_be16(&q, region_id); /* object_id == region_id */ |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
312 *q++ = (0 << 6) | (0 << 4); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
313 *q++ = 0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
314 *q++ = 0xf0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
315 *q++ = 0; |
2756 | 316 } |
317 | |
5067 | 318 bytestream_put_be16(&pseg_len, q - pseg_len - 2); |
2756 | 319 } |
320 | |
321 if (!s->hide_state) { | |
2967 | 322 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
323 for (object_id = 0; object_id < h->num_rects; object_id++) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
324 /* Object Data segment */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
325 |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
326 if (h->rects[object_id]->nb_colors <= 4) { |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
327 /* 2 bpp, some decoders do not support it correctly */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
328 bpp_index = 0; |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
329 } else if (h->rects[object_id]->nb_colors <= 16) { |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
330 /* 4 bpp, standard encoding */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
331 bpp_index = 1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
332 } else { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
333 return -1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
334 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
335 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
336 *q++ = 0x0f; /* sync byte */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
337 *q++ = 0x13; |
5067 | 338 bytestream_put_be16(&q, page_id); |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
339 pseg_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
340 q += 2; /* segment length */ |
2756 | 341 |
5067 | 342 bytestream_put_be16(&q, object_id); |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
343 *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
344 onject_coding_method, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
345 non_modifying_color_flag */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
346 { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
347 uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
348 void (*dvb_encode_rle)(uint8_t **pq, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
349 const uint8_t *bitmap, int linesize, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
350 int w, int h); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
351 ptop_field_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
352 q += 2; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
353 pbottom_field_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
354 q += 2; |
2756 | 355 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
356 if (bpp_index == 0) |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
357 dvb_encode_rle = dvb_encode_rle2; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
358 else |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
359 dvb_encode_rle = dvb_encode_rle4; |
2756 | 360 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
361 top_ptr = q; |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8512
diff
changeset
|
362 dvb_encode_rle(&q, h->rects[object_id]->pict.data[0], h->rects[object_id]->w * 2, |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
363 h->rects[object_id]->w, h->rects[object_id]->h >> 1); |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
364 bottom_ptr = q; |
8516
315b302fcd1d
Replace AVSubtitleRect.rgba_palette and bitmap by AVPicture.
michael
parents:
8512
diff
changeset
|
365 dvb_encode_rle(&q, h->rects[object_id]->pict.data[0] + h->rects[object_id]->w, |
8512
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
366 h->rects[object_id]->w * 2, h->rects[object_id]->w, |
aa45029f5cd7
Change AVSubtitle.rects to an array of pointers so ABI does not break
michael
parents:
7040
diff
changeset
|
367 h->rects[object_id]->h >> 1); |
2756 | 368 |
5067 | 369 bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr); |
370 bytestream_put_be16(&pbottom_field_len, q - bottom_ptr); | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
371 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
372 |
5067 | 373 bytestream_put_be16(&pseg_len, q - pseg_len - 2); |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
374 } |
2756 | 375 } |
376 | |
377 /* end of display set segment */ | |
378 | |
379 *q++ = 0x0f; /* sync_byte */ | |
380 *q++ = 0x80; /* segment_type */ | |
5067 | 381 bytestream_put_be16(&q, page_id); |
2756 | 382 pseg_len = q; |
383 q += 2; /* segment length */ | |
384 | |
5067 | 385 bytestream_put_be16(&pseg_len, q - pseg_len - 2); |
2756 | 386 |
387 *q++ = 0xff; /* end of PES data */ | |
388 | |
389 s->object_version = (s->object_version + 1) & 0xf; | |
390 s->hide_state = !s->hide_state; | |
391 return q - outbuf; | |
392 } | |
393 | |
394 static int dvbsub_encode(AVCodecContext *avctx, | |
395 unsigned char *buf, int buf_size, void *data) | |
396 { | |
397 DVBSubtitleContext *s = avctx->priv_data; | |
398 AVSubtitle *sub = data; | |
399 int ret; | |
400 | |
401 ret = encode_dvb_subtitles(s, buf, sub); | |
402 return ret; | |
403 } | |
404 | |
405 AVCodec dvbsub_encoder = { | |
406 "dvbsub", | |
407 CODEC_TYPE_SUBTITLE, | |
408 CODEC_ID_DVB_SUBTITLE, | |
409 sizeof(DVBSubtitleContext), | |
5941 | 410 NULL, |
2756 | 411 dvbsub_encode, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
412 .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"), |
2756 | 413 }; |