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