Ticket #6748: bluray_subtitles_mythtv_trunk_20972.diff

File bluray_subtitles_mythtv_trunk_20972.diff, 23.7 KB (added by Stephen <stev391@…>, 10 years ago)

Patch as per original description

  • 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 */
     
    340341    REGISTER_PARSER  (MPEG4VIDEO, mpeg4video);
    341342    REGISTER_PARSER  (MPEGAUDIO, mpegaudio);
    342343    REGISTER_PARSER  (MPEGVIDEO, mpegvideo);
     344    REGISTER_PARSER  (PGSSUB, pgssub);
    343345    REGISTER_PARSER  (PNM, pnm);
    344346    REGISTER_PARSER  (VC1, vc1);
    345347    REGISTER_PARSER  (VP3, vp3);
  • libs/libavcodec/avcodec.h

     
    329329    CODEC_ID_XSUB,
    330330    CODEC_ID_SSA,
    331331    CODEC_ID_MOV_TEXT,
     332    CODEC_ID_HDMV_PGS_SUBTITLE,
    332333
    333334    /* teletext codecs */
    334335    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 }
     
    466467contains( CONFIG_MPEG4VIDEO_PARSER, yes )       { SOURCES *= mpeg4video_parser.c mpeg12data.c mpegvideo.c error_resilience.c }
    467468contains( CONFIG_MPEGAUDIO_PARSER, yes )        { SOURCES *= mpegaudio_parser.c mpegaudiodecheader.c }
    468469contains( CONFIG_MPEGVIDEO_PARSER, yes )        { SOURCES *= mpegvideo_parser.c mpeg12.c mpeg12data.c mpegvideo.c error_resilience.c }
     470contains( CONFIG_PGSSUB_PARSER, yes )           { SOURCES *= pgssub_parser.c }
    469471contains( CONFIG_PNM_PARSER, yes )              { SOURCES *= pnm_parser.c pnm.c }
    470472contains( CONFIG_VC1_PARSER, yes )              { SOURCES *= vc1_parser.c vc1.c vc1data.c msmpeg4data.c h263dec.c h263.c error_resilience.c intrax8.c mpegvideo.c msmpeg4.c }
    471473contains( CONFIG_VP3_PARSER, yes )              { SOURCES *= vp3_parser.c }
  • libs/libavcodec/pgssub_parser.c

     
     1/*
     2 * PGS subtitle parser for FFmpeg
     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 "get_bits.h"
     30
     31//#define DEBUG
     32//#define DEBUG_PACKET_CONTENTS
     33
     34/* Parser (mostly) copied from dvbsub_parser.c */
     35
     36#define PARSE_BUF_SIZE  (65536)
     37
     38
     39/* parser definition */
     40typedef struct PGSSubParseContext {
     41    uint8_t *packet;
     42    int packet_len;
     43    int packet_index;
     44} PGSSubParseContext;
     45
     46static av_cold int pgssub_parse_init(AVCodecParserContext *s)
     47{
     48    PGSSubParseContext *pc = s->priv_data;
     49    pc->packet = av_malloc(PARSE_BUF_SIZE);
     50
     51    return 0;
     52}
     53
     54static int pgssub_parse(AVCodecParserContext *s,
     55                        AVCodecContext *avctx,
     56                        const uint8_t **poutbuf, int *poutbuf_size,
     57                        const uint8_t *buf, int buf_size)
     58{
     59    PGSSubParseContext *pc = s->priv_data;
     60
     61    uint8_t *p, *p_end;
     62    int len, buf_pos = 0;
     63
     64#ifdef DEBUG
     65    av_log(avctx, AV_LOG_INFO, "PGS parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64", buf_size=%d:\n",
     66            s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index], buf_size);
     67#endif
     68
     69#ifdef DEBUG_PACKET_CONTENTS
     70    int i;
     71
     72    for (i=0; i < buf_size; i++)
     73    {
     74        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
     75        if (i % 16 == 15)
     76            av_log(avctx, AV_LOG_INFO, "\n");
     77    }
     78
     79    if (i % 16 != 0)
     80        av_log(avctx, AV_LOG_INFO, "\n");
     81
     82#endif
     83
     84    *poutbuf = NULL;
     85    *poutbuf_size = 0;
     86
     87    if (buf_size < 3) {
     88#ifdef DEBUG
     89        av_log(avctx, AV_LOG_INFO, "Bad packet, not enough data \n");
     90#endif
     91        return -1;
     92    }
     93
     94    pc->packet_len = buf_size;
     95    pc->packet_index = 0;
     96
     97    /* Check we have a large enough buffer */
     98    if (buf_size > PARSE_BUF_SIZE)
     99        return -1;
     100
     101    if (pc->packet)
     102        memcpy(pc->packet, buf, buf_size);
     103    else {
     104#ifdef DEBUG
     105        av_log(avctx, AV_LOG_INFO, "No Buffer Allocated!\n");
     106#endif
     107        return -1;
     108    }
     109
     110    *poutbuf_size = pc->packet_len;
     111    *poutbuf = pc->packet;
     112
     113    return buf_size;
     114}
     115
     116static av_cold void pgssub_parse_close(AVCodecParserContext *s)
     117{
     118    PGSSubParseContext *pc = s->priv_data;
     119    av_freep(&pc->packet);
     120}
     121
     122AVCodecParser pgssub_parser = {
     123    { CODEC_ID_HDMV_PGS_SUBTITLE },
     124    sizeof(PGSSubParseContext),
     125    pgssub_parse_init,
     126    pgssub_parse,
     127    pgssub_parse_close,
     128};
  • libs/libavcodec/pgssubdec.c

     
     1/*
     2 * PGS subtitle decoding for ffmpeg
     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
     31//#define DEBUG
     32//#define DEBUG_PACKET_CONTENTS
     33//#define DEBUG_SAVE_IMAGES
     34
     35#define PGSSUB_PALETTE_SEGMENT      0x14
     36#define PGSSUB_PICTURE_SEGMENT      0x15
     37#define PGSSUB_PRESENTATION_SEGMENT 0x16
     38#define PGSSUB_WINDOW_SEGMENT       0x17
     39#define PGSSUB_DISPLAY_SEGMENT      0x80
     40
     41#define cm (ff_cropTbl + MAX_NEG_CROP)
     42#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
     43
     44typedef struct PGSSubPresentation {
     45    int x;
     46    int y;
     47    int video_w;
     48    int video_h;
     49    int id_number;
     50
     51} PGSSubPresentation;
     52
     53typedef struct PGSSubWindow {
     54    int x;
     55    int y;
     56    int w;
     57    int h;
     58
     59} PGSSubWindow;
     60
     61typedef struct PGSSubPicture {
     62    int w;
     63    int h;
     64
     65    uint8_t *bitmap;
     66
     67} PGSSubPicture;
     68
     69typedef struct PGSSubContext {
     70    PGSSubPresentation *presentation;
     71    PGSSubWindow       *window;
     72    uint32_t clut[256];
     73    PGSSubPicture *picture;
     74
     75} PGSSubContext;
     76
     77static av_cold int pgssub_init_decoder(AVCodecContext *avctx)
     78{
     79    avctx->pix_fmt = PIX_FMT_RGB32;
     80    PGSSubContext *ctx = (PGSSubContext*) avctx->priv_data;
     81    ctx->presentation = av_mallocz(sizeof(PGSSubPresentation));
     82    ctx->window       = av_mallocz(sizeof(PGSSubWindow));
     83    ctx->picture      = av_mallocz(sizeof(PGSSubPicture));
     84
     85    return 0;
     86}
     87
     88static av_cold int pgssub_close_decoder(AVCodecContext *avctx)
     89{
     90    PGSSubContext *ctx = (PGSSubContext*) avctx->priv_data;
     91
     92    if (ctx->picture->bitmap)
     93        av_freep(&ctx->picture->bitmap);
     94
     95    av_freep(&ctx->presentation);
     96    av_freep(&ctx->window);
     97    av_freep(&ctx->picture);
     98    return 0;
     99}
     100
     101static void pgssub_parse_picture_segment(AVCodecContext *avctx,
     102                                        const uint8_t *buf, int buf_size)
     103{
     104    PGSSubContext *ctx = (PGSSubContext*) avctx->priv_data;
     105
     106    uint8_t block;
     107    uint8_t flags;
     108    uint8_t colour;
     109    uint8_t *rle_bitmap_end;
     110    uint8_t sequence_desc;
     111    int rle_bitmap_len, pixel_count, line_count, run, width, height;
     112
     113    /* skip 3 unknown bytes: Object ID (2 bytes), Version Number */
     114    buf += 3;
     115
     116    /* Read the Sequence Description to determine if start of RLE data or Appended to previous RLE */
     117    sequence_desc = AV_RB8(buf);
     118    buf += 1;
     119
     120    if (!(sequence_desc & 0x80)) {
     121        av_log(avctx, AV_LOG_ERROR, "Decoder currently does not support object data over multiple packets.\n", rle_bitmap_len);
     122        return;
     123    }
     124
     125    /* Decode rle bitmap length */
     126    rle_bitmap_len = AV_RB24(buf);
     127    buf += 3;
     128
     129    /* Check to ensure we have enough data for rle_bitmap_length if just a single packet*/
     130    if (rle_bitmap_len > (buf_size - 7)) {
     131        av_log(avctx, AV_LOG_ERROR, "Not enough RLE data for specified length of %d.\n", rle_bitmap_len);
     132        return;
     133    }
     134
     135    rle_bitmap_end = buf + rle_bitmap_len;
     136
     137    /* Get bitmap dimensions from data */
     138    width = AV_RB16(buf);
     139    buf += 2;
     140
     141    height = AV_RB16(buf);
     142    buf += 2;
     143
     144    /* Make sure the bitmap is not too large. */
     145    if (ctx->presentation->video_w < width || ctx->presentation->video_h < height) {
     146        av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger then video. Width=%d Height=%d\n", width, height);
     147        return;
     148    }
     149
     150    ctx->picture->w = width;
     151    ctx->picture->h = height;
     152
     153    ctx->picture->bitmap = av_malloc(width * height * sizeof(uint8_t));
     154
     155    pixel_count = 0;
     156    line_count = 0;
     157
     158    while (buf < rle_bitmap_end && line_count < height) {
     159        block = AV_RB8(buf);
     160        buf += 1;
     161
     162        if (block == 0x00) {
     163            block = AV_RB8(buf);
     164            buf += 1;
     165            flags = block & 0xC0;
     166
     167            switch (flags) {
     168            case 0x00:
     169                run = block & 0x3F;
     170                if (run > 0)
     171                    colour = 0;
     172                break;
     173            case 0xC0:
     174                run = (block & 0x3F) << 8 | AV_RB8(buf);
     175                colour = AV_RB8(buf + 1);
     176                buf += 2;
     177                break;
     178            case 0x80:
     179                run = block & 0x3F;
     180                colour = AV_RB8(buf);
     181                buf += 1;
     182                break;
     183            case 0x40:
     184                run = (block & 0x3F) << 8 | AV_RB8(buf);
     185                colour = 0;
     186                buf += 1;
     187                break;
     188            default:
     189                av_log(avctx, AV_LOG_ERROR, "Unknown RLE code.\n");
     190                run = -1;
     191                break;
     192            }
     193        }
     194        else {
     195            run = 1;
     196            colour = block;
     197        }           
     198
     199        if (run > 0) {
     200            memset(ctx->picture->bitmap + pixel_count, colour, run);
     201            pixel_count += run;
     202        }
     203        else if (run == 0) {
     204            /* New Line. Check if correct pixels decoded, if not display warning and adjust bitmap pointer to correct new line position. */
     205            if (pixel_count % width == width - 1) {
     206                av_log(avctx, AV_LOG_ERROR, "Decoded %d pixels, when line should be %d pixels\n", pixel_count % width, width);
     207            }
     208            line_count++;
     209        }
     210    }
     211#ifdef DEBUG
     212    av_log(avctx, AV_LOG_INFO, "Pixel Count = %d, Area = %d\n", pixel_count, width * height);
     213#endif
     214}
     215
     216static void pgssub_parse_palette_segment(AVCodecContext *avctx,
     217                                        const uint8_t *buf, int buf_size)
     218{
     219    PGSSubContext *ctx = (PGSSubContext*) avctx->priv_data;
     220
     221    const uint8_t *buf_end = buf + buf_size;
     222    int colour_id, max_colour_id;
     223    int y, cb, cr, alpha;
     224    int r, g, b, r_add, g_add, b_add;
     225
     226#ifdef DEBUG_PACKET_CONTENTS
     227    int i;
     228
     229    av_log(avctx, AV_LOG_INFO, "PGS palette packet:\n");
     230
     231    for (i=0; i < buf_size; i++) {
     232        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
     233    }
     234
     235    av_log(avctx, AV_LOG_INFO, "\n");
     236
     237#endif
     238
     239    max_colour_id = (buf_size - 2) % 5;
     240
     241    /* Check to ensure that the buffer provided is not larger then the maximum palette */
     242    if (max_colour_id > 255) {
     243        av_log(avctx, AV_LOG_INFO, "max_colour_id to large at %d\n", max_colour_id);
     244        return;
     245    }
     246
     247    /* Skip two null bytes */
     248    buf += 2;
     249
     250    while (buf < buf_end) {
     251        colour_id = AV_RB8(buf);
     252        buf += 1;
     253        y = AV_RB8(buf);
     254        buf += 1;
     255        cb = AV_RB8(buf);
     256        buf += 1;
     257        cr = AV_RB8(buf);
     258        buf += 1;
     259        alpha = AV_RB8(buf);
     260        buf += 1;
     261
     262        YUV_TO_RGB1(cb, cr);
     263        YUV_TO_RGB2(r, g, b, y);
     264
     265#ifdef DEBUG
     266        av_log(avctx, AV_LOG_INFO, "Colour %d := (%d,%d,%d,%d)\n", colour_id, r, g, b, alpha);
     267#endif
     268
     269        /* Store colour in palette */
     270        if (colour_id < 255)
     271            ctx->clut[colour_id] = RGBA(r,g,b,255 - alpha);
     272    }
     273}
     274
     275
     276static void pgssub_parse_presentation_segment(AVCodecContext *avctx,
     277                                        const uint8_t *buf, int buf_size)
     278{
     279    PGSSubContext *ctx = (PGSSubContext*) avctx->priv_data;
     280    int x, y, video_w, video_h;
     281    uint8_t block;
     282
     283#ifdef DEBUG_PACKET_CONTENTS
     284    int i;
     285
     286    av_log(avctx, AV_LOG_INFO, "PGS presentation packet:\n");
     287
     288    for (i=0; i < buf_size; i++) {
     289        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
     290    }
     291
     292    av_log(avctx, AV_LOG_INFO, "\n");
     293
     294#endif
     295
     296    video_w = AV_RB16(buf);
     297    buf += 2;
     298
     299    video_h = AV_RB16(buf);
     300    buf += 2;
     301
     302    av_log(avctx, AV_LOG_INFO, "Video Dimensions %dx%d\n", video_w, video_h);
     303
     304    ctx->presentation->video_w = video_w;
     305    ctx->presentation->video_h = video_h;
     306
     307    /* Skip 1 bytes of unknown, frame rate? */
     308    buf += 1;
     309
     310    ctx->presentation->id_number = AV_RB16(buf);
     311    buf += 2;
     312
     313    /* Next byte is the state. */
     314    block = AV_RB8(buf);
     315    if (block == 0x80) {
     316        /* Skip 7 bytes (+1 for previous byte) of unknown:
     317               pallete_update_flag (0x80),
     318               pallete_id_to_use,
     319               Object Number (if > 0 determines if more data to process),
     320               object_id_ref (2 bytes),
     321               window_id_ref,
     322               composition_flag (0x80 - object cropped, 0x40 - object forced) */
     323        buf += 8;
     324       
     325        x = AV_RB16(buf);
     326        buf += 2;
     327
     328        y = AV_RB16(buf);
     329        buf += 2;
     330
     331        /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping Height (all 2 bytes). */
     332        av_log(avctx, AV_LOG_INFO, "Subtitle Placement x=%d, y=%d\n", x, y);
     333
     334        if (x > video_w || y > video_h) {
     335            av_log(avctx, AV_LOG_ERROR, "Subtitle Rectangle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n", x, y, video_w, video_h);
     336            x = 0; y =0;
     337        }
     338        /* Fill in dimensions */
     339        ctx->presentation->x = x;
     340        ctx->presentation->y = y;
     341    }
     342    else if (block == 0x00) {
     343        /* No useful information here as the subtitle is about to be blanked.
     344           How do I blank a subtitle??? */
     345    }
     346}
     347
     348static void pgssub_parse_window_segment(AVCodecContext *avctx,
     349                                        const uint8_t *buf, int buf_size)
     350{
     351    PGSSubContext *ctx = (PGSSubContext*) avctx->priv_data;
     352    int x, y, w, h;
     353
     354#ifdef DEBUG_PACKET_CONTENTS
     355    int i;
     356
     357    av_log(avctx, AV_LOG_INFO, "PGS window packet:\n");
     358
     359    for (i=0; i < buf_size; i++) {
     360        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
     361    }
     362
     363    av_log(avctx, AV_LOG_INFO, "\n");
     364
     365#endif
     366    /* Skip 2 bytes of unknown, */
     367    buf += 2;
     368
     369    x = AV_RB16(buf);
     370    buf += 2;
     371
     372    y = AV_RB16(buf);
     373    buf += 2;
     374
     375    w = AV_RB16(buf);
     376    buf += 2;
     377
     378    h = AV_RB16(buf);
     379    buf += 2;
     380
     381#ifdef DEBUG
     382    av_log(avctx, AV_LOG_INFO, "Window dimensions x=%d, y=%d, w=%d, h=%d\n", x, y, w, h);
     383#endif
     384
     385    ctx->window->x = x;
     386    ctx->window->y = y;
     387    ctx->window->w = w;
     388    ctx->window->h = h;
     389
     390}
     391
     392
     393#ifdef DEBUG_SAVE_IMAGES
     394#undef fprintf
     395#undef perror
     396#undef exit
     397static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h,
     398                     uint32_t *rgba_palette)
     399{
     400    int x, y, v;
     401    FILE *f;
     402
     403    f = fopen(filename, "w");
     404    if (!f) {
     405        perror(filename);
     406        exit(1);
     407    }
     408    fprintf(f, "P6\n"
     409            "%d %d\n"
     410            "%d\n",
     411            w, h, 255);
     412    for(y = 0; y < h; y++) {
     413        for(x = 0; x < w; x++) {
     414            v = rgba_palette[bitmap[y * w + x]];
     415            putc((v >> 16) & 0xff, f);
     416            putc((v >> 8) & 0xff, f);
     417            putc((v >> 0) & 0xff, f);
     418        }
     419    }
     420    fclose(f);
     421}
     422#endif
     423
     424static int pgssub_display_end_segment(AVCodecContext *avctx,
     425                                        void *data,
     426                                        const uint8_t *buf, int buf_size)
     427{
     428    AVSubtitle *sub = data;
     429    PGSSubContext *ctx = (PGSSubContext*) avctx->priv_data;
     430
     431    sub->start_display_time = 0;
     432    sub->end_display_time = 10000;
     433    sub->format = 0;
     434
     435    if (!sub->rects) {
     436        sub->rects     = av_mallocz(sizeof(*sub->rects));
     437        sub->rects[0]  = av_mallocz(sizeof(*sub->rects[0]));
     438        sub->num_rects = 1;
     439    }
     440
     441    sub->rects[0]->x    = ctx->presentation->x;
     442    sub->rects[0]->y    = ctx->presentation->y;
     443    sub->rects[0]->w    = ctx->picture->w;
     444    sub->rects[0]->h    = ctx->picture->h;
     445    sub->rects[0]->type = SUBTITLE_BITMAP;
     446
     447    /* Allocate memory for bitmap */
     448    sub->rects[0]->pict.data[0]     = av_malloc(ctx->picture->w * ctx->picture->h);
     449    sub->rects[0]->pict.linesize[0] = ctx->picture->w;
     450
     451    memcpy(sub->rects[0]->pict.data[0], ctx->picture->bitmap, ctx->picture->w * ctx->picture->h);
     452
     453    /* Allocate memory for colours */
     454    sub->rects[0]->nb_colors    = 256;
     455    sub->rects[0]->pict.data[1] = av_mallocz(sub->rects[0]->nb_colors * sizeof(uint32_t));
     456
     457    memcpy(sub->rects[0]->pict.data[1], ctx->clut, sub->rects[0]->nb_colors * sizeof(uint32_t));
     458
     459#ifdef DEBUG_SAVE_IMAGES
     460    ppm_save("/tmp/a.ppm", sub->rects[0]->pict.data[0],
     461             sub->rects[0]->w, sub->rects[0]->h, sub->rects[0]->pict.data[1]);
     462#endif
     463
     464    return 1;
     465}
     466
     467static int pgssub_decode(AVCodecContext *avctx,
     468                         void *data, int *data_size,
     469                         AVPacket *avpkt)
     470{
     471    const uint8_t *buf = avpkt->data;
     472    PGSSubContext *ctx = (PGSSubContext*) avctx->priv_data;
     473    int buf_size = avpkt->size;
     474    const uint8_t *buf_end;
     475    uint8_t segment_type;
     476    int segment_length;
     477
     478#ifdef DEBUG_PACKET_CONTENTS
     479    int i;
     480
     481    av_log(avctx, AV_LOG_INFO, "PGS sub packet:\n");
     482
     483    for (i=0; i < buf_size; i++) {
     484        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
     485        if (i % 16 == 15)
     486            av_log(avctx, AV_LOG_INFO, "\n");
     487    }
     488
     489    if (i % 16)
     490        av_log(avctx, AV_LOG_INFO, "\n");
     491
     492#endif
     493
     494    *data_size = 0;
     495
     496    /* Ensure that we have received at a least a segment code and segment length */
     497    if (buf_size < 3)
     498        return -1;
     499
     500    buf_end = buf + buf_size;
     501
     502    /* Step through buffer to identify segments */
     503    while (buf < buf_end) {
     504        segment_type = AV_RB8(buf);
     505        buf += 1;
     506        segment_length = AV_RB16(buf);
     507        buf += 2;
     508
     509#ifdef DEBUG
     510        av_log(avctx, AV_LOG_INFO, "Segment Length %d, Segment Type %x\n", segment_length,segment_type);
     511#endif
     512
     513        if (!(segment_type == PGSSUB_DISPLAY_SEGMENT) && (buf + segment_length > buf_end))
     514            break;
     515
     516        switch (segment_type) {
     517        case PGSSUB_PALETTE_SEGMENT:
     518            pgssub_parse_palette_segment(avctx, buf, segment_length);
     519            break;
     520        case PGSSUB_PICTURE_SEGMENT:
     521            pgssub_parse_picture_segment(avctx, buf, segment_length);
     522            break;
     523        case PGSSUB_PRESENTATION_SEGMENT:
     524            pgssub_parse_presentation_segment(avctx, buf, segment_length);
     525            break;
     526        case PGSSUB_WINDOW_SEGMENT:
     527            pgssub_parse_window_segment(avctx, buf, segment_length);
     528            break;
     529        case PGSSUB_DISPLAY_SEGMENT:
     530            *data_size = pgssub_display_end_segment(avctx, data, buf, segment_length);
     531            break;
     532        default:
     533#ifdef DEBUG
     534            av_log(avctx, AV_LOG_INFO, "Subtitling segment type 0x%x, length %d\n",
     535                   segment_type, segment_length);
     536#endif
     537            break;
     538        }
     539
     540        buf += segment_length;
     541    }
     542
     543    return buf_size;
     544}
     545
     546
     547AVCodec pgssub_decoder = {
     548    "pgssub",
     549    CODEC_TYPE_SUBTITLE,
     550    CODEC_ID_HDMV_PGS_SUBTITLE,
     551    sizeof(PGSSubContext),
     552    pgssub_init_decoder,
     553    NULL,
     554    pgssub_close_decoder,
     555    pgssub_decode,
     556    .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"),
     557};
  • libs/libavcodec/myth_utils.c

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

     
    574574static const StreamType HDMV_types[] = {
    575575    { 0x81, CODEC_TYPE_AUDIO, CODEC_ID_AC3 },
    576576    { 0x82, CODEC_TYPE_AUDIO, CODEC_ID_DTS },
     577    { 0x90, CODEC_TYPE_SUBTITLE, CODEC_ID_HDMV_PGS_SUBTITLE },
    577578    { 0 },
    578579};
    579580
     
    10011002            //case STREAM_TYPE_PRIVATE_DATA:
    10021003        case STREAM_TYPE_VBI_DVB:
    10031004        case STREAM_TYPE_SUBTITLE_DVB:
     1005        case STREAM_TYPE_SUBTITLE_PGS:
    10041006        case STREAM_TYPE_DSMCC_B:
    10051007            val = 1;
    10061008            break;
     
    15841586            codec_type = CODEC_TYPE_SUBTITLE;
    15851587            codec_id = CODEC_ID_DVB_SUBTITLE;
    15861588            break;
     1589        case STREAM_TYPE_SUBTITLE_PGS:
     1590            codec_type = CODEC_TYPE_SUBTITLE;
     1591            codec_id = CODEC_ID_HDMV_PGS_SUBTITLE;
     1592            break;
    15871593        case STREAM_TYPE_DSMCC_B:
    15881594            codec_type = CODEC_TYPE_DATA;
    15891595            codec_id = CODEC_ID_DSMCC_B;
  • libs/libavformat/mpegts.h

     
    6363#define STREAM_TYPE_AUDIO_DTS       0x8a
    6464
    6565#define STREAM_TYPE_SUBTITLE_DVB    0x100
     66#define STREAM_TYPE_SUBTITLE_PGS    0x90
    6667#define STREAM_TYPE_VBI_DVB         0x101
    6768
    6869typedef struct MpegTSContext MpegTSContext;