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 }
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 }