void CDVBSub::Render(SubPicDesc& spd, REFERENCE_TIME rt, RECT& bbox) { DVB_PAGE* pPage = FindPage(rt); if (pPage != NULL) { pPage->rendered = true; TRACE_DVB(_T("DVB - Renderer - %s - %s\n"), ReftimeToString(pPage->rtStart), ReftimeToString(pPage->rtStop)); for (int i = 0; i < pPage->regionCount; i++) { DVB_REGION* pRegion = &pPage->regions[i]; DVB_CLUT* pCLUT = FindClut(pPage, pRegion->CLUT_id); if (pCLUT) { for (int j = 0; j < pRegion->objectCount; j++) { CompositionObject* pObject = FindObject(pPage, pRegion->objects[j].object_id); if (pObject) { short nX, nY; nX = pRegion->horizAddr + pRegion->objects[j].object_horizontal_position; nY = pRegion->vertAddr + pRegion->objects[j].object_vertical_position; pObject->m_width = pRegion->width; pObject->m_height = pRegion->height; pObject->SetPalette(pCLUT->size, pCLUT->palette, m_Display.width > 720); pObject->RenderDvb(spd, nX, nY); TRACE_DVB(_T(" --> %d/%d - %d/%d\n"), i + 1, pPage->regionCount, j + 1, pRegion->objectCount); } } } } bbox.left = 0; bbox.top = 0; bbox.right = m_Display.width; bbox.bottom = m_Display.height; } }
HRESULT CDVBSub::ParseClut(CGolombBuffer& gb, WORD wSegLength) { HRESULT hr = E_POINTER; if (m_pCurrentPage) { size_t nExpectedSize = 2; size_t nEnd = gb.GetPos() + wSegLength; BYTE id = gb.ReadByte(); POSITION posClut = FindClut(m_pCurrentPage, id); if (!posClut) { posClut = m_pCurrentPage->CLUTs.AddTail(CAutoPtr<DVB_CLUT>(DEBUG_NEW DVB_CLUT())); } const auto& pClut = m_pCurrentPage->CLUTs.GetAt(posClut); pClut->id = id; pClut->version_number = (BYTE)gb.BitRead(4); gb.BitRead(4); // Reserved pClut->size = 0; while (gb.GetPos() < nEnd) { nExpectedSize += 2; pClut->palette[pClut->size].entry_id = gb.ReadByte(); BYTE _2_bit = (BYTE)gb.BitRead(1); BYTE _4_bit = (BYTE)gb.BitRead(1); BYTE _8_bit = (BYTE)gb.BitRead(1); UNREFERENCED_PARAMETER(_2_bit); UNREFERENCED_PARAMETER(_4_bit); UNREFERENCED_PARAMETER(_8_bit); gb.BitRead(4); // Reserved if (gb.BitRead(1)) { nExpectedSize += 4; pClut->palette[pClut->size].Y = gb.ReadByte(); pClut->palette[pClut->size].Cr = gb.ReadByte(); pClut->palette[pClut->size].Cb = gb.ReadByte(); pClut->palette[pClut->size].T = 0xff - gb.ReadByte(); } else { nExpectedSize += 2; pClut->palette[pClut->size].Y = (BYTE)gb.BitRead(6) << 2; pClut->palette[pClut->size].Cr = (BYTE)gb.BitRead(4) << 4; pClut->palette[pClut->size].Cb = (BYTE)gb.BitRead(4) << 4; pClut->palette[pClut->size].T = 0xff - ((BYTE)gb.BitRead(2) << 6); } if (!pClut->palette[pClut->size].Y) { pClut->palette[pClut->size].Cr = 0; pClut->palette[pClut->size].Cb = 0; pClut->palette[pClut->size].T = 0; } pClut->size++; } hr = (wSegLength == nExpectedSize) ? S_OK : E_UNEXPECTED; } return hr; }
HRESULT CDVBSub::ParseClut(CGolombBuffer& gb, WORD wSegLength) { HRESULT hr = S_OK; int nEnd = gb.GetPos() + wSegLength; BYTE CLUT_id = gb.ReadByte(); if (m_pCurrentPage != NULL) { CDVBSub::DVB_CLUT DummyClut; CDVBSub::DVB_CLUT* pClut = FindClut(m_pCurrentPage, CLUT_id); if (pClut == NULL) { pClut = &DummyClut; } pClut->id = CLUT_id; pClut->version_number = (BYTE)gb.BitRead(4); gb.BitRead(4); // Reserved pClut->Size = 0; while (gb.GetPos() < nEnd) { BYTE entry_id = gb.ReadByte(); BYTE _2_bit = (BYTE)gb.BitRead(1); BYTE _4_bit = (BYTE)gb.BitRead(1); BYTE _8_bit = (BYTE)gb.BitRead(1); UNREFERENCED_PARAMETER(_2_bit); UNREFERENCED_PARAMETER(_4_bit); UNREFERENCED_PARAMETER(_8_bit); gb.BitRead(4); // Reserved pClut->Palette[entry_id].entry_id = entry_id; if (gb.BitRead(1)) { pClut->Palette[entry_id].Y = gb.ReadByte(); pClut->Palette[entry_id].Cr = gb.ReadByte(); pClut->Palette[entry_id].Cb = gb.ReadByte(); pClut->Palette[entry_id].T = 0xff-gb.ReadByte(); } else { pClut->Palette[entry_id].Y = (BYTE)gb.BitRead(6)<<2; pClut->Palette[entry_id].Cr = (BYTE)gb.BitRead(4)<<4; pClut->Palette[entry_id].Cb = (BYTE)gb.BitRead(4)<<4; pClut->Palette[entry_id].T = 0xff-((BYTE)gb.BitRead(2)<<6); } if (!pClut->Palette[entry_id].Y) { pClut->Palette[entry_id].Cr = 0; pClut->Palette[entry_id].Cb = 0; pClut->Palette[entry_id].T = 0; } pClut->Size = max (pClut->Size, entry_id + 1); } if (DummyClut.Size) { m_pCurrentPage->Clut.AddTail(DummyClut); } } return hr; }
STDMETHODIMP CDVBSub::Render(SubPicDesc& spd, REFERENCE_TIME rt, double fps, RECT& bbox) { CAutoLock cAutoLock(&m_csCritSec); rt -= m_rtCurrentSegmentStart; // Make sure the timing are relative to the current segment start RemoveOldPages(rt); if (POSITION posPage = FindPage(rt)) { const auto& pPage = m_pages.GetAt(posPage); bool BT709 = m_infoSourceTarget.sourceMatrix == BT_709 ? true : m_infoSourceTarget.sourceMatrix == NONE ? (m_displayInfo.width > 720) : false; pPage->rendered = true; TRACE_DVB(_T("DVB - Renderer - %s - %s\n"), ReftimeToString(pPage->rtStart + m_rtCurrentSegmentStart), ReftimeToString(pPage->rtStop + m_rtCurrentSegmentStart)); int nRegion = 1, nObject = 1; for (POSITION pos = pPage->regionsPos.GetHeadPosition(); pos; nRegion++) { DVB_REGION_POS regionPos = pPage->regionsPos.GetNext(pos); if (POSITION posRegion = FindRegion(pPage, regionPos.id)) { const auto& pRegion = pPage->regions.GetAt(posRegion); if (POSITION posCLUT = FindClut(pPage, pRegion->CLUT_id)) { const auto& pCLUT = pPage->CLUTs.GetAt(posCLUT); for (POSITION posO = pRegion->objects.GetHeadPosition(); posO; nObject++) { DVB_OBJECT objectPos = pRegion->objects.GetNext(posO); if (POSITION posObject = FindObject(pPage, objectPos.object_id)) { const auto& pObject = pPage->objects.GetAt(posObject); short nX = regionPos.horizAddr + objectPos.object_horizontal_position; short nY = regionPos.vertAddr + objectPos.object_vertical_position; pObject->m_width = pRegion->width; pObject->m_height = pRegion->height; pObject->SetPalette(pCLUT->size, pCLUT->palette, BT709, m_infoSourceTarget.sourceBlackLevel, m_infoSourceTarget.sourceWhiteLevel, m_infoSourceTarget.targetBlackLevel, m_infoSourceTarget.targetWhiteLevel); pObject->RenderDvb(spd, nX, nY); TRACE_DVB(_T(" --> %d/%d - %d/%d\n"), nRegion, pPage->regionsPos.GetCount(), nObject, pRegion->objects.GetCount()); } } } } } bbox.left = 0; bbox.top = 0; bbox.right = m_displayInfo.width; bbox.bottom = m_displayInfo.height; } return S_OK; }
HRESULT CDVBSub::ParseClut(CGolombBuffer& gb, WORD wSegLength) { HRESULT hr = S_OK; WORD wEnd = (WORD)gb.GetPos() + wSegLength; CDVBSub::DVB_CLUT* pClut; pClut = FindClut (m_pCurrentPage, gb.ReadByte()); // ASSERT (pClut != NULL); if (pClut != NULL) { pClut->version_number = (BYTE)gb.BitRead(4); gb.BitRead(4); // Reserved pClut->Size = 0; while (gb.GetPos() < wEnd) { BYTE entry_id = gb.ReadByte()+1; BYTE _2_bit = (BYTE)gb.BitRead(1); BYTE _4_bit = (BYTE)gb.BitRead(1); BYTE _8_bit = (BYTE)gb.BitRead(1); gb.BitRead(4); // Reserved pClut->Palette[entry_id].entry_id = entry_id; if (gb.BitRead(1)) { pClut->Palette[entry_id].Y = gb.ReadByte(); pClut->Palette[entry_id].Cr = gb.ReadByte(); pClut->Palette[entry_id].Cb = gb.ReadByte(); pClut->Palette[entry_id].T = 255-gb.ReadByte(); } else { pClut->Palette[entry_id].Y = (BYTE)gb.BitRead(6)<<2; pClut->Palette[entry_id].Cr = (BYTE)gb.BitRead(4)<<4; pClut->Palette[entry_id].Cb = (BYTE)gb.BitRead(4)<<4; pClut->Palette[entry_id].T = 255-((BYTE)gb.BitRead(2)<<6); } pClut->Size = max (pClut->Size, entry_id); } } return hr; }
void CDVBSub::Render(SubPicDesc& spd, REFERENCE_TIME rt, RECT& bbox) { DVB_PAGE* pPage = FindPage (rt); if (pPage != NULL) { pPage->Rendered = true; for (int i=0; i<pPage->RegionCount; i++) { CDVBSub::DVB_REGION* pRegion = &pPage->Regions[i]; for (int j=0; j<pRegion->ObjectCount; j++) { CompositionObject* pObject = FindObject (pPage, pRegion->Objects[j].object_id); if (pObject) { SHORT nX, nY; nX = pRegion->HorizAddr + pRegion->Objects[j].object_horizontal_position; nY = pRegion->VertAddr + pRegion->Objects[j].object_vertical_position; pObject->m_width = pRegion->width; pObject->m_height = pRegion->height; CDVBSub::DVB_CLUT* pClut = FindClut(pPage, pRegion->CLUT_id); if (pClut != NULL) { pObject->SetPalette(pClut->Size, pClut->Palette, m_Display.width > 720); } TRACE_DVB (_T("CDVBSub::Render() : size = %ld, %d:%d, ObjRes = %dx%d, SPDRes = %dx%d, %I64d = %ws, [%ws => %ws]\n"), pObject->GetRLEDataSize(), nX, nY, pObject->m_width, pObject->m_height, spd.w, spd.h, rt, ReftimeToString(rt), ReftimeToString(pPage->rtStart), ReftimeToString(pPage->rtStop)); pObject->RenderDvb(spd, nX, nY); } } } bbox.left = 0; bbox.top = 0; bbox.right = m_Display.width < spd.w ? m_Display.width : spd.w; ASSERT(spd.h >= 0); bbox.bottom = m_Display.height < spd.h ? m_Display.height : spd.h; } }
HRESULT CDVBSub::ParseClut(CGolombBuffer& gb, WORD wSegLength) { HRESULT hr = E_FAIL; int nEnd = gb.GetPos() + wSegLength; if (m_pCurrentPage && wSegLength > 2) { BYTE id = gb.ReadByte(); DVB_CLUT* pClut = FindClut(m_pCurrentPage, id); bool bIsNewClut = (pClut == nullptr); if (bIsNewClut) { pClut = DEBUG_NEW DVB_CLUT(); } if (pClut) { pClut->id = id; pClut->version_number = (BYTE)gb.BitRead(4); gb.BitRead(4); // Reserved pClut->size = 0; while (gb.GetPos() < nEnd) { pClut->palette[pClut->size].entry_id = gb.ReadByte(); BYTE _2_bit = (BYTE)gb.BitRead(1); BYTE _4_bit = (BYTE)gb.BitRead(1); BYTE _8_bit = (BYTE)gb.BitRead(1); UNREFERENCED_PARAMETER(_2_bit); UNREFERENCED_PARAMETER(_4_bit); UNREFERENCED_PARAMETER(_8_bit); gb.BitRead(4); // Reserved if (gb.BitRead(1)) { pClut->palette[pClut->size].Y = gb.ReadByte(); pClut->palette[pClut->size].Cr = gb.ReadByte(); pClut->palette[pClut->size].Cb = gb.ReadByte(); pClut->palette[pClut->size].T = 0xff - gb.ReadByte(); } else { pClut->palette[pClut->size].Y = (BYTE)gb.BitRead(6) << 2; pClut->palette[pClut->size].Cr = (BYTE)gb.BitRead(4) << 4; pClut->palette[pClut->size].Cb = (BYTE)gb.BitRead(4) << 4; pClut->palette[pClut->size].T = 0xff - ((BYTE)gb.BitRead(2) << 6); } if (!pClut->palette[pClut->size].Y) { pClut->palette[pClut->size].Cr = 0; pClut->palette[pClut->size].Cb = 0; pClut->palette[pClut->size].T = 0; } pClut->size++; } if (bIsNewClut) { m_pCurrentPage->CLUTs.AddTail(pClut); } hr = S_OK; } else { hr = E_OUTOFMEMORY; } } return hr; }