Ticket #8061: hd_dvbsubs.diff

File hd_dvbsubs.diff, 8.1 KB (added by markk, 14 years ago)

Patch to support Display Definition Segment in the DVB subtitle decoder.

  • libs/libmythtv/NuppelVideoPlayer.cpp

     
    71047104            {
    71057105                // AVSubtitleRect's image data's not guaranteed to be 4 byte
    71067106                // aligned.
    7107 
    7108                 QRect qrect(rect->x, rect->y, rect->w, rect->h);
    7109                 QRect scaled = videoOutput->GetImageRect(qrect);
    7110 
    7111                 QImage qImage(rect->w, rect->h, QImage::Format_ARGB32);
     7107                QSize img_size(rect->w, rect->h);
     7108                QRect img_rect(rect->x, rect->y, rect->w, rect->h);
     7109                QRect display(rect->display_x, rect->display_y,
     7110                              rect->display_w, rect->display_h);
     7111                QRect scaled = videoOutput->GetImageRect(img_rect, &display);
     7112                QImage qImage(img_size, QImage::Format_ARGB32);
    71127113                for (int y = 0; y < rect->h; ++y)
    71137114                {
    71147115                    for (int x = 0; x < rect->w; ++x)
     
    71207121                }
    71217122
    71227123
    7123                 if (scaled.size() != qrect.size())
     7124                if (scaled.size() != img_size)
    71247125                {
    71257126                    qImage = qImage.scaled(scaled.width(), scaled.height(),
    71267127                             Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
  • libs/libmythtv/videooutbase.cpp

     
    13991399*/
    14001400}
    14011401
    1402 QRect VideoOutput::GetImageRect(const QRect &rect)
     1402QRect VideoOutput::GetImageRect(const QRect &rect, QRect *display)
    14031403{
    1404     QRect result = rect;
    14051404    float hscale, vscale, tmp;
    14061405    tmp = 0.0;
    14071406    QRect visible_osd  = GetVisibleOSDBounds(tmp, tmp, tmp);
     
    14131412    float pixel_aspect = (float)video_size.width() /
    14141413                         (float)video_size.height();
    14151414
     1415    QRect rect1 = rect;
     1416    if (display && display->isValid())
     1417    {
     1418        QMatrix m0;
     1419        m0.scale((float)image_width  / (float)display->width(),
     1420                 (float)image_height / (float)display->height());
     1421        rect1 = m0.mapRect(rect1);
     1422        rect1.translate(display->left(), display->top());
     1423    }
     1424    QRect result = rect1;
     1425
    14161426    if (hasFullScreenOSD())
    14171427    {
    14181428        QRect dvr_rec = windows[0].GetDisplayVideoRect();
     
    14451455    hscale = pixel_aspect / image_aspect;
    14461456    if (hscale < 0.99f || hscale > 1.01f)
    14471457    {
    1448         result.setLeft((int)(((float)rect.left() * hscale) + 0.5f));
    1449         result.setWidth((int)(((float)rect.width() * hscale) + 0.5f));
     1458        result.setLeft((int)(((float)rect1.left() * hscale) + 0.5f));
     1459        result.setWidth((int)(((float)rect1.width() * hscale) + 0.5f));
    14501460    }
    14511461
    14521462    result.translate(-visible_osd.left(), -visible_osd.top());
  • libs/libmythtv/videooutbase.h

     
    244244
    245245    QString GetFilters(void) const;
    246246    /// \brief translates caption/dvd button rectangle into 'screen' space
    247     QRect   GetImageRect(const QRect &rect);
     247    QRect   GetImageRect(const QRect &rect, QRect *display = NULL);
    248248
    249249  protected:
    250250    void InitBuffers(int numdecode, bool extra_for_pause, int need_free,
  • libs/libavcodec/dvbsubdec.c

     
    3131#define DVBSUB_REGION_SEGMENT   0x11
    3232#define DVBSUB_CLUT_SEGMENT     0x12
    3333#define DVBSUB_OBJECT_SEGMENT   0x13
     34#define DVBSUB_DISPDEF_SEGMENT  0x14
    3435#define DVBSUB_DISPLAY_SEGMENT  0x80
    3536
    3637#define cm (ff_cropTbl + MAX_NEG_CROP)
     
    216217    struct DVBSubRegion *next;
    217218} DVBSubRegion;
    218219
     220typedef struct DVBSubDisplayDefinition {
     221    int version;
     222
     223    int x;
     224    int y;
     225    int width;
     226    int height;
     227} DVBSubDisplayDefinition;
     228
    219229typedef struct DVBSubContext {
    220230    int composition_id;
    221231    int ancillary_id;
     
    227237
    228238    int display_list_size;
    229239    DVBSubRegionDisplay *display_list;
     240    DVBSubDisplayDefinition *display_definition;
    230241} DVBSubContext;
    231242
    232243
     
    334345        av_free(clut);
    335346    }
    336347
     348    if (ctx->display_definition)
     349        av_free(ctx->display_definition);
     350
    337351    /* Should already be null */
    338352    if (ctx->object_list)
    339353        av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n");
     
    12741288}
    12751289#endif
    12761290
     1291static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx,
     1292                                                   const uint8_t *buf,
     1293                                                   int buf_size)
     1294{
     1295    DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
     1296    DVBSubDisplayDefinition *display_def = ctx->display_definition;
     1297    int dds_version, window_max_x, window_max_y, i;
     1298
     1299    if (buf_size < 5)
     1300        return;
     1301
     1302    i = AV_RB8(buf++);
     1303    dds_version = (i >> 4) & 0xF;
     1304    if (display_def && (display_def->version == dds_version)) {
     1305        return;
     1306    }
     1307
     1308    if (!display_def) {
     1309        ctx->display_definition = av_mallocz(sizeof(DVBSubDisplayDefinition));
     1310        display_def = ctx->display_definition;
     1311    }
     1312
     1313    display_def->version = dds_version;
     1314    display_def->x       = 0;
     1315    display_def->y       = 0;
     1316    display_def->width   = AV_RB16(buf) + 1;
     1317    buf += 2;
     1318    display_def->height  = AV_RB16(buf) + 1;
     1319    buf += 2;
     1320
     1321    if (buf_size < 13)
     1322        return;
     1323
     1324    if ((i >> 3) & 1) { // window definition
     1325        display_def->x = AV_RB16(buf);
     1326        buf += 2;
     1327        display_def->y = AV_RB16(buf);
     1328        buf += 2;
     1329        window_max_x = AV_RB16(buf);
     1330        buf += 2;
     1331        window_max_y = AV_RB16(buf);
     1332        display_def->width  = window_max_x - display_def->x;
     1333        display_def->height = window_max_y - display_def->y;
     1334    }
     1335}
     1336
    12771337static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
    12781338                                        int buf_size, AVSubtitle *sub)
    12791339{
    12801340    DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
     1341    DVBSubDisplayDefinition *display_def = ctx->display_definition;
    12811342
    12821343    DVBSubRegion *region;
    12831344    DVBSubRegionDisplay *display;
     
    13161377        rect->type      = SUBTITLE_BITMAP;
    13171378        rect->pict.linesize[0] = region->width;
    13181379
     1380        if (display_def) {
     1381            rect->display_x = display_def->x;
     1382            rect->display_y = display_def->y;
     1383            rect->display_w = display_def->width;
     1384            rect->display_h = display_def->height;
     1385        }
     1386        else {
     1387            rect->display_w = 720;
     1388            rect->display_h = 576;
     1389        }
     1390
    13191391        clut = get_clut(ctx, region->clut);
    13201392
    13211393        if (!clut)
     
    14091481            case DVBSUB_OBJECT_SEGMENT:
    14101482                dvbsub_parse_object_segment(avctx, p, segment_length);
    14111483                break;
     1484            case DVBSUB_DISPDEF_SEGMENT:
     1485                dvbsub_parse_display_definition_segment(avctx, p, segment_length);
    14121486            case DVBSUB_DISPLAY_SEGMENT:
    14131487                *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub);
    14141488                break;
  • libs/libavcodec/avcodec.h

     
    28342834    int w;         ///< width            of pict, undefined when pict is not set
    28352835    int h;         ///< height           of pict, undefined when pict is not set
    28362836    int nb_colors; ///< number of colors in pict, undefined when pict is not set
     2837    int display_x; ///< top left corner of region into which pict is displayed
     2838    int display_y; ///< top left corner of region into which pict is displayed
     2839    int display_w; ///< width           of region into which pict is displayed
     2840    int display_h; ///< height          of region into which pict is displayed
    28372841
    28382842    /**
    28392843     * data+linesize for the bitmap of this subtitle.