dvbsubdec.c 45.9 KB
Newer Older
1
/*
2
 * DVB subtitle decoding
3
 * Copyright (c) 2005 Ian Caulfield
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * 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 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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

22
#include "avcodec.h"
23
#include "get_bits.h"
24
#include "bytestream.h"
25
#include "internal.h"
26
#include "libavutil/colorspace.h"
27
#include "libavutil/opt.h"
28 29 30 31 32

#define DVBSUB_PAGE_SEGMENT     0x10
#define DVBSUB_REGION_SEGMENT   0x11
#define DVBSUB_CLUT_SEGMENT     0x12
#define DVBSUB_OBJECT_SEGMENT   0x13
33
#define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
34 35
#define DVBSUB_DISPLAY_SEGMENT  0x80

36
#define cm (ff_crop_tab + MAX_NEG_CROP)
37

38
#ifdef DEBUG
39 40 41 42 43 44 45 46
#if 0
static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
                     uint32_t *rgba_palette)
{
    int x, y, v;
    FILE *f;
    char fname[40], fname2[40];
    char command[1024];
47

48 49 50 51 52
    snprintf(fname, 40, "%s.ppm", filename);

    f = fopen(fname, "w");
    if (!f) {
        perror(fname);
53
        return;
54 55 56 57 58 59 60 61 62 63 64 65 66 67
    }
    fprintf(f, "P6\n"
            "%d %d\n"
            "%d\n",
            w, h, 255);
    for(y = 0; y < h; y++) {
        for(x = 0; x < w; x++) {
            v = rgba_palette[bitmap[y * w + x]];
            putc((v >> 16) & 0xff, f);
            putc((v >> 8) & 0xff, f);
            putc((v >> 0) & 0xff, f);
        }
    }
    fclose(f);
68 69


70 71 72 73 74
    snprintf(fname2, 40, "%s-a.pgm", filename);

    f = fopen(fname2, "w");
    if (!f) {
        perror(fname2);
75
        return;
76 77 78 79 80 81 82 83 84 85 86 87
    }
    fprintf(f, "P5\n"
            "%d %d\n"
            "%d\n",
            w, h, 255);
    for(y = 0; y < h; y++) {
        for(x = 0; x < w; x++) {
            v = rgba_palette[bitmap[y * w + x]];
            putc((v >> 24) & 0xff, f);
        }
    }
    fclose(f);
88

89 90
    snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
    system(command);
91

92 93 94 95 96 97 98 99 100 101 102
    snprintf(command, 1024, "rm %s %s", fname, fname2);
    system(command);
}
#endif

static void png_save2(const char *filename, uint32_t *bitmap, int w, int h)
{
    int x, y, v;
    FILE *f;
    char fname[40], fname2[40];
    char command[1024];
103

104
    snprintf(fname, sizeof(fname), "%s.ppm", filename);
105 106 107 108

    f = fopen(fname, "w");
    if (!f) {
        perror(fname);
109
        return;
110 111 112 113 114 115 116 117 118 119 120 121 122 123
    }
    fprintf(f, "P6\n"
            "%d %d\n"
            "%d\n",
            w, h, 255);
    for(y = 0; y < h; y++) {
        for(x = 0; x < w; x++) {
            v = bitmap[y * w + x];
            putc((v >> 16) & 0xff, f);
            putc((v >> 8) & 0xff, f);
            putc((v >> 0) & 0xff, f);
        }
    }
    fclose(f);
124 125


126
    snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename);
127 128 129 130

    f = fopen(fname2, "w");
    if (!f) {
        perror(fname2);
131
        return;
132 133 134 135 136 137 138 139 140 141 142 143
    }
    fprintf(f, "P5\n"
            "%d %d\n"
            "%d\n",
            w, h, 255);
    for(y = 0; y < h; y++) {
        for(x = 0; x < w; x++) {
            v = bitmap[y * w + x];
            putc((v >> 24) & 0xff, f);
        }
    }
    fclose(f);
144

145
    snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
146
    system(command);
147

148
    snprintf(command, sizeof(command), "rm %s %s", fname, fname2);
149 150 151 152
    system(command);
}
#endif

153
#define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
154 155 156

typedef struct DVBSubCLUT {
    int id;
157
    int version;
158 159 160 161

    uint32_t clut4[4];
    uint32_t clut16[16];
    uint32_t clut256[256];
162

163 164 165 166 167 168 169 170 171 172 173 174
    struct DVBSubCLUT *next;
} DVBSubCLUT;

static DVBSubCLUT default_clut;

typedef struct DVBSubObjectDisplay {
    int object_id;
    int region_id;

    int x_pos;
    int y_pos;

175 176
    int fgcolor;
    int bgcolor;
177

178
    struct DVBSubObjectDisplay *region_list_next;
179
    struct DVBSubObjectDisplay *object_list_next;
180 181 182 183
} DVBSubObjectDisplay;

typedef struct DVBSubObject {
    int id;
184
    int version;
185 186

    int type;
187 188 189

    DVBSubObjectDisplay *display_list;

190 191 192 193 194 195 196 197 198 199 200 201 202 203
    struct DVBSubObject *next;
} DVBSubObject;

typedef struct DVBSubRegionDisplay {
    int region_id;

    int x_pos;
    int y_pos;

    struct DVBSubRegionDisplay *next;
} DVBSubRegionDisplay;

typedef struct DVBSubRegion {
    int id;
204
    int version;
205 206 207 208

    int width;
    int height;
    int depth;
209

210
    int clut;
211
    int bgcolor;
212

213 214
    uint8_t *pbuf;
    int buf_size;
215
    int dirty;
216 217

    DVBSubObjectDisplay *display_list;
218

219 220 221
    struct DVBSubRegion *next;
} DVBSubRegion;

222 223 224 225 226 227 228 229 230
typedef struct DVBSubDisplayDefinition {
    int version;

    int x;
    int y;
    int width;
    int height;
} DVBSubDisplayDefinition;

231
typedef struct DVBSubContext {
232
    AVClass *class;
233 234 235
    int composition_id;
    int ancillary_id;

236
    int version;
237
    int time_out;
238 239 240
    int compute_edt; /**< if 1 end display time calculated using pts
                          if 0 (Default) calculated using time out */
    int64_t prev_start;
241 242 243
    DVBSubRegion *region_list;
    DVBSubCLUT   *clut_list;
    DVBSubObject *object_list;
244

245
    DVBSubRegionDisplay *display_list;
246
    DVBSubDisplayDefinition *display_definition;
247 248 249 250 251 252 253
} DVBSubContext;


static DVBSubObject* get_object(DVBSubContext *ctx, int object_id)
{
    DVBSubObject *ptr = ctx->object_list;

254
    while (ptr && ptr->id != object_id) {
255 256
        ptr = ptr->next;
    }
257

258 259 260 261 262 263 264
    return ptr;
}

static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id)
{
    DVBSubCLUT *ptr = ctx->clut_list;

265
    while (ptr && ptr->id != clut_id) {
266 267
        ptr = ptr->next;
    }
268

269 270 271 272 273 274 275
    return ptr;
}

static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id)
{
    DVBSubRegion *ptr = ctx->region_list;

276
    while (ptr && ptr->id != region_id) {
277 278
        ptr = ptr->next;
    }
279

280 281 282 283 284 285 286 287
    return ptr;
}

static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region)
{
    DVBSubObject *object, *obj2, **obj2_ptr;
    DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;

288
    while (region->display_list) {
289
        display = region->display_list;
290

291
        object = get_object(ctx, display->object_id);
292

293
        if (object) {
294
            obj_disp_ptr = &object->display_list;
295
            obj_disp = *obj_disp_ptr;
296

297
            while (obj_disp && obj_disp != display) {
298
                obj_disp_ptr = &obj_disp->object_list_next;
299
                obj_disp = *obj_disp_ptr;
300
            }
301

302 303
            if (obj_disp) {
                *obj_disp_ptr = obj_disp->object_list_next;
304

305
                if (!object->display_list) {
306
                    obj2_ptr = &ctx->object_list;
307
                    obj2 = *obj2_ptr;
308

Michael Niedermayer's avatar
Michael Niedermayer committed
309
                    while (obj2 != object) {
310
                        av_assert0(obj2);
311
                        obj2_ptr = &obj2->next;
312
                        obj2 = *obj2_ptr;
313
                    }
314

315
                    *obj2_ptr = obj2->next;
316

317
                    av_freep(&obj2);
318 319 320
                }
            }
        }
321

322
        region->display_list = display->region_list_next;
323

324
        av_freep(&display);
325
    }
326

327 328
}

329
static void delete_cluts(DVBSubContext *ctx)
330
{
331
    while (ctx->clut_list) {
332
        DVBSubCLUT *clut = ctx->clut_list;
333 334 335

        ctx->clut_list = clut->next;

336
        av_freep(&clut);
337
    }
338
}
339

340 341 342
static void delete_objects(DVBSubContext *ctx)
{
    while (ctx->object_list) {
343
        DVBSubObject *object = ctx->object_list;
344 345 346

        ctx->object_list = object->next;

347
        av_freep(&object);
348 349 350 351 352 353
    }
}

static void delete_regions(DVBSubContext *ctx)
{
    while (ctx->region_list) {
354
        DVBSubRegion *region = ctx->region_list;
355 356 357 358 359

        ctx->region_list = region->next;

        delete_region_display_list(ctx, region);

360 361
        av_freep(&region->pbuf);
        av_freep(&region);
362
    }
363 364
}

365
static av_cold int dvbsub_init_decoder(AVCodecContext *avctx)
366 367
{
    int i, r, g, b, a = 0;
368
    DVBSubContext *ctx = avctx->priv_data;
369

370 371
    if (!avctx->extradata || (avctx->extradata_size < 4) || ((avctx->extradata_size % 5 != 0) && (avctx->extradata_size != 4))) {
        av_log(avctx, AV_LOG_WARNING, "Invalid DVB subtitles stream extradata!\n");
372 373 374
        ctx->composition_id = -1;
        ctx->ancillary_id   = -1;
    } else {
375 376 377 378
        if (avctx->extradata_size > 5) {
            av_log(avctx, AV_LOG_WARNING, "Decoding first DVB subtitles sub-stream\n");
        }

379 380 381
        ctx->composition_id = AV_RB16(avctx->extradata);
        ctx->ancillary_id   = AV_RB16(avctx->extradata + 2);
    }
382

383
    ctx->version = -1;
384
    ctx->prev_start = AV_NOPTS_VALUE;
385

386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
    default_clut.id = -1;
    default_clut.next = NULL;

    default_clut.clut4[0] = RGBA(  0,   0,   0,   0);
    default_clut.clut4[1] = RGBA(255, 255, 255, 255);
    default_clut.clut4[2] = RGBA(  0,   0,   0, 255);
    default_clut.clut4[3] = RGBA(127, 127, 127, 255);

    default_clut.clut16[0] = RGBA(  0,   0,   0,   0);
    for (i = 1; i < 16; i++) {
        if (i < 8) {
            r = (i & 1) ? 255 : 0;
            g = (i & 2) ? 255 : 0;
            b = (i & 4) ? 255 : 0;
        } else {
            r = (i & 1) ? 127 : 0;
            g = (i & 2) ? 127 : 0;
            b = (i & 4) ? 127 : 0;
404
        }
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
        default_clut.clut16[i] = RGBA(r, g, b, 255);
    }

    default_clut.clut256[0] = RGBA(  0,   0,   0,   0);
    for (i = 1; i < 256; i++) {
        if (i < 8) {
            r = (i & 1) ? 255 : 0;
            g = (i & 2) ? 255 : 0;
            b = (i & 4) ? 255 : 0;
            a = 63;
        } else {
            switch (i & 0x88) {
            case 0x00:
                r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
                g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
                b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
                a = 255;
                break;
            case 0x08:
                r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
                g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
                b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
                a = 127;
                break;
            case 0x80:
                r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
                g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
                b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
                a = 255;
                break;
            case 0x88:
                r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
                g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
                b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
                a = 255;
                break;
            }
442
        }
443 444 445 446 447 448
        default_clut.clut256[i] = RGBA(r, g, b, a);
    }

    return 0;
}

449
static av_cold int dvbsub_close_decoder(AVCodecContext *avctx)
450
{
451
    DVBSubContext *ctx = avctx->priv_data;
452 453
    DVBSubRegionDisplay *display;

454 455 456 457 458 459 460
    delete_regions(ctx);

    delete_objects(ctx);

    delete_cluts(ctx);

    av_freep(&ctx->display_definition);
461

462
    while (ctx->display_list) {
463 464
        display = ctx->display_list;
        ctx->display_list = display->next;
465

466
        av_freep(&display);
467 468 469 470 471
    }

    return 0;
}

472 473
static int dvbsub_read_2bit_string(AVCodecContext *avctx,
                                   uint8_t *destbuf, int dbuf_len,
Michael Niedermayer's avatar
Michael Niedermayer committed
474
                                   const uint8_t **srcbuf, int buf_size,
475
                                   int non_mod, uint8_t *map_table, int x_pos)
476 477
{
    GetBitContext gb;
478

479 480
    int bits;
    int run_length;
481
    int pixels_read = x_pos;
482

483
    init_get_bits(&gb, *srcbuf, buf_size << 3);
484

485 486
    destbuf += x_pos;

487
    while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
488 489
        bits = get_bits(&gb, 2);

490
        if (bits) {
491
            if (non_mod != 1 || bits != 1) {
492
                if (map_table)
493 494 495 496 497 498
                    *destbuf++ = map_table[bits];
                else
                    *destbuf++ = bits;
            }
            pixels_read++;
        } else {
499
            bits = get_bits1(&gb);
500 501 502
            if (bits == 1) {
                run_length = get_bits(&gb, 3) + 3;
                bits = get_bits(&gb, 2);
503

504 505 506
                if (non_mod == 1 && bits == 1)
                    pixels_read += run_length;
                else {
507
                    if (map_table)
508 509 510 511 512 513 514
                        bits = map_table[bits];
                    while (run_length-- > 0 && pixels_read < dbuf_len) {
                        *destbuf++ = bits;
                        pixels_read++;
                    }
                }
            } else {
515
                bits = get_bits1(&gb);
516 517 518 519 520 521 522 523 524
                if (bits == 0) {
                    bits = get_bits(&gb, 2);
                    if (bits == 2) {
                        run_length = get_bits(&gb, 4) + 12;
                        bits = get_bits(&gb, 2);

                        if (non_mod == 1 && bits == 1)
                            pixels_read += run_length;
                        else {
525
                            if (map_table)
526 527 528 529 530 531 532 533 534 535 536 537 538
                                bits = map_table[bits];
                            while (run_length-- > 0 && pixels_read < dbuf_len) {
                                *destbuf++ = bits;
                                pixels_read++;
                            }
                        }
                    } else if (bits == 3) {
                        run_length = get_bits(&gb, 8) + 29;
                        bits = get_bits(&gb, 2);

                        if (non_mod == 1 && bits == 1)
                            pixels_read += run_length;
                        else {
539
                            if (map_table)
540 541 542 543 544 545 546
                                bits = map_table[bits];
                            while (run_length-- > 0 && pixels_read < dbuf_len) {
                                *destbuf++ = bits;
                                pixels_read++;
                            }
                        }
                    } else if (bits == 1) {
547
                        if (map_table)
548 549 550
                            bits = map_table[0];
                        else
                            bits = 0;
551 552
                        run_length = 2;
                        while (run_length-- > 0 && pixels_read < dbuf_len) {
553
                            *destbuf++ = bits;
554
                            pixels_read++;
555 556 557 558 559 560
                        }
                    } else {
                        (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
                        return pixels_read;
                    }
                } else {
561
                    if (map_table)
562 563 564 565 566 567 568 569 570
                        bits = map_table[0];
                    else
                        bits = 0;
                    *destbuf++ = bits;
                    pixels_read++;
                }
            }
        }
    }
571

572
    if (get_bits(&gb, 6))
573
        av_log(avctx, AV_LOG_ERROR, "line overflow\n");
574 575 576 577 578

    (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;

    return pixels_read;
}
579

580
static int dvbsub_read_4bit_string(AVCodecContext *avctx, uint8_t *destbuf, int dbuf_len,
Michael Niedermayer's avatar
Michael Niedermayer committed
581
                                   const uint8_t **srcbuf, int buf_size,
582
                                   int non_mod, uint8_t *map_table, int x_pos)
583 584
{
    GetBitContext gb;
585

586 587
    int bits;
    int run_length;
588
    int pixels_read = x_pos;
589

590
    init_get_bits(&gb, *srcbuf, buf_size << 3);
591

592 593
    destbuf += x_pos;

594
    while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
595 596
        bits = get_bits(&gb, 4);

597
        if (bits) {
598
            if (non_mod != 1 || bits != 1) {
599
                if (map_table)
600 601 602 603 604 605
                    *destbuf++ = map_table[bits];
                else
                    *destbuf++ = bits;
            }
            pixels_read++;
        } else {
606
            bits = get_bits1(&gb);
607 608
            if (bits == 0) {
                run_length = get_bits(&gb, 3);
609

610 611 612 613
                if (run_length == 0) {
                    (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
                    return pixels_read;
                }
614

615
                run_length += 2;
616

617
                if (map_table)
618 619 620
                    bits = map_table[0];
                else
                    bits = 0;
621

622 623 624 625 626
                while (run_length-- > 0 && pixels_read < dbuf_len) {
                    *destbuf++ = bits;
                    pixels_read++;
                }
            } else {
627
                bits = get_bits1(&gb);
628 629 630 631 632 633 634
                if (bits == 0) {
                    run_length = get_bits(&gb, 2) + 4;
                    bits = get_bits(&gb, 4);

                    if (non_mod == 1 && bits == 1)
                        pixels_read += run_length;
                    else {
635
                        if (map_table)
636 637 638 639 640 641 642 643 644 645 646
                            bits = map_table[bits];
                        while (run_length-- > 0 && pixels_read < dbuf_len) {
                            *destbuf++ = bits;
                            pixels_read++;
                        }
                    }
                } else {
                    bits = get_bits(&gb, 2);
                    if (bits == 2) {
                        run_length = get_bits(&gb, 4) + 9;
                        bits = get_bits(&gb, 4);
647

648 649 650
                        if (non_mod == 1 && bits == 1)
                            pixels_read += run_length;
                        else {
651
                            if (map_table)
652 653 654 655 656 657 658 659 660 661 662 663 664
                                bits = map_table[bits];
                            while (run_length-- > 0 && pixels_read < dbuf_len) {
                                *destbuf++ = bits;
                                pixels_read++;
                            }
                        }
                    } else if (bits == 3) {
                        run_length = get_bits(&gb, 8) + 25;
                        bits = get_bits(&gb, 4);

                        if (non_mod == 1 && bits == 1)
                            pixels_read += run_length;
                        else {
665
                            if (map_table)
666 667 668 669 670 671 672
                                bits = map_table[bits];
                            while (run_length-- > 0 && pixels_read < dbuf_len) {
                                *destbuf++ = bits;
                                pixels_read++;
                            }
                        }
                    } else if (bits == 1) {
673
                        if (map_table)
674 675 676
                            bits = map_table[0];
                        else
                            bits = 0;
677 678
                        run_length = 2;
                        while (run_length-- > 0 && pixels_read < dbuf_len) {
679
                            *destbuf++ = bits;
680
                            pixels_read++;
681 682
                        }
                    } else {
683
                        if (map_table)
684 685 686 687 688 689 690 691 692 693
                            bits = map_table[0];
                        else
                            bits = 0;
                        *destbuf++ = bits;
                        pixels_read ++;
                    }
                }
            }
        }
    }
694

695
    if (get_bits(&gb, 8))
696
        av_log(avctx, AV_LOG_ERROR, "line overflow\n");
697

698 699 700 701
    (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;

    return pixels_read;
}
702

703 704
static int dvbsub_read_8bit_string(AVCodecContext *avctx,
                                   uint8_t *destbuf, int dbuf_len,
Michael Niedermayer's avatar
Michael Niedermayer committed
705
                                    const uint8_t **srcbuf, int buf_size,
706
                                    int non_mod, uint8_t *map_table, int x_pos)
707
{
Michael Niedermayer's avatar
Michael Niedermayer committed
708
    const uint8_t *sbuf_end = (*srcbuf) + buf_size;
709 710
    int bits;
    int run_length;
711 712 713
    int pixels_read = x_pos;

    destbuf += x_pos;
714

715 716
    while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
        bits = *(*srcbuf)++;
717

718
        if (bits) {
719
            if (non_mod != 1 || bits != 1) {
720
                if (map_table)
721 722 723 724 725 726 727 728 729 730 731 732
                    *destbuf++ = map_table[bits];
                else
                    *destbuf++ = bits;
            }
            pixels_read++;
        } else {
            bits = *(*srcbuf)++;
            run_length = bits & 0x7f;
            if ((bits & 0x80) == 0) {
                if (run_length == 0) {
                    return pixels_read;
                }
733

734
                bits = 0;
735 736
            } else {
                bits = *(*srcbuf)++;
737
            }
738 739 740
            if (non_mod == 1 && bits == 1)
                pixels_read += run_length;
            else {
741
                if (map_table)
742
                    bits = map_table[bits];
743 744 745 746 747 748 749
                while (run_length-- > 0 && pixels_read < dbuf_len) {
                    *destbuf++ = bits;
                    pixels_read++;
                }
            }
        }
    }
750

751
    if (*(*srcbuf)++)
752
        av_log(avctx, AV_LOG_ERROR, "line overflow\n");
753

754 755
    return pixels_read;
}
756

757
static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
758 759 760 761 762 763 764 765 766 767
{
    DVBSubContext *ctx = avctx->priv_data;
    DVBSubRegionDisplay *display;
    DVBSubDisplayDefinition *display_def = ctx->display_definition;
    DVBSubRegion *region;
    AVSubtitleRect *rect;
    DVBSubCLUT *clut;
    uint32_t *clut_table;
    int i;
    int offset_x=0, offset_y=0;
768
    int ret = 0;
769 770 771 772 773 774 775


    if (display_def) {
        offset_x = display_def->x;
        offset_y = display_def->y;
    }

776 777 778
    /* Not touching AVSubtitles again*/
    if(sub->num_rects) {
        avpriv_request_sample(ctx, "Different Version of Segment asked Twice\n");
779
        return AVERROR_PATCHWELCOME;
780
    }
781 782 783 784 785 786
    for (display = ctx->display_list; display; display = display->next) {
        region = get_region(ctx, display->region_id);
        if (region && region->dirty)
            sub->num_rects++;
    }

787 788 789 790 791 792 793
    if(ctx->compute_edt == 0) {
        sub->end_display_time = ctx->time_out * 1000;
        *got_output = 1;
    } else if (ctx->prev_start != AV_NOPTS_VALUE) {
        sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1;
        *got_output = 1;
    }
794
    if (sub->num_rects > 0) {
795

796
        sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects);
797 798 799 800
        if (!sub->rects) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }
801

802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841
        for(i=0; i<sub->num_rects; i++)
            sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));

        i = 0;

        for (display = ctx->display_list; display; display = display->next) {
            region = get_region(ctx, display->region_id);

            if (!region)
                continue;

            if (!region->dirty)
                continue;

            rect = sub->rects[i];
            rect->x = display->x_pos + offset_x;
            rect->y = display->y_pos + offset_y;
            rect->w = region->width;
            rect->h = region->height;
            rect->nb_colors = (1 << region->depth);
            rect->type      = SUBTITLE_BITMAP;
            rect->pict.linesize[0] = region->width;

            clut = get_clut(ctx, region->clut);

            if (!clut)
                clut = &default_clut;

            switch (region->depth) {
            case 2:
                clut_table = clut->clut4;
                break;
            case 8:
                clut_table = clut->clut256;
                break;
            case 4:
            default:
                clut_table = clut->clut16;
                break;
            }
842

843
            rect->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
844
            if (!rect->pict.data[1]) {
845 846
                ret = AVERROR(ENOMEM);
                goto fail;
847
            }
848 849 850
            memcpy(rect->pict.data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));

            rect->pict.data[0] = av_malloc(region->buf_size);
851
            if (!rect->pict.data[0]) {
852 853
                ret = AVERROR(ENOMEM);
                goto fail;
854 855
            }

856 857 858 859 860
            memcpy(rect->pict.data[0], region->pbuf, region->buf_size);

            i++;
        }
    }
861 862

    return 0;
863 864 865 866 867 868 869 870 871 872 873 874 875 876
fail:
    if (sub->rects) {
        for(i=0; i<sub->num_rects; i++) {
            rect = sub->rects[i];
            if (rect) {
                av_freep(&rect->pict.data[0]);
                av_freep(&rect->pict.data[1]);
            }
            av_freep(&sub->rects[i]);
        }
        av_freep(&sub->rects);
    }
    sub->num_rects = 0;
    return ret;
877
}
878 879

static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display,
Michael Niedermayer's avatar
Michael Niedermayer committed
880
                                          const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
881
{
882
    DVBSubContext *ctx = avctx->priv_data;
883 884

    DVBSubRegion *region = get_region(ctx, display->region_id);
Michael Niedermayer's avatar
Michael Niedermayer committed
885
    const uint8_t *buf_end = buf + buf_size;
886 887 888
    uint8_t *pbuf;
    int x_pos, y_pos;
    int i;
889

890 891
    uint8_t map2to4[] = { 0x0,  0x7,  0x8,  0xf};
    uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
892
    uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
893 894
                         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
    uint8_t *map_table;
895

896
#if 0
897
    ff_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
898
            top_bottom ? "bottom" : "top");
899

900
    for (i = 0; i < buf_size; i++) {
901
        if (i % 16 == 0)
902
            ff_dlog(avctx, "0x%8p: ", buf+i);
903

904
        ff_dlog(avctx, "%02x ", buf[i]);
905
        if (i % 16 == 15)
906
            ff_dlog(avctx, "\n");
907
    }
908

909
    if (i % 16)
910
        ff_dlog(avctx, "\n");
911
#endif
912

913
    if (!region)
914
        return;
915

916
    pbuf = region->pbuf;
917
    region->dirty = 1;
918

919 920
    x_pos = display->x_pos;
    y_pos = display->y_pos;
921

922
    y_pos += top_bottom;
923 924

    while (buf < buf_end) {
925
        if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) {
926
            av_log(avctx, AV_LOG_ERROR, "Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf);
927 928
            return;
        }
929

930 931 932 933 934 935 936 937
        switch (*buf++) {
        case 0x10:
            if (region->depth == 8)
                map_table = map2to8;
            else if (region->depth == 4)
                map_table = map2to4;
            else
                map_table = NULL;
938

939
            x_pos = dvbsub_read_2bit_string(avctx, pbuf + (y_pos * region->width),
940 941
                                            region->width, &buf, buf_end - buf,
                                            non_mod, map_table, x_pos);
942 943 944 945 946 947
            break;
        case 0x11:
            if (region->depth < 4) {
                av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
                return;
            }
948

949 950 951 952
            if (region->depth == 8)
                map_table = map4to8;
            else
                map_table = NULL;
953

954
            x_pos = dvbsub_read_4bit_string(avctx, pbuf + (y_pos * region->width),
955 956
                                            region->width, &buf, buf_end - buf,
                                            non_mod, map_table, x_pos);
957 958 959 960 961 962
            break;
        case 0x12:
            if (region->depth < 8) {
                av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
                return;
            }
963

964
            x_pos = dvbsub_read_8bit_string(avctx, pbuf + (y_pos * region->width),
965 966
                                            region->width, &buf, buf_end - buf,
                                            non_mod, NULL, x_pos);
967
            break;
968

969 970 971 972 973 974 975 976 977 978 979 980 981 982
        case 0x20:
            map2to4[0] = (*buf) >> 4;
            map2to4[1] = (*buf++) & 0xf;
            map2to4[2] = (*buf) >> 4;
            map2to4[3] = (*buf++) & 0xf;
            break;
        case 0x21:
            for (i = 0; i < 4; i++)
                map2to8[i] = *buf++;
            break;
        case 0x22:
            for (i = 0; i < 16; i++)
                map4to8[i] = *buf++;
            break;
983

984 985 986 987 988 989 990 991
        case 0xf0:
            x_pos = display->x_pos;
            y_pos += 2;
            break;
        default:
            av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
        }
    }
992

993 994
}

995 996
static int dvbsub_parse_object_segment(AVCodecContext *avctx,
                                       const uint8_t *buf, int buf_size)
997
{
998
    DVBSubContext *ctx = avctx->priv_data;
999

Michael Niedermayer's avatar
Michael Niedermayer committed
1000
    const uint8_t *buf_end = buf + buf_size;
1001 1002 1003 1004
    int object_id;
    DVBSubObject *object;
    DVBSubObjectDisplay *display;
    int top_field_len, bottom_field_len;
1005

1006
    int coding_method, non_modifying_color;
1007

1008
    object_id = AV_RB16(buf);
1009
    buf += 2;
1010

1011 1012
    object = get_object(ctx, object_id);

1013
    if (!object)
1014
        return AVERROR_INVALIDDATA;
1015

1016
    coding_method = ((*buf) >> 2) & 3;
1017
    non_modifying_color = ((*buf++) >> 1) & 1;
1018

1019
    if (coding_method == 0) {
1020
        top_field_len = AV_RB16(buf);
1021
        buf += 2;
1022
        bottom_field_len = AV_RB16(buf);
1023
        buf += 2;
1024

1025 1026
        if (buf + top_field_len + bottom_field_len > buf_end) {
            av_log(avctx, AV_LOG_ERROR, "Field data size too large\n");
1027
            return AVERROR_INVALIDDATA;
1028 1029
        }

1030
        for (display = object->display_list; display; display = display->object_list_next) {
1031 1032
            const uint8_t *block = buf;
            int bfl = bottom_field_len;
1033 1034

            dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
1035
                                            non_modifying_color);
1036 1037 1038 1039

            if (bottom_field_len > 0)
                block = buf + top_field_len;
            else
1040
                bfl = top_field_len;
1041

1042
            dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1,
1043
                                            non_modifying_color);
1044
        }
1045

1046
/*  } else if (coding_method == 1) {*/
1047

1048 1049 1050
    } else {
        av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
    }
1051

1052
    return 0;
1053 1054
}

1055
static int dvbsub_parse_clut_segment(AVCodecContext *avctx,
1056
                                     const uint8_t *buf, int buf_size)
1057
{
1058
    DVBSubContext *ctx = avctx->priv_data;
1059

Michael Niedermayer's avatar
Michael Niedermayer committed
1060
    const uint8_t *buf_end = buf + buf_size;
1061
    int i, clut_id;
1062
    int version;
1063 1064 1065 1066 1067
    DVBSubCLUT *clut;
    int entry_id, depth , full_range;
    int y, cr, cb, alpha;
    int r, g, b, r_add, g_add, b_add;

1068
    ff_dlog(avctx, "DVB clut packet:\n");
1069

1070
    for (i=0; i < buf_size; i++) {
1071
        ff_dlog(avctx, "%02x ", buf[i]);
1072
        if (i % 16 == 15)
1073
            ff_dlog(avctx, "\n");
1074
    }
1075

1076
    if (i % 16)
1077
        ff_dlog(avctx, "\n");
1078 1079

    clut_id = *buf++;
1080
    version = ((*buf)>>4)&15;
1081
    buf += 1;
1082

1083
    clut = get_clut(ctx, clut_id);
1084

1085
    if (!clut) {
1086
        clut = av_malloc(sizeof(DVBSubCLUT));
1087 1088
        if (!clut)
            return AVERROR(ENOMEM);
1089

1090 1091 1092
        memcpy(clut, &default_clut, sizeof(DVBSubCLUT));

        clut->id = clut_id;
1093
        clut->version = -1;
1094 1095

        clut->next = ctx->clut_list;
1096 1097
        ctx->clut_list = clut;
    }
1098

1099 1100 1101 1102
    if (clut->version != version) {

    clut->version = version;

1103
    while (buf + 4 < buf_end) {
1104
        entry_id = *buf++;
1105

1106
        depth = (*buf) & 0xe0;
1107

1108 1109
        if (depth == 0) {
            av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
1110
            return AVERROR_INVALIDDATA;
1111
        }
1112

1113
        full_range = (*buf++) & 1;
1114

1115 1116 1117 1118 1119 1120 1121 1122 1123 1124
        if (full_range) {
            y = *buf++;
            cr = *buf++;
            cb = *buf++;
            alpha = *buf++;
        } else {
            y = buf[0] & 0xfc;
            cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
            cb = (buf[1] << 2) & 0xf0;
            alpha = (buf[1] << 6) & 0xc0;
1125

1126 1127
            buf += 2;
        }
1128

1129 1130
        if (y == 0)
            alpha = 0xff;
1131

1132 1133
        YUV_TO_RGB1_CCIR(cb, cr);
        YUV_TO_RGB2_CCIR(r, g, b, y);
1134

1135
        ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
1136
        if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
1137
            ff_dlog(avctx, "More than one bit level marked: %x\n", depth);
1138 1139 1140
            if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL)
                return AVERROR_INVALIDDATA;
        }
1141

1142 1143
        if (depth & 0x80)
            clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
1144
        else if (depth & 0x40)
1145
            clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
1146
        else if (depth & 0x20)
1147 1148
            clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
    }
1149
    }
1150

1151
    return 0;
1152 1153 1154
}


1155
static int dvbsub_parse_region_segment(AVCodecContext *avctx,
1156
                                       const uint8_t *buf, int buf_size)
1157
{
1158
    DVBSubContext *ctx = avctx->priv_data;
1159

Michael Niedermayer's avatar
Michael Niedermayer committed
1160
    const uint8_t *buf_end = buf + buf_size;
1161
    int region_id, object_id;
1162
    int av_unused version;
1163 1164 1165 1166
    DVBSubRegion *region;
    DVBSubObject *object;
    DVBSubObjectDisplay *display;
    int fill;
1167

1168
    if (buf_size < 10)
1169
        return AVERROR_INVALIDDATA;
1170

1171
    region_id = *buf++;
1172

1173
    region = get_region(ctx, region_id);
1174

1175
    if (!region) {
1176
        region = av_mallocz(sizeof(DVBSubRegion));
1177
        if (!region)
1178
            return AVERROR(ENOMEM);
1179

1180
        region->id = region_id;
1181
        region->version = -1;
1182

1183 1184 1185
        region->next = ctx->region_list;
        ctx->region_list = region;
    }
1186

1187
    version = ((*buf)>>4) & 15;
1188
    fill = ((*buf++) >> 3) & 1;
1189

1190
    region->width = AV_RB16(buf);
1191
    buf += 2;
1192
    region->height = AV_RB16(buf);
1193
    buf += 2;
1194

1195
    if (region->width * region->height != region->buf_size) {
1196
        av_free(region->pbuf);
1197

1198
        region->buf_size = region->width * region->height;
1199

1200
        region->pbuf = av_malloc(region->buf_size);
1201 1202 1203 1204
        if (!region->pbuf) {
            region->buf_size =
            region->width =
            region->height = 0;
1205
            return AVERROR(ENOMEM);
1206
        }
1207

1208
        fill = 1;
1209
        region->dirty = 0;
1210
    }
1211

1212
    region->depth = 1 << (((*buf++) >> 2) & 7);
1213 1214 1215 1216
    if(region->depth<2 || region->depth>8){
        av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
        region->depth= 4;
    }
1217
    region->clut = *buf++;
1218

1219
    if (region->depth == 8) {
1220
        region->bgcolor = *buf++;
1221 1222
        buf += 1;
    } else {
1223
        buf += 1;
1224

1225
        if (region->depth == 4)
1226
            region->bgcolor = (((*buf++) >> 4) & 15);
1227
        else
1228
            region->bgcolor = (((*buf++) >> 2) & 3);
1229 1230
    }

1231
    ff_dlog(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
1232 1233

    if (fill) {
1234
        memset(region->pbuf, region->bgcolor, region->buf_size);
1235
        ff_dlog(avctx, "Fill region (%d)\n", region->bgcolor);
1236 1237 1238 1239 1240
    }

    delete_region_display_list(ctx, region);

    while (buf + 5 < buf_end) {
1241
        object_id = AV_RB16(buf);
1242
        buf += 2;
1243

1244 1245
        object = get_object(ctx, object_id);

1246
        if (!object) {
1247
            object = av_mallocz(sizeof(DVBSubObject));
1248 1249
            if (!object)
                return AVERROR(ENOMEM);
1250

1251 1252 1253 1254
            object->id = object_id;
            object->next = ctx->object_list;
            ctx->object_list = object;
        }
1255

1256
        object->type = (*buf) >> 6;
1257

1258
        display = av_mallocz(sizeof(DVBSubObjectDisplay));
1259 1260
        if (!display)
            return AVERROR(ENOMEM);
1261

1262 1263
        display->object_id = object_id;
        display->region_id = region_id;
1264

1265
        display->x_pos = AV_RB16(buf) & 0xfff;
1266
        buf += 2;
1267
        display->y_pos = AV_RB16(buf) & 0xfff;
1268
        buf += 2;
1269

1270
        if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
1271 1272
            display->fgcolor = *buf++;
            display->bgcolor = *buf++;
1273
        }
1274

1275 1276
        display->region_list_next = region->display_list;
        region->display_list = display;
1277

1278 1279 1280
        display->object_list_next = object->display_list;
        object->display_list = display;
    }
1281 1282

    return 0;
1283 1284
}

1285
static int dvbsub_parse_page_segment(AVCodecContext *avctx,
1286
                                     const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
1287
{
1288
    DVBSubContext *ctx = avctx->priv_data;
1289 1290
    DVBSubRegionDisplay *display;
    DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
1291

Michael Niedermayer's avatar
Michael Niedermayer committed
1292
    const uint8_t *buf_end = buf + buf_size;
1293 1294
    int region_id;
    int page_state;
1295 1296
    int timeout;
    int version;
1297

1298
    if (buf_size < 1)
1299
        return AVERROR_INVALIDDATA;
1300

1301 1302
    timeout = *buf++;
    version = ((*buf)>>4) & 15;
1303
    page_state = ((*buf++) >> 2) & 3;
1304

1305
    if (ctx->version == version) {
1306
        return 0;
1307
    }
1308 1309 1310 1311

    ctx->time_out = timeout;
    ctx->version = version;

1312
    ff_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
1313

1314 1315 1316
    if(ctx->compute_edt == 1)
        save_subtitle_set(avctx, sub, got_output);

1317
    if (page_state == 1 || page_state == 2) {
1318 1319 1320
        delete_regions(ctx);
        delete_objects(ctx);
        delete_cluts(ctx);
1321
    }
1322

1323 1324
    tmp_display_list = ctx->display_list;
    ctx->display_list = NULL;
1325

1326 1327 1328
    while (buf + 5 < buf_end) {
        region_id = *buf++;
        buf += 1;
1329

1330 1331
        display = tmp_display_list;
        tmp_ptr = &tmp_display_list;
1332

1333
        while (display && display->region_id != region_id) {
1334 1335 1336
            tmp_ptr = &display->next;
            display = display->next;
        }
1337

1338
        if (!display) {
1339
            display = av_mallocz(sizeof(DVBSubRegionDisplay));
1340 1341 1342
            if (!display)
                return AVERROR(ENOMEM);
        }
1343

1344
        display->region_id = region_id;
1345

1346
        display->x_pos = AV_RB16(buf);
1347
        buf += 2;
1348
        display->y_pos = AV_RB16(buf);
1349
        buf += 2;
1350

1351
        *tmp_ptr = display->next;
1352

1353 1354
        display->next = ctx->display_list;
        ctx->display_list = display;
1355

1356
        ff_dlog(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
1357
    }
1358

1359
    while (tmp_display_list) {
1360
        display = tmp_display_list;
1361

1362
        tmp_display_list = display->next;
1363

1364
        av_freep(&display);
1365
    }
1366

1367
    return 0;
1368 1369 1370
}


1371
#ifdef DEBUG
1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387
static void save_display_set(DVBSubContext *ctx)
{
    DVBSubRegion *region;
    DVBSubRegionDisplay *display;
    DVBSubCLUT *clut;
    uint32_t *clut_table;
    int x_pos, y_pos, width, height;
    int x, y, y_off, x_off;
    uint32_t *pbuf;
    char filename[32];
    static int fileno_index = 0;

    x_pos = -1;
    y_pos = -1;
    width = 0;
    height = 0;
1388

1389
    for (display = ctx->display_list; display; display = display->next) {
1390
        region = get_region(ctx, display->region_id);
1391

1392 1393 1394
        if (!region)
            return;

1395 1396 1397 1398 1399 1400 1401 1402 1403 1404
        if (x_pos == -1) {
            x_pos = display->x_pos;
            y_pos = display->y_pos;
            width = region->width;
            height = region->height;
        } else {
            if (display->x_pos < x_pos) {
                width += (x_pos - display->x_pos);
                x_pos = display->x_pos;
            }
1405

1406 1407 1408 1409
            if (display->y_pos < y_pos) {
                height += (y_pos - display->y_pos);
                y_pos = display->y_pos;
            }
1410

1411 1412 1413
            if (display->x_pos + region->width > x_pos + width) {
                width = display->x_pos + region->width - x_pos;
            }
1414

1415 1416 1417 1418 1419
            if (display->y_pos + region->height > y_pos + height) {
                height = display->y_pos + region->height - y_pos;
            }
        }
    }
1420

1421
    if (x_pos >= 0) {
1422

1423
        pbuf = av_malloc(width * height * 4);
1424
        if (!pbuf)
1425
            return;
1426

1427
        for (display = ctx->display_list; display; display = display->next) {
1428 1429
            region = get_region(ctx, display->region_id);

1430 1431 1432
            if (!region)
                return;

1433 1434 1435 1436 1437
            x_off = display->x_pos - x_pos;
            y_off = display->y_pos - y_pos;

            clut = get_clut(ctx, region->clut);

1438
            if (!clut)
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452
                clut = &default_clut;

            switch (region->depth) {
            case 2:
                clut_table = clut->clut4;
                break;
            case 8:
                clut_table = clut->clut256;
                break;
            case 4:
            default:
                clut_table = clut->clut16;
                break;
            }
1453

1454 1455
            for (y = 0; y < region->height; y++) {
                for (x = 0; x < region->width; x++) {
1456
                    pbuf[((y + y_off) * width) + x_off + x] =
1457 1458 1459 1460
                        clut_table[region->pbuf[y * region->width + x]];
                }
            }

1461
        }
1462

1463
        snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
1464 1465 1466

        png_save2(filename, pbuf, width, height);

1467
        av_freep(&pbuf);
1468
    }
1469

1470 1471 1472 1473
    fileno_index++;
}
#endif

1474
static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx,
1475 1476
                                                   const uint8_t *buf,
                                                   int buf_size)
1477 1478 1479 1480 1481 1482
{
    DVBSubContext *ctx = avctx->priv_data;
    DVBSubDisplayDefinition *display_def = ctx->display_definition;
    int dds_version, info_byte;

    if (buf_size < 5)
1483
        return AVERROR_INVALIDDATA;
1484 1485 1486 1487

    info_byte   = bytestream_get_byte(&buf);
    dds_version = info_byte >> 4;
    if (display_def && display_def->version == dds_version)
1488
        return 0; // already have this display definition version
1489 1490 1491

    if (!display_def) {
        display_def             = av_mallocz(sizeof(*display_def));
1492 1493
        if (!display_def)
            return AVERROR(ENOMEM);
1494 1495 1496 1497 1498 1499 1500 1501
        ctx->display_definition = display_def;
    }

    display_def->version = dds_version;
    display_def->x       = 0;
    display_def->y       = 0;
    display_def->width   = bytestream_get_be16(&buf) + 1;
    display_def->height  = bytestream_get_be16(&buf) + 1;
1502 1503 1504 1505
    if (!avctx->width || !avctx->height) {
        avctx->width  = display_def->width;
        avctx->height = display_def->height;
    }
1506 1507

    if (info_byte & 1<<3) { // display_window_flag
1508 1509 1510
        if (buf_size < 13)
            return AVERROR_INVALIDDATA;

1511 1512
        display_def->x = bytestream_get_be16(&buf);
        display_def->width  = bytestream_get_be16(&buf) - display_def->x + 1;
1513
        display_def->y = bytestream_get_be16(&buf);
1514 1515
        display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
    }
1516 1517

    return 0;
1518 1519
}

Michael Niedermayer's avatar
Michael Niedermayer committed
1520
static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
1521
                                      int buf_size, AVSubtitle *sub,int *got_output)
1522
{
1523
    DVBSubContext *ctx = avctx->priv_data;
1524

1525 1526
    if(ctx->compute_edt == 0)
        save_subtitle_set(avctx, sub, got_output);
1527
#ifdef DEBUG
1528 1529
    save_display_set(ctx);
#endif
1530
    return 0;
1531 1532 1533 1534
}

static int dvbsub_decode(AVCodecContext *avctx,
                         void *data, int *data_size,
1535
                         AVPacket *avpkt)
1536
{
1537 1538
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
1539 1540
    DVBSubContext *ctx = avctx->priv_data;
    AVSubtitle *sub = data;
Michael Niedermayer's avatar
Michael Niedermayer committed
1541
    const uint8_t *p, *p_end;
1542 1543 1544 1545
    int segment_type;
    int page_id;
    int segment_length;
    int i;
1546
    int ret = 0;
1547
    int got_segment = 0;
1548

1549
    ff_dlog(avctx, "DVB sub packet:\n");
1550

1551
    for (i=0; i < buf_size; i++) {
1552
        ff_dlog(avctx, "%02x ", buf[i]);
1553
        if (i % 16 == 15)
1554
            ff_dlog(avctx, "\n");
1555
    }
1556

1557
    if (i % 16)
1558
        ff_dlog(avctx, "\n");
1559

1560
    if (buf_size <= 6 || *buf != 0x0f) {
1561
        ff_dlog(avctx, "incomplete or broken packet");
1562
        return AVERROR_INVALIDDATA;
1563
    }
1564

1565 1566
    p = buf;
    p_end = buf + buf_size;
1567

1568
    while (p_end - p >= 6 && *p == 0x0f) {
1569 1570
        p += 1;
        segment_type = *p++;
1571
        page_id = AV_RB16(p);
1572
        p += 2;
1573
        segment_length = AV_RB16(p);
1574
        p += 2;
1575

1576 1577 1578 1579
        if (avctx->debug & FF_DEBUG_STARTCODE) {
            av_log(avctx, AV_LOG_DEBUG, "segment_type:%d page_id:%d segment_length:%d\n", segment_type, page_id, segment_length);
        }

1580
        if (p_end - p < segment_length) {
1581
            ff_dlog(avctx, "incomplete or broken packet");
1582 1583
            ret = -1;
            goto end;
1584 1585
        }

1586 1587
        if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
            ctx->composition_id == -1 || ctx->ancillary_id == -1) {
1588
            int ret = 0;
1589 1590
            switch (segment_type) {
            case DVBSUB_PAGE_SEGMENT:
1591
                ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size);
1592
                got_segment |= 1;
1593 1594
                break;
            case DVBSUB_REGION_SEGMENT:
1595
                ret = dvbsub_parse_region_segment(avctx, p, segment_length);
1596
                got_segment |= 2;
1597 1598
                break;
            case DVBSUB_CLUT_SEGMENT:
1599
                ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
1600
                if (ret < 0) goto end;
1601
                got_segment |= 4;
1602 1603
                break;
            case DVBSUB_OBJECT_SEGMENT:
1604
                ret = dvbsub_parse_object_segment(avctx, p, segment_length);
1605
                got_segment |= 8;
1606
                break;
1607
            case DVBSUB_DISPLAYDEFINITION_SEGMENT:
1608 1609
                ret = dvbsub_parse_display_definition_segment(avctx, p,
                                                              segment_length);
1610
                break;
1611
            case DVBSUB_DISPLAY_SEGMENT:
1612
                ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size);
1613
                got_segment |= 16;
1614 1615
                break;
            default:
1616
                ff_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
1617 1618 1619
                        segment_type, page_id, segment_length);
                break;
            }
1620
            if (ret < 0)
1621
                goto end;
1622 1623 1624 1625
        }

        p += segment_length;
    }
1626 1627
    // Some streams do not send a display segment but if we have all the other
    // segments then we need no further data.
1628
    if (got_segment == 15) {
1629
        av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n");
1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640
        dvbsub_display_end_segment(avctx, p, 0, sub, data_size);
    }

end:
    if(ret < 0) {
        *data_size = 0;
        avsubtitle_free(sub);
        return ret;
    } else {
        if(ctx->compute_edt == 1 )
            FFSWAP(int64_t, ctx->prev_start, sub->pts);
1641
    }
1642

1643
    return p - buf;
1644 1645
}

1646
#define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
1647
static const AVOption options[] = {
1648
    {"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DS},
1649 1650 1651 1652 1653 1654 1655 1656
    {NULL}
};
static const AVClass dvbsubdec_class = {
    .class_name = "DVB Sub Decoder",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};
1657

1658
AVCodec ff_dvbsub_decoder = {
1659
    .name           = "dvbsub",
1660
    .long_name      = NULL_IF_CONFIG_SMALL("DVB subtitles"),
1661
    .type           = AVMEDIA_TYPE_SUBTITLE,
1662
    .id             = AV_CODEC_ID_DVB_SUBTITLE,
1663 1664 1665 1666
    .priv_data_size = sizeof(DVBSubContext),
    .init           = dvbsub_init_decoder,
    .close          = dvbsub_close_decoder,
    .decode         = dvbsub_decode,
1667
    .priv_class     = &dvbsubdec_class,
1668
};