Mercurial > libavcodec.hg
annotate dvbsub.c @ 4166:eced83504436 libavcodec
mp3 header (de)compression bitstream filter
this will make mp3 frames 4 bytes smaller, it will not give you binary identical mp3 files, but it will give you mp3 files which decode to binary identical output
this will only work in containers providing at least packet size, sample_rate and number of channels
bugreports about mp3 files for which this fails are welcome
and this is experimental (dont expect compatibility and dont even expect to be able to decompress what you compressed, hell dont even expect this to work without editing the source a little)
author | michael |
---|---|
date | Fri, 10 Nov 2006 01:41:53 +0000 |
parents | c8c591fe26f8 |
children | 6166fbf375cc |
rev | line source |
---|---|
2756 | 1 /* |
2 * DVB subtitle encoding for ffmpeg | |
3 * Copyright (c) 2005 Fabrice Bellard. | |
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" | |
22 | |
23 typedef struct DVBSubtitleContext { | |
24 int hide_state; | |
25 int object_version; | |
26 } DVBSubtitleContext; | |
27 | |
28 #define PUTBITS2(val)\ | |
29 {\ | |
30 bitbuf |= (val) << bitcnt;\ | |
31 bitcnt -= 2;\ | |
32 if (bitcnt < 0) {\ | |
33 bitcnt = 6;\ | |
34 *q++ = bitbuf;\ | |
35 bitbuf = 0;\ | |
36 }\ | |
37 } | |
38 | |
39 static void dvb_encode_rle2(uint8_t **pq, | |
40 const uint8_t *bitmap, int linesize, | |
41 int w, int h) | |
42 { | |
43 uint8_t *q; | |
44 unsigned int bitbuf; | |
45 int bitcnt; | |
46 int x, y, len, x1, v, color; | |
47 | |
48 q = *pq; | |
2967 | 49 |
2756 | 50 for(y = 0; y < h; y++) { |
51 *q++ = 0x10; | |
52 bitbuf = 0; | |
53 bitcnt = 6; | |
2967 | 54 |
2756 | 55 x = 0; |
56 while (x < w) { | |
57 x1 = x; | |
58 color = bitmap[x1++]; | |
59 while (x1 < w && bitmap[x1] == color) | |
60 x1++; | |
61 len = x1 - x; | |
62 if (color == 0 && len == 2) { | |
63 PUTBITS2(0); | |
64 PUTBITS2(0); | |
65 PUTBITS2(1); | |
66 } else if (len >= 3 && len <= 10) { | |
67 v = len - 3; | |
68 PUTBITS2(0); | |
69 PUTBITS2((v >> 2) | 2); | |
70 PUTBITS2(v & 3); | |
71 PUTBITS2(color); | |
72 } else if (len >= 12 && len <= 27) { | |
73 v = len - 12; | |
74 PUTBITS2(0); | |
75 PUTBITS2(0); | |
76 PUTBITS2(2); | |
77 PUTBITS2(v >> 2); | |
78 PUTBITS2(v & 3); | |
79 PUTBITS2(color); | |
80 } else if (len >= 29) { | |
81 /* length = 29 ... 284 */ | |
82 if (len > 284) | |
83 len = 284; | |
84 v = len - 29; | |
85 PUTBITS2(0); | |
86 PUTBITS2(0); | |
87 PUTBITS2(3); | |
88 PUTBITS2((v >> 6)); | |
89 PUTBITS2((v >> 4) & 3); | |
90 PUTBITS2((v >> 2) & 3); | |
91 PUTBITS2(v & 3); | |
92 PUTBITS2(color); | |
93 } else { | |
94 PUTBITS2(color); | |
95 if (color == 0) { | |
96 PUTBITS2(1); | |
97 } | |
98 len = 1; | |
99 } | |
100 x += len; | |
101 } | |
102 /* end of line */ | |
103 PUTBITS2(0); | |
104 PUTBITS2(0); | |
105 PUTBITS2(0); | |
106 if (bitcnt != 6) { | |
107 *q++ = bitbuf; | |
108 } | |
109 *q++ = 0xf0; | |
110 bitmap += linesize; | |
111 } | |
112 *pq = q; | |
113 } | |
114 | |
115 #define PUTBITS4(val)\ | |
116 {\ | |
117 bitbuf |= (val) << bitcnt;\ | |
118 bitcnt -= 4;\ | |
119 if (bitcnt < 0) {\ | |
120 bitcnt = 4;\ | |
121 *q++ = bitbuf;\ | |
122 bitbuf = 0;\ | |
123 }\ | |
124 } | |
125 | |
126 /* some DVB decoders only implement 4 bits/pixel */ | |
127 static void dvb_encode_rle4(uint8_t **pq, | |
128 const uint8_t *bitmap, int linesize, | |
129 int w, int h) | |
130 { | |
131 uint8_t *q; | |
132 unsigned int bitbuf; | |
133 int bitcnt; | |
134 int x, y, len, x1, v, color; | |
135 | |
136 q = *pq; | |
2967 | 137 |
2756 | 138 for(y = 0; y < h; y++) { |
139 *q++ = 0x11; | |
140 bitbuf = 0; | |
141 bitcnt = 4; | |
2967 | 142 |
2756 | 143 x = 0; |
144 while (x < w) { | |
145 x1 = x; | |
146 color = bitmap[x1++]; | |
147 while (x1 < w && bitmap[x1] == color) | |
148 x1++; | |
149 len = x1 - x; | |
150 if (color == 0 && len == 2) { | |
151 PUTBITS4(0); | |
152 PUTBITS4(0xd); | |
153 } else if (color == 0 && (len >= 3 && len <= 9)) { | |
154 PUTBITS4(0); | |
155 PUTBITS4(len - 2); | |
156 } else if (len >= 4 && len <= 7) { | |
157 PUTBITS4(0); | |
158 PUTBITS4(8 + len - 4); | |
159 PUTBITS4(color); | |
160 } else if (len >= 9 && len <= 24) { | |
161 PUTBITS4(0); | |
162 PUTBITS4(0xe); | |
163 PUTBITS4(len - 9); | |
164 PUTBITS4(color); | |
165 } else if (len >= 25) { | |
166 if (len > 280) | |
167 len = 280; | |
168 v = len - 25; | |
169 PUTBITS4(0); | |
170 PUTBITS4(0xf); | |
171 PUTBITS4(v >> 4); | |
172 PUTBITS4(v & 0xf); | |
173 PUTBITS4(color); | |
174 } else { | |
175 PUTBITS4(color); | |
176 if (color == 0) { | |
177 PUTBITS4(0xc); | |
178 } | |
179 len = 1; | |
180 } | |
181 x += len; | |
182 } | |
183 /* end of line */ | |
184 PUTBITS4(0); | |
185 PUTBITS4(0); | |
186 if (bitcnt != 4) { | |
187 *q++ = bitbuf; | |
188 } | |
189 *q++ = 0xf0; | |
190 bitmap += linesize; | |
191 } | |
192 *pq = q; | |
193 } | |
194 | |
195 #define SCALEBITS 10 | |
196 #define ONE_HALF (1 << (SCALEBITS - 1)) | |
2979 | 197 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5)) |
2756 | 198 |
199 #define RGB_TO_Y_CCIR(r, g, b) \ | |
200 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \ | |
201 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) | |
202 | |
203 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\ | |
204 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ | |
205 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) | |
206 | |
207 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\ | |
208 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ | |
209 FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) | |
210 | |
211 static inline void putbe16(uint8_t **pq, uint16_t v) | |
212 { | |
213 uint8_t *q; | |
214 q = *pq; | |
215 *q++ = v >> 8; | |
216 *q++ = v; | |
217 *pq = q; | |
218 } | |
219 | |
2967 | 220 static int encode_dvb_subtitles(DVBSubtitleContext *s, |
2756 | 221 uint8_t *outbuf, AVSubtitle *h) |
222 { | |
223 uint8_t *q, *pseg_len; | |
224 int page_id, region_id, clut_id, object_id, i, bpp_index, page_state; | |
225 | |
226 | |
227 q = outbuf; | |
228 | |
229 page_id = 1; | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
230 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
231 if (h->num_rects == 0 || h->rects == NULL) |
2756 | 232 return -1; |
233 | |
234 *q++ = 0x00; /* subtitle_stream_id */ | |
235 | |
236 /* page composition segment */ | |
237 | |
238 *q++ = 0x0f; /* sync_byte */ | |
239 *q++ = 0x10; /* segment_type */ | |
240 putbe16(&q, page_id); | |
241 pseg_len = q; | |
242 q += 2; /* segment length */ | |
243 *q++ = 30; /* page_timeout (seconds) */ | |
244 if (s->hide_state) | |
245 page_state = 0; /* normal case */ | |
246 else | |
247 page_state = 2; /* mode change */ | |
248 /* page_version = 0 + page_state */ | |
2967 | 249 *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
|
250 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
251 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
|
252 *q++ = region_id; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
253 *q++ = 0xff; /* reserved */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
254 putbe16(&q, h->rects[region_id].x); /* left pos */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
255 putbe16(&q, h->rects[region_id].y); /* top pos */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
256 } |
2756 | 257 |
258 putbe16(&pseg_len, q - pseg_len - 2); | |
259 | |
260 if (!s->hide_state) { | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
261 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
|
262 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
263 /* CLUT segment */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
264 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
265 if (h->rects[clut_id].nb_colors <= 4) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
266 /* 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
|
267 bpp_index = 0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
268 } else if (h->rects[clut_id].nb_colors <= 16) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
269 /* 4 bpp, standard encoding */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
270 bpp_index = 1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
271 } else { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
272 return -1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
273 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
274 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
275 *q++ = 0x0f; /* sync byte */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
276 *q++ = 0x12; /* CLUT definition segment */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
277 putbe16(&q, page_id); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
278 pseg_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
279 q += 2; /* segment length */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
280 *q++ = clut_id; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
281 *q++ = (0 << 4) | 0xf; /* version = 0 */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
282 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
283 for(i = 0; i < h->rects[clut_id].nb_colors; i++) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
284 *q++ = i; /* clut_entry_id */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
285 *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
|
286 { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
287 int a, r, g, b; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
288 a = (h->rects[clut_id].rgba_palette[i] >> 24) & 0xff; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
289 r = (h->rects[clut_id].rgba_palette[i] >> 16) & 0xff; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
290 g = (h->rects[clut_id].rgba_palette[i] >> 8) & 0xff; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
291 b = (h->rects[clut_id].rgba_palette[i] >> 0) & 0xff; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
292 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
293 *q++ = RGB_TO_Y_CCIR(r, g, b); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
294 *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
|
295 *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
|
296 *q++ = 255 - a; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
297 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
298 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
299 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
300 putbe16(&pseg_len, q - pseg_len - 2); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
301 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
302 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
303 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
304 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
|
305 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
306 /* region composition segment */ |
2967 | 307 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
308 if (h->rects[region_id].nb_colors <= 4) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
309 /* 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
|
310 bpp_index = 0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
311 } else if (h->rects[region_id].nb_colors <= 16) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
312 /* 4 bpp, standard encoding */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
313 bpp_index = 1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
314 } else { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
315 return -1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
316 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
317 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
318 *q++ = 0x0f; /* sync_byte */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
319 *q++ = 0x11; /* segment_type */ |
2756 | 320 putbe16(&q, page_id); |
321 pseg_len = q; | |
322 q += 2; /* segment length */ | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
323 *q++ = region_id; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
324 *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
325 putbe16(&q, h->rects[region_id].w); /* region width */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
326 putbe16(&q, h->rects[region_id].h); /* region height */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
327 *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
|
328 *q++ = region_id; /* clut_id == region_id */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
329 *q++ = 0; /* 8 bit fill colors */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
330 *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
|
331 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
332 if (!s->hide_state) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
333 putbe16(&q, region_id); /* object_id == region_id */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
334 *q++ = (0 << 6) | (0 << 4); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
335 *q++ = 0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
336 *q++ = 0xf0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
337 *q++ = 0; |
2756 | 338 } |
339 | |
340 putbe16(&pseg_len, q - pseg_len - 2); | |
341 } | |
342 | |
343 if (!s->hide_state) { | |
2967 | 344 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
345 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
|
346 /* Object Data segment */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
347 |
2946
ac94d509884e
dvbsub encoder, patch by Wolfram Gloger < wmglo AH dent POIS med POIS uni-muenchen POIS de >
gpoirier
parents:
2796
diff
changeset
|
348 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
|
349 /* 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
|
350 bpp_index = 0; |
2946
ac94d509884e
dvbsub encoder, patch by Wolfram Gloger < wmglo AH dent POIS med POIS uni-muenchen POIS de >
gpoirier
parents:
2796
diff
changeset
|
351 } 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
|
352 /* 4 bpp, standard encoding */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
353 bpp_index = 1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
354 } else { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
355 return -1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
356 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
357 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
358 *q++ = 0x0f; /* sync byte */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
359 *q++ = 0x13; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
360 putbe16(&q, page_id); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
361 pseg_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
362 q += 2; /* segment length */ |
2756 | 363 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
364 putbe16(&q, object_id); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
365 *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
|
366 onject_coding_method, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
367 non_modifying_color_flag */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
368 { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
369 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
|
370 void (*dvb_encode_rle)(uint8_t **pq, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
371 const uint8_t *bitmap, int linesize, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
372 int w, int h); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
373 ptop_field_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
374 q += 2; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
375 pbottom_field_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
376 q += 2; |
2756 | 377 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
378 if (bpp_index == 0) |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
379 dvb_encode_rle = dvb_encode_rle2; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
380 else |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
381 dvb_encode_rle = dvb_encode_rle4; |
2756 | 382 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
383 top_ptr = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
384 dvb_encode_rle(&q, h->rects[object_id].bitmap, h->rects[object_id].w * 2, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
385 h->rects[object_id].w, h->rects[object_id].h >> 1); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
386 bottom_ptr = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
387 dvb_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
388 h->rects[object_id].w * 2, h->rects[object_id].w, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
389 h->rects[object_id].h >> 1); |
2756 | 390 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
391 putbe16(&ptop_field_len, bottom_ptr - top_ptr); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
392 putbe16(&pbottom_field_len, q - bottom_ptr); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
393 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
394 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
395 putbe16(&pseg_len, q - pseg_len - 2); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
396 } |
2756 | 397 } |
398 | |
399 /* end of display set segment */ | |
400 | |
401 *q++ = 0x0f; /* sync_byte */ | |
402 *q++ = 0x80; /* segment_type */ | |
403 putbe16(&q, page_id); | |
404 pseg_len = q; | |
405 q += 2; /* segment length */ | |
406 | |
407 putbe16(&pseg_len, q - pseg_len - 2); | |
408 | |
409 *q++ = 0xff; /* end of PES data */ | |
410 | |
411 s->object_version = (s->object_version + 1) & 0xf; | |
412 s->hide_state = !s->hide_state; | |
413 return q - outbuf; | |
414 } | |
415 | |
416 static int dvbsub_init_decoder(AVCodecContext *avctx) | |
417 { | |
418 return 0; | |
419 } | |
420 | |
421 static int dvbsub_close_decoder(AVCodecContext *avctx) | |
422 { | |
423 return 0; | |
424 } | |
425 | |
426 static int dvbsub_encode(AVCodecContext *avctx, | |
427 unsigned char *buf, int buf_size, void *data) | |
428 { | |
429 DVBSubtitleContext *s = avctx->priv_data; | |
430 AVSubtitle *sub = data; | |
431 int ret; | |
432 | |
433 ret = encode_dvb_subtitles(s, buf, sub); | |
434 return ret; | |
435 } | |
436 | |
437 AVCodec dvbsub_encoder = { | |
438 "dvbsub", | |
439 CODEC_TYPE_SUBTITLE, | |
440 CODEC_ID_DVB_SUBTITLE, | |
441 sizeof(DVBSubtitleContext), | |
442 dvbsub_init_decoder, | |
443 dvbsub_encode, | |
444 dvbsub_close_decoder, | |
445 }; |