mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented scaling of SPU bitmaps
This commit is contained in:
parent
6a8a790312
commit
db98ecf54e
@ -2712,6 +2712,7 @@ Johann Friedrichs <johann.friedrichs@web.de>
|
|||||||
for some fixes to dvbspu.[hc]
|
for some fixes to dvbspu.[hc]
|
||||||
for fixing a busy loop when moving editing marks
|
for fixing a busy loop when moving editing marks
|
||||||
for making cPalette::ClosestColor() treat fully transparent colors as "equal"
|
for making cPalette::ClosestColor() treat fully transparent colors as "equal"
|
||||||
|
for implementing scaling of SPU bitmaps
|
||||||
|
|
||||||
Timo Helkio <timolavi@mbnet.fi>
|
Timo Helkio <timolavi@mbnet.fi>
|
||||||
for reporting a hangup when replaying a TS recording with subtitles activated
|
for reporting a hangup when replaying a TS recording with subtitles activated
|
||||||
|
3
HISTORY
3
HISTORY
@ -7494,7 +7494,7 @@ Video Disk Recorder Revision History
|
|||||||
use it.
|
use it.
|
||||||
- Added maximum SNR value for PCTV Systems PCTV 73ESE (thanks to Cedric Dewijs).
|
- Added maximum SNR value for PCTV Systems PCTV 73ESE (thanks to Cedric Dewijs).
|
||||||
|
|
||||||
2013-01-17: Version 1.7.36
|
2013-01-20: Version 1.7.36
|
||||||
|
|
||||||
- Added maximum SNR value for PCTV Systems nanoStick T2 290e (thanks to Antti
|
- Added maximum SNR value for PCTV Systems nanoStick T2 290e (thanks to Antti
|
||||||
Hartikainen).
|
Hartikainen).
|
||||||
@ -7529,3 +7529,4 @@ Video Disk Recorder Revision History
|
|||||||
"Resume" key in the main menu to work even after a restart of VDR.
|
"Resume" key in the main menu to work even after a restart of VDR.
|
||||||
- The SVDRP command NEWT no longer checks whether a timer with the given data already
|
- The SVDRP command NEWT no longer checks whether a timer with the given data already
|
||||||
exists (suggested by Malte Forkel).
|
exists (suggested by Malte Forkel).
|
||||||
|
- Implemented scaling of SPU bitmaps (thanks to Johann Friedrichs).
|
||||||
|
102
dvbspu.c
102
dvbspu.c
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* parts of this file are derived from the OMS program.
|
* parts of this file are derived from the OMS program.
|
||||||
*
|
*
|
||||||
* $Id: dvbspu.c 2.9 2011/12/10 14:39:19 kls Exp $
|
* $Id: dvbspu.c 2.10 2013/01/20 10:36:58 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbspu.h"
|
#include "dvbspu.h"
|
||||||
@ -54,6 +54,7 @@ void cDvbSpuPalette::setPalette(const uint32_t * pal)
|
|||||||
#define setMin(a, b) if (a > b) a = b
|
#define setMin(a, b) if (a > b) a = b
|
||||||
#define setMax(a, b) if (a < b) a = b
|
#define setMax(a, b) if (a < b) a = b
|
||||||
|
|
||||||
|
// DVD SPU bitmaps cover max. 720 x 576 - this sizes the SPU bitmap
|
||||||
#define spuXres 720
|
#define spuXres 720
|
||||||
#define spuYres 576
|
#define spuYres 576
|
||||||
|
|
||||||
@ -243,6 +244,36 @@ cDvbSpuDecoder::~cDvbSpuDecoder()
|
|||||||
delete osd;
|
delete osd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SPUs must be scaled if screensize is not 720x576
|
||||||
|
|
||||||
|
void cDvbSpuDecoder::SetSpuScaling(void)
|
||||||
|
{
|
||||||
|
int Width = spuXres;
|
||||||
|
int Height = spuYres;
|
||||||
|
int OsdWidth = 0;
|
||||||
|
int OsdHeight = 0;
|
||||||
|
double VideoAspect;
|
||||||
|
cDevice::PrimaryDevice()->GetOsdSize(OsdWidth, OsdHeight, VideoAspect);
|
||||||
|
DEBUG("dvbspu SetSpuScaling OsdSize %d x %d\n", OsdWidth, OsdHeight);
|
||||||
|
if (!OsdWidth) { // guess correct size
|
||||||
|
if (Setup.OSDWidth <= 720 || Setup.OSDHeight <= 576)
|
||||||
|
xscaling = yscaling = 1.0;
|
||||||
|
else if (Setup.OSDWidth <= 1280 || Setup.OSDHeight <= 720) {
|
||||||
|
xscaling = 1280.0 / Width;
|
||||||
|
yscaling = 720.0 / Height;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xscaling = 1920.0 / Width;
|
||||||
|
yscaling = 1080.0/ Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xscaling = (double)OsdWidth / Width;
|
||||||
|
yscaling = (double)OsdHeight / Height;
|
||||||
|
}
|
||||||
|
DEBUG("dvbspu xscaling = %f yscaling = %f\n", xscaling, yscaling);
|
||||||
|
}
|
||||||
|
|
||||||
void cDvbSpuDecoder::processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow)
|
void cDvbSpuDecoder::processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow)
|
||||||
{
|
{
|
||||||
setTime(pts);
|
setTime(pts);
|
||||||
@ -296,6 +327,7 @@ void cDvbSpuDecoder::setHighlight(uint16_t sx, uint16_t sy,
|
|||||||
memcpy(hlpDescr, pld, sizeof(aDvbSpuPalDescr));
|
memcpy(hlpDescr, pld, sizeof(aDvbSpuPalDescr));
|
||||||
highlight = true;
|
highlight = true;
|
||||||
clean = false;
|
clean = false;
|
||||||
|
Draw(); // we have to trigger Draw() here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,32 +408,52 @@ void cDvbSpuDecoder::Draw(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sDvbSpuRect bgsize;
|
sDvbSpuRect bgsize;
|
||||||
|
sDvbSpuRect drawsize;
|
||||||
|
sDvbSpuRect bgdrawsize;
|
||||||
cBitmap *fg = NULL;
|
cBitmap *fg = NULL;
|
||||||
cBitmap *bg = NULL;
|
cBitmap *bg = NULL;
|
||||||
|
cBitmap *tmp = NULL;
|
||||||
|
|
||||||
if (highlight)
|
SetSpuScaling(); // always set current scaling, size could have changed
|
||||||
fg = spubmp->getBitmap(hlpDescr, palette, hlpsize);
|
|
||||||
|
|
||||||
if (spubmp->getMinSize(palDescr, bgsize))
|
if (highlight) {
|
||||||
bg = spubmp->getBitmap(palDescr, palette, bgsize);
|
tmp = spubmp->getBitmap(hlpDescr, palette, hlpsize);
|
||||||
|
fg = tmp->Scaled(xscaling, yscaling, true);
|
||||||
|
drawsize.x1 = hlpsize.x1 * xscaling;
|
||||||
|
drawsize.y1 = hlpsize.y1 * yscaling;
|
||||||
|
drawsize.x2 = drawsize.x1 + fg->Width();
|
||||||
|
drawsize.y2 = drawsize.y1 + fg->Height();
|
||||||
|
}
|
||||||
|
|
||||||
if (!fg || !bg || !osd)
|
if (spubmp->getMinSize(palDescr, bgsize)) {
|
||||||
|
tmp = spubmp->getBitmap(palDescr, palette, bgsize);
|
||||||
|
bg = tmp->Scaled(xscaling, yscaling, true);
|
||||||
|
bgdrawsize.x1 = bgsize.x1 * xscaling;
|
||||||
|
bgdrawsize.y1 = bgsize.y1 * yscaling;
|
||||||
|
bgdrawsize.x2 = bgdrawsize.x1 + bg->Width();
|
||||||
|
bgdrawsize.y2 = bgdrawsize.y1 + bg->Height();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (osd) // always rewrite OSD
|
||||||
Hide();
|
Hide();
|
||||||
|
|
||||||
if (osd == NULL) {
|
if (osd == NULL) {
|
||||||
restricted_osd = false;
|
restricted_osd = false;
|
||||||
osd = cOsdProvider::NewOsd(0, 0);
|
osd = cOsdProvider::NewOsd(0, 0);
|
||||||
|
|
||||||
tArea Area = { size.x1, size.y1, size.x2, size.y2, 4};
|
sDvbSpuRect areaSize = CalcAreaSize(drawsize, fg, bgdrawsize, bg); // combine
|
||||||
if (osd->CanHandleAreas(&Area, 1) != oeOk)
|
tArea Area = { areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2, 4 };
|
||||||
|
if (osd->CanHandleAreas(&Area, 1) != oeOk) {
|
||||||
|
DEBUG("dvbspu CanHandleAreas (%d,%d)x(%d,%d), 4 failed\n", areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2);
|
||||||
restricted_osd = true;
|
restricted_osd = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
osd->SetAreas(&Area, 1);
|
osd->SetAreas(&Area, 1);
|
||||||
}
|
}
|
||||||
if (restricted_osd) {
|
if (restricted_osd) {
|
||||||
sDvbSpuRect hlsize;
|
sDvbSpuRect hlsize;
|
||||||
bool setarea = false;
|
bool setarea = false;
|
||||||
/* reduce fg area (only valid if there is no bg below) */
|
/* reduce fg area */
|
||||||
if (fg) {
|
if (fg) {
|
||||||
spubmp->getMinSize(hlpDescr,hlsize);
|
spubmp->getMinSize(hlpDescr,hlsize);
|
||||||
/* clip to the highligh area */
|
/* clip to the highligh area */
|
||||||
@ -409,11 +461,15 @@ void cDvbSpuDecoder::Draw(void)
|
|||||||
setMax(hlsize.y1, hlpsize.y1);
|
setMax(hlsize.y1, hlpsize.y1);
|
||||||
setMin(hlsize.x2, hlpsize.x2);
|
setMin(hlsize.x2, hlpsize.x2);
|
||||||
setMin(hlsize.y2, hlpsize.y2);
|
setMin(hlsize.y2, hlpsize.y2);
|
||||||
if (hlsize.x1 > hlsize.x2 || hlsize.y1 > hlsize.y2) {
|
if (hlsize.x1 > hlsize.x2 || hlsize.y1 > hlsize.y2)
|
||||||
hlsize.x1 = hlsize.x2 = hlsize.y1 = hlsize.y2 = 0;
|
hlsize.x1 = hlsize.x2 = hlsize.y1 = hlsize.y2 = 0;
|
||||||
|
/* resize scaled fg */
|
||||||
|
drawsize.x1=hlsize.x1 * xscaling;
|
||||||
|
drawsize.y1=hlsize.y1 * yscaling;
|
||||||
|
drawsize.x2=hlsize.x2 * xscaling;
|
||||||
|
drawsize.y2=hlsize.y2 * yscaling;
|
||||||
}
|
}
|
||||||
}
|
sDvbSpuRect areaSize = CalcAreaSize(drawsize, fg, bgdrawsize, bg);
|
||||||
sDvbSpuRect areaSize = CalcAreaSize((fg && bg) ? hlpsize : hlsize, fg, bgsize, bg);
|
|
||||||
|
|
||||||
#define DIV(a, b) (a/b)?:1
|
#define DIV(a, b) (a/b)?:1
|
||||||
for (int d = 1; !setarea && d <= 2; d++) {
|
for (int d = 1; !setarea && d <= 2; d++) {
|
||||||
@ -431,16 +487,11 @@ void cDvbSpuDecoder::Draw(void)
|
|||||||
/* second try to split area if there is both area */
|
/* second try to split area if there is both area */
|
||||||
if (!setarea && fg && bg) {
|
if (!setarea && fg && bg) {
|
||||||
tArea Area_Both [2] = {
|
tArea Area_Both [2] = {
|
||||||
{bgsize.x1, bgsize.y1, bgsize.x2, bgsize.y2, DIV(CalcAreaBpp(0, bg), d)},
|
{ bgdrawsize.x1, bgdrawsize.y1, bgdrawsize.x2, bgdrawsize.y2, DIV(CalcAreaBpp(0, bg), d) },
|
||||||
{hlpsize.x1, hlpsize.y1, hlpsize.x2, hlpsize.y2, DIV(CalcAreaBpp(fg, 0), d)}
|
{ drawsize.x1, drawsize.y1, drawsize.x2, drawsize.y2, DIV(CalcAreaBpp(fg, 0), d) }
|
||||||
};
|
};
|
||||||
if (!Area_Both[0].Intersects(Area_Both[1])) {
|
if (!Area_Both[0].Intersects(Area_Both[1])) {
|
||||||
/* there is no intersection. We can reduce hl */
|
/* there is no intersection. We can try with split areas */
|
||||||
Area_Both[1].x1 = hlsize.x1;
|
|
||||||
Area_Both[1].y1 = hlsize.y1;
|
|
||||||
Area_Both[1].x2 = hlsize.x2;
|
|
||||||
Area_Both[1].y2 = hlsize.y2;
|
|
||||||
|
|
||||||
if ((Area_Both[0].Width() & 7) != 0)
|
if ((Area_Both[0].Width() & 7) != 0)
|
||||||
Area_Both[0].x2 += 8 - (Area_Both[0].Width() & 7);
|
Area_Both[0].x2 += 8 - (Area_Both[0].Width() & 7);
|
||||||
if ((Area_Both[1].Width() & 7) != 0)
|
if ((Area_Both[1].Width() & 7) != 0)
|
||||||
@ -451,18 +502,21 @@ void cDvbSpuDecoder::Draw(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!setarea)
|
if (setarea)
|
||||||
dsyslog("dvbspu: AreaSize (%d, %d) (%d, %d) Bpp %d", areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2, (fg && bg) ? 4 : 2 );
|
DEBUG("dvbspu: reduced AreaSize (%d, %d) (%d, %d) Bpp %d\n", areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2, (fg && bg) ? 4 : 2);
|
||||||
|
else
|
||||||
|
dsyslog("dvbspu: reduced AreaSize (%d, %d) (%d, %d) Bpp %d failed", areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2, (fg && bg) ? 4 : 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we could draw use DrawPixel on osd */
|
/* we could draw use DrawPixel on osd */
|
||||||
if (bg || fg) {
|
if (bg || fg) {
|
||||||
if (bg)
|
if (bg)
|
||||||
osd->DrawBitmap(bgsize.x1, bgsize.y1, *bg);
|
osd->DrawBitmap(bgdrawsize.x1, bgdrawsize.y1, *bg);
|
||||||
if (fg)
|
if (fg)
|
||||||
osd->DrawBitmap(hlpsize.x1, hlpsize.y1, *fg);
|
osd->DrawBitmap(drawsize.x1, drawsize.y1, *fg);
|
||||||
delete fg;
|
delete fg;
|
||||||
delete bg;
|
delete bg;
|
||||||
|
delete tmp;
|
||||||
|
|
||||||
osd->Flush();
|
osd->Flush();
|
||||||
}
|
}
|
||||||
|
5
dvbspu.h
5
dvbspu.h
@ -8,13 +8,14 @@
|
|||||||
*
|
*
|
||||||
* parts of this file are derived from the OMS program.
|
* parts of this file are derived from the OMS program.
|
||||||
*
|
*
|
||||||
* $Id: dvbspu.h 2.5 2011/03/27 14:50:48 kls Exp $
|
* $Id: dvbspu.h 2.6 2013/01/20 10:15:47 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBSPU_H
|
#ifndef __DVBSPU_H
|
||||||
#define __DVBSPU_H
|
#define __DVBSPU_H
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include "device.h"
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
#include "spu.h"
|
#include "spu.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
@ -107,6 +108,7 @@ class cDvbSpuDecoder:public cSpuDecoder {
|
|||||||
spFlag state;
|
spFlag state;
|
||||||
|
|
||||||
cSpuDecoder::eScaleMode scaleMode;
|
cSpuDecoder::eScaleMode scaleMode;
|
||||||
|
double xscaling, yscaling;
|
||||||
|
|
||||||
//highligh area
|
//highligh area
|
||||||
bool highlight;
|
bool highlight;
|
||||||
@ -133,6 +135,7 @@ class cDvbSpuDecoder:public cSpuDecoder {
|
|||||||
return ((spu[0] << 8) | spu[1]);
|
return ((spu[0] << 8) | spu[1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void SetSpuScaling(void);
|
||||||
sDvbSpuRect CalcAreaSize(sDvbSpuRect fgsize, cBitmap *fgbmp, sDvbSpuRect bgsize, cBitmap *bgbmp);
|
sDvbSpuRect CalcAreaSize(sDvbSpuRect fgsize, cBitmap *fgbmp, sDvbSpuRect bgsize, cBitmap *bgbmp);
|
||||||
int CalcAreaBpp(cBitmap *fgbmp, cBitmap *bgbmp);
|
int CalcAreaBpp(cBitmap *fgbmp, cBitmap *bgbmp);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user