dvbsubdec.c 44.2 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 "libavutil/colorspace.h"
26
#include "libavutil/opt.h"
27 28 29 30 31

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

35
#define cm (ff_crop_tab + MAX_NEG_CROP)
36

37
#ifdef DEBUG
38 39 40 41 42 43 44 45
#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];
46

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

    f = fopen(fname, "w");
    if (!f) {
        perror(fname);
52
        return;
53 54 55 56 57 58 59 60 61 62 63 64 65 66
    }
    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);
67 68


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

    f = fopen(fname2, "w");
    if (!f) {
        perror(fname2);
74
        return;
75 76 77 78 79 80 81 82 83 84 85 86
    }
    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);
87

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

91 92 93 94 95 96 97 98 99 100 101
    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];
102

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

    f = fopen(fname, "w");
    if (!f) {
        perror(fname);
108
        return;
109 110 111 112 113 114 115 116 117 118 119 120 121 122
    }
    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);
123 124


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

    f = fopen(fname2, "w");
    if (!f) {
        perror(fname2);
130
        return;
131 132 133 134 135 136 137 138 139 140 141 142
    }
    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);
143

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

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

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

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

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

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

static DVBSubCLUT default_clut;

typedef struct DVBSubObjectDisplay {
    int object_id;
    int region_id;

    int x_pos;
    int y_pos;

174 175
    int fgcolor;
    int bgcolor;
176

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

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

    int type;
186 187 188

    DVBSubObjectDisplay *display_list;

189 190 191 192 193 194 195 196 197 198 199 200 201 202
    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;
203
    int version;
204 205 206 207

    int width;
    int height;
    int depth;
208

209
    int clut;
210
    int bgcolor;
211

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

    DVBSubObjectDisplay *display_list;
217

218 219 220
    struct DVBSubRegion *next;
} DVBSubRegion;

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

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

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

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

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


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

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

257 258 259 260 261 262 263
    return ptr;
}

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

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

268 269 270 271 272 273 274
    return ptr;
}

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

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

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

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

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

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

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

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

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

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

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

314
                    *obj2_ptr = obj2->next;
315

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

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

323
        av_freep(&display);
324
    }
325

326 327
}

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

        ctx->clut_list = clut->next;

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

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

        ctx->object_list = object->next;

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

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

        ctx->region_list = region->next;

        delete_region_display_list(ctx, region);

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

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

369 370
    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");
371 372 373
        ctx->composition_id = -1;
        ctx->ancillary_id   = -1;
    } else {
374 375 376 377
        if (avctx->extradata_size > 5) {
            av_log(avctx, AV_LOG_WARNING, "Decoding first DVB subtitles sub-stream\n");
        }

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

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

385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
    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;
403
        }
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
        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;
            }
441
        }
442 443 444 445 446 447
        default_clut.clut256[i] = RGBA(r, g, b, a);
    }

    return 0;
}

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

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

    delete_objects(ctx);

    delete_cluts(ctx);

    av_freep(&ctx->display_definition);
460

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

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

    return 0;
}

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

477 478
    int bits;
    int run_length;
479
    int pixels_read = x_pos;
480

481
    init_get_bits(&gb, *srcbuf, buf_size << 3);
482

483 484
    destbuf += x_pos;

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

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

502 503 504
                if (non_mod == 1 && bits == 1)
                    pixels_read += run_length;
                else {
505
                    if (map_table)
506 507 508 509 510 511 512
                        bits = map_table[bits];
                    while (run_length-- > 0 && pixels_read < dbuf_len) {
                        *destbuf++ = bits;
                        pixels_read++;
                    }
                }
            } else {
513
                bits = get_bits1(&gb);
514 515 516 517 518 519 520 521 522
                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 {
523
                            if (map_table)
524 525 526 527 528 529 530 531 532 533 534 535 536
                                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 {
537
                            if (map_table)
538 539 540 541 542 543 544
                                bits = map_table[bits];
                            while (run_length-- > 0 && pixels_read < dbuf_len) {
                                *destbuf++ = bits;
                                pixels_read++;
                            }
                        }
                    } else if (bits == 1) {
545
                        if (map_table)
546 547 548
                            bits = map_table[0];
                        else
                            bits = 0;
549 550
                        run_length = 2;
                        while (run_length-- > 0 && pixels_read < dbuf_len) {
551
                            *destbuf++ = bits;
552
                            pixels_read++;
553 554 555 556 557 558
                        }
                    } else {
                        (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
                        return pixels_read;
                    }
                } else {
559
                    if (map_table)
560 561 562 563 564 565 566 567 568
                        bits = map_table[0];
                    else
                        bits = 0;
                    *destbuf++ = bits;
                    pixels_read++;
                }
            }
        }
    }
569

570
    if (get_bits(&gb, 6))
571 572 573 574 575 576
        av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");

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

    return pixels_read;
}
577 578

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

584 585
    int bits;
    int run_length;
586
    int pixels_read = x_pos;
587

588
    init_get_bits(&gb, *srcbuf, buf_size << 3);
589

590 591
    destbuf += x_pos;

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

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

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

613
                run_length += 2;
614

615
                if (map_table)
616 617 618
                    bits = map_table[0];
                else
                    bits = 0;
619

620 621 622 623 624
                while (run_length-- > 0 && pixels_read < dbuf_len) {
                    *destbuf++ = bits;
                    pixels_read++;
                }
            } else {
625
                bits = get_bits1(&gb);
626 627 628 629 630 631 632
                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 {
633
                        if (map_table)
634 635 636 637 638 639 640 641 642 643 644
                            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);
645

646 647 648
                        if (non_mod == 1 && bits == 1)
                            pixels_read += run_length;
                        else {
649
                            if (map_table)
650 651 652 653 654 655 656 657 658 659 660 661 662
                                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 {
663
                            if (map_table)
664 665 666 667 668 669 670
                                bits = map_table[bits];
                            while (run_length-- > 0 && pixels_read < dbuf_len) {
                                *destbuf++ = bits;
                                pixels_read++;
                            }
                        }
                    } else if (bits == 1) {
671
                        if (map_table)
672 673 674
                            bits = map_table[0];
                        else
                            bits = 0;
675 676
                        run_length = 2;
                        while (run_length-- > 0 && pixels_read < dbuf_len) {
677
                            *destbuf++ = bits;
678
                            pixels_read++;
679 680
                        }
                    } else {
681
                        if (map_table)
682 683 684 685 686 687 688 689 690 691
                            bits = map_table[0];
                        else
                            bits = 0;
                        *destbuf++ = bits;
                        pixels_read ++;
                    }
                }
            }
        }
    }
692

693
    if (get_bits(&gb, 8))
694
        av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
695

696 697 698 699
    (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;

    return pixels_read;
}
700 701

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

    destbuf += x_pos;
711

712 713
    while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
        bits = *(*srcbuf)++;
714

715
        if (bits) {
716
            if (non_mod != 1 || bits != 1) {
717
                if (map_table)
718 719 720 721 722 723 724 725 726 727 728 729
                    *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;
                }
730

731
                if (map_table)
732 733 734 735 736 737 738 739 740 741 742 743
                    bits = map_table[0];
                else
                    bits = 0;
                while (run_length-- > 0 && pixels_read < dbuf_len) {
                    *destbuf++ = bits;
                    pixels_read++;
                }
            } else {
                bits = *(*srcbuf)++;

                if (non_mod == 1 && bits == 1)
                    pixels_read += run_length;
744
                if (map_table)
745 746 747 748 749 750 751 752
                    bits = map_table[bits];
                else while (run_length-- > 0 && pixels_read < dbuf_len) {
                    *destbuf++ = bits;
                    pixels_read++;
                }
            }
        }
    }
753

754
    if (*(*srcbuf)++)
755
        av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
756

757 758
    return pixels_read;
}
759

760
static void save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
{
    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;


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

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

789 790 791 792 793 794 795
    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;
    }
796
    if (sub->num_rects > 0) {
797

798 799 800 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
        sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects);
        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;
            }
839

840 841 842 843 844 845 846 847 848 849
            rect->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
            memcpy(rect->pict.data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));

            rect->pict.data[0] = av_malloc(region->buf_size);
            memcpy(rect->pict.data[0], region->pbuf, region->buf_size);

            i++;
        }
    }
}
850 851

static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display,
Michael Niedermayer's avatar
Michael Niedermayer committed
852
                                          const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
853
{
854
    DVBSubContext *ctx = avctx->priv_data;
855 856

    DVBSubRegion *region = get_region(ctx, display->region_id);
Michael Niedermayer's avatar
Michael Niedermayer committed
857
    const uint8_t *buf_end = buf + buf_size;
858 859 860
    uint8_t *pbuf;
    int x_pos, y_pos;
    int i;
861

862 863
    uint8_t map2to4[] = { 0x0,  0x7,  0x8,  0xf};
    uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
864
    uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
865 866
                         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
    uint8_t *map_table;
867

868
#if 0
869
    av_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
870
            top_bottom ? "bottom" : "top");
871

872
    for (i = 0; i < buf_size; i++) {
873
        if (i % 16 == 0)
874
            av_dlog(avctx, "0x%8p: ", buf+i);
875

876
        av_dlog(avctx, "%02x ", buf[i]);
877
        if (i % 16 == 15)
878
            av_dlog(avctx, "\n");
879
    }
880

881
    if (i % 16)
882
        av_dlog(avctx, "\n");
883
#endif
884

885
    if (!region)
886
        return;
887

888
    pbuf = region->pbuf;
889
    region->dirty = 1;
890

891 892
    x_pos = display->x_pos;
    y_pos = display->y_pos;
893

894
    y_pos += top_bottom;
895 896

    while (buf < buf_end) {
897
        if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) {
898
            av_log(avctx, AV_LOG_ERROR, "Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf);
899 900
            return;
        }
901

902 903 904 905 906 907 908 909
        switch (*buf++) {
        case 0x10:
            if (region->depth == 8)
                map_table = map2to8;
            else if (region->depth == 4)
                map_table = map2to4;
            else
                map_table = NULL;
910

911 912 913
            x_pos = dvbsub_read_2bit_string(pbuf + (y_pos * region->width),
                                            region->width, &buf, buf_end - buf,
                                            non_mod, map_table, x_pos);
914 915 916 917 918 919
            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;
            }
920

921 922 923 924
            if (region->depth == 8)
                map_table = map4to8;
            else
                map_table = NULL;
925

926 927 928
            x_pos = dvbsub_read_4bit_string(pbuf + (y_pos * region->width),
                                            region->width, &buf, buf_end - buf,
                                            non_mod, map_table, x_pos);
929 930 931 932 933 934
            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;
            }
935

936 937 938
            x_pos = dvbsub_read_8bit_string(pbuf + (y_pos * region->width),
                                            region->width, &buf, buf_end - buf,
                                            non_mod, NULL, x_pos);
939
            break;
940

941 942 943 944 945 946 947 948 949 950 951 952 953 954
        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;
955

956 957 958 959 960 961 962 963
        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));
        }
    }
964

965 966 967
}

static void dvbsub_parse_object_segment(AVCodecContext *avctx,
Michael Niedermayer's avatar
Michael Niedermayer committed
968
                                        const uint8_t *buf, int buf_size)
969
{
970
    DVBSubContext *ctx = avctx->priv_data;
971

Michael Niedermayer's avatar
Michael Niedermayer committed
972
    const uint8_t *buf_end = buf + buf_size;
973 974 975 976
    int object_id;
    DVBSubObject *object;
    DVBSubObjectDisplay *display;
    int top_field_len, bottom_field_len;
977

978
    int coding_method, non_modifying_color;
979

980
    object_id = AV_RB16(buf);
981
    buf += 2;
982

983 984
    object = get_object(ctx, object_id);

985 986 987
    if (!object)
        return;

988
    coding_method = ((*buf) >> 2) & 3;
989
    non_modifying_color = ((*buf++) >> 1) & 1;
990

991
    if (coding_method == 0) {
992
        top_field_len = AV_RB16(buf);
993
        buf += 2;
994
        bottom_field_len = AV_RB16(buf);
995
        buf += 2;
996

997 998 999
        if (buf + top_field_len + bottom_field_len > buf_end) {
            av_log(avctx, AV_LOG_ERROR, "Field data size too large\n");
            return;
1000 1001
        }

1002
        for (display = object->display_list; display; display = display->object_list_next) {
1003 1004
            const uint8_t *block = buf;
            int bfl = bottom_field_len;
1005 1006

            dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
1007
                                            non_modifying_color);
1008 1009 1010 1011

            if (bottom_field_len > 0)
                block = buf + top_field_len;
            else
1012
                bfl = top_field_len;
1013

1014
            dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1,
1015
                                            non_modifying_color);
1016
        }
1017

1018
/*  } else if (coding_method == 1) {*/
1019

1020 1021 1022
    } else {
        av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
    }
1023

1024 1025
}

1026
static int dvbsub_parse_clut_segment(AVCodecContext *avctx,
Michael Niedermayer's avatar
Michael Niedermayer committed
1027
                                        const uint8_t *buf, int buf_size)
1028
{
1029
    DVBSubContext *ctx = avctx->priv_data;
1030

Michael Niedermayer's avatar
Michael Niedermayer committed
1031
    const uint8_t *buf_end = buf + buf_size;
1032
    int i, clut_id;
1033
    int version;
1034 1035 1036 1037 1038
    DVBSubCLUT *clut;
    int entry_id, depth , full_range;
    int y, cr, cb, alpha;
    int r, g, b, r_add, g_add, b_add;

1039
    av_dlog(avctx, "DVB clut packet:\n");
1040

1041
    for (i=0; i < buf_size; i++) {
1042
        av_dlog(avctx, "%02x ", buf[i]);
1043
        if (i % 16 == 15)
1044
            av_dlog(avctx, "\n");
1045
    }
1046

1047
    if (i % 16)
1048
        av_dlog(avctx, "\n");
1049 1050

    clut_id = *buf++;
1051
    version = ((*buf)>>4)&15;
1052
    buf += 1;
1053

1054
    clut = get_clut(ctx, clut_id);
1055

1056
    if (!clut) {
1057
        clut = av_malloc(sizeof(DVBSubCLUT));
1058

1059 1060 1061
        memcpy(clut, &default_clut, sizeof(DVBSubCLUT));

        clut->id = clut_id;
1062
        clut->version = -1;
1063 1064

        clut->next = ctx->clut_list;
1065 1066
        ctx->clut_list = clut;
    }
1067

1068 1069 1070 1071
    if (clut->version != version) {

    clut->version = version;

1072
    while (buf + 4 < buf_end) {
1073
        entry_id = *buf++;
1074

1075
        depth = (*buf) & 0xe0;
1076

1077 1078
        if (depth == 0) {
            av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
1079
            return 0;
1080
        }
1081

1082
        full_range = (*buf++) & 1;
1083

1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
        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;
1094

1095 1096
            buf += 2;
        }
1097

1098 1099
        if (y == 0)
            alpha = 0xff;
1100

1101 1102
        YUV_TO_RGB1_CCIR(cb, cr);
        YUV_TO_RGB2_CCIR(r, g, b, y);
1103

1104
        av_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
1105 1106 1107 1108 1109
        if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
            av_dlog(avctx, "More than one bit level marked: %x\n", depth);
            if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL)
                return AVERROR_INVALIDDATA;
        }
1110

1111 1112
        if (depth & 0x80)
            clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
1113
        else if (depth & 0x40)
1114
            clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
1115
        else if (depth & 0x20)
1116 1117
            clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
    }
1118
    }
1119
    return 0;
1120 1121 1122 1123
}


static void dvbsub_parse_region_segment(AVCodecContext *avctx,
Michael Niedermayer's avatar
Michael Niedermayer committed
1124
                                        const uint8_t *buf, int buf_size)
1125
{
1126
    DVBSubContext *ctx = avctx->priv_data;
1127

Michael Niedermayer's avatar
Michael Niedermayer committed
1128
    const uint8_t *buf_end = buf + buf_size;
1129
    int region_id, object_id;
1130
    int av_unused version;
1131 1132 1133 1134
    DVBSubRegion *region;
    DVBSubObject *object;
    DVBSubObjectDisplay *display;
    int fill;
1135

1136 1137
    if (buf_size < 10)
        return;
1138

1139
    region_id = *buf++;
1140

1141
    region = get_region(ctx, region_id);
1142

1143
    if (!region) {
1144
        region = av_mallocz(sizeof(DVBSubRegion));
1145

1146
        region->id = region_id;
1147
        region->version = -1;
1148

1149 1150 1151
        region->next = ctx->region_list;
        ctx->region_list = region;
    }
1152

1153
    version = ((*buf)>>4) & 15;
1154
    fill = ((*buf++) >> 3) & 1;
1155

1156
    region->width = AV_RB16(buf);
1157
    buf += 2;
1158
    region->height = AV_RB16(buf);
1159
    buf += 2;
1160

1161
    if (region->width * region->height != region->buf_size) {
1162
        av_free(region->pbuf);
1163

1164
        region->buf_size = region->width * region->height;
1165

1166
        region->pbuf = av_malloc(region->buf_size);
1167

1168
        fill = 1;
1169
        region->dirty = 0;
1170
    }
1171

1172
    region->depth = 1 << (((*buf++) >> 2) & 7);
1173 1174 1175 1176
    if(region->depth<2 || region->depth>8){
        av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
        region->depth= 4;
    }
1177
    region->clut = *buf++;
1178

1179
    if (region->depth == 8) {
1180
        region->bgcolor = *buf++;
1181 1182
        buf += 1;
    } else {
1183
        buf += 1;
1184

1185
        if (region->depth == 4)
1186
            region->bgcolor = (((*buf++) >> 4) & 15);
1187
        else
1188
            region->bgcolor = (((*buf++) >> 2) & 3);
1189 1190
    }

1191
    av_dlog(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
1192 1193

    if (fill) {
1194
        memset(region->pbuf, region->bgcolor, region->buf_size);
1195
        av_dlog(avctx, "Fill region (%d)\n", region->bgcolor);
1196 1197 1198 1199 1200
    }

    delete_region_display_list(ctx, region);

    while (buf + 5 < buf_end) {
1201
        object_id = AV_RB16(buf);
1202
        buf += 2;
1203

1204 1205
        object = get_object(ctx, object_id);

1206
        if (!object) {
1207
            object = av_mallocz(sizeof(DVBSubObject));
1208

1209 1210 1211 1212
            object->id = object_id;
            object->next = ctx->object_list;
            ctx->object_list = object;
        }
1213

1214
        object->type = (*buf) >> 6;
1215

1216
        display = av_mallocz(sizeof(DVBSubObjectDisplay));
1217

1218 1219
        display->object_id = object_id;
        display->region_id = region_id;
1220

1221
        display->x_pos = AV_RB16(buf) & 0xfff;
1222
        buf += 2;
1223
        display->y_pos = AV_RB16(buf) & 0xfff;
1224
        buf += 2;
1225

1226
        if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
1227 1228
            display->fgcolor = *buf++;
            display->bgcolor = *buf++;
1229
        }
1230

1231 1232
        display->region_list_next = region->display_list;
        region->display_list = display;
1233

1234 1235 1236 1237 1238 1239
        display->object_list_next = object->display_list;
        object->display_list = display;
    }
}

static void dvbsub_parse_page_segment(AVCodecContext *avctx,
1240
                                        const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
1241
{
1242
    DVBSubContext *ctx = avctx->priv_data;
1243 1244
    DVBSubRegionDisplay *display;
    DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
1245

Michael Niedermayer's avatar
Michael Niedermayer committed
1246
    const uint8_t *buf_end = buf + buf_size;
1247 1248
    int region_id;
    int page_state;
1249 1250
    int timeout;
    int version;
1251

1252 1253
    if (buf_size < 1)
        return;
1254

1255 1256
    timeout = *buf++;
    version = ((*buf)>>4) & 15;
1257
    page_state = ((*buf++) >> 2) & 3;
1258

1259 1260 1261
    if (ctx->version == version) {
        return;
    }
1262 1263 1264 1265

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

1266
    av_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
1267

1268 1269 1270
    if(ctx->compute_edt == 1)
        save_subtitle_set(avctx, sub, got_output);

1271
    if (page_state == 1 || page_state == 2) {
1272 1273 1274
        delete_regions(ctx);
        delete_objects(ctx);
        delete_cluts(ctx);
1275
    }
1276

1277 1278
    tmp_display_list = ctx->display_list;
    ctx->display_list = NULL;
1279

1280 1281 1282
    while (buf + 5 < buf_end) {
        region_id = *buf++;
        buf += 1;
1283

1284 1285
        display = tmp_display_list;
        tmp_ptr = &tmp_display_list;
1286

1287
        while (display && display->region_id != region_id) {
1288 1289 1290
            tmp_ptr = &display->next;
            display = display->next;
        }
1291

1292
        if (!display)
1293
            display = av_mallocz(sizeof(DVBSubRegionDisplay));
1294

1295
        display->region_id = region_id;
1296

1297
        display->x_pos = AV_RB16(buf);
1298
        buf += 2;
1299
        display->y_pos = AV_RB16(buf);
1300
        buf += 2;
1301

1302
        *tmp_ptr = display->next;
1303

1304 1305
        display->next = ctx->display_list;
        ctx->display_list = display;
1306

1307
        av_dlog(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
1308
    }
1309

1310
    while (tmp_display_list) {
1311
        display = tmp_display_list;
1312

1313
        tmp_display_list = display->next;
1314

1315
        av_freep(&display);
1316
    }
1317

1318 1319 1320
}


1321
#ifdef DEBUG
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
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;
1338

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

1342 1343 1344 1345 1346 1347 1348 1349 1350 1351
        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;
            }
1352

1353 1354 1355 1356
            if (display->y_pos < y_pos) {
                height += (y_pos - display->y_pos);
                y_pos = display->y_pos;
            }
1357

1358 1359 1360
            if (display->x_pos + region->width > x_pos + width) {
                width = display->x_pos + region->width - x_pos;
            }
1361

1362 1363 1364 1365 1366
            if (display->y_pos + region->height > y_pos + height) {
                height = display->y_pos + region->height - y_pos;
            }
        }
    }
1367

1368
    if (x_pos >= 0) {
1369

1370 1371
        pbuf = av_malloc(width * height * 4);

1372
        for (display = ctx->display_list; display; display = display->next) {
1373 1374 1375 1376 1377 1378 1379
            region = get_region(ctx, display->region_id);

            x_off = display->x_pos - x_pos;
            y_off = display->y_pos - y_pos;

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

1380
            if (!clut)
1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394
                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;
            }
1395

1396 1397
            for (y = 0; y < region->height; y++) {
                for (x = 0; x < region->width; x++) {
1398
                    pbuf[((y + y_off) * width) + x_off + x] =
1399 1400 1401 1402
                        clut_table[region->pbuf[y * region->width + x]];
                }
            }

1403
        }
1404

1405
        snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
1406 1407 1408

        png_save2(filename, pbuf, width, height);

1409
        av_freep(&pbuf);
1410
    }
1411

1412 1413 1414 1415
    fileno_index++;
}
#endif

1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443
static void dvbsub_parse_display_definition_segment(AVCodecContext *avctx,
                                                    const uint8_t *buf,
                                                    int buf_size)
{
    DVBSubContext *ctx = avctx->priv_data;
    DVBSubDisplayDefinition *display_def = ctx->display_definition;
    int dds_version, info_byte;

    if (buf_size < 5)
        return;

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

    if (!display_def) {
        display_def             = av_mallocz(sizeof(*display_def));
        ctx->display_definition = display_def;
    }
    if (!display_def)
        return;

    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;
1444 1445 1446 1447
    if (!avctx->width || !avctx->height) {
        avctx->width  = display_def->width;
        avctx->height = display_def->height;
    }
1448 1449 1450 1451 1452 1453 1454

    if (buf_size < 13)
        return;

    if (info_byte & 1<<3) { // display_window_flag
        display_def->x = bytestream_get_be16(&buf);
        display_def->width  = bytestream_get_be16(&buf) - display_def->x + 1;
1455
        display_def->y = bytestream_get_be16(&buf);
1456 1457 1458 1459
        display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
    }
}

1460 1461
static void dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
                                        int buf_size, AVSubtitle *sub,int *got_output)
1462
{
1463
    DVBSubContext *ctx = avctx->priv_data;
1464

1465 1466
    if(ctx->compute_edt == 0)
        save_subtitle_set(avctx, sub, got_output);
1467
#ifdef DEBUG
1468 1469
    save_display_set(ctx);
#endif
1470

1471 1472 1473 1474
}

static int dvbsub_decode(AVCodecContext *avctx,
                         void *data, int *data_size,
1475
                         AVPacket *avpkt)
1476
{
1477 1478
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
1479 1480
    DVBSubContext *ctx = avctx->priv_data;
    AVSubtitle *sub = data;
Michael Niedermayer's avatar
Michael Niedermayer committed
1481
    const uint8_t *p, *p_end;
1482 1483 1484 1485
    int segment_type;
    int page_id;
    int segment_length;
    int i;
1486
    int ret = 0;
1487
    int got_segment = 0;
1488

1489
    av_dlog(avctx, "DVB sub packet:\n");
1490

1491
    for (i=0; i < buf_size; i++) {
1492
        av_dlog(avctx, "%02x ", buf[i]);
1493
        if (i % 16 == 15)
1494
            av_dlog(avctx, "\n");
1495
    }
1496

1497
    if (i % 16)
1498
        av_dlog(avctx, "\n");
1499

1500 1501
    if (buf_size <= 6 || *buf != 0x0f) {
        av_dlog(avctx, "incomplete or broken packet");
1502
        return -1;
1503
    }
1504

1505 1506
    p = buf;
    p_end = buf + buf_size;
1507

1508
    while (p_end - p >= 6 && *p == 0x0f) {
1509 1510
        p += 1;
        segment_type = *p++;
1511
        page_id = AV_RB16(p);
1512
        p += 2;
1513
        segment_length = AV_RB16(p);
1514
        p += 2;
1515

1516 1517 1518 1519
        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);
        }

1520 1521
        if (p_end - p < segment_length) {
            av_dlog(avctx, "incomplete or broken packet");
1522 1523
            ret = -1;
            goto end;
1524 1525
        }

1526 1527
        if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
            ctx->composition_id == -1 || ctx->ancillary_id == -1) {
1528 1529
            switch (segment_type) {
            case DVBSUB_PAGE_SEGMENT:
1530
                dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size);
1531
                got_segment |= 1;
1532 1533 1534
                break;
            case DVBSUB_REGION_SEGMENT:
                dvbsub_parse_region_segment(avctx, p, segment_length);
1535
                got_segment |= 2;
1536 1537
                break;
            case DVBSUB_CLUT_SEGMENT:
1538
                ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
1539
                if (ret < 0) goto end;
1540
                got_segment |= 4;
1541 1542 1543
                break;
            case DVBSUB_OBJECT_SEGMENT:
                dvbsub_parse_object_segment(avctx, p, segment_length);
1544
                got_segment |= 8;
1545
                break;
1546 1547
            case DVBSUB_DISPLAYDEFINITION_SEGMENT:
                dvbsub_parse_display_definition_segment(avctx, p, segment_length);
1548
                break;
1549
            case DVBSUB_DISPLAY_SEGMENT:
1550
                dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size);
1551
                got_segment |= 16;
1552 1553
                break;
            default:
1554
                av_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
1555 1556 1557 1558 1559 1560 1561
                        segment_type, page_id, segment_length);
                break;
            }
        }

        p += segment_length;
    }
1562 1563
    // Some streams do not send a display segment but if we have all the other
    // segments then we need no further data.
1564
    if (got_segment == 15) {
1565
        av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n");
1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576
        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);
1577
    }
1578

1579
    return p - buf;
1580 1581
}

1582
#define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
1583
static const AVOption options[] = {
1584
    {"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DS},
1585 1586 1587 1588 1589 1590 1591 1592
    {NULL}
};
static const AVClass dvbsubdec_class = {
    .class_name = "DVB Sub Decoder",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};
1593

1594
AVCodec ff_dvbsub_decoder = {
1595
    .name           = "dvbsub",
1596
    .long_name      = NULL_IF_CONFIG_SMALL("DVB subtitles"),
1597
    .type           = AVMEDIA_TYPE_SUBTITLE,
1598
    .id             = AV_CODEC_ID_DVB_SUBTITLE,
1599 1600 1601 1602
    .priv_data_size = sizeof(DVBSubContext),
    .init           = dvbsub_init_decoder,
    .close          = dvbsub_close_decoder,
    .decode         = dvbsub_decode,
1603
    .priv_class     = &dvbsubdec_class,
1604
};