Ticket #6748: bluray_subtitles_mythtv_trunk_21485.diff

File bluray_subtitles_mythtv_trunk_21485.diff, 19.4 KB (added by Stephen <stev391@…>, 3 years ago)

Updated patch with cleanups suggested by FFmpeg Developers.

  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    71927192                if (player_ctx->buffer->isDVD()) 
    71937193                    vsize = (float) video_disp_dim.height(); 
    71947194 
    7195                 float hmult = osd->GetSubtitleBounds().width() / 720.0; 
    7196                 float vmult = osd->GetSubtitleBounds().height() / vsize; 
     7195//                float hmult = osd->GetSubtitleBounds().width() / 720.0; 
     7196//                float vmult = osd->GetSubtitleBounds().height() / vsize; 
     7197                float hmult = 1.0; 
     7198                float vmult = 1.0; 
    71977199 
    7198                 rect->x = (int)(rect->x * hmult); 
    7199                 rect->y = (int)(rect->y * vmult); 
    7200                 rect->w = (int)(rect->w * hmult); 
    7201                 rect->h = (int)(rect->h * vmult); 
     7200                rect->x = (int)(rect->x / hmult); 
     7201                rect->y = (int)(rect->y / vmult); 
     7202                rect->w = (int)(rect->w / hmult); 
     7203                rect->h = (int)(rect->h / vmult); 
    72027204 
    72037205                if (hmult < 0.98 || hmult > 1.02 || vmult < 0.98 || hmult > 1.02) 
    72047206                    qImage = qImage.scaled(rect->w, rect->h, 
  • libs/libavcodec/allcodecs.c

     
    302302    /* subtitles */ 
    303303    REGISTER_ENCDEC  (DVBSUB, dvbsub); 
    304304    REGISTER_ENCDEC  (DVDSUB, dvdsub); 
     305    REGISTER_DECODER (PGSSUB, pgssub); 
    305306    REGISTER_ENCDEC  (XSUB, xsub); 
    306307 
    307308    /* external libraries */ 
  • libs/libavcodec/avcodec.h

     
    330330    CODEC_ID_XSUB, 
    331331    CODEC_ID_SSA, 
    332332    CODEC_ID_MOV_TEXT, 
     333    CODEC_ID_HDMV_PGS_SUBTITLE, 
    333334 
    334335    /* teletext codecs */ 
    335336    CODEC_ID_MPEG2VBI, 
  • libs/libavcodec/libavcodec.pro

     
    222222contains( CONFIG_PGM_ENCODER, yes )             { SOURCES *= pnmenc.c } 
    223223contains( CONFIG_PGMYUV_DECODER, yes )          { SOURCES *= pnmenc.c pnm.c } 
    224224contains( CONFIG_PGMYUV_ENCODER, yes )          { SOURCES *= pnmenc.c } 
     225contains( CONFIG_PGSSUB_DECODER, yes )          { SOURCES *= pgssubdec.c } 
    225226contains( CONFIG_PNG_DECODER, yes )             { SOURCES *= png.c pngdec.c } 
    226227contains( CONFIG_PNG_ENCODER, yes )             { SOURCES *= png.c pngenc.c } 
    227228contains( CONFIG_PPM_DECODER, yes )             { SOURCES *= pnmenc.c pnm.c } 
  • libs/libavcodec/pgssubdec.c

     
     1/* 
     2 * PGS subtitle decoder 
     3 * Copyright (c) 2009 Stephen Backway 
     4 * 
     5 * This file is part of FFmpeg. 
     6 * 
     7 * FFmpeg is free software; you can redistribute it and/or 
     8 * modify it under the terms of the GNU Lesser General Public 
     9 * License as published by the Free Software Foundation; either 
     10 * version 2.1 of the License, or (at your option) any later version. 
     11 * 
     12 * FFmpeg is distributed in the hope that it will be useful, 
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     15 * Lesser General Public License for more details. 
     16 * 
     17 * You should have received a copy of the GNU Lesser General Public 
     18 * License along with FFmpeg; if not, write to the Free Software 
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 
     20 */ 
     21 
     22/** 
     23 * @file libavcodec/pgssubdec.c 
     24 * PGS subtitle decoder 
     25 */ 
     26 
     27#include "avcodec.h" 
     28#include "dsputil.h" 
     29#include "colorspace.h" 
     30#include "bytestream.h" 
     31 
     32//#define DEBUG_PACKET_CONTENTS 
     33 
     34#define cm  (ff_cropTbl + MAX_NEG_CROP) 
     35#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) 
     36 
     37enum SegmentType { 
     38    PALETTE_SEGMENT      = 0x14, 
     39    PICTURE_SEGMENT      = 0x15, 
     40    PRESENTATION_SEGMENT = 0x16, 
     41    WINDOW_SEGMENT       = 0x17, 
     42    DISPLAY_SEGMENT      = 0x80, 
     43}; 
     44 
     45typedef struct PGSSubPresentation { 
     46    int x; 
     47    int y; 
     48    int video_w; 
     49    int video_h; 
     50    int id_number; 
     51} PGSSubPresentation; 
     52 
     53typedef struct PGSSubPicture { 
     54    int          w; 
     55    int          h; 
     56    uint8_t      *rle; 
     57    unsigned int rle_size, rle_len; 
     58} PGSSubPicture; 
     59 
     60typedef struct PGSSubContext { 
     61    PGSSubPresentation presentation; 
     62    uint32_t           clut[256]; 
     63    PGSSubPicture      picture; 
     64} PGSSubContext; 
     65 
     66static av_cold int init_decoder(AVCodecContext *avctx) 
     67{ 
     68    avctx->pix_fmt     = PIX_FMT_RGB32; 
     69 
     70    return 0; 
     71} 
     72 
     73static av_cold int close_decoder(AVCodecContext *avctx) 
     74{ 
     75    PGSSubContext *ctx = avctx->priv_data; 
     76 
     77    av_freep(&ctx->picture.rle); 
     78    ctx->picture.rle_size  = 0; 
     79 
     80    return 0; 
     81} 
     82 
     83/** 
     84 * Decodes the RLE data. 
     85 * 
     86 * The subtitle is stored as an Run Length Encoded image. 
     87 * 
     88 * @param avctx contains the current codec context 
     89 * @param sub pointer to the processed subtitle data 
     90 * @param buf pointer to the RLE data to process 
     91 * @param buf_size size of the RLE data to process 
     92 */ 
     93static int decode_rle(AVCodecContext *avctx, AVSubtitle *sub, 
     94                      const uint8_t *buf, unsigned int buf_size) 
     95{ 
     96    uint8_t *rle_bitmap_end; 
     97    int pixel_count, line_count; 
     98 
     99    rle_bitmap_end = buf + buf_size; 
     100 
     101    sub->rects[0]->pict.data[0] = av_malloc(sub->rects[0]->w * sub->rects[0]->h); 
     102 
     103    if (!sub->rects[0]->pict.data[0]) 
     104        return -1; 
     105 
     106    pixel_count = 0; 
     107    line_count  = 0; 
     108 
     109    while (buf < rle_bitmap_end && line_count < sub->rects[0]->h) { 
     110        uint8_t flags, color; 
     111        int run; 
     112 
     113        color = bytestream_get_byte(&buf); 
     114        run   = 1; 
     115 
     116        if (color == 0x00) { 
     117            flags = bytestream_get_byte(&buf); 
     118            run   = flags & 0x3f; 
     119            if (flags & 0x40) 
     120                run = (run << 8) + bytestream_get_byte(&buf); 
     121            color = flags & 0x80 ? bytestream_get_byte(&buf) : 0; 
     122        } 
     123 
     124        if (run > 0 && pixel_count + run <= sub->rects[0]->w * sub->rects[0]->h) { 
     125            memset(sub->rects[0]->pict.data[0] + pixel_count, color, run); 
     126            pixel_count += run; 
     127        } else if (run == 0) { 
     128            /* 
     129             * New Line. Check if correct pixels decoded, 
     130             * if not display warning and adjust bitmap 
     131             * pointer to correct new line position. 
     132             */ 
     133            if (pixel_count % sub->rects[0]->w > 0) 
     134                av_log(avctx, AV_LOG_ERROR, "Decoded %d pixels, when line should be %d pixels\n", 
     135                       pixel_count % sub->rects[0]->w, sub->rects[0]->w); 
     136            line_count++; 
     137        } 
     138    } 
     139 
     140    dprintf(avctx, "Pixel Count = %d, Area = %d\n", pixel_count, sub->rects[0]->w * sub->rects[0]->h); 
     141 
     142    return 0; 
     143} 
     144 
     145/** 
     146 * Parses the picture segment packet. 
     147 * 
     148 * The picture segment contains details on the sequence id, 
     149 * width, height and Run Length Encoded (RLE) bitmap data. 
     150 * 
     151 * @param avctx contains the current codec context 
     152 * @param buf pointer to the packet to process 
     153 * @param buf_size size of packet to process 
     154 * @todo TODO: Enable support for RLE data over multiple packets 
     155 */ 
     156static int parse_picture_segment(AVCodecContext *avctx, 
     157                                  const uint8_t *buf, int buf_size) 
     158{ 
     159    PGSSubContext *ctx = avctx->priv_data; 
     160 
     161    uint8_t sequence_desc; 
     162    unsigned int rle_bitmap_len, width, height; 
     163 
     164    /* skip 3 unknown bytes: Object ID (2 bytes), Version Number */ 
     165    buf += 3; 
     166 
     167    /* Read the Sequence Description to determine if start of RLE data or appended to previous RLE */ 
     168    sequence_desc = bytestream_get_byte(&buf); 
     169 
     170    if (!(sequence_desc & 0x80)) { 
     171        av_log(avctx, AV_LOG_ERROR, "Decoder does not support object data over multiple packets.\n"); 
     172        return -1; 
     173    } 
     174 
     175    /* Decode rle bitmap length */ 
     176    rle_bitmap_len = bytestream_get_be24(&buf); 
     177 
     178    /* Check to ensure we have enough data for rle_bitmap_length if just a single packet */ 
     179    if (rle_bitmap_len > buf_size - 7) { 
     180        av_log(avctx, AV_LOG_ERROR, "Not enough RLE data for specified length of %d.\n", rle_bitmap_len); 
     181        return -1; 
     182    } 
     183 
     184    ctx->picture.rle_len = rle_bitmap_len; 
     185 
     186    /* Get bitmap dimensions from data */ 
     187    width  = bytestream_get_be16(&buf); 
     188    height = bytestream_get_be16(&buf); 
     189 
     190    /* Make sure the bitmap is not too large */ 
     191    if (ctx->presentation.video_w < width || ctx->presentation.video_h < height) { 
     192        av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger then video.\n"); 
     193        return -1; 
     194    } 
     195 
     196    ctx->picture.w = width; 
     197    ctx->picture.h = height; 
     198 
     199    av_fast_malloc(&ctx->picture.rle, &ctx->picture.rle_size, rle_bitmap_len); 
     200 
     201    if (!ctx->picture.rle) 
     202        return -1; 
     203 
     204    memcpy(ctx->picture.rle, buf, rle_bitmap_len); 
     205 
     206    return 0; 
     207} 
     208 
     209/** 
     210 * Parses the palette segment packet. 
     211 * 
     212 * The palette segment contains details of the palette, 
     213 * a maximum of 256 colors can be defined. 
     214 * 
     215 * @param avctx contains the current codec context 
     216 * @param buf pointer to the packet to process 
     217 * @param buf_size size of packet to process 
     218 */ 
     219static void parse_palette_segment(AVCodecContext *avctx, 
     220                                  const uint8_t *buf, int buf_size) 
     221{ 
     222    PGSSubContext *ctx = avctx->priv_data; 
     223 
     224    const uint8_t *buf_end = buf + buf_size; 
     225    int color_id; 
     226    int y, cb, cr, alpha; 
     227    int r, g, b, r_add, g_add, b_add; 
     228 
     229    /* Skip two null bytes */ 
     230    buf += 2; 
     231 
     232    while (buf < buf_end) { 
     233        color_id  = bytestream_get_byte(&buf); 
     234        y         = bytestream_get_byte(&buf); 
     235        cb        = bytestream_get_byte(&buf); 
     236        cr        = bytestream_get_byte(&buf); 
     237        alpha     = bytestream_get_byte(&buf); 
     238 
     239        YUV_TO_RGB1(cb, cr); 
     240        YUV_TO_RGB2(r, g, b, y); 
     241 
     242        dprintf(avctx, "Color %d := (%d,%d,%d,%d)\n", color_id, r, g, b, alpha); 
     243 
     244        /* Store color in palette */ 
     245        ctx->clut[color_id] = RGBA(r,g,b,alpha); 
     246    } 
     247} 
     248 
     249/** 
     250 * Parses the presentation segment packet. 
     251 * 
     252 * The presentation segment contains details on the video 
     253 * width, video height, x & y subtitle position. 
     254 * 
     255 * @param avctx contains the current codec context 
     256 * @param buf pointer to the packet to process 
     257 * @param buf_size size of packet to process 
     258 * @todo TODO: Implement cropping 
     259 * @todo TODO: Implement forcing of subtitles 
     260 * @todo TODO: Blanking of subtitle 
     261 */ 
     262static void parse_presentation_segment(AVCodecContext *avctx, 
     263                                       const uint8_t *buf, int buf_size) 
     264{ 
     265    PGSSubContext *ctx = avctx->priv_data; 
     266 
     267    int x, y; 
     268    uint8_t block; 
     269 
     270    ctx->presentation.video_w = bytestream_get_be16(&buf); 
     271    ctx->presentation.video_h = bytestream_get_be16(&buf); 
     272 
     273    dprintf(avctx, "Video Dimensions %dx%d\n", 
     274            ctx->presentation.video_w, ctx->presentation.video_h); 
     275 
     276    /* Skip 1 bytes of unknown, frame rate? */ 
     277    buf++; 
     278 
     279    ctx->presentation.id_number = bytestream_get_be16(&buf); 
     280 
     281    /* Next byte is the state. */ 
     282    block = bytestream_get_byte(&buf);; 
     283    if (block == 0x80) { 
     284        /* 
     285         * Skip 7 bytes of unknown: 
     286         *     palette_update_flag (0x80), 
     287         *     palette_id_to_use, 
     288         *     Object Number (if > 0 determines if more data to process), 
     289         *     object_id_ref (2 bytes), 
     290         *     window_id_ref, 
     291         *     composition_flag (0x80 - object cropped, 0x40 - object forced) 
     292         */ 
     293        buf += 7; 
     294 
     295        x = bytestream_get_be16(&buf); 
     296        y = bytestream_get_be16(&buf); 
     297 
     298        /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_height (all 2 bytes).*/ 
     299 
     300        dprintf(avctx, "Subtitle Placement x=%d, y=%d\n", x, y); 
     301 
     302        if (x > ctx->presentation.video_w || y > ctx->presentation.video_h) { 
     303            av_log(avctx, AV_LOG_ERROR, "Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n", 
     304                   x, y, ctx->presentation.video_w, ctx->presentation.video_h); 
     305            x = 0; y = 0; 
     306        } 
     307 
     308        /* Fill in dimensions */ 
     309        ctx->presentation.x = x; 
     310        ctx->presentation.y = y; 
     311    } else if (block == 0x00) { 
     312        /* TODO: Blank context as subtitle should not be displayed. 
     313         *       If the subtitle is blanked now the subtitle is not 
     314         *       on screen long enough to read, due to a delay in 
     315         *       initial display timing. 
     316         */ 
     317    } 
     318} 
     319 
     320/** 
     321 * Parses the display segment packet. 
     322 * 
     323 * The display segment controls the updating of the display. 
     324 * 
     325 * @param avctx contains the current codec context 
     326 * @param data pointer to the data pertaining the subtitle to display 
     327 * @param buf pointer to the packet to process 
     328 * @param buf_size size of packet to process 
     329 * @todo TODO: Fix start time, relies on correct PTS, currently too late 
     330 * 
     331 * @todo TODO: Fix end time, normally cleared by a second display 
     332 * @todo       segment, which is currently ignored as it clears 
     333 * @todo       the subtitle too early. 
     334 */ 
     335static int display_end_segment(AVCodecContext *avctx, void *data, 
     336                               const uint8_t *buf, int buf_size) 
     337{ 
     338    AVSubtitle    *sub = data; 
     339    PGSSubContext *ctx = avctx->priv_data; 
     340 
     341    /* 
     342     *      The end display time is a timeout value and is only reached 
     343     *      if the next subtitle is later then timeout or subtitle has 
     344     *      not been cleared by a subsequent empty display command. 
     345     */ 
     346 
     347    sub->start_display_time = 0; 
     348    sub->end_display_time   = 20000; 
     349    sub->format             = 0; 
     350 
     351    if (!sub->rects) { 
     352        sub->rects     = av_mallocz(sizeof(*sub->rects)); 
     353        sub->rects[0]  = av_mallocz(sizeof(*sub->rects[0])); 
     354        sub->num_rects = 1; 
     355    } 
     356 
     357    sub->rects[0]->x    = ctx->presentation.x; 
     358    sub->rects[0]->y    = ctx->presentation.y; 
     359    sub->rects[0]->w    = ctx->picture.w; 
     360    sub->rects[0]->h    = ctx->picture.h; 
     361    sub->rects[0]->type = SUBTITLE_BITMAP; 
     362 
     363    /* Process bitmap */ 
     364    sub->rects[0]->pict.linesize[0] = ctx->picture.w; 
     365 
     366    if (ctx->picture.rle) 
     367        if(decode_rle(avctx, sub, ctx->picture.rle, ctx->picture.rle_len) < 0) 
     368            return 0; 
     369 
     370    /* Allocate memory for colors */ 
     371    sub->rects[0]->nb_colors    = 256; 
     372    sub->rects[0]->pict.data[1] = av_malloc(sub->rects[0]->nb_colors * sizeof(uint32_t)); 
     373 
     374    memcpy(sub->rects[0]->pict.data[1], ctx->clut, sub->rects[0]->nb_colors * sizeof(uint32_t)); 
     375 
     376    return 1; 
     377} 
     378 
     379static int decode(AVCodecContext *avctx, void *data, int *data_size, 
     380                  AVPacket *avpkt) 
     381{ 
     382    const uint8_t *buf = avpkt->data; 
     383    int buf_size       = avpkt->size; 
     384 
     385    const uint8_t *buf_end; 
     386    uint8_t       segment_type; 
     387    int           segment_length; 
     388 
     389#ifdef DEBUG_PACKET_CONTENTS 
     390    int i; 
     391 
     392    av_log(avctx, AV_LOG_INFO, "PGS sub packet:\n"); 
     393 
     394    for (i = 0; i < buf_size; i++) { 
     395        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); 
     396        if (i % 16 == 15) 
     397            av_log(avctx, AV_LOG_INFO, "\n"); 
     398    } 
     399 
     400    if (i & 15) 
     401        av_log(avctx, AV_LOG_INFO, "\n"); 
     402#endif 
     403 
     404    *data_size = 0; 
     405 
     406    /* Ensure that we have received at a least a segment code and segment length */ 
     407    if (buf_size < 3) 
     408        return -1; 
     409 
     410    buf_end = buf + buf_size; 
     411 
     412    /* Step through buffer to identify segments */ 
     413    while (buf < buf_end) { 
     414        segment_type   = bytestream_get_byte(&buf); 
     415        segment_length = bytestream_get_be16(&buf); 
     416 
     417        dprintf(avctx, "Segment Length %d, Segment Type %x\n", segment_length, segment_type); 
     418 
     419        if (segment_type != DISPLAY_SEGMENT && segment_length > buf_end - buf) 
     420            break; 
     421 
     422        switch (segment_type) { 
     423        case PALETTE_SEGMENT: 
     424            parse_palette_segment(avctx, buf, segment_length); 
     425            break; 
     426        case PICTURE_SEGMENT: 
     427            parse_picture_segment(avctx, buf, segment_length); 
     428            break; 
     429        case PRESENTATION_SEGMENT: 
     430            parse_presentation_segment(avctx, buf, segment_length); 
     431            break; 
     432        case WINDOW_SEGMENT: 
     433            /* 
     434             * Window Segment Structure (No new information provided): 
     435             *     2 bytes: Unkown, 
     436             *     2 bytes: X position of subtitle, 
     437             *     2 bytes: Y position of subtitle, 
     438             *     2 bytes: Width of subtitle, 
     439             *     2 bytes: Height of subtitle. 
     440             */ 
     441            break; 
     442        case DISPLAY_SEGMENT: 
     443            *data_size = display_end_segment(avctx, data, buf, segment_length); 
     444            break; 
     445        default: 
     446            av_log(avctx, AV_LOG_ERROR, "Unknown subtitle segment type 0x%x, length %d\n", 
     447                   segment_type, segment_length); 
     448            break; 
     449        } 
     450 
     451        buf += segment_length; 
     452    } 
     453 
     454    return buf_size; 
     455} 
     456 
     457AVCodec pgssub_decoder = { 
     458    "pgssub", 
     459    CODEC_TYPE_SUBTITLE, 
     460    CODEC_ID_HDMV_PGS_SUBTITLE, 
     461    sizeof(PGSSubContext), 
     462    init_decoder, 
     463    NULL, 
     464    close_decoder, 
     465    decode, 
     466    .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"), 
     467}; 
  • libs/libavcodec/myth_utils.c

     
    202202            /* subtitle codecs */ 
    203203        case CODEC_ID_DVD_SUBTITLE:     return "DVD_SUBTITLE"; 
    204204        case CODEC_ID_DVB_SUBTITLE:     return "DVB_SUBTITLE"; 
     205        case CODEC_ID_HDMV_PGS_SUBTITLE: 
     206             return "HDMV_PGS_SUBTITLE"; 
    205207 
    206208        case CODEC_ID_MPEG2VBI:         return "MPEG2VBI"; 
    207209        case CODEC_ID_DVB_VBI:          return "DVB_VBI"; 
  • libs/libavformat/mpegts.c

     
    578578    { 0x84, CODEC_TYPE_AUDIO, CODEC_ID_AC3 }, 
    579579    { 0x85, CODEC_TYPE_AUDIO, CODEC_ID_DTS }, 
    580580    { 0x86, CODEC_TYPE_AUDIO, CODEC_ID_DTS }, 
     581    { 0x90, CODEC_TYPE_SUBTITLE, CODEC_ID_HDMV_PGS_SUBTITLE }, 
    581582    { 0 }, 
    582583}; 
    583584 
     
    10111012            //case STREAM_TYPE_PRIVATE_DATA: 
    10121013        case STREAM_TYPE_VBI_DVB: 
    10131014        case STREAM_TYPE_SUBTITLE_DVB: 
     1015        case STREAM_TYPE_SUBTITLE_PGS: 
    10141016        case STREAM_TYPE_DSMCC_B: 
    10151017            val = 1; 
    10161018            break; 
     
    15981600            codec_type = CODEC_TYPE_SUBTITLE; 
    15991601            codec_id = CODEC_ID_DVB_SUBTITLE; 
    16001602            break; 
     1603        case STREAM_TYPE_SUBTITLE_PGS: 
     1604            codec_type = CODEC_TYPE_SUBTITLE; 
     1605            codec_id = CODEC_ID_HDMV_PGS_SUBTITLE; 
     1606            break; 
    16011607        case STREAM_TYPE_DSMCC_B: 
    16021608            codec_type = CODEC_TYPE_DATA; 
    16031609            codec_id = CODEC_ID_DSMCC_B; 
  • libs/libavformat/mpegts.h

     
    6969#define STREAM_TYPE_AUDIO_HDMV_DTS_HD_MASTER 0x86 
    7070 
    7171#define STREAM_TYPE_SUBTITLE_DVB    0x100 
     72#define STREAM_TYPE_SUBTITLE_PGS    0x90 
    7273#define STREAM_TYPE_VBI_DVB         0x101 
    7374 
    7475typedef struct MpegTSContext MpegTSContext;