Fixed horizontal scaling of subtitles

This commit is contained in:
Klaus Schmidinger 2011-03-20 15:19:28 +01:00
parent 31d4abab37
commit d7d57c3d2a
4 changed files with 32 additions and 33 deletions

View File

@ -1264,6 +1264,7 @@ Reinhard Nissl <rnissl@gmx.de>
for some valuable input during development of the TrueColor OSD, help with for some valuable input during development of the TrueColor OSD, help with
debugging, and an implementation of the AlphaBlend() function. debugging, and an implementation of the AlphaBlend() function.
for storing the original display size when handling DVB subtitles for storing the original display size when handling DVB subtitles
for reporting a problem with horizontal scaling of subtitles
Richard Robson <richard_robson@beeb.net> Richard Robson <richard_robson@beeb.net>
for reporting freezing replay if a timer starts while in Transfer Mode from the for reporting freezing replay if a timer starts while in Transfer Mode from the

View File

@ -6566,3 +6566,4 @@ Video Disk Recorder Revision History
of complete frames. of complete frames.
- Made updating the editing marks during replay react faster in case the marks - Made updating the editing marks during replay react faster in case the marks
file has just been written. file has just been written.
- Fixed horizontal scaling of subtitles (reported by Reinhard Nissl).

View File

@ -7,7 +7,7 @@
* Original author: Marco Schlüßler <marco@lordzodiac.de> * Original author: Marco Schlüßler <marco@lordzodiac.de>
* With some input from the "subtitle plugin" by Pekka Virtanen <pekka.virtanen@sci.fi> * With some input from the "subtitle plugin" by Pekka Virtanen <pekka.virtanen@sci.fi>
* *
* $Id: dvbsubtitle.c 2.12 2011/03/13 13:54:05 kls Exp $ * $Id: dvbsubtitle.c 2.13 2011/03/20 15:10:30 kls Exp $
*/ */
#include "dvbsubtitle.h" #include "dvbsubtitle.h"
@ -420,7 +420,7 @@ public:
int PageId(void) { return pageId; } int PageId(void) { return pageId; }
int Version(void) { return version; } int Version(void) { return version; }
int State(void) { return state; } int State(void) { return state; }
tArea *GetAreas(double Factor); tArea *GetAreas(double FactorX, double FactorY);
cSubtitleClut *GetClutById(int ClutId, bool New = false); cSubtitleClut *GetClutById(int ClutId, bool New = false);
cSubtitleObject *GetObjectById(int ObjectId); cSubtitleObject *GetObjectById(int ObjectId);
cSubtitleRegion *GetRegionById(int RegionId, bool New = false); cSubtitleRegion *GetRegionById(int RegionId, bool New = false);
@ -446,16 +446,16 @@ cDvbSubtitlePage::~cDvbSubtitlePage()
{ {
} }
tArea *cDvbSubtitlePage::GetAreas(double Factor) tArea *cDvbSubtitlePage::GetAreas(double FactorX, double FactorY)
{ {
if (regions.Count() > 0) { if (regions.Count() > 0) {
tArea *Areas = new tArea[regions.Count()]; tArea *Areas = new tArea[regions.Count()];
tArea *a = Areas; tArea *a = Areas;
for (cSubtitleRegion *sr = regions.First(); sr; sr = regions.Next(sr)) { for (cSubtitleRegion *sr = regions.First(); sr; sr = regions.Next(sr)) {
a->x1 = int(round(Factor * sr->HorizontalAddress())); a->x1 = int(round(FactorX * sr->HorizontalAddress()));
a->y1 = int(round(Factor * sr->VerticalAddress())); a->y1 = int(round(FactorY * sr->VerticalAddress()));
a->x2 = int(round(Factor * (sr->HorizontalAddress() + sr->Width() - 1))); a->x2 = int(round(FactorX * (sr->HorizontalAddress() + sr->Width() - 1)));
a->y2 = int(round(Factor * (sr->VerticalAddress() + sr->Height() - 1))); a->y2 = int(round(FactorY * (sr->VerticalAddress() + sr->Height() - 1)));
a->bpp = sr->Bpp(); a->bpp = sr->Bpp();
while ((a->Width() & 3) != 0) while ((a->Width() & 3) != 0)
a->x2++; // aligns width to a multiple of 4, so 2, 4 and 8 bpp will work a->x2++; // aligns width to a multiple of 4, so 2, 4 and 8 bpp will work
@ -616,10 +616,11 @@ private:
int timeout; int timeout;
tArea *areas; tArea *areas;
int numAreas; int numAreas;
double osdFactor; double osdFactorX;
double osdFactorY;
cVector<cBitmap *> bitmaps; cVector<cBitmap *> bitmaps;
public: public:
cDvbSubtitleBitmaps(int64_t Pts, int Timeout, tArea *Areas, int NumAreas, double OsdFactor); cDvbSubtitleBitmaps(int64_t Pts, int Timeout, tArea *Areas, int NumAreas, double OsdFactorX, double OsdFactorY);
~cDvbSubtitleBitmaps(); ~cDvbSubtitleBitmaps();
int64_t Pts(void) { return pts; } int64_t Pts(void) { return pts; }
int Timeout(void) { return timeout; } int Timeout(void) { return timeout; }
@ -627,13 +628,14 @@ public:
void Draw(cOsd *Osd); void Draw(cOsd *Osd);
}; };
cDvbSubtitleBitmaps::cDvbSubtitleBitmaps(int64_t Pts, int Timeout, tArea *Areas, int NumAreas, double OsdFactor) cDvbSubtitleBitmaps::cDvbSubtitleBitmaps(int64_t Pts, int Timeout, tArea *Areas, int NumAreas, double OsdFactorX, double OsdFactorY)
{ {
pts = Pts; pts = Pts;
timeout = Timeout; timeout = Timeout;
areas = Areas; areas = Areas;
numAreas = NumAreas; numAreas = NumAreas;
osdFactor = OsdFactor; osdFactorX = OsdFactorX;
osdFactorY = OsdFactorY;
} }
cDvbSubtitleBitmaps::~cDvbSubtitleBitmaps() cDvbSubtitleBitmaps::~cDvbSubtitleBitmaps()
@ -653,9 +655,9 @@ void cDvbSubtitleBitmaps::Draw(cOsd *Osd)
if (Osd->SetAreas(areas, numAreas) == oeOk) { if (Osd->SetAreas(areas, numAreas) == oeOk) {
for (int i = 0; i < bitmaps.Size(); i++) { for (int i = 0; i < bitmaps.Size(); i++) {
cBitmap *b = bitmaps[i]; cBitmap *b = bitmaps[i];
if (!DoubleEqual(osdFactor, 1.0)) if (!(DoubleEqual(osdFactorX, 1.0) && DoubleEqual(osdFactorY, 1.0)))
b = b->Scale(osdFactor, osdFactor); b = b->Scale(osdFactorX, osdFactorY);
Osd->DrawBitmap(int(round(b->X0() * osdFactor)), int(round(b->Y0() * osdFactor)), *b); Osd->DrawBitmap(int(round(b->X0() * osdFactorX)), int(round(b->Y0() * osdFactorY)), *b);
if (b != bitmaps[i]) if (b != bitmaps[i])
delete b; delete b;
} }
@ -862,27 +864,21 @@ tColor cDvbSubtitleConverter::yuv2rgb(int Y, int Cb, int Cr)
void cDvbSubtitleConverter::SetOsdData(void) void cDvbSubtitleConverter::SetOsdData(void)
{ {
int OsdWidth; int OsdWidth, OsdHeight;
int OsdHeight;
double OsdAspect; double OsdAspect;
int VideoWidth, VideoHeight;
double VideoAspect;
cDevice::PrimaryDevice()->GetOsdSize(OsdWidth, OsdHeight, OsdAspect); cDevice::PrimaryDevice()->GetOsdSize(OsdWidth, OsdHeight, OsdAspect);
osdDeltaX = osdDeltaY = 0; cDevice::PrimaryDevice()->GetVideoSize(VideoWidth, VideoHeight, VideoAspect);
osdFactor = 1.0; osdFactorX = VideoAspect * OsdHeight / displayWidth;
double fw = double(OsdWidth) / displayWidth; osdFactorY = double(OsdHeight) / displayHeight;
double fh = double(OsdHeight) / displayHeight; osdDeltaX = (OsdWidth - displayWidth * osdFactorX) / 2;
if (fw >= fh) { osdDeltaY = (OsdHeight - displayHeight * osdFactorY) / 2;
osdFactor = fh;
osdDeltaX = (OsdWidth - displayWidth * osdFactor) / 2;
}
else {
osdFactor = fw;
osdDeltaY = (OsdHeight - displayHeight * osdFactor) / 2;
}
} }
bool cDvbSubtitleConverter::AssertOsd(void) bool cDvbSubtitleConverter::AssertOsd(void)
{ {
return osd || (osd = cOsdProvider::NewOsd(int(round(osdFactor * windowHorizontalOffset + osdDeltaX)), int(round(osdFactor * windowVerticalOffset + osdDeltaY)) + Setup.SubtitleOffset, OSD_LEVEL_SUBTITLES)); return osd || (osd = cOsdProvider::NewOsd(int(round(osdFactorX * windowHorizontalOffset + osdDeltaX)), int(round(osdFactorY * windowVerticalOffset + osdDeltaY)) + Setup.SubtitleOffset, OSD_LEVEL_SUBTITLES));
} }
int cDvbSubtitleConverter::ExtractSegment(const uchar *Data, int Length, int64_t Pts) int cDvbSubtitleConverter::ExtractSegment(const uchar *Data, int Length, int64_t Pts)
@ -1079,7 +1075,7 @@ void cDvbSubtitleConverter::FinishPage(cDvbSubtitlePage *Page)
{ {
if (!AssertOsd()) if (!AssertOsd())
return; return;
tArea *Areas = Page->GetAreas(osdFactor); tArea *Areas = Page->GetAreas(osdFactorX, osdFactorY);
int NumAreas = Page->regions.Count(); int NumAreas = Page->regions.Count();
int Bpp = 8; int Bpp = 8;
bool Reduced = false; bool Reduced = false;
@ -1116,7 +1112,7 @@ void cDvbSubtitleConverter::FinishPage(cDvbSubtitlePage *Page)
} }
} }
} }
cDvbSubtitleBitmaps *Bitmaps = new cDvbSubtitleBitmaps(Page->Pts(), Page->Timeout(), Areas, NumAreas, osdFactor); cDvbSubtitleBitmaps *Bitmaps = new cDvbSubtitleBitmaps(Page->Pts(), Page->Timeout(), Areas, NumAreas, osdFactorX, osdFactorY);
bitmaps->Add(Bitmaps); bitmaps->Add(Bitmaps);
for (cSubtitleRegion *sr = Page->regions.First(); sr; sr = Page->regions.Next(sr)) { for (cSubtitleRegion *sr = Page->regions.First(); sr; sr = Page->regions.Next(sr)) {
int posX = sr->HorizontalAddress(); int posX = sr->HorizontalAddress();

View File

@ -6,7 +6,7 @@
* *
* Original author: Marco Schlüßler <marco@lordzodiac.de> * Original author: Marco Schlüßler <marco@lordzodiac.de>
* *
* $Id: dvbsubtitle.h 2.5 2011/03/12 14:03:42 kls Exp $ * $Id: dvbsubtitle.h 2.6 2011/03/20 15:10:30 kls Exp $
*/ */
#ifndef __DVBSUBTITLE_H #ifndef __DVBSUBTITLE_H
@ -35,7 +35,8 @@ private:
int windowHeight; int windowHeight;
int osdDeltaX; int osdDeltaX;
int osdDeltaY; int osdDeltaY;
double osdFactor; double osdFactorX;
double osdFactorY;
cList<cDvbSubtitlePage> *pages; cList<cDvbSubtitlePage> *pages;
cList<cDvbSubtitleBitmaps> *bitmaps; cList<cDvbSubtitleBitmaps> *bitmaps;
tColor yuv2rgb(int Y, int Cb, int Cr); tColor yuv2rgb(int Y, int Cb, int Cr);