yading@10
|
1 /*
|
yading@10
|
2 * DVB subtitle encoding
|
yading@10
|
3 * Copyright (c) 2005 Fabrice Bellard
|
yading@10
|
4 *
|
yading@10
|
5 * This file is part of FFmpeg.
|
yading@10
|
6 *
|
yading@10
|
7 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
8 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
9 * License as published by the Free Software Foundation; either
|
yading@10
|
10 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
11 *
|
yading@10
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
15 * Lesser General Public License for more details.
|
yading@10
|
16 *
|
yading@10
|
17 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
18 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
20 */
|
yading@10
|
21 #include "avcodec.h"
|
yading@10
|
22 #include "bytestream.h"
|
yading@10
|
23 #include "libavutil/colorspace.h"
|
yading@10
|
24
|
yading@10
|
25 typedef struct DVBSubtitleContext {
|
yading@10
|
26 int object_version;
|
yading@10
|
27 } DVBSubtitleContext;
|
yading@10
|
28
|
yading@10
|
29 #define PUTBITS2(val)\
|
yading@10
|
30 {\
|
yading@10
|
31 bitbuf |= (val) << bitcnt;\
|
yading@10
|
32 bitcnt -= 2;\
|
yading@10
|
33 if (bitcnt < 0) {\
|
yading@10
|
34 bitcnt = 6;\
|
yading@10
|
35 *q++ = bitbuf;\
|
yading@10
|
36 bitbuf = 0;\
|
yading@10
|
37 }\
|
yading@10
|
38 }
|
yading@10
|
39
|
yading@10
|
40 static void dvb_encode_rle2(uint8_t **pq,
|
yading@10
|
41 const uint8_t *bitmap, int linesize,
|
yading@10
|
42 int w, int h)
|
yading@10
|
43 {
|
yading@10
|
44 uint8_t *q;
|
yading@10
|
45 unsigned int bitbuf;
|
yading@10
|
46 int bitcnt;
|
yading@10
|
47 int x, y, len, x1, v, color;
|
yading@10
|
48
|
yading@10
|
49 q = *pq;
|
yading@10
|
50
|
yading@10
|
51 for(y = 0; y < h; y++) {
|
yading@10
|
52 *q++ = 0x10;
|
yading@10
|
53 bitbuf = 0;
|
yading@10
|
54 bitcnt = 6;
|
yading@10
|
55
|
yading@10
|
56 x = 0;
|
yading@10
|
57 while (x < w) {
|
yading@10
|
58 x1 = x;
|
yading@10
|
59 color = bitmap[x1++];
|
yading@10
|
60 while (x1 < w && bitmap[x1] == color)
|
yading@10
|
61 x1++;
|
yading@10
|
62 len = x1 - x;
|
yading@10
|
63 if (color == 0 && len == 2) {
|
yading@10
|
64 PUTBITS2(0);
|
yading@10
|
65 PUTBITS2(0);
|
yading@10
|
66 PUTBITS2(1);
|
yading@10
|
67 } else if (len >= 3 && len <= 10) {
|
yading@10
|
68 v = len - 3;
|
yading@10
|
69 PUTBITS2(0);
|
yading@10
|
70 PUTBITS2((v >> 2) | 2);
|
yading@10
|
71 PUTBITS2(v & 3);
|
yading@10
|
72 PUTBITS2(color);
|
yading@10
|
73 } else if (len >= 12 && len <= 27) {
|
yading@10
|
74 v = len - 12;
|
yading@10
|
75 PUTBITS2(0);
|
yading@10
|
76 PUTBITS2(0);
|
yading@10
|
77 PUTBITS2(2);
|
yading@10
|
78 PUTBITS2(v >> 2);
|
yading@10
|
79 PUTBITS2(v & 3);
|
yading@10
|
80 PUTBITS2(color);
|
yading@10
|
81 } else if (len >= 29) {
|
yading@10
|
82 /* length = 29 ... 284 */
|
yading@10
|
83 if (len > 284)
|
yading@10
|
84 len = 284;
|
yading@10
|
85 v = len - 29;
|
yading@10
|
86 PUTBITS2(0);
|
yading@10
|
87 PUTBITS2(0);
|
yading@10
|
88 PUTBITS2(3);
|
yading@10
|
89 PUTBITS2((v >> 6));
|
yading@10
|
90 PUTBITS2((v >> 4) & 3);
|
yading@10
|
91 PUTBITS2((v >> 2) & 3);
|
yading@10
|
92 PUTBITS2(v & 3);
|
yading@10
|
93 PUTBITS2(color);
|
yading@10
|
94 } else {
|
yading@10
|
95 PUTBITS2(color);
|
yading@10
|
96 if (color == 0) {
|
yading@10
|
97 PUTBITS2(1);
|
yading@10
|
98 }
|
yading@10
|
99 len = 1;
|
yading@10
|
100 }
|
yading@10
|
101 x += len;
|
yading@10
|
102 }
|
yading@10
|
103 /* end of line */
|
yading@10
|
104 PUTBITS2(0);
|
yading@10
|
105 PUTBITS2(0);
|
yading@10
|
106 PUTBITS2(0);
|
yading@10
|
107 if (bitcnt != 6) {
|
yading@10
|
108 *q++ = bitbuf;
|
yading@10
|
109 }
|
yading@10
|
110 *q++ = 0xf0;
|
yading@10
|
111 bitmap += linesize;
|
yading@10
|
112 }
|
yading@10
|
113 *pq = q;
|
yading@10
|
114 }
|
yading@10
|
115
|
yading@10
|
116 #define PUTBITS4(val)\
|
yading@10
|
117 {\
|
yading@10
|
118 bitbuf |= (val) << bitcnt;\
|
yading@10
|
119 bitcnt -= 4;\
|
yading@10
|
120 if (bitcnt < 0) {\
|
yading@10
|
121 bitcnt = 4;\
|
yading@10
|
122 *q++ = bitbuf;\
|
yading@10
|
123 bitbuf = 0;\
|
yading@10
|
124 }\
|
yading@10
|
125 }
|
yading@10
|
126
|
yading@10
|
127 /* some DVB decoders only implement 4 bits/pixel */
|
yading@10
|
128 static void dvb_encode_rle4(uint8_t **pq,
|
yading@10
|
129 const uint8_t *bitmap, int linesize,
|
yading@10
|
130 int w, int h)
|
yading@10
|
131 {
|
yading@10
|
132 uint8_t *q;
|
yading@10
|
133 unsigned int bitbuf;
|
yading@10
|
134 int bitcnt;
|
yading@10
|
135 int x, y, len, x1, v, color;
|
yading@10
|
136
|
yading@10
|
137 q = *pq;
|
yading@10
|
138
|
yading@10
|
139 for(y = 0; y < h; y++) {
|
yading@10
|
140 *q++ = 0x11;
|
yading@10
|
141 bitbuf = 0;
|
yading@10
|
142 bitcnt = 4;
|
yading@10
|
143
|
yading@10
|
144 x = 0;
|
yading@10
|
145 while (x < w) {
|
yading@10
|
146 x1 = x;
|
yading@10
|
147 color = bitmap[x1++];
|
yading@10
|
148 while (x1 < w && bitmap[x1] == color)
|
yading@10
|
149 x1++;
|
yading@10
|
150 len = x1 - x;
|
yading@10
|
151 if (color == 0 && len == 2) {
|
yading@10
|
152 PUTBITS4(0);
|
yading@10
|
153 PUTBITS4(0xd);
|
yading@10
|
154 } else if (color == 0 && (len >= 3 && len <= 9)) {
|
yading@10
|
155 PUTBITS4(0);
|
yading@10
|
156 PUTBITS4(len - 2);
|
yading@10
|
157 } else if (len >= 4 && len <= 7) {
|
yading@10
|
158 PUTBITS4(0);
|
yading@10
|
159 PUTBITS4(8 + len - 4);
|
yading@10
|
160 PUTBITS4(color);
|
yading@10
|
161 } else if (len >= 9 && len <= 24) {
|
yading@10
|
162 PUTBITS4(0);
|
yading@10
|
163 PUTBITS4(0xe);
|
yading@10
|
164 PUTBITS4(len - 9);
|
yading@10
|
165 PUTBITS4(color);
|
yading@10
|
166 } else if (len >= 25) {
|
yading@10
|
167 if (len > 280)
|
yading@10
|
168 len = 280;
|
yading@10
|
169 v = len - 25;
|
yading@10
|
170 PUTBITS4(0);
|
yading@10
|
171 PUTBITS4(0xf);
|
yading@10
|
172 PUTBITS4(v >> 4);
|
yading@10
|
173 PUTBITS4(v & 0xf);
|
yading@10
|
174 PUTBITS4(color);
|
yading@10
|
175 } else {
|
yading@10
|
176 PUTBITS4(color);
|
yading@10
|
177 if (color == 0) {
|
yading@10
|
178 PUTBITS4(0xc);
|
yading@10
|
179 }
|
yading@10
|
180 len = 1;
|
yading@10
|
181 }
|
yading@10
|
182 x += len;
|
yading@10
|
183 }
|
yading@10
|
184 /* end of line */
|
yading@10
|
185 PUTBITS4(0);
|
yading@10
|
186 PUTBITS4(0);
|
yading@10
|
187 if (bitcnt != 4) {
|
yading@10
|
188 *q++ = bitbuf;
|
yading@10
|
189 }
|
yading@10
|
190 *q++ = 0xf0;
|
yading@10
|
191 bitmap += linesize;
|
yading@10
|
192 }
|
yading@10
|
193 *pq = q;
|
yading@10
|
194 }
|
yading@10
|
195
|
yading@10
|
196 static void dvb_encode_rle8(uint8_t **pq,
|
yading@10
|
197 const uint8_t *bitmap, int linesize,
|
yading@10
|
198 int w, int h)
|
yading@10
|
199 {
|
yading@10
|
200 uint8_t *q;
|
yading@10
|
201 int x, y, len, x1, color;
|
yading@10
|
202
|
yading@10
|
203 q = *pq;
|
yading@10
|
204
|
yading@10
|
205 for (y = 0; y < h; y++) {
|
yading@10
|
206 *q++ = 0x12;
|
yading@10
|
207
|
yading@10
|
208 x = 0;
|
yading@10
|
209 while (x < w) {
|
yading@10
|
210 x1 = x;
|
yading@10
|
211 color = bitmap[x1++];
|
yading@10
|
212 while (x1 < w && bitmap[x1] == color)
|
yading@10
|
213 x1++;
|
yading@10
|
214 len = x1 - x;
|
yading@10
|
215 if (len == 1 && color) {
|
yading@10
|
216 // 00000001 to 11111111 1 pixel in colour x
|
yading@10
|
217 *q++ = color;
|
yading@10
|
218 } else {
|
yading@10
|
219 if (color == 0x00) {
|
yading@10
|
220 // 00000000 0LLLLLLL L pixels (1-127) in colour 0 (L > 0)
|
yading@10
|
221 len = FFMIN(len, 127);
|
yading@10
|
222 *q++ = 0x00;
|
yading@10
|
223 *q++ = len;
|
yading@10
|
224 } else if (len > 2) {
|
yading@10
|
225 // 00000000 1LLLLLLL CCCCCCCC L pixels (3-127) in colour C (L > 2)
|
yading@10
|
226 len = FFMIN(len, 127);
|
yading@10
|
227 *q++ = 0x00;
|
yading@10
|
228 *q++ = 0x80+len;
|
yading@10
|
229 *q++ = color;
|
yading@10
|
230 }
|
yading@10
|
231 else if (len == 2) {
|
yading@10
|
232 *q++ = color;
|
yading@10
|
233 *q++ = color;
|
yading@10
|
234 } else {
|
yading@10
|
235 *q++ = color;
|
yading@10
|
236 len = 1;
|
yading@10
|
237 }
|
yading@10
|
238 }
|
yading@10
|
239 x += len;
|
yading@10
|
240 }
|
yading@10
|
241 /* end of line */
|
yading@10
|
242 // 00000000 00000000 end of 8-bit/pixel_code_string
|
yading@10
|
243 *q++ = 0x00;
|
yading@10
|
244 *q++ = 0x00;
|
yading@10
|
245 bitmap += linesize;
|
yading@10
|
246 }
|
yading@10
|
247 *pq = q;
|
yading@10
|
248 }
|
yading@10
|
249
|
yading@10
|
250 static int encode_dvb_subtitles(DVBSubtitleContext *s,
|
yading@10
|
251 uint8_t *outbuf, const AVSubtitle *h)
|
yading@10
|
252 {
|
yading@10
|
253 uint8_t *q, *pseg_len;
|
yading@10
|
254 int page_id, region_id, clut_id, object_id, i, bpp_index, page_state;
|
yading@10
|
255
|
yading@10
|
256
|
yading@10
|
257 q = outbuf;
|
yading@10
|
258
|
yading@10
|
259 page_id = 1;
|
yading@10
|
260
|
yading@10
|
261 if (h->num_rects && h->rects == NULL)
|
yading@10
|
262 return -1;
|
yading@10
|
263
|
yading@10
|
264 *q++ = 0x00; /* subtitle_stream_id */
|
yading@10
|
265
|
yading@10
|
266 /* page composition segment */
|
yading@10
|
267
|
yading@10
|
268 *q++ = 0x0f; /* sync_byte */
|
yading@10
|
269 *q++ = 0x10; /* segment_type */
|
yading@10
|
270 bytestream_put_be16(&q, page_id);
|
yading@10
|
271 pseg_len = q;
|
yading@10
|
272 q += 2; /* segment length */
|
yading@10
|
273 *q++ = 30; /* page_timeout (seconds) */
|
yading@10
|
274 page_state = 2; /* mode change */
|
yading@10
|
275 /* page_version = 0 + page_state */
|
yading@10
|
276 *q++ = (s->object_version << 4) | (page_state << 2) | 3;
|
yading@10
|
277
|
yading@10
|
278 for (region_id = 0; region_id < h->num_rects; region_id++) {
|
yading@10
|
279 *q++ = region_id;
|
yading@10
|
280 *q++ = 0xff; /* reserved */
|
yading@10
|
281 bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */
|
yading@10
|
282 bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */
|
yading@10
|
283 }
|
yading@10
|
284
|
yading@10
|
285 bytestream_put_be16(&pseg_len, q - pseg_len - 2);
|
yading@10
|
286
|
yading@10
|
287 if (h->num_rects) {
|
yading@10
|
288 for (clut_id = 0; clut_id < h->num_rects; clut_id++) {
|
yading@10
|
289
|
yading@10
|
290 /* CLUT segment */
|
yading@10
|
291
|
yading@10
|
292 if (h->rects[clut_id]->nb_colors <= 4) {
|
yading@10
|
293 /* 2 bpp, some decoders do not support it correctly */
|
yading@10
|
294 bpp_index = 0;
|
yading@10
|
295 } else if (h->rects[clut_id]->nb_colors <= 16) {
|
yading@10
|
296 /* 4 bpp, standard encoding */
|
yading@10
|
297 bpp_index = 1;
|
yading@10
|
298 } else if (h->rects[clut_id]->nb_colors <= 256) {
|
yading@10
|
299 /* 8 bpp, standard encoding */
|
yading@10
|
300 bpp_index = 2;
|
yading@10
|
301 } else {
|
yading@10
|
302 return -1;
|
yading@10
|
303 }
|
yading@10
|
304
|
yading@10
|
305
|
yading@10
|
306 /* CLUT segment */
|
yading@10
|
307 *q++ = 0x0f; /* sync byte */
|
yading@10
|
308 *q++ = 0x12; /* CLUT definition segment */
|
yading@10
|
309 bytestream_put_be16(&q, page_id);
|
yading@10
|
310 pseg_len = q;
|
yading@10
|
311 q += 2; /* segment length */
|
yading@10
|
312 *q++ = clut_id;
|
yading@10
|
313 *q++ = (0 << 4) | 0xf; /* version = 0 */
|
yading@10
|
314
|
yading@10
|
315 for(i = 0; i < h->rects[clut_id]->nb_colors; i++) {
|
yading@10
|
316 *q++ = i; /* clut_entry_id */
|
yading@10
|
317 *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */
|
yading@10
|
318 {
|
yading@10
|
319 int a, r, g, b;
|
yading@10
|
320 uint32_t x= ((uint32_t*)h->rects[clut_id]->pict.data[1])[i];
|
yading@10
|
321 a = (x >> 24) & 0xff;
|
yading@10
|
322 r = (x >> 16) & 0xff;
|
yading@10
|
323 g = (x >> 8) & 0xff;
|
yading@10
|
324 b = (x >> 0) & 0xff;
|
yading@10
|
325
|
yading@10
|
326 *q++ = RGB_TO_Y_CCIR(r, g, b);
|
yading@10
|
327 *q++ = RGB_TO_V_CCIR(r, g, b, 0);
|
yading@10
|
328 *q++ = RGB_TO_U_CCIR(r, g, b, 0);
|
yading@10
|
329 *q++ = 255 - a;
|
yading@10
|
330 }
|
yading@10
|
331 }
|
yading@10
|
332
|
yading@10
|
333 bytestream_put_be16(&pseg_len, q - pseg_len - 2);
|
yading@10
|
334 }
|
yading@10
|
335 }
|
yading@10
|
336
|
yading@10
|
337 for (region_id = 0; region_id < h->num_rects; region_id++) {
|
yading@10
|
338
|
yading@10
|
339 /* region composition segment */
|
yading@10
|
340
|
yading@10
|
341 if (h->rects[region_id]->nb_colors <= 4) {
|
yading@10
|
342 /* 2 bpp, some decoders do not support it correctly */
|
yading@10
|
343 bpp_index = 0;
|
yading@10
|
344 } else if (h->rects[region_id]->nb_colors <= 16) {
|
yading@10
|
345 /* 4 bpp, standard encoding */
|
yading@10
|
346 bpp_index = 1;
|
yading@10
|
347 } else {
|
yading@10
|
348 return -1;
|
yading@10
|
349 }
|
yading@10
|
350
|
yading@10
|
351 *q++ = 0x0f; /* sync_byte */
|
yading@10
|
352 *q++ = 0x11; /* segment_type */
|
yading@10
|
353 bytestream_put_be16(&q, page_id);
|
yading@10
|
354 pseg_len = q;
|
yading@10
|
355 q += 2; /* segment length */
|
yading@10
|
356 *q++ = region_id;
|
yading@10
|
357 *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
|
yading@10
|
358 bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */
|
yading@10
|
359 bytestream_put_be16(&q, h->rects[region_id]->h); /* region height */
|
yading@10
|
360 *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
|
yading@10
|
361 *q++ = region_id; /* clut_id == region_id */
|
yading@10
|
362 *q++ = 0; /* 8 bit fill colors */
|
yading@10
|
363 *q++ = 0x03; /* 4 bit and 2 bit fill colors */
|
yading@10
|
364
|
yading@10
|
365 bytestream_put_be16(&q, region_id); /* object_id == region_id */
|
yading@10
|
366 *q++ = (0 << 6) | (0 << 4);
|
yading@10
|
367 *q++ = 0;
|
yading@10
|
368 *q++ = 0xf0;
|
yading@10
|
369 *q++ = 0;
|
yading@10
|
370
|
yading@10
|
371 bytestream_put_be16(&pseg_len, q - pseg_len - 2);
|
yading@10
|
372 }
|
yading@10
|
373
|
yading@10
|
374 if (h->num_rects) {
|
yading@10
|
375
|
yading@10
|
376 for (object_id = 0; object_id < h->num_rects; object_id++) {
|
yading@10
|
377 void (*dvb_encode_rle)(uint8_t **pq,
|
yading@10
|
378 const uint8_t *bitmap, int linesize,
|
yading@10
|
379 int w, int h);
|
yading@10
|
380
|
yading@10
|
381 /* bpp_index maths */
|
yading@10
|
382 if (h->rects[object_id]->nb_colors <= 4) {
|
yading@10
|
383 /* 2 bpp, some decoders do not support it correctly */
|
yading@10
|
384 dvb_encode_rle = dvb_encode_rle2;
|
yading@10
|
385 } else if (h->rects[object_id]->nb_colors <= 16) {
|
yading@10
|
386 /* 4 bpp, standard encoding */
|
yading@10
|
387 dvb_encode_rle = dvb_encode_rle4;
|
yading@10
|
388 } else if (h->rects[object_id]->nb_colors <= 256) {
|
yading@10
|
389 /* 8 bpp, standard encoding */
|
yading@10
|
390 dvb_encode_rle = dvb_encode_rle8;
|
yading@10
|
391 } else {
|
yading@10
|
392 return -1;
|
yading@10
|
393 }
|
yading@10
|
394
|
yading@10
|
395 /* Object Data segment */
|
yading@10
|
396 *q++ = 0x0f; /* sync byte */
|
yading@10
|
397 *q++ = 0x13;
|
yading@10
|
398 bytestream_put_be16(&q, page_id);
|
yading@10
|
399 pseg_len = q;
|
yading@10
|
400 q += 2; /* segment length */
|
yading@10
|
401
|
yading@10
|
402 bytestream_put_be16(&q, object_id);
|
yading@10
|
403 *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0,
|
yading@10
|
404 onject_coding_method,
|
yading@10
|
405 non_modifying_color_flag */
|
yading@10
|
406 {
|
yading@10
|
407 uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr;
|
yading@10
|
408
|
yading@10
|
409 ptop_field_len = q;
|
yading@10
|
410 q += 2;
|
yading@10
|
411 pbottom_field_len = q;
|
yading@10
|
412 q += 2;
|
yading@10
|
413
|
yading@10
|
414 top_ptr = q;
|
yading@10
|
415 dvb_encode_rle(&q, h->rects[object_id]->pict.data[0], h->rects[object_id]->w * 2,
|
yading@10
|
416 h->rects[object_id]->w, h->rects[object_id]->h >> 1);
|
yading@10
|
417 bottom_ptr = q;
|
yading@10
|
418 dvb_encode_rle(&q, h->rects[object_id]->pict.data[0] + h->rects[object_id]->w,
|
yading@10
|
419 h->rects[object_id]->w * 2, h->rects[object_id]->w,
|
yading@10
|
420 h->rects[object_id]->h >> 1);
|
yading@10
|
421
|
yading@10
|
422 bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr);
|
yading@10
|
423 bytestream_put_be16(&pbottom_field_len, q - bottom_ptr);
|
yading@10
|
424 }
|
yading@10
|
425
|
yading@10
|
426 bytestream_put_be16(&pseg_len, q - pseg_len - 2);
|
yading@10
|
427 }
|
yading@10
|
428 }
|
yading@10
|
429
|
yading@10
|
430 /* end of display set segment */
|
yading@10
|
431
|
yading@10
|
432 *q++ = 0x0f; /* sync_byte */
|
yading@10
|
433 *q++ = 0x80; /* segment_type */
|
yading@10
|
434 bytestream_put_be16(&q, page_id);
|
yading@10
|
435 pseg_len = q;
|
yading@10
|
436 q += 2; /* segment length */
|
yading@10
|
437
|
yading@10
|
438 bytestream_put_be16(&pseg_len, q - pseg_len - 2);
|
yading@10
|
439
|
yading@10
|
440 *q++ = 0xff; /* end of PES data */
|
yading@10
|
441
|
yading@10
|
442 s->object_version = (s->object_version + 1) & 0xf;
|
yading@10
|
443 return q - outbuf;
|
yading@10
|
444 }
|
yading@10
|
445
|
yading@10
|
446 static int dvbsub_encode(AVCodecContext *avctx,
|
yading@10
|
447 unsigned char *buf, int buf_size,
|
yading@10
|
448 const AVSubtitle *sub)
|
yading@10
|
449 {
|
yading@10
|
450 DVBSubtitleContext *s = avctx->priv_data;
|
yading@10
|
451 int ret;
|
yading@10
|
452
|
yading@10
|
453 ret = encode_dvb_subtitles(s, buf, sub);
|
yading@10
|
454 return ret;
|
yading@10
|
455 }
|
yading@10
|
456
|
yading@10
|
457 AVCodec ff_dvbsub_encoder = {
|
yading@10
|
458 .name = "dvbsub",
|
yading@10
|
459 .type = AVMEDIA_TYPE_SUBTITLE,
|
yading@10
|
460 .id = AV_CODEC_ID_DVB_SUBTITLE,
|
yading@10
|
461 .priv_data_size = sizeof(DVBSubtitleContext),
|
yading@10
|
462 .encode_sub = dvbsub_encode,
|
yading@10
|
463 .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
|
yading@10
|
464 };
|