44ba19d864826dd7d6ae5d90e190749586524a60
[ffmpeg.git] / libavcodec / dvbsub.c
1 /*
2  * DVB subtitle encoding for ffmpeg
3  * Copyright (c) 2005 Fabrice Bellard.
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
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
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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;
49
50     for(y = 0; y < h; y++) {
51         *q++ = 0x10;
52         bitbuf = 0;
53         bitcnt = 6;
54
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;
137
138     for(y = 0; y < h; y++) {
139         *q++ = 0x11;
140         bitbuf = 0;
141         bitcnt = 4;
142
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))
197 #define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
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
220 static int encode_dvb_subtitles(DVBSubtitleContext *s,
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;
230
231     if (h->num_rects == 0 || h->rects == NULL)
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 */
249     *q++ = s->object_version | (page_state << 2) | 3;
250
251     for (region_id = 0; region_id < h->num_rects; region_id++) {
252         *q++ = region_id;
253         *q++ = 0xff; /* reserved */
254         putbe16(&q, h->rects[region_id].x); /* left pos */
255         putbe16(&q, h->rects[region_id].y); /* top pos */
256     }
257
258     putbe16(&pseg_len, q - pseg_len - 2);
259
260     if (!s->hide_state) {
261         for (clut_id = 0; clut_id < h->num_rects; clut_id++) {
262
263             /* CLUT segment */
264
265             if (h->rects[clut_id].nb_colors <= 4) {
266                 /* 2 bpp, some decoders do not support it correctly */
267                 bpp_index = 0;
268             } else if (h->rects[clut_id].nb_colors <= 16) {
269                 /* 4 bpp, standard encoding */
270                 bpp_index = 1;
271             } else {
272                 return -1;
273             }
274
275             *q++ = 0x0f; /* sync byte */
276             *q++ = 0x12; /* CLUT definition segment */
277             putbe16(&q, page_id);
278             pseg_len = q;
279             q += 2; /* segment length */
280             *q++ = clut_id;
281             *q++ = (0 << 4) | 0xf; /* version = 0 */
282
283             for(i = 0; i < h->rects[clut_id].nb_colors; i++) {
284                 *q++ = i; /* clut_entry_id */
285                 *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */
286                 {
287                     int a, r, g, b;
288                     a = (h->rects[clut_id].rgba_palette[i] >> 24) & 0xff;
289                     r = (h->rects[clut_id].rgba_palette[i] >> 16) & 0xff;
290                     g = (h->rects[clut_id].rgba_palette[i] >> 8) & 0xff;
291                     b = (h->rects[clut_id].rgba_palette[i] >> 0) & 0xff;
292
293                     *q++ = RGB_TO_Y_CCIR(r, g, b);
294                     *q++ = RGB_TO_V_CCIR(r, g, b, 0);
295                     *q++ = RGB_TO_U_CCIR(r, g, b, 0);
296                     *q++ = 255 - a;
297                 }
298             }
299
300             putbe16(&pseg_len, q - pseg_len - 2);
301         }
302     }
303
304     for (region_id = 0; region_id < h->num_rects; region_id++) {
305
306         /* region composition segment */
307
308         if (h->rects[region_id].nb_colors <= 4) {
309             /* 2 bpp, some decoders do not support it correctly */
310             bpp_index = 0;
311         } else if (h->rects[region_id].nb_colors <= 16) {
312             /* 4 bpp, standard encoding */
313             bpp_index = 1;
314         } else {
315             return -1;
316         }
317
318         *q++ = 0x0f; /* sync_byte */
319         *q++ = 0x11; /* segment_type */
320         putbe16(&q, page_id);
321         pseg_len = q;
322         q += 2; /* segment length */
323         *q++ = region_id;
324         *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
325         putbe16(&q, h->rects[region_id].w); /* region width */
326         putbe16(&q, h->rects[region_id].h); /* region height */
327         *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
328         *q++ = region_id; /* clut_id == region_id */
329         *q++ = 0; /* 8 bit fill colors */
330         *q++ = 0x03; /* 4 bit and 2 bit fill colors */
331
332         if (!s->hide_state) {
333             putbe16(&q, region_id); /* object_id == region_id */
334             *q++ = (0 << 6) | (0 << 4);
335             *q++ = 0;
336             *q++ = 0xf0;
337             *q++ = 0;
338         }
339
340         putbe16(&pseg_len, q - pseg_len - 2);
341     }
342
343     if (!s->hide_state) {
344
345         for (object_id = 0; object_id < h->num_rects; object_id++) {
346             /* Object Data segment */
347
348             if (h->rects[object_id].nb_colors <= 4) {
349                 /* 2 bpp, some decoders do not support it correctly */
350                 bpp_index = 0;
351             } else if (h->rects[object_id].nb_colors <= 16) {
352                 /* 4 bpp, standard encoding */
353                 bpp_index = 1;
354             } else {
355                 return -1;
356             }
357
358             *q++ = 0x0f; /* sync byte */
359             *q++ = 0x13;
360             putbe16(&q, page_id);
361             pseg_len = q;
362             q += 2; /* segment length */
363
364             putbe16(&q, object_id);
365             *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0,
366                                                                        onject_coding_method,
367                                                                        non_modifying_color_flag */
368             {
369                 uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr;
370                 void (*dvb_encode_rle)(uint8_t **pq,
371                                         const uint8_t *bitmap, int linesize,
372                                         int w, int h);
373                 ptop_field_len = q;
374                 q += 2;
375                 pbottom_field_len = q;
376                 q += 2;
377
378                 if (bpp_index == 0)
379                     dvb_encode_rle = dvb_encode_rle2;
380                 else
381                     dvb_encode_rle = dvb_encode_rle4;
382
383                 top_ptr = q;
384                 dvb_encode_rle(&q, h->rects[object_id].bitmap, h->rects[object_id].w * 2,
385                                     h->rects[object_id].w, h->rects[object_id].h >> 1);
386                 bottom_ptr = q;
387                 dvb_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w,
388                                     h->rects[object_id].w * 2, h->rects[object_id].w,
389                                     h->rects[object_id].h >> 1);
390
391                 putbe16(&ptop_field_len, bottom_ptr - top_ptr);
392                 putbe16(&pbottom_field_len, q - bottom_ptr);
393             }
394
395             putbe16(&pseg_len, q - pseg_len - 2);
396         }
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 };