• 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 "bitstream.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 << 8);
00443 
00444     while (get_bits_count(&gb) < (buf_size << 8) && 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 << 8);
00548 
00549     while (get_bits_count(&gb) < (buf_size << 8) && 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 #ifdef DEBUG
00735     av_log(avctx, AV_LOG_INFO, "DVB pixel block size %d, %s field:\n", buf_size,
00736                 top_bottom ? "bottom" : "top");
00737 #endif
00738 
00739 #ifdef DEBUG_PACKET_CONTENTS
00740     for (i = 0; i < buf_size; i++) {
00741         if (i % 16 == 0)
00742             av_log(avctx, AV_LOG_INFO, "0x%08p: ", buf+i);
00743 
00744         av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
00745         if (i % 16 == 15)
00746             av_log(avctx, AV_LOG_INFO, "\n");
00747     }
00748 
00749     if (i % 16)
00750         av_log(avctx, AV_LOG_INFO, "\n");
00751 
00752 #endif
00753 
00754     if (region == 0)
00755         return;
00756 
00757     pbuf = region->pbuf;
00758 
00759     x_pos = display->x_pos;
00760     y_pos = display->y_pos;
00761 
00762     if ((y_pos & 1) != top_bottom)
00763         y_pos++;
00764 
00765     while (buf < buf_end) {
00766         if (x_pos > region->width || y_pos > region->height) {
00767             av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n");
00768             return;
00769         }
00770 
00771         switch (*buf++) {
00772         case 0x10:
00773             if (region->depth == 8)
00774                 map_table = map2to8;
00775             else if (region->depth == 4)
00776                 map_table = map2to4;
00777             else
00778                 map_table = NULL;
00779 
00780             x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos,
00781                                                 region->width - x_pos, &buf, buf_size,
00782                                                 non_mod, map_table);
00783             break;
00784         case 0x11:
00785             if (region->depth < 4) {
00786                 av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
00787                 return;
00788             }
00789 
00790             if (region->depth == 8)
00791                 map_table = map4to8;
00792             else
00793                 map_table = NULL;
00794 
00795             x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos,
00796                                                 region->width - x_pos, &buf, buf_size,
00797                                                 non_mod, map_table);
00798             break;
00799         case 0x12:
00800             if (region->depth < 8) {
00801                 av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
00802                 return;
00803             }
00804 
00805             x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos,
00806                                                 region->width - x_pos, &buf, buf_size,
00807                                                 non_mod, NULL);
00808             break;
00809 
00810         case 0x20:
00811             map2to4[0] = (*buf) >> 4;
00812             map2to4[1] = (*buf++) & 0xf;
00813             map2to4[2] = (*buf) >> 4;
00814             map2to4[3] = (*buf++) & 0xf;
00815             break;
00816         case 0x21:
00817             for (i = 0; i < 4; i++)
00818                 map2to8[i] = *buf++;
00819             break;
00820         case 0x22:
00821             for (i = 0; i < 16; i++)
00822                 map4to8[i] = *buf++;
00823             break;
00824 
00825         case 0xf0:
00826             x_pos = display->x_pos;
00827             y_pos += 2;
00828             break;
00829         default:
00830             av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
00831         }
00832     }
00833 
00834 }
00835 
00836 static void dvbsub_parse_object_segment(AVCodecContext *avctx,
00837                                         const uint8_t *buf, int buf_size)
00838 {
00839     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00840 
00841     const uint8_t *buf_end = buf + buf_size;
00842     const uint8_t *block;
00843     int object_id;
00844     DVBSubObject *object;
00845     DVBSubObjectDisplay *display;
00846     int top_field_len, bottom_field_len;
00847 
00848     int coding_method, non_modifying_color;
00849 
00850     object_id = AV_RB16(buf);
00851     buf += 2;
00852 
00853     object = get_object(ctx, object_id);
00854 
00855     if (!object)
00856         return;
00857 
00858     coding_method = ((*buf) >> 2) & 3;
00859     non_modifying_color = ((*buf++) >> 1) & 1;
00860 
00861     if (coding_method == 0) {
00862         top_field_len = AV_RB16(buf);
00863         buf += 2;
00864         bottom_field_len = AV_RB16(buf);
00865         buf += 2;
00866 
00867         if (buf + top_field_len + bottom_field_len > buf_end) {
00868             av_log(avctx, AV_LOG_ERROR, "Field data size too large\n");
00869             return;
00870         }
00871 
00872         for (display = object->display_list; display; display = display->object_list_next) {
00873             block = buf;
00874 
00875             dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
00876                                             non_modifying_color);
00877 
00878             if (bottom_field_len > 0)
00879                 block = buf + top_field_len;
00880             else
00881                 bottom_field_len = top_field_len;
00882 
00883             dvbsub_parse_pixel_data_block(avctx, display, block, bottom_field_len, 1,
00884                                             non_modifying_color);
00885         }
00886 
00887 /*  } else if (coding_method == 1) {*/
00888 
00889     } else {
00890         av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
00891     }
00892 
00893 }
00894 
00895 static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
00896                                         const uint8_t *buf, int buf_size)
00897 {
00898     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00899 
00900     const uint8_t *buf_end = buf + buf_size;
00901     int clut_id;
00902     DVBSubCLUT *clut;
00903     int entry_id, depth , full_range;
00904     int y, cr, cb, alpha;
00905     int r, g, b, r_add, g_add, b_add;
00906 
00907 #ifdef DEBUG_PACKET_CONTENTS
00908     int i;
00909 
00910     av_log(avctx, AV_LOG_INFO, "DVB clut packet:\n");
00911 
00912     for (i=0; i < buf_size; i++) {
00913         av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
00914         if (i % 16 == 15)
00915             av_log(avctx, AV_LOG_INFO, "\n");
00916     }
00917 
00918     if (i % 16)
00919         av_log(avctx, AV_LOG_INFO, "\n");
00920 
00921 #endif
00922 
00923     clut_id = *buf++;
00924     buf += 1;
00925 
00926     clut = get_clut(ctx, clut_id);
00927 
00928     if (!clut) {
00929         clut = av_malloc(sizeof(DVBSubCLUT));
00930 
00931         memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
00932 
00933         clut->id = clut_id;
00934 
00935         clut->next = ctx->clut_list;
00936         ctx->clut_list = clut;
00937     }
00938 
00939     while (buf + 4 < buf_end) {
00940         entry_id = *buf++;
00941 
00942         depth = (*buf) & 0xe0;
00943 
00944         if (depth == 0) {
00945             av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
00946             return;
00947         }
00948 
00949         full_range = (*buf++) & 1;
00950 
00951         if (full_range) {
00952             y = *buf++;
00953             cr = *buf++;
00954             cb = *buf++;
00955             alpha = *buf++;
00956         } else {
00957             y = buf[0] & 0xfc;
00958             cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
00959             cb = (buf[1] << 2) & 0xf0;
00960             alpha = (buf[1] << 6) & 0xc0;
00961 
00962             buf += 2;
00963         }
00964 
00965         if (y == 0)
00966             alpha = 0xff;
00967 
00968         YUV_TO_RGB1_CCIR(cb, cr);
00969         YUV_TO_RGB2_CCIR(r, g, b, y);
00970 
00971 #ifdef DEBUG
00972         av_log(avctx, AV_LOG_INFO, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
00973 #endif
00974 
00975         if (depth & 0x80)
00976             clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
00977         if (depth & 0x40)
00978             clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
00979         if (depth & 0x20)
00980             clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
00981     }
00982 }
00983 
00984 
00985 static void dvbsub_parse_region_segment(AVCodecContext *avctx,
00986                                         const uint8_t *buf, int buf_size)
00987 {
00988     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
00989 
00990     const uint8_t *buf_end = buf + buf_size;
00991     int region_id, object_id;
00992     DVBSubRegion *region;
00993     DVBSubObject *object;
00994     DVBSubObjectDisplay *display;
00995     int fill;
00996 
00997     if (buf_size < 10)
00998         return;
00999 
01000     region_id = *buf++;
01001 
01002     region = get_region(ctx, region_id);
01003 
01004     if (!region) {
01005         region = av_mallocz(sizeof(DVBSubRegion));
01006 
01007         region->id = region_id;
01008 
01009         region->next = ctx->region_list;
01010         ctx->region_list = region;
01011     }
01012 
01013     fill = ((*buf++) >> 3) & 1;
01014 
01015     region->width = AV_RB16(buf);
01016     buf += 2;
01017     region->height = AV_RB16(buf);
01018     buf += 2;
01019 
01020     if (region->width * region->height != region->buf_size) {
01021         if (region->pbuf)
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 #ifdef DEBUG
01050     av_log(avctx, AV_LOG_INFO, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
01051 #endif
01052 
01053     if (fill) {
01054         memset(region->pbuf, region->bgcolor, region->buf_size);
01055 #ifdef DEBUG
01056         av_log(avctx, AV_LOG_INFO, "Fill region (%d)\n", region->bgcolor);
01057 #endif
01058     }
01059 
01060     delete_region_display_list(ctx, region);
01061 
01062     while (buf + 5 < buf_end) {
01063         object_id = AV_RB16(buf);
01064         buf += 2;
01065 
01066         object = get_object(ctx, object_id);
01067 
01068         if (!object) {
01069             object = av_mallocz(sizeof(DVBSubObject));
01070 
01071             object->id = object_id;
01072             object->next = ctx->object_list;
01073             ctx->object_list = object;
01074         }
01075 
01076         object->type = (*buf) >> 6;
01077 
01078         display = av_mallocz(sizeof(DVBSubObjectDisplay));
01079 
01080         display->object_id = object_id;
01081         display->region_id = region_id;
01082 
01083         display->x_pos = AV_RB16(buf) & 0xfff;
01084         buf += 2;
01085         display->y_pos = AV_RB16(buf) & 0xfff;
01086         buf += 2;
01087 
01088         if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
01089             display->fgcolor = *buf++;
01090             display->bgcolor = *buf++;
01091         }
01092 
01093         display->region_list_next = region->display_list;
01094         region->display_list = display;
01095 
01096         display->object_list_next = object->display_list;
01097         object->display_list = display;
01098     }
01099 }
01100 
01101 static void dvbsub_parse_page_segment(AVCodecContext *avctx,
01102                                         const uint8_t *buf, int buf_size)
01103 {
01104     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
01105     DVBSubRegionDisplay *display;
01106     DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
01107 
01108     const uint8_t *buf_end = buf + buf_size;
01109     int region_id;
01110     int page_state;
01111 
01112     if (buf_size < 1)
01113         return;
01114 
01115     ctx->time_out = *buf++;
01116     page_state = ((*buf++) >> 2) & 3;
01117 
01118 #ifdef DEBUG
01119     av_log(avctx, AV_LOG_INFO, "Page time out %ds, state %d\n", ctx->time_out, page_state);
01120 #endif
01121 
01122     if (page_state == 2) {
01123         delete_state(ctx);
01124     }
01125 
01126     tmp_display_list = ctx->display_list;
01127     ctx->display_list = NULL;
01128     ctx->display_list_size = 0;
01129 
01130     while (buf + 5 < buf_end) {
01131         region_id = *buf++;
01132         buf += 1;
01133 
01134         display = tmp_display_list;
01135         tmp_ptr = &tmp_display_list;
01136 
01137         while (display && display->region_id != region_id) {
01138             tmp_ptr = &display->next;
01139             display = display->next;
01140         }
01141 
01142         if (!display)
01143             display = av_mallocz(sizeof(DVBSubRegionDisplay));
01144 
01145         display->region_id = region_id;
01146 
01147         display->x_pos = AV_RB16(buf);
01148         buf += 2;
01149         display->y_pos = AV_RB16(buf);
01150         buf += 2;
01151 
01152         *tmp_ptr = display->next;
01153 
01154         display->next = ctx->display_list;
01155         ctx->display_list = display;
01156         ctx->display_list_size++;
01157 
01158 #ifdef DEBUG
01159         av_log(avctx, AV_LOG_INFO, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
01160 #endif
01161     }
01162 
01163     while (tmp_display_list) {
01164         display = tmp_display_list;
01165 
01166         tmp_display_list = display->next;
01167 
01168         av_free(display);
01169     }
01170 
01171 }
01172 
01173 
01174 #ifdef DEBUG_SAVE_IMAGES
01175 static void save_display_set(DVBSubContext *ctx)
01176 {
01177     DVBSubRegion *region;
01178     DVBSubRegionDisplay *display;
01179     DVBSubCLUT *clut;
01180     uint32_t *clut_table;
01181     int x_pos, y_pos, width, height;
01182     int x, y, y_off, x_off;
01183     uint32_t *pbuf;
01184     char filename[32];
01185     static int fileno_index = 0;
01186 
01187     x_pos = -1;
01188     y_pos = -1;
01189     width = 0;
01190     height = 0;
01191 
01192     for (display = ctx->display_list; display; display = display->next) {
01193         region = get_region(ctx, display->region_id);
01194 
01195         if (x_pos == -1) {
01196             x_pos = display->x_pos;
01197             y_pos = display->y_pos;
01198             width = region->width;
01199             height = region->height;
01200         } else {
01201             if (display->x_pos < x_pos) {
01202                 width += (x_pos - display->x_pos);
01203                 x_pos = display->x_pos;
01204             }
01205 
01206             if (display->y_pos < y_pos) {
01207                 height += (y_pos - display->y_pos);
01208                 y_pos = display->y_pos;
01209             }
01210 
01211             if (display->x_pos + region->width > x_pos + width) {
01212                 width = display->x_pos + region->width - x_pos;
01213             }
01214 
01215             if (display->y_pos + region->height > y_pos + height) {
01216                 height = display->y_pos + region->height - y_pos;
01217             }
01218         }
01219     }
01220 
01221     if (x_pos >= 0) {
01222 
01223         pbuf = av_malloc(width * height * 4);
01224 
01225         for (display = ctx->display_list; display; display = display->next) {
01226             region = get_region(ctx, display->region_id);
01227 
01228             x_off = display->x_pos - x_pos;
01229             y_off = display->y_pos - y_pos;
01230 
01231             clut = get_clut(ctx, region->clut);
01232 
01233             if (clut == 0)
01234                 clut = &default_clut;
01235 
01236             switch (region->depth) {
01237             case 2:
01238                 clut_table = clut->clut4;
01239                 break;
01240             case 8:
01241                 clut_table = clut->clut256;
01242                 break;
01243             case 4:
01244             default:
01245                 clut_table = clut->clut16;
01246                 break;
01247             }
01248 
01249             for (y = 0; y < region->height; y++) {
01250                 for (x = 0; x < region->width; x++) {
01251                     pbuf[((y + y_off) * width) + x_off + x] =
01252                         clut_table[region->pbuf[y * region->width + x]];
01253                 }
01254             }
01255 
01256         }
01257 
01258         snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
01259 
01260         png_save2(filename, pbuf, width, height);
01261 
01262         av_free(pbuf);
01263     }
01264 
01265     fileno_index++;
01266 }
01267 #endif
01268 
01269 static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
01270                                         int buf_size, AVSubtitle *sub)
01271 {
01272     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
01273 
01274     DVBSubRegion *region;
01275     DVBSubRegionDisplay *display;
01276     AVSubtitleRect *rect;
01277     DVBSubCLUT *clut;
01278     uint32_t *clut_table;
01279     int i;
01280 
01281     sub->rects = NULL;
01282     sub->start_display_time = 0;
01283     sub->end_display_time = ctx->time_out * 1000;
01284     sub->format = 0;
01285 
01286     sub->num_rects = ctx->display_list_size;
01287 
01288     if (sub->num_rects > 0){
01289         sub->rects = av_mallocz(sizeof(*sub->rects) * sub->num_rects);
01290         for(i=0; i<sub->num_rects; i++)
01291             sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
01292     }
01293 
01294     i = 0;
01295 
01296     for (display = ctx->display_list; display; display = display->next) {
01297         region = get_region(ctx, display->region_id);
01298         rect = sub->rects[i];
01299 
01300         if (!region)
01301             continue;
01302 
01303         rect->x = display->x_pos;
01304         rect->y = display->y_pos;
01305         rect->w = region->width;
01306         rect->h = region->height;
01307         rect->nb_colors = 16;
01308         rect->pict.linesize[0] = region->width;
01309 
01310         clut = get_clut(ctx, region->clut);
01311 
01312         if (!clut)
01313             clut = &default_clut;
01314 
01315         switch (region->depth) {
01316         case 2:
01317             clut_table = clut->clut4;
01318             break;
01319         case 8:
01320             clut_table = clut->clut256;
01321             break;
01322         case 4:
01323         default:
01324             clut_table = clut->clut16;
01325             break;
01326         }
01327 
01328         rect->pict.data[1] = av_malloc((1 << region->depth) * sizeof(uint32_t));
01329         memcpy(rect->pict.data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));
01330 
01331         rect->pict.data[0] = av_malloc(region->buf_size);
01332         memcpy(rect->pict.data[0], region->pbuf, region->buf_size);
01333 
01334         i++;
01335     }
01336 
01337     sub->num_rects = i;
01338 
01339 #ifdef DEBUG_SAVE_IMAGES
01340     save_display_set(ctx);
01341 #endif
01342 
01343     return 1;
01344 }
01345 
01346 static int dvbsub_decode(AVCodecContext *avctx,
01347                          void *data, int *data_size,
01348                          const uint8_t *buf, int buf_size)
01349 {
01350     DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
01351     AVSubtitle *sub = (AVSubtitle*) data;
01352     const uint8_t *p, *p_end;
01353     int segment_type;
01354     int page_id;
01355     int segment_length;
01356 
01357 #ifdef DEBUG_PACKET_CONTENTS
01358     int i;
01359 
01360     av_log(avctx, AV_LOG_INFO, "DVB sub packet:\n");
01361 
01362     for (i=0; i < buf_size; i++) {
01363         av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
01364         if (i % 16 == 15)
01365             av_log(avctx, AV_LOG_INFO, "\n");
01366     }
01367 
01368     if (i % 16)
01369         av_log(avctx, AV_LOG_INFO, "\n");
01370 
01371 #endif
01372 
01373     if (buf_size <= 2)
01374         return -1;
01375 
01376     p = buf;
01377     p_end = buf + buf_size;
01378 
01379     while (p < p_end && *p == 0x0f) {
01380         p += 1;
01381         segment_type = *p++;
01382         page_id = AV_RB16(p);
01383         p += 2;
01384         segment_length = AV_RB16(p);
01385         p += 2;
01386 
01387         if (page_id == ctx->composition_id || page_id == ctx->ancillary_id) {
01388             switch (segment_type) {
01389             case DVBSUB_PAGE_SEGMENT:
01390                 dvbsub_parse_page_segment(avctx, p, segment_length);
01391                 break;
01392             case DVBSUB_REGION_SEGMENT:
01393                 dvbsub_parse_region_segment(avctx, p, segment_length);
01394                 break;
01395             case DVBSUB_CLUT_SEGMENT:
01396                 dvbsub_parse_clut_segment(avctx, p, segment_length);
01397                 break;
01398             case DVBSUB_OBJECT_SEGMENT:
01399                 dvbsub_parse_object_segment(avctx, p, segment_length);
01400                 break;
01401             case DVBSUB_DISPLAY_SEGMENT:
01402                 *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub);
01403                 break;
01404             default:
01405 #ifdef DEBUG
01406                 av_log(avctx, AV_LOG_INFO, "Subtitling segment type 0x%x, page id %d, length %d\n",
01407                         segment_type, page_id, segment_length);
01408 #endif
01409                 break;
01410             }
01411         }
01412 
01413         p += segment_length;
01414     }
01415 
01416     if (p != p_end) {
01417 #ifdef DEBUG
01418         av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n");
01419 #endif
01420         return -1;
01421     }
01422 
01423     return buf_size;
01424 }
01425 
01426 
01427 AVCodec dvbsub_decoder = {
01428     "dvbsub",
01429     CODEC_TYPE_SUBTITLE,
01430     CODEC_ID_DVB_SUBTITLE,
01431     sizeof(DVBSubContext),
01432     dvbsub_init_decoder,
01433     NULL,
01434     dvbsub_close_decoder,
01435     dvbsub_decode,
01436     .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
01437 };

Generated on Tue Nov 4 2014 12:59:21 for ffmpeg by  doxygen 1.7.1