Mercurial > libavcodec.hg
annotate dvbsub.c @ 2892:41315d0120b3 libavcodec
replace a few mov + psrlq with pshufw, there are more cases which could benefit from this but they would require us to duplicate some functions ...
the trick is from various places (my own code in libpostproc, a patch on the x264 list, ...)
author | michael |
---|---|
date | Wed, 21 Sep 2005 21:17:09 +0000 |
parents | 95c35706acbb |
children | ac94d509884e |
rev | line source |
---|---|
2756 | 1 /* |
2 * DVB subtitle encoding for ffmpeg | |
3 * Copyright (c) 2005 Fabrice Bellard. | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
19 #include "avcodec.h" | |
20 | |
21 typedef struct DVBSubtitleContext { | |
22 int hide_state; | |
23 int object_version; | |
24 } DVBSubtitleContext; | |
25 | |
26 #define PUTBITS2(val)\ | |
27 {\ | |
28 bitbuf |= (val) << bitcnt;\ | |
29 bitcnt -= 2;\ | |
30 if (bitcnt < 0) {\ | |
31 bitcnt = 6;\ | |
32 *q++ = bitbuf;\ | |
33 bitbuf = 0;\ | |
34 }\ | |
35 } | |
36 | |
37 static void dvb_encode_rle2(uint8_t **pq, | |
38 const uint8_t *bitmap, int linesize, | |
39 int w, int h) | |
40 { | |
41 uint8_t *q; | |
42 unsigned int bitbuf; | |
43 int bitcnt; | |
44 int x, y, len, x1, v, color; | |
45 | |
46 q = *pq; | |
47 | |
48 for(y = 0; y < h; y++) { | |
49 *q++ = 0x10; | |
50 bitbuf = 0; | |
51 bitcnt = 6; | |
52 | |
53 x = 0; | |
54 while (x < w) { | |
55 x1 = x; | |
56 color = bitmap[x1++]; | |
57 while (x1 < w && bitmap[x1] == color) | |
58 x1++; | |
59 len = x1 - x; | |
60 if (color == 0 && len == 2) { | |
61 PUTBITS2(0); | |
62 PUTBITS2(0); | |
63 PUTBITS2(1); | |
64 } else if (len >= 3 && len <= 10) { | |
65 v = len - 3; | |
66 PUTBITS2(0); | |
67 PUTBITS2((v >> 2) | 2); | |
68 PUTBITS2(v & 3); | |
69 PUTBITS2(color); | |
70 } else if (len >= 12 && len <= 27) { | |
71 v = len - 12; | |
72 PUTBITS2(0); | |
73 PUTBITS2(0); | |
74 PUTBITS2(2); | |
75 PUTBITS2(v >> 2); | |
76 PUTBITS2(v & 3); | |
77 PUTBITS2(color); | |
78 } else if (len >= 29) { | |
79 /* length = 29 ... 284 */ | |
80 if (len > 284) | |
81 len = 284; | |
82 v = len - 29; | |
83 PUTBITS2(0); | |
84 PUTBITS2(0); | |
85 PUTBITS2(3); | |
86 PUTBITS2((v >> 6)); | |
87 PUTBITS2((v >> 4) & 3); | |
88 PUTBITS2((v >> 2) & 3); | |
89 PUTBITS2(v & 3); | |
90 PUTBITS2(color); | |
91 } else { | |
92 PUTBITS2(color); | |
93 if (color == 0) { | |
94 PUTBITS2(1); | |
95 } | |
96 len = 1; | |
97 } | |
98 x += len; | |
99 } | |
100 /* end of line */ | |
101 PUTBITS2(0); | |
102 PUTBITS2(0); | |
103 PUTBITS2(0); | |
104 if (bitcnt != 6) { | |
105 *q++ = bitbuf; | |
106 } | |
107 *q++ = 0xf0; | |
108 bitmap += linesize; | |
109 } | |
110 *pq = q; | |
111 } | |
112 | |
113 #define PUTBITS4(val)\ | |
114 {\ | |
115 bitbuf |= (val) << bitcnt;\ | |
116 bitcnt -= 4;\ | |
117 if (bitcnt < 0) {\ | |
118 bitcnt = 4;\ | |
119 *q++ = bitbuf;\ | |
120 bitbuf = 0;\ | |
121 }\ | |
122 } | |
123 | |
124 /* some DVB decoders only implement 4 bits/pixel */ | |
125 static void dvb_encode_rle4(uint8_t **pq, | |
126 const uint8_t *bitmap, int linesize, | |
127 int w, int h) | |
128 { | |
129 uint8_t *q; | |
130 unsigned int bitbuf; | |
131 int bitcnt; | |
132 int x, y, len, x1, v, color; | |
133 | |
134 q = *pq; | |
135 | |
136 for(y = 0; y < h; y++) { | |
137 *q++ = 0x11; | |
138 bitbuf = 0; | |
139 bitcnt = 4; | |
140 | |
141 x = 0; | |
142 while (x < w) { | |
143 x1 = x; | |
144 color = bitmap[x1++]; | |
145 while (x1 < w && bitmap[x1] == color) | |
146 x1++; | |
147 len = x1 - x; | |
148 if (color == 0 && len == 2) { | |
149 PUTBITS4(0); | |
150 PUTBITS4(0xd); | |
151 } else if (color == 0 && (len >= 3 && len <= 9)) { | |
152 PUTBITS4(0); | |
153 PUTBITS4(len - 2); | |
154 } else if (len >= 4 && len <= 7) { | |
155 PUTBITS4(0); | |
156 PUTBITS4(8 + len - 4); | |
157 PUTBITS4(color); | |
158 } else if (len >= 9 && len <= 24) { | |
159 PUTBITS4(0); | |
160 PUTBITS4(0xe); | |
161 PUTBITS4(len - 9); | |
162 PUTBITS4(color); | |
163 } else if (len >= 25) { | |
164 if (len > 280) | |
165 len = 280; | |
166 v = len - 25; | |
167 PUTBITS4(0); | |
168 PUTBITS4(0xf); | |
169 PUTBITS4(v >> 4); | |
170 PUTBITS4(v & 0xf); | |
171 PUTBITS4(color); | |
172 } else { | |
173 PUTBITS4(color); | |
174 if (color == 0) { | |
175 PUTBITS4(0xc); | |
176 } | |
177 len = 1; | |
178 } | |
179 x += len; | |
180 } | |
181 /* end of line */ | |
182 PUTBITS4(0); | |
183 PUTBITS4(0); | |
184 if (bitcnt != 4) { | |
185 *q++ = bitbuf; | |
186 } | |
187 *q++ = 0xf0; | |
188 bitmap += linesize; | |
189 } | |
190 *pq = q; | |
191 } | |
192 | |
193 #define SCALEBITS 10 | |
194 #define ONE_HALF (1 << (SCALEBITS - 1)) | |
195 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5)) | |
196 | |
197 #define RGB_TO_Y_CCIR(r, g, b) \ | |
198 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \ | |
199 FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) | |
200 | |
201 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\ | |
202 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ | |
203 FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) | |
204 | |
205 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\ | |
206 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ | |
207 FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) | |
208 | |
209 static inline void putbe16(uint8_t **pq, uint16_t v) | |
210 { | |
211 uint8_t *q; | |
212 q = *pq; | |
213 *q++ = v >> 8; | |
214 *q++ = v; | |
215 *pq = q; | |
216 } | |
217 | |
218 static int encode_dvb_subtitles(DVBSubtitleContext *s, | |
219 uint8_t *outbuf, AVSubtitle *h) | |
220 { | |
221 uint8_t *q, *pseg_len; | |
222 int page_id, region_id, clut_id, object_id, i, bpp_index, page_state; | |
223 | |
224 | |
225 q = outbuf; | |
226 | |
227 page_id = 1; | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
228 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
229 if (h->num_rects == 0 || h->rects == NULL) |
2756 | 230 return -1; |
231 | |
232 *q++ = 0x00; /* subtitle_stream_id */ | |
233 | |
234 /* page composition segment */ | |
235 | |
236 *q++ = 0x0f; /* sync_byte */ | |
237 *q++ = 0x10; /* segment_type */ | |
238 putbe16(&q, page_id); | |
239 pseg_len = q; | |
240 q += 2; /* segment length */ | |
241 *q++ = 30; /* page_timeout (seconds) */ | |
242 if (s->hide_state) | |
243 page_state = 0; /* normal case */ | |
244 else | |
245 page_state = 2; /* mode change */ | |
246 /* page_version = 0 + page_state */ | |
247 *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
|
248 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
249 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
|
250 *q++ = region_id; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
251 *q++ = 0xff; /* reserved */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
252 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
|
253 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
|
254 } |
2756 | 255 |
256 putbe16(&pseg_len, q - pseg_len - 2); | |
257 | |
258 if (!s->hide_state) { | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
259 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
|
260 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
261 /* CLUT segment */ |
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 if (h->rects[clut_id].nb_colors <= 4) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
264 /* 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
|
265 bpp_index = 0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
266 } 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
|
267 /* 4 bpp, standard encoding */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
268 bpp_index = 1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
269 } else { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
270 return -1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
271 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
272 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
273 *q++ = 0x0f; /* sync byte */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
274 *q++ = 0x12; /* CLUT definition segment */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
275 putbe16(&q, page_id); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
276 pseg_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
277 q += 2; /* segment length */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
278 *q++ = clut_id; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
279 *q++ = (0 << 4) | 0xf; /* version = 0 */ |
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 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
|
282 *q++ = i; /* clut_entry_id */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
283 *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
|
284 { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
285 int a, r, g, b; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
286 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
|
287 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
|
288 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
|
289 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
|
290 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
291 *q++ = RGB_TO_Y_CCIR(r, g, b); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
292 *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
|
293 *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
|
294 *q++ = 255 - a; |
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 } |
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 putbe16(&pseg_len, q - pseg_len - 2); |
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 } |
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 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
|
303 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
304 /* region composition segment */ |
2756 | 305 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
306 if (h->rects[region_id].nb_colors <= 4) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
307 /* 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
|
308 bpp_index = 0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
309 } 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
|
310 /* 4 bpp, standard encoding */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
311 bpp_index = 1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
312 } else { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
313 return -1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
314 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
315 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
316 *q++ = 0x0f; /* sync_byte */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
317 *q++ = 0x11; /* segment_type */ |
2756 | 318 putbe16(&q, page_id); |
319 pseg_len = q; | |
320 q += 2; /* segment length */ | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
321 *q++ = region_id; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
322 *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
|
323 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
|
324 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
|
325 *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
|
326 *q++ = region_id; /* clut_id == region_id */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
327 *q++ = 0; /* 8 bit fill colors */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
328 *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
|
329 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
330 if (!s->hide_state) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
331 putbe16(&q, region_id); /* object_id == region_id */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
332 *q++ = (0 << 6) | (0 << 4); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
333 *q++ = 0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
334 *q++ = 0xf0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
335 *q++ = 0; |
2756 | 336 } |
337 | |
338 putbe16(&pseg_len, q - pseg_len - 2); | |
339 } | |
340 | |
341 if (!s->hide_state) { | |
342 | |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
343 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
|
344 /* Object Data segment */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
345 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
346 if (h->rects[region_id].nb_colors <= 4) { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
347 /* 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
|
348 bpp_index = 0; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
349 } 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
|
350 /* 4 bpp, standard encoding */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
351 bpp_index = 1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
352 } else { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
353 return -1; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
354 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
355 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
356 *q++ = 0x0f; /* sync byte */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
357 *q++ = 0x13; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
358 putbe16(&q, page_id); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
359 pseg_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
360 q += 2; /* segment length */ |
2756 | 361 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
362 putbe16(&q, object_id); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
363 *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
|
364 onject_coding_method, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
365 non_modifying_color_flag */ |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
366 { |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
367 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
|
368 void (*dvb_encode_rle)(uint8_t **pq, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
369 const uint8_t *bitmap, int linesize, |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
370 int w, int h); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
371 ptop_field_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
372 q += 2; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
373 pbottom_field_len = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
374 q += 2; |
2756 | 375 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
376 if (bpp_index == 0) |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
377 dvb_encode_rle = dvb_encode_rle2; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
378 else |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
379 dvb_encode_rle = dvb_encode_rle4; |
2756 | 380 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
381 top_ptr = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
382 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
|
383 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
|
384 bottom_ptr = q; |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
385 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
|
386 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
|
387 h->rects[object_id].h >> 1); |
2756 | 388 |
2796
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
389 putbe16(&ptop_field_len, bottom_ptr - top_ptr); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
390 putbe16(&pbottom_field_len, q - bottom_ptr); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
391 } |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
392 |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
393 putbe16(&pseg_len, q - pseg_len - 2); |
95c35706acbb
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
michael
parents:
2756
diff
changeset
|
394 } |
2756 | 395 } |
396 | |
397 /* end of display set segment */ | |
398 | |
399 *q++ = 0x0f; /* sync_byte */ | |
400 *q++ = 0x80; /* segment_type */ | |
401 putbe16(&q, page_id); | |
402 pseg_len = q; | |
403 q += 2; /* segment length */ | |
404 | |
405 putbe16(&pseg_len, q - pseg_len - 2); | |
406 | |
407 *q++ = 0xff; /* end of PES data */ | |
408 | |
409 s->object_version = (s->object_version + 1) & 0xf; | |
410 s->hide_state = !s->hide_state; | |
411 return q - outbuf; | |
412 } | |
413 | |
414 static int dvbsub_init_decoder(AVCodecContext *avctx) | |
415 { | |
416 return 0; | |
417 } | |
418 | |
419 static int dvbsub_close_decoder(AVCodecContext *avctx) | |
420 { | |
421 return 0; | |
422 } | |
423 | |
424 static int dvbsub_encode(AVCodecContext *avctx, | |
425 unsigned char *buf, int buf_size, void *data) | |
426 { | |
427 DVBSubtitleContext *s = avctx->priv_data; | |
428 AVSubtitle *sub = data; | |
429 int ret; | |
430 | |
431 ret = encode_dvb_subtitles(s, buf, sub); | |
432 return ret; | |
433 } | |
434 | |
435 AVCodec dvbsub_encoder = { | |
436 "dvbsub", | |
437 CODEC_TYPE_SUBTITLE, | |
438 CODEC_ID_DVB_SUBTITLE, | |
439 sizeof(DVBSubtitleContext), | |
440 dvbsub_init_decoder, | |
441 dvbsub_encode, | |
442 dvbsub_close_decoder, | |
443 }; |