• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/dvbsubdec.c

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

Generated on Fri Sep 16 2011 17:17:35 for FFmpeg by  doxygen 1.7.1