~ubuntu-branches/ubuntu/hardy/avidemux/hardy

« back to all changes in this revision

Viewing changes to avidemux/ADM_libraries/ADM_lavcodec/dvbsub.c

  • Committer: Bazaar Package Importer
  • Author(s): Matvey Kozhev
  • Date: 2007-12-18 13:53:04 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20071218135304-cdqec2lg2bglyz15
Tags: 1:2.4~preview3-0.0ubuntu1
* Upload to Ubuntu. (LP: #163287, LP: #126572)
* debian/changelog: re-added Ubuntu releases.
* debian/control:
  - Require debhelper >= 5.0.51 (for dh_icons) and imagemagick.
  - Build-depend on libsdl1.2-dev instead of libsdl-dev.
  - Build against newer libx264-dev. (LP: #138854)
  - Removed libamrnb-dev, not in Ubuntu yet.
* debian/rules:
  - Install all icon sizes, using convert (upstream installs none).
  - Added missing calls to dh_installmenu, dh_installman, dh_icons and
    dh_desktop.
* debian/menu, debian/avidemux-qt.menu:
  - Corrected package and executable names.
* debian/avidemux-common.install: Install icons.
* debian/avidemux.common.manpages: Install man/avidemux.1.
* debian/links, debian/avidemux-cli.links, debian/avidemux-gtk.links:
  - Link manpages to avidemux.1.gz.
* debian/install, debian/avidemux-qt.install, debian/avidemux-gtk.desktop,
  debian/avidemux-qt.desktop: Install desktop files.

Show diffs side-by-side

added added

removed removed

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