00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avcodec.h"
00022 #include "dsputil.h"
00023 #include "bitstream.h"
00024 #include "colorspace.h"
00025
00026
00027
00028
00029
00030 #define DVBSUB_PAGE_SEGMENT 0x10
00031 #define DVBSUB_REGION_SEGMENT 0x11
00032 #define DVBSUB_CLUT_SEGMENT 0x12
00033 #define DVBSUB_OBJECT_SEGMENT 0x13
00034 #define DVBSUB_DISPLAY_SEGMENT 0x80
00035
00036 #define cm (ff_cropTbl + MAX_NEG_CROP)
00037
00038 #ifdef DEBUG_SAVE_IMAGES
00039 #undef fprintf
00040 #if 0
00041 static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
00042 uint32_t *rgba_palette)
00043 {
00044 int x, y, v;
00045 FILE *f;
00046 char fname[40], fname2[40];
00047 char command[1024];
00048
00049 snprintf(fname, 40, "%s.ppm", filename);
00050
00051 f = fopen(fname, "w");
00052 if (!f) {
00053 perror(fname);
00054 exit(1);
00055 }
00056 fprintf(f, "P6\n"
00057 "%d %d\n"
00058 "%d\n",
00059 w, h, 255);
00060 for(y = 0; y < h; y++) {
00061 for(x = 0; x < w; x++) {
00062 v = rgba_palette[bitmap[y * w + x]];
00063 putc((v >> 16) & 0xff, f);
00064 putc((v >> 8) & 0xff, f);
00065 putc((v >> 0) & 0xff, f);
00066 }
00067 }
00068 fclose(f);
00069
00070
00071 snprintf(fname2, 40, "%s-a.pgm", filename);
00072
00073 f = fopen(fname2, "w");
00074 if (!f) {
00075 perror(fname2);
00076 exit(1);
00077 }
00078 fprintf(f, "P5\n"
00079 "%d %d\n"
00080 "%d\n",
00081 w, h, 255);
00082 for(y = 0; y < h; y++) {
00083 for(x = 0; x < w; x++) {
00084 v = rgba_palette[bitmap[y * w + x]];
00085 putc((v >> 24) & 0xff, f);
00086 }
00087 }
00088 fclose(f);
00089
00090 snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
00091 system(command);
00092
00093 snprintf(command, 1024, "rm %s %s", fname, fname2);
00094 system(command);
00095 }
00096 #endif
00097
00098 static void png_save2(const char *filename, uint32_t *bitmap, int w, int h)
00099 {
00100 int x, y, v;
00101 FILE *f;
00102 char fname[40], fname2[40];
00103 char command[1024];
00104
00105 snprintf(fname, sizeof(fname), "%s.ppm", filename);
00106
00107 f = fopen(fname, "w");
00108 if (!f) {
00109 perror(fname);
00110 exit(1);
00111 }
00112 fprintf(f, "P6\n"
00113 "%d %d\n"
00114 "%d\n",
00115 w, h, 255);
00116 for(y = 0; y < h; y++) {
00117 for(x = 0; x < w; x++) {
00118 v = bitmap[y * w + x];
00119 putc((v >> 16) & 0xff, f);
00120 putc((v >> 8) & 0xff, f);
00121 putc((v >> 0) & 0xff, f);
00122 }
00123 }
00124 fclose(f);
00125
00126
00127 snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename);
00128
00129 f = fopen(fname2, "w");
00130 if (!f) {
00131 perror(fname2);
00132 exit(1);
00133 }
00134 fprintf(f, "P5\n"
00135 "%d %d\n"
00136 "%d\n",
00137 w, h, 255);
00138 for(y = 0; y < h; y++) {
00139 for(x = 0; x < w; x++) {
00140 v = bitmap[y * w + x];
00141 putc((v >> 24) & 0xff, f);
00142 }
00143 }
00144 fclose(f);
00145
00146 snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
00147 system(command);
00148
00149 snprintf(command, sizeof(command), "rm %s %s", fname, fname2);
00150 system(command);
00151 }
00152 #endif
00153
00154 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
00155
00156 typedef struct DVBSubCLUT {
00157 int id;
00158
00159 uint32_t clut4[4];
00160 uint32_t clut16[16];
00161 uint32_t clut256[256];
00162
00163 struct DVBSubCLUT *next;
00164 } DVBSubCLUT;
00165
00166 static DVBSubCLUT default_clut;
00167
00168 typedef struct DVBSubObjectDisplay {
00169 int object_id;
00170 int region_id;
00171
00172 int x_pos;
00173 int y_pos;
00174
00175 int fgcolor;
00176 int bgcolor;
00177
00178 struct DVBSubObjectDisplay *region_list_next;
00179 struct DVBSubObjectDisplay *object_list_next;
00180 } DVBSubObjectDisplay;
00181
00182 typedef struct DVBSubObject {
00183 int id;
00184
00185 int type;
00186
00187 DVBSubObjectDisplay *display_list;
00188
00189 struct DVBSubObject *next;
00190 } DVBSubObject;
00191
00192 typedef struct DVBSubRegionDisplay {
00193 int region_id;
00194
00195 int x_pos;
00196 int y_pos;
00197
00198 struct DVBSubRegionDisplay *next;
00199 } DVBSubRegionDisplay;
00200
00201 typedef struct DVBSubRegion {
00202 int id;
00203
00204 int width;
00205 int height;
00206 int depth;
00207
00208 int clut;
00209 int bgcolor;
00210
00211 uint8_t *pbuf;
00212 int buf_size;
00213
00214 DVBSubObjectDisplay *display_list;
00215
00216 struct DVBSubRegion *next;
00217 } DVBSubRegion;
00218
00219 typedef struct DVBSubContext {
00220 int composition_id;
00221 int ancillary_id;
00222
00223 int time_out;
00224 DVBSubRegion *region_list;
00225 DVBSubCLUT *clut_list;
00226 DVBSubObject *object_list;
00227
00228 int display_list_size;
00229 DVBSubRegionDisplay *display_list;
00230 } DVBSubContext;
00231
00232
00233 static DVBSubObject* get_object(DVBSubContext *ctx, int object_id)
00234 {
00235 DVBSubObject *ptr = ctx->object_list;
00236
00237 while (ptr && ptr->id != object_id) {
00238 ptr = ptr->next;
00239 }
00240
00241 return ptr;
00242 }
00243
00244 static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id)
00245 {
00246 DVBSubCLUT *ptr = ctx->clut_list;
00247
00248 while (ptr && ptr->id != clut_id) {
00249 ptr = ptr->next;
00250 }
00251
00252 return ptr;
00253 }
00254
00255 static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id)
00256 {
00257 DVBSubRegion *ptr = ctx->region_list;
00258
00259 while (ptr && ptr->id != region_id) {
00260 ptr = ptr->next;
00261 }
00262
00263 return ptr;
00264 }
00265
00266 static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region)
00267 {
00268 DVBSubObject *object, *obj2, **obj2_ptr;
00269 DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;
00270
00271 while (region->display_list) {
00272 display = region->display_list;
00273
00274 object = get_object(ctx, display->object_id);
00275
00276 if (object) {
00277 obj_disp = object->display_list;
00278 obj_disp_ptr = &object->display_list;
00279
00280 while (obj_disp && obj_disp != display) {
00281 obj_disp_ptr = &obj_disp->object_list_next;
00282 obj_disp = obj_disp->object_list_next;
00283 }
00284
00285 if (obj_disp) {
00286 *obj_disp_ptr = obj_disp->object_list_next;
00287
00288 if (!object->display_list) {
00289 obj2 = ctx->object_list;
00290 obj2_ptr = &ctx->object_list;
00291
00292 while (obj2 && obj2 != object) {
00293 obj2_ptr = &obj2->next;
00294 obj2 = obj2->next;
00295 }
00296
00297 *obj2_ptr = obj2->next;
00298
00299 av_free(obj2);
00300 }
00301 }
00302 }
00303
00304 region->display_list = display->region_list_next;
00305
00306 av_free(display);
00307 }
00308
00309 }
00310
00311 static void delete_state(DVBSubContext *ctx)
00312 {
00313 DVBSubRegion *region;
00314 DVBSubCLUT *clut;
00315
00316 while (ctx->region_list) {
00317 region = ctx->region_list;
00318
00319 ctx->region_list = region->next;
00320
00321 delete_region_display_list(ctx, region);
00322 if (region->pbuf)
00323 av_free(region->pbuf);
00324
00325 av_free(region);
00326 }
00327
00328 while (ctx->clut_list) {
00329 clut = ctx->clut_list;
00330
00331 ctx->clut_list = clut->next;
00332
00333 av_free(clut);
00334 }
00335
00336
00337 if (ctx->object_list)
00338 av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n");
00339 }
00340
00341 static int dvbsub_init_decoder(AVCodecContext *avctx)
00342 {
00343 int i, r, g, b, a = 0;
00344 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00345
00346 memset(avctx->priv_data, 0, sizeof(DVBSubContext));
00347
00348 ctx->composition_id = avctx->sub_id & 0xffff;
00349 ctx->ancillary_id = avctx->sub_id >> 16;
00350
00351 default_clut.id = -1;
00352 default_clut.next = NULL;
00353
00354 default_clut.clut4[0] = RGBA( 0, 0, 0, 0);
00355 default_clut.clut4[1] = RGBA(255, 255, 255, 255);
00356 default_clut.clut4[2] = RGBA( 0, 0, 0, 255);
00357 default_clut.clut4[3] = RGBA(127, 127, 127, 255);
00358
00359 default_clut.clut16[0] = RGBA( 0, 0, 0, 0);
00360 for (i = 1; i < 16; i++) {
00361 if (i < 8) {
00362 r = (i & 1) ? 255 : 0;
00363 g = (i & 2) ? 255 : 0;
00364 b = (i & 4) ? 255 : 0;
00365 } else {
00366 r = (i & 1) ? 127 : 0;
00367 g = (i & 2) ? 127 : 0;
00368 b = (i & 4) ? 127 : 0;
00369 }
00370 default_clut.clut16[i] = RGBA(r, g, b, 255);
00371 }
00372
00373 default_clut.clut256[0] = RGBA( 0, 0, 0, 0);
00374 for (i = 1; i < 256; i++) {
00375 if (i < 8) {
00376 r = (i & 1) ? 255 : 0;
00377 g = (i & 2) ? 255 : 0;
00378 b = (i & 4) ? 255 : 0;
00379 a = 63;
00380 } else {
00381 switch (i & 0x88) {
00382 case 0x00:
00383 r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
00384 g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
00385 b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
00386 a = 255;
00387 break;
00388 case 0x08:
00389 r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
00390 g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
00391 b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
00392 a = 127;
00393 break;
00394 case 0x80:
00395 r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
00396 g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
00397 b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
00398 a = 255;
00399 break;
00400 case 0x88:
00401 r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
00402 g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
00403 b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
00404 a = 255;
00405 break;
00406 }
00407 }
00408 default_clut.clut256[i] = RGBA(r, g, b, a);
00409 }
00410
00411 return 0;
00412 }
00413
00414 static int dvbsub_close_decoder(AVCodecContext *avctx)
00415 {
00416 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00417 DVBSubRegionDisplay *display;
00418
00419 delete_state(ctx);
00420
00421 while (ctx->display_list) {
00422 display = ctx->display_list;
00423 ctx->display_list = display->next;
00424
00425 av_free(display);
00426 }
00427
00428 return 0;
00429 }
00430
00431 static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len,
00432 const uint8_t **srcbuf, int buf_size,
00433 int non_mod, uint8_t *map_table)
00434 {
00435 GetBitContext gb;
00436
00437 int bits;
00438 int run_length;
00439 int pixels_read = 0;
00440
00441 init_get_bits(&gb, *srcbuf, buf_size << 8);
00442
00443 while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) {
00444 bits = get_bits(&gb, 2);
00445
00446 if (bits) {
00447 if (non_mod != 1 || bits != 1) {
00448 if (map_table)
00449 *destbuf++ = map_table[bits];
00450 else
00451 *destbuf++ = bits;
00452 }
00453 pixels_read++;
00454 } else {
00455 bits = get_bits1(&gb);
00456 if (bits == 1) {
00457 run_length = get_bits(&gb, 3) + 3;
00458 bits = get_bits(&gb, 2);
00459
00460 if (non_mod == 1 && bits == 1)
00461 pixels_read += run_length;
00462 else {
00463 if (map_table)
00464 bits = map_table[bits];
00465 while (run_length-- > 0 && pixels_read < dbuf_len) {
00466 *destbuf++ = bits;
00467 pixels_read++;
00468 }
00469 }
00470 } else {
00471 bits = get_bits1(&gb);
00472 if (bits == 0) {
00473 bits = get_bits(&gb, 2);
00474 if (bits == 2) {
00475 run_length = get_bits(&gb, 4) + 12;
00476 bits = get_bits(&gb, 2);
00477
00478 if (non_mod == 1 && bits == 1)
00479 pixels_read += run_length;
00480 else {
00481 if (map_table)
00482 bits = map_table[bits];
00483 while (run_length-- > 0 && pixels_read < dbuf_len) {
00484 *destbuf++ = bits;
00485 pixels_read++;
00486 }
00487 }
00488 } else if (bits == 3) {
00489 run_length = get_bits(&gb, 8) + 29;
00490 bits = get_bits(&gb, 2);
00491
00492 if (non_mod == 1 && bits == 1)
00493 pixels_read += run_length;
00494 else {
00495 if (map_table)
00496 bits = map_table[bits];
00497 while (run_length-- > 0 && pixels_read < dbuf_len) {
00498 *destbuf++ = bits;
00499 pixels_read++;
00500 }
00501 }
00502 } else if (bits == 1) {
00503 pixels_read += 2;
00504 if (map_table)
00505 bits = map_table[0];
00506 else
00507 bits = 0;
00508 if (pixels_read <= dbuf_len) {
00509 *destbuf++ = bits;
00510 *destbuf++ = bits;
00511 }
00512 } else {
00513 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
00514 return pixels_read;
00515 }
00516 } else {
00517 if (map_table)
00518 bits = map_table[0];
00519 else
00520 bits = 0;
00521 *destbuf++ = bits;
00522 pixels_read++;
00523 }
00524 }
00525 }
00526 }
00527
00528 if (get_bits(&gb, 6))
00529 av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
00530
00531 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
00532
00533 return pixels_read;
00534 }
00535
00536 static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len,
00537 const uint8_t **srcbuf, int buf_size,
00538 int non_mod, uint8_t *map_table)
00539 {
00540 GetBitContext gb;
00541
00542 int bits;
00543 int run_length;
00544 int pixels_read = 0;
00545
00546 init_get_bits(&gb, *srcbuf, buf_size << 8);
00547
00548 while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) {
00549 bits = get_bits(&gb, 4);
00550
00551 if (bits) {
00552 if (non_mod != 1 || bits != 1) {
00553 if (map_table)
00554 *destbuf++ = map_table[bits];
00555 else
00556 *destbuf++ = bits;
00557 }
00558 pixels_read++;
00559 } else {
00560 bits = get_bits1(&gb);
00561 if (bits == 0) {
00562 run_length = get_bits(&gb, 3);
00563
00564 if (run_length == 0) {
00565 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
00566 return pixels_read;
00567 }
00568
00569 run_length += 2;
00570
00571 if (map_table)
00572 bits = map_table[0];
00573 else
00574 bits = 0;
00575
00576 while (run_length-- > 0 && pixels_read < dbuf_len) {
00577 *destbuf++ = bits;
00578 pixels_read++;
00579 }
00580 } else {
00581 bits = get_bits1(&gb);
00582 if (bits == 0) {
00583 run_length = get_bits(&gb, 2) + 4;
00584 bits = get_bits(&gb, 4);
00585
00586 if (non_mod == 1 && bits == 1)
00587 pixels_read += run_length;
00588 else {
00589 if (map_table)
00590 bits = map_table[bits];
00591 while (run_length-- > 0 && pixels_read < dbuf_len) {
00592 *destbuf++ = bits;
00593 pixels_read++;
00594 }
00595 }
00596 } else {
00597 bits = get_bits(&gb, 2);
00598 if (bits == 2) {
00599 run_length = get_bits(&gb, 4) + 9;
00600 bits = get_bits(&gb, 4);
00601
00602 if (non_mod == 1 && bits == 1)
00603 pixels_read += run_length;
00604 else {
00605 if (map_table)
00606 bits = map_table[bits];
00607 while (run_length-- > 0 && pixels_read < dbuf_len) {
00608 *destbuf++ = bits;
00609 pixels_read++;
00610 }
00611 }
00612 } else if (bits == 3) {
00613 run_length = get_bits(&gb, 8) + 25;
00614 bits = get_bits(&gb, 4);
00615
00616 if (non_mod == 1 && bits == 1)
00617 pixels_read += run_length;
00618 else {
00619 if (map_table)
00620 bits = map_table[bits];
00621 while (run_length-- > 0 && pixels_read < dbuf_len) {
00622 *destbuf++ = bits;
00623 pixels_read++;
00624 }
00625 }
00626 } else if (bits == 1) {
00627 pixels_read += 2;
00628 if (map_table)
00629 bits = map_table[0];
00630 else
00631 bits = 0;
00632 if (pixels_read <= dbuf_len) {
00633 *destbuf++ = bits;
00634 *destbuf++ = bits;
00635 }
00636 } else {
00637 if (map_table)
00638 bits = map_table[0];
00639 else
00640 bits = 0;
00641 *destbuf++ = bits;
00642 pixels_read ++;
00643 }
00644 }
00645 }
00646 }
00647 }
00648
00649 if (get_bits(&gb, 8))
00650 av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
00651
00652 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
00653
00654 return pixels_read;
00655 }
00656
00657 static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len,
00658 const uint8_t **srcbuf, int buf_size,
00659 int non_mod, uint8_t *map_table)
00660 {
00661 const uint8_t *sbuf_end = (*srcbuf) + buf_size;
00662 int bits;
00663 int run_length;
00664 int pixels_read = 0;
00665
00666 while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
00667 bits = *(*srcbuf)++;
00668
00669 if (bits) {
00670 if (non_mod != 1 || bits != 1) {
00671 if (map_table)
00672 *destbuf++ = map_table[bits];
00673 else
00674 *destbuf++ = bits;
00675 }
00676 pixels_read++;
00677 } else {
00678 bits = *(*srcbuf)++;
00679 run_length = bits & 0x7f;
00680 if ((bits & 0x80) == 0) {
00681 if (run_length == 0) {
00682 return pixels_read;
00683 }
00684
00685 if (map_table)
00686 bits = map_table[0];
00687 else
00688 bits = 0;
00689 while (run_length-- > 0 && pixels_read < dbuf_len) {
00690 *destbuf++ = bits;
00691 pixels_read++;
00692 }
00693 } else {
00694 bits = *(*srcbuf)++;
00695
00696 if (non_mod == 1 && bits == 1)
00697 pixels_read += run_length;
00698 if (map_table)
00699 bits = map_table[bits];
00700 else while (run_length-- > 0 && pixels_read < dbuf_len) {
00701 *destbuf++ = bits;
00702 pixels_read++;
00703 }
00704 }
00705 }
00706 }
00707
00708 if (*(*srcbuf)++)
00709 av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
00710
00711 return pixels_read;
00712 }
00713
00714
00715
00716 static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display,
00717 const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
00718 {
00719 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00720
00721 DVBSubRegion *region = get_region(ctx, display->region_id);
00722 const uint8_t *buf_end = buf + buf_size;
00723 uint8_t *pbuf;
00724 int x_pos, y_pos;
00725 int i;
00726
00727 uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf};
00728 uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
00729 uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
00730 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
00731 uint8_t *map_table;
00732
00733 #ifdef DEBUG
00734 av_log(avctx, AV_LOG_INFO, "DVB pixel block size %d, %s field:\n", buf_size,
00735 top_bottom ? "bottom" : "top");
00736 #endif
00737
00738 #ifdef DEBUG_PACKET_CONTENTS
00739 for (i = 0; i < buf_size; i++) {
00740 if (i % 16 == 0)
00741 av_log(avctx, AV_LOG_INFO, "0x%08p: ", buf+i);
00742
00743 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
00744 if (i % 16 == 15)
00745 av_log(avctx, AV_LOG_INFO, "\n");
00746 }
00747
00748 if (i % 16)
00749 av_log(avctx, AV_LOG_INFO, "\n");
00750
00751 #endif
00752
00753 if (region == 0)
00754 return;
00755
00756 pbuf = region->pbuf;
00757
00758 x_pos = display->x_pos;
00759 y_pos = display->y_pos;
00760
00761 if ((y_pos & 1) != top_bottom)
00762 y_pos++;
00763
00764 while (buf < buf_end) {
00765 if (x_pos > region->width || y_pos > region->height) {
00766 av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n");
00767 return;
00768 }
00769
00770 switch (*buf++) {
00771 case 0x10:
00772 if (region->depth == 8)
00773 map_table = map2to8;
00774 else if (region->depth == 4)
00775 map_table = map2to4;
00776 else
00777 map_table = NULL;
00778
00779 x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos,
00780 region->width - x_pos, &buf, buf_size,
00781 non_mod, map_table);
00782 break;
00783 case 0x11:
00784 if (region->depth < 4) {
00785 av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
00786 return;
00787 }
00788
00789 if (region->depth == 8)
00790 map_table = map4to8;
00791 else
00792 map_table = NULL;
00793
00794 x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos,
00795 region->width - x_pos, &buf, buf_size,
00796 non_mod, map_table);
00797 break;
00798 case 0x12:
00799 if (region->depth < 8) {
00800 av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
00801 return;
00802 }
00803
00804 x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos,
00805 region->width - x_pos, &buf, buf_size,
00806 non_mod, NULL);
00807 break;
00808
00809 case 0x20:
00810 map2to4[0] = (*buf) >> 4;
00811 map2to4[1] = (*buf++) & 0xf;
00812 map2to4[2] = (*buf) >> 4;
00813 map2to4[3] = (*buf++) & 0xf;
00814 break;
00815 case 0x21:
00816 for (i = 0; i < 4; i++)
00817 map2to8[i] = *buf++;
00818 break;
00819 case 0x22:
00820 for (i = 0; i < 16; i++)
00821 map4to8[i] = *buf++;
00822 break;
00823
00824 case 0xf0:
00825 x_pos = display->x_pos;
00826 y_pos += 2;
00827 break;
00828 default:
00829 av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
00830 }
00831 }
00832
00833 }
00834
00835 static void dvbsub_parse_object_segment(AVCodecContext *avctx,
00836 const uint8_t *buf, int buf_size)
00837 {
00838 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00839
00840 const uint8_t *buf_end = buf + buf_size;
00841 const uint8_t *block;
00842 int object_id;
00843 DVBSubObject *object;
00844 DVBSubObjectDisplay *display;
00845 int top_field_len, bottom_field_len;
00846
00847 int coding_method, non_modifying_color;
00848
00849 object_id = AV_RB16(buf);
00850 buf += 2;
00851
00852 object = get_object(ctx, object_id);
00853
00854 if (!object)
00855 return;
00856
00857 coding_method = ((*buf) >> 2) & 3;
00858 non_modifying_color = ((*buf++) >> 1) & 1;
00859
00860 if (coding_method == 0) {
00861 top_field_len = AV_RB16(buf);
00862 buf += 2;
00863 bottom_field_len = AV_RB16(buf);
00864 buf += 2;
00865
00866 if (buf + top_field_len + bottom_field_len > buf_end) {
00867 av_log(avctx, AV_LOG_ERROR, "Field data size too large\n");
00868 return;
00869 }
00870
00871 for (display = object->display_list; display; display = display->object_list_next) {
00872 block = buf;
00873
00874 dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
00875 non_modifying_color);
00876
00877 if (bottom_field_len > 0)
00878 block = buf + top_field_len;
00879 else
00880 bottom_field_len = top_field_len;
00881
00882 dvbsub_parse_pixel_data_block(avctx, display, block, bottom_field_len, 1,
00883 non_modifying_color);
00884 }
00885
00886
00887
00888 } else {
00889 av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
00890 }
00891
00892 }
00893
00894 static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
00895 const uint8_t *buf, int buf_size)
00896 {
00897 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00898
00899 const uint8_t *buf_end = buf + buf_size;
00900 int clut_id;
00901 DVBSubCLUT *clut;
00902 int entry_id, depth , full_range;
00903 int y, cr, cb, alpha;
00904 int r, g, b, r_add, g_add, b_add;
00905
00906 #ifdef DEBUG_PACKET_CONTENTS
00907 int i;
00908
00909 av_log(avctx, AV_LOG_INFO, "DVB clut packet:\n");
00910
00911 for (i=0; i < buf_size; i++) {
00912 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
00913 if (i % 16 == 15)
00914 av_log(avctx, AV_LOG_INFO, "\n");
00915 }
00916
00917 if (i % 16)
00918 av_log(avctx, AV_LOG_INFO, "\n");
00919
00920 #endif
00921
00922 clut_id = *buf++;
00923 buf += 1;
00924
00925 clut = get_clut(ctx, clut_id);
00926
00927 if (!clut) {
00928 clut = av_malloc(sizeof(DVBSubCLUT));
00929
00930 memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
00931
00932 clut->id = clut_id;
00933
00934 clut->next = ctx->clut_list;
00935 ctx->clut_list = clut;
00936 }
00937
00938 while (buf + 4 < buf_end) {
00939 entry_id = *buf++;
00940
00941 depth = (*buf) & 0xe0;
00942
00943 if (depth == 0) {
00944 av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
00945 return;
00946 }
00947
00948 full_range = (*buf++) & 1;
00949
00950 if (full_range) {
00951 y = *buf++;
00952 cr = *buf++;
00953 cb = *buf++;
00954 alpha = *buf++;
00955 } else {
00956 y = buf[0] & 0xfc;
00957 cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
00958 cb = (buf[1] << 2) & 0xf0;
00959 alpha = (buf[1] << 6) & 0xc0;
00960
00961 buf += 2;
00962 }
00963
00964 if (y == 0)
00965 alpha = 0xff;
00966
00967 YUV_TO_RGB1_CCIR(cb, cr);
00968 YUV_TO_RGB2_CCIR(r, g, b, y);
00969
00970 #ifdef DEBUG
00971 av_log(avctx, AV_LOG_INFO, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
00972 #endif
00973
00974 if (depth & 0x80)
00975 clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
00976 if (depth & 0x40)
00977 clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
00978 if (depth & 0x20)
00979 clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
00980 }
00981 }
00982
00983
00984 static void dvbsub_parse_region_segment(AVCodecContext *avctx,
00985 const uint8_t *buf, int buf_size)
00986 {
00987 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00988
00989 const uint8_t *buf_end = buf + buf_size;
00990 int region_id, object_id;
00991 DVBSubRegion *region;
00992 DVBSubObject *object;
00993 DVBSubObjectDisplay *display;
00994 int fill;
00995
00996 if (buf_size < 10)
00997 return;
00998
00999 region_id = *buf++;
01000
01001 region = get_region(ctx, region_id);
01002
01003 if (!region) {
01004 region = av_mallocz(sizeof(DVBSubRegion));
01005
01006 region->id = region_id;
01007
01008 region->next = ctx->region_list;
01009 ctx->region_list = region;
01010 }
01011
01012 fill = ((*buf++) >> 3) & 1;
01013
01014 region->width = AV_RB16(buf);
01015 buf += 2;
01016 region->height = AV_RB16(buf);
01017 buf += 2;
01018
01019 if (region->width * region->height != region->buf_size) {
01020 if (region->pbuf)
01021 av_free(region->pbuf);
01022
01023 region->buf_size = region->width * region->height;
01024
01025 region->pbuf = av_malloc(region->buf_size);
01026
01027 fill = 1;
01028 }
01029
01030 region->depth = 1 << (((*buf++) >> 2) & 7);
01031 if(region->depth<2 || region->depth>8){
01032 av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
01033 region->depth= 4;
01034 }
01035 region->clut = *buf++;
01036
01037 if (region->depth == 8)
01038 region->bgcolor = *buf++;
01039 else {
01040 buf += 1;
01041
01042 if (region->depth == 4)
01043 region->bgcolor = (((*buf++) >> 4) & 15);
01044 else
01045 region->bgcolor = (((*buf++) >> 2) & 3);
01046 }
01047
01048 #ifdef DEBUG
01049 av_log(avctx, AV_LOG_INFO, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
01050 #endif
01051
01052 if (fill) {
01053 memset(region->pbuf, region->bgcolor, region->buf_size);
01054 #ifdef DEBUG
01055 av_log(avctx, AV_LOG_INFO, "Fill region (%d)\n", region->bgcolor);
01056 #endif
01057 }
01058
01059 delete_region_display_list(ctx, region);
01060
01061 while (buf + 5 < buf_end) {
01062 object_id = AV_RB16(buf);
01063 buf += 2;
01064
01065 object = get_object(ctx, object_id);
01066
01067 if (!object) {
01068 object = av_mallocz(sizeof(DVBSubObject));
01069
01070 object->id = object_id;
01071 object->next = ctx->object_list;
01072 ctx->object_list = object;
01073 }
01074
01075 object->type = (*buf) >> 6;
01076
01077 display = av_mallocz(sizeof(DVBSubObjectDisplay));
01078
01079 display->object_id = object_id;
01080 display->region_id = region_id;
01081
01082 display->x_pos = AV_RB16(buf) & 0xfff;
01083 buf += 2;
01084 display->y_pos = AV_RB16(buf) & 0xfff;
01085 buf += 2;
01086
01087 if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
01088 display->fgcolor = *buf++;
01089 display->bgcolor = *buf++;
01090 }
01091
01092 display->region_list_next = region->display_list;
01093 region->display_list = display;
01094
01095 display->object_list_next = object->display_list;
01096 object->display_list = display;
01097 }
01098 }
01099
01100 static void dvbsub_parse_page_segment(AVCodecContext *avctx,
01101 const uint8_t *buf, int buf_size)
01102 {
01103 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
01104 DVBSubRegionDisplay *display;
01105 DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
01106
01107 const uint8_t *buf_end = buf + buf_size;
01108 int region_id;
01109 int page_state;
01110
01111 if (buf_size < 1)
01112 return;
01113
01114 ctx->time_out = *buf++;
01115 page_state = ((*buf++) >> 2) & 3;
01116
01117 #ifdef DEBUG
01118 av_log(avctx, AV_LOG_INFO, "Page time out %ds, state %d\n", ctx->time_out, page_state);
01119 #endif
01120
01121 if (page_state == 2) {
01122 delete_state(ctx);
01123 }
01124
01125 tmp_display_list = ctx->display_list;
01126 ctx->display_list = NULL;
01127 ctx->display_list_size = 0;
01128
01129 while (buf + 5 < buf_end) {
01130 region_id = *buf++;
01131 buf += 1;
01132
01133 display = tmp_display_list;
01134 tmp_ptr = &tmp_display_list;
01135
01136 while (display && display->region_id != region_id) {
01137 tmp_ptr = &display->next;
01138 display = display->next;
01139 }
01140
01141 if (!display)
01142 display = av_mallocz(sizeof(DVBSubRegionDisplay));
01143
01144 display->region_id = region_id;
01145
01146 display->x_pos = AV_RB16(buf);
01147 buf += 2;
01148 display->y_pos = AV_RB16(buf);
01149 buf += 2;
01150
01151 *tmp_ptr = display->next;
01152
01153 display->next = ctx->display_list;
01154 ctx->display_list = display;
01155 ctx->display_list_size++;
01156
01157 #ifdef DEBUG
01158 av_log(avctx, AV_LOG_INFO, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
01159 #endif
01160 }
01161
01162 while (tmp_display_list) {
01163 display = tmp_display_list;
01164
01165 tmp_display_list = display->next;
01166
01167 av_free(display);
01168 }
01169
01170 }
01171
01172
01173 #ifdef DEBUG_SAVE_IMAGES
01174 static void save_display_set(DVBSubContext *ctx)
01175 {
01176 DVBSubRegion *region;
01177 DVBSubRegionDisplay *display;
01178 DVBSubCLUT *clut;
01179 uint32_t *clut_table;
01180 int x_pos, y_pos, width, height;
01181 int x, y, y_off, x_off;
01182 uint32_t *pbuf;
01183 char filename[32];
01184 static int fileno_index = 0;
01185
01186 x_pos = -1;
01187 y_pos = -1;
01188 width = 0;
01189 height = 0;
01190
01191 for (display = ctx->display_list; display; display = display->next) {
01192 region = get_region(ctx, display->region_id);
01193
01194 if (x_pos == -1) {
01195 x_pos = display->x_pos;
01196 y_pos = display->y_pos;
01197 width = region->width;
01198 height = region->height;
01199 } else {
01200 if (display->x_pos < x_pos) {
01201 width += (x_pos - display->x_pos);
01202 x_pos = display->x_pos;
01203 }
01204
01205 if (display->y_pos < y_pos) {
01206 height += (y_pos - display->y_pos);
01207 y_pos = display->y_pos;
01208 }
01209
01210 if (display->x_pos + region->width > x_pos + width) {
01211 width = display->x_pos + region->width - x_pos;
01212 }
01213
01214 if (display->y_pos + region->height > y_pos + height) {
01215 height = display->y_pos + region->height - y_pos;
01216 }
01217 }
01218 }
01219
01220 if (x_pos >= 0) {
01221
01222 pbuf = av_malloc(width * height * 4);
01223
01224 for (display = ctx->display_list; display; display = display->next) {
01225 region = get_region(ctx, display->region_id);
01226
01227 x_off = display->x_pos - x_pos;
01228 y_off = display->y_pos - y_pos;
01229
01230 clut = get_clut(ctx, region->clut);
01231
01232 if (clut == 0)
01233 clut = &default_clut;
01234
01235 switch (region->depth) {
01236 case 2:
01237 clut_table = clut->clut4;
01238 break;
01239 case 8:
01240 clut_table = clut->clut256;
01241 break;
01242 case 4:
01243 default:
01244 clut_table = clut->clut16;
01245 break;
01246 }
01247
01248 for (y = 0; y < region->height; y++) {
01249 for (x = 0; x < region->width; x++) {
01250 pbuf[((y + y_off) * width) + x_off + x] =
01251 clut_table[region->pbuf[y * region->width + x]];
01252 }
01253 }
01254
01255 }
01256
01257 snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
01258
01259 png_save2(filename, pbuf, width, height);
01260
01261 av_free(pbuf);
01262 }
01263
01264 fileno_index++;
01265 }
01266 #endif
01267
01268 static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
01269 int buf_size, AVSubtitle *sub)
01270 {
01271 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
01272
01273 DVBSubRegion *region;
01274 DVBSubRegionDisplay *display;
01275 AVSubtitleRect *rect;
01276 DVBSubCLUT *clut;
01277 uint32_t *clut_table;
01278 int i;
01279
01280 sub->rects = NULL;
01281 sub->start_display_time = 0;
01282 sub->end_display_time = ctx->time_out * 1000;
01283 sub->format = 0;
01284
01285 sub->num_rects = ctx->display_list_size;
01286
01287 if (sub->num_rects > 0)
01288 sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects);
01289
01290 i = 0;
01291
01292 for (display = ctx->display_list; display; display = display->next) {
01293 region = get_region(ctx, display->region_id);
01294 rect = &sub->rects[i];
01295
01296 if (!region)
01297 continue;
01298
01299 rect->x = display->x_pos;
01300 rect->y = display->y_pos;
01301 rect->w = region->width;
01302 rect->h = region->height;
01303 rect->nb_colors = 16;
01304 rect->linesize = region->width;
01305
01306 clut = get_clut(ctx, region->clut);
01307
01308 if (!clut)
01309 clut = &default_clut;
01310
01311 switch (region->depth) {
01312 case 2:
01313 clut_table = clut->clut4;
01314 break;
01315 case 8:
01316 clut_table = clut->clut256;
01317 break;
01318 case 4:
01319 default:
01320 clut_table = clut->clut16;
01321 break;
01322 }
01323
01324 rect->rgba_palette = av_malloc((1 << region->depth) * sizeof(uint32_t));
01325 memcpy(rect->rgba_palette, clut_table, (1 << region->depth) * sizeof(uint32_t));
01326
01327 rect->bitmap = av_malloc(region->buf_size);
01328 memcpy(rect->bitmap, region->pbuf, region->buf_size);
01329
01330 i++;
01331 }
01332
01333 sub->num_rects = i;
01334
01335 #ifdef DEBUG_SAVE_IMAGES
01336 save_display_set(ctx);
01337 #endif
01338
01339 return 1;
01340 }
01341
01342 static int dvbsub_decode(AVCodecContext *avctx,
01343 void *data, int *data_size,
01344 const uint8_t *buf, int buf_size)
01345 {
01346 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
01347 AVSubtitle *sub = (AVSubtitle*) data;
01348 const uint8_t *p, *p_end;
01349 int segment_type;
01350 int page_id;
01351 int segment_length;
01352
01353 #ifdef DEBUG_PACKET_CONTENTS
01354 int i;
01355
01356 av_log(avctx, AV_LOG_INFO, "DVB sub packet:\n");
01357
01358 for (i=0; i < buf_size; i++) {
01359 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
01360 if (i % 16 == 15)
01361 av_log(avctx, AV_LOG_INFO, "\n");
01362 }
01363
01364 if (i % 16)
01365 av_log(avctx, AV_LOG_INFO, "\n");
01366
01367 #endif
01368
01369 if (buf_size <= 2)
01370 return -1;
01371
01372 p = buf;
01373 p_end = buf + buf_size;
01374
01375 while (p < p_end && *p == 0x0f) {
01376 p += 1;
01377 segment_type = *p++;
01378 page_id = AV_RB16(p);
01379 p += 2;
01380 segment_length = AV_RB16(p);
01381 p += 2;
01382
01383 if (page_id == ctx->composition_id || page_id == ctx->ancillary_id) {
01384 switch (segment_type) {
01385 case DVBSUB_PAGE_SEGMENT:
01386 dvbsub_parse_page_segment(avctx, p, segment_length);
01387 break;
01388 case DVBSUB_REGION_SEGMENT:
01389 dvbsub_parse_region_segment(avctx, p, segment_length);
01390 break;
01391 case DVBSUB_CLUT_SEGMENT:
01392 dvbsub_parse_clut_segment(avctx, p, segment_length);
01393 break;
01394 case DVBSUB_OBJECT_SEGMENT:
01395 dvbsub_parse_object_segment(avctx, p, segment_length);
01396 break;
01397 case DVBSUB_DISPLAY_SEGMENT:
01398 *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub);
01399 break;
01400 default:
01401 #ifdef DEBUG
01402 av_log(avctx, AV_LOG_INFO, "Subtitling segment type 0x%x, page id %d, length %d\n",
01403 segment_type, page_id, segment_length);
01404 #endif
01405 break;
01406 }
01407 }
01408
01409 p += segment_length;
01410 }
01411
01412 if (p != p_end) {
01413 #ifdef DEBUG
01414 av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n");
01415 #endif
01416 return -1;
01417 }
01418
01419 return buf_size;
01420 }
01421
01422
01423 AVCodec dvbsub_decoder = {
01424 "dvbsub",
01425 CODEC_TYPE_SUBTITLE,
01426 CODEC_ID_DVB_SUBTITLE,
01427 sizeof(DVBSubContext),
01428 dvbsub_init_decoder,
01429 NULL,
01430 dvbsub_close_decoder,
01431 dvbsub_decode,
01432 };