Пример #1
0
void CDVDInputStreamBluray::OverlayClear(SPlane& plane, int x, int y, int w, int h)
{
#if(BD_OVERLAY_INTERFACE_VERSION >= 2)
  CRectInt ovr(x
          , y
          , x + w
          , y + h);

  /* fixup existing overlays */
  for(SOverlays::iterator it = plane.o.begin(); it != plane.o.end();)
  {
    CRectInt old((*it)->x
            , (*it)->y
            , (*it)->x + (*it)->width
            , (*it)->y + (*it)->height);

    std::vector<CRectInt> rem = old.SubtractRect(ovr);

    /* if no overlap we are done */
    if(rem.size() == 1 && !(rem[0] != old))
    {
      ++it;
      continue;
    }

    SOverlays add;
    for(std::vector<CRectInt>::iterator itr = rem.begin(); itr != rem.end(); ++itr)
    {
      SOverlay overlay(new CDVDOverlayImage(*(*it)
                                            , itr->x1
                                            , itr->y1
                                            , itr->Width()
                                            , itr->Height())
                    , std::ptr_fun(CDVDOverlay::Release));
      add.push_back(overlay);
    }

    it = plane.o.erase(it);
    plane.o.insert(it, add.begin(), add.end());
  }
#endif
}
Пример #2
0
void CDVDInputStreamBluray::OverlayCallback(const BD_OVERLAY * const ov)
{
#if(BD_OVERLAY_INTERFACE_VERSION >= 2)
    if(ov == NULL || ov->cmd == BD_OVERLAY_CLOSE)
    {
        for(unsigned i = 0; i < 2; ++i)
            m_planes[i].o.clear();
        CDVDOverlayGroup* group   = new CDVDOverlayGroup();
        group->bForced = true;
        m_player->OnDVDNavResult(group, 0);
        return;
    }

    if (ov->plane > 1)
    {
        CLog::Log(LOGWARNING, "CDVDInputStreamBluray - Ignoring overlay with multiple planes");
        return;
    }

    SPlane& plane(m_planes[ov->plane]);

    if (ov->cmd == BD_OVERLAY_CLEAR)
    {
        plane.o.clear();
        return;
    }

    if (ov->cmd == BD_OVERLAY_INIT)
    {
        plane.o.clear();
        plane.w = ov->w;
        plane.h = ov->h;
        return;
    }

    if (ov->cmd == BD_OVERLAY_DRAW
            ||  ov->cmd == BD_OVERLAY_WIPE)
    {
        CRect ovr(ov->x
                  , ov->y
                  , ov->x + ov->w
                  , ov->y + ov->h);

        /* fixup existing overlays */
        for(SOverlays::iterator it = plane.o.begin(); it != plane.o.end();)
        {
            CRect old((*it)->x
                      , (*it)->y
                      , (*it)->x + (*it)->width
                      , (*it)->y + (*it)->height);

            vector<CRect> rem = old.SubtractRect(ovr);

            /* if no overlap we are done */
            if(rem.size() == 1 && !(rem[0] != old))
            {
                it++;
                continue;
            }

            SOverlays add;
            for(vector<CRect>::iterator itr = rem.begin(); itr != rem.end(); ++itr)
            {
                SOverlay overlay(new CDVDOverlayImage(*(*it)
                                                      , itr->x1
                                                      , itr->y1
                                                      , itr->Width()
                                                      , itr->Height())
                                 , std::ptr_fun(CDVDOverlay::Release));
                add.push_back(overlay);
            }

            it = plane.o.erase(it);
            plane.o.insert(it, add.begin(), add.end());
        }
    }

    /* uncompress and draw bitmap */
    if (ov->img && ov->cmd == BD_OVERLAY_DRAW)
    {
        SOverlay overlay(new CDVDOverlayImage(), std::ptr_fun(CDVDOverlay::Release));

        if (ov->palette)
        {
            overlay->palette_colors = 256;
            overlay->palette        = (uint32_t*)calloc(overlay->palette_colors, 4);

            for(unsigned i = 0; i < 256; i++)
                overlay->palette[i] = build_rgba(ov->palette[i]);
        }

        const BD_PG_RLE_ELEM *rlep = ov->img;
        uint8_t *img = (uint8_t*) malloc(ov->w * ov->h);
        unsigned pixels = ov->w * ov->h;

        for (unsigned i = 0; i < pixels; i += rlep->len, rlep++) {
            memset(img + i, rlep->color, rlep->len);
        }

        overlay->data     = img;
        overlay->linesize = ov->w;
        overlay->x        = ov->x;
        overlay->y        = ov->y;
        overlay->height   = ov->h;
        overlay->width    = ov->w;
        overlay->source_height = plane.h;
        overlay->source_width  = plane.w;
        plane.o.push_back(overlay);
    }

    if(ov->cmd == BD_OVERLAY_FLUSH)
    {
        CDVDOverlayGroup* group   = new CDVDOverlayGroup();
        group->bForced       = true;
        group->iPTSStartTime = (double) ov->pts;
        group->iPTSStopTime  = 0;

        for(unsigned i = 0; i < 2; ++i)
        {
            for(SOverlays::iterator it = m_planes[i].o.begin(); it != m_planes[i].o.end(); ++it)
                group->m_overlays.push_back((*it)->Acquire());
        }

        m_player->OnDVDNavResult(group, 0);
    }
#endif
}