mirror of
https://github.com/SourMesen/Mesen.git
synced 2025-04-02 10:52:48 -04:00
Video Decoder: Improved performance (slightly reduces CPU usage)
This commit is contained in:
parent
fc20c2019c
commit
d03e66839f
2 changed files with 72 additions and 46 deletions
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
DefaultVideoFilter::DefaultVideoFilter()
|
DefaultVideoFilter::DefaultVideoFilter()
|
||||||
{
|
{
|
||||||
|
InitDecodeTables();
|
||||||
|
|
||||||
InitConversionMatrix(_pictureSettings.Hue, _pictureSettings.Saturation);
|
InitConversionMatrix(_pictureSettings.Hue, _pictureSettings.Saturation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,56 +89,75 @@ void DefaultVideoFilter::YiqToRgb(double y, double i, double q, double &r, doubl
|
||||||
b = std::max(0.0, std::min(1.0, (y + _yiqToRgbMatrix[4] * i + _yiqToRgbMatrix[5] * q)));
|
b = std::max(0.0, std::min(1.0, (y + _yiqToRgbMatrix[4] * i + _yiqToRgbMatrix[5] * q)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefaultVideoFilter::InitDecodeTables()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 256; i++) {
|
||||||
|
for(int j = 0; j < 8; j++) {
|
||||||
|
double redColor = i;
|
||||||
|
double greenColor = i;
|
||||||
|
double blueColor = i;
|
||||||
|
if(j & 0x01) {
|
||||||
|
//Intensify red
|
||||||
|
redColor *= 1.1;
|
||||||
|
greenColor *= 0.9;
|
||||||
|
blueColor *= 0.9;
|
||||||
|
}
|
||||||
|
if(j & 0x02) {
|
||||||
|
//Intensify green
|
||||||
|
greenColor *= 1.1;
|
||||||
|
redColor *= 0.9;
|
||||||
|
blueColor *= 0.9;
|
||||||
|
}
|
||||||
|
if(j & 0x04) {
|
||||||
|
//Intensify blue
|
||||||
|
blueColor *= 1.1;
|
||||||
|
redColor *= 0.9;
|
||||||
|
greenColor *= 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
redColor = (redColor > 255 ? 255 : redColor) / 255.0;
|
||||||
|
greenColor = (greenColor > 255 ? 255 : greenColor) / 255.0;
|
||||||
|
blueColor = (blueColor > 255 ? 255 : blueColor) / 255.0;
|
||||||
|
|
||||||
|
_redDecodeTable[i][j] = redColor;
|
||||||
|
_greenDecodeTable[i][j] = greenColor;
|
||||||
|
_blueDecodeTable[i][j] = blueColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t DefaultVideoFilter::ProcessIntensifyBits(uint16_t ppuPixel, double scanlineIntensity)
|
uint32_t DefaultVideoFilter::ProcessIntensifyBits(uint16_t ppuPixel, double scanlineIntensity)
|
||||||
{
|
{
|
||||||
uint32_t pixelOutput = EmulationSettings::GetRgbPalette()[ppuPixel & 0x3F];
|
uint32_t pixelOutput = EmulationSettings::GetRgbPalette()[ppuPixel & 0x3F];
|
||||||
|
uint32_t intensifyBits = (ppuPixel >> 6) & 0x07;
|
||||||
|
|
||||||
//Incorrect emphasis bit implementation, but will do for now.
|
if(intensifyBits || _needToProcess || scanlineIntensity < 1.0) {
|
||||||
double redChannel = (double)((pixelOutput & 0xFF0000) >> 16);
|
//Incorrect emphasis bit implementation, but will do for now.
|
||||||
double greenChannel = (double)((pixelOutput & 0xFF00) >> 8);
|
double redChannel = _redDecodeTable[((pixelOutput & 0xFF0000) >> 16)][intensifyBits];
|
||||||
double blueChannel = (double)(pixelOutput & 0xFF);
|
double greenChannel = _greenDecodeTable[((pixelOutput & 0xFF00) >> 8)][intensifyBits];
|
||||||
|
double blueChannel = _blueDecodeTable[(pixelOutput & 0xFF)][intensifyBits];
|
||||||
|
|
||||||
if(ppuPixel & 0x40) {
|
//Apply brightness, contrast, hue & saturation
|
||||||
//Intensify red
|
if(_needToProcess) {
|
||||||
redChannel *= 1.1;
|
double y, i, q;
|
||||||
greenChannel *= 0.9;
|
RgbToYiq(redChannel, greenChannel, blueChannel, y, i, q);
|
||||||
blueChannel *= 0.9;
|
y *= _pictureSettings.Contrast * 0.5f + 1;
|
||||||
|
y += _pictureSettings.Brightness * 0.5f;
|
||||||
|
YiqToRgb(y, i, q, redChannel, greenChannel, blueChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scanlineIntensity < 1.0) {
|
||||||
|
redChannel *= scanlineIntensity;
|
||||||
|
greenChannel *= scanlineIntensity;
|
||||||
|
blueChannel *= scanlineIntensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
int r = std::min(255, (int)(redChannel * 255));
|
||||||
|
int g = std::min(255, (int)(greenChannel * 255));
|
||||||
|
int b = std::min(255, (int)(blueChannel * 255));
|
||||||
|
|
||||||
|
return 0xFF000000 | (r << 16) | (g << 8) | b;
|
||||||
|
} else {
|
||||||
|
return pixelOutput;
|
||||||
}
|
}
|
||||||
if(ppuPixel & 0x80) {
|
|
||||||
//Intensify green
|
|
||||||
greenChannel *= 1.1;
|
|
||||||
redChannel *= 0.9;
|
|
||||||
blueChannel *= 0.9;
|
|
||||||
}
|
|
||||||
if(ppuPixel & 0x100) {
|
|
||||||
//Intensify blue
|
|
||||||
blueChannel *= 1.1;
|
|
||||||
redChannel *= 0.9;
|
|
||||||
greenChannel *= 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
redChannel = (float)(redChannel > 255 ? 255 : redChannel) / 255.0;
|
|
||||||
greenChannel = (float)(greenChannel > 255 ? 255 : greenChannel) / 255.0;
|
|
||||||
blueChannel = (float)(blueChannel > 255 ? 255 : blueChannel) / 255.0;
|
|
||||||
|
|
||||||
//Apply brightness, contrast, hue & saturation
|
|
||||||
if(_needToProcess) {
|
|
||||||
double y, i, q;
|
|
||||||
RgbToYiq(redChannel, greenChannel, blueChannel, y, i, q);
|
|
||||||
y *= _pictureSettings.Contrast * 0.5f + 1;
|
|
||||||
y += _pictureSettings.Brightness * 0.5f;
|
|
||||||
YiqToRgb(y, i, q, redChannel, greenChannel, blueChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(scanlineIntensity < 1.0) {
|
|
||||||
redChannel *= scanlineIntensity;
|
|
||||||
greenChannel *= scanlineIntensity;
|
|
||||||
blueChannel *= scanlineIntensity;
|
|
||||||
}
|
|
||||||
|
|
||||||
int r = std::min(255, (int)(redChannel * 255));
|
|
||||||
int g = std::min(255, (int)(greenChannel * 255));
|
|
||||||
int b = std::min(255, (int)(blueChannel * 255));
|
|
||||||
|
|
||||||
return 0xFF000000 | (r << 16) | (g << 8) | b;
|
|
||||||
}
|
}
|
|
@ -6,10 +6,15 @@
|
||||||
class DefaultVideoFilter : public BaseVideoFilter
|
class DefaultVideoFilter : public BaseVideoFilter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
double _redDecodeTable[256][8];
|
||||||
|
double _greenDecodeTable[256][8];
|
||||||
|
double _blueDecodeTable[256][8];
|
||||||
|
|
||||||
double _yiqToRgbMatrix[6];
|
double _yiqToRgbMatrix[6];
|
||||||
PictureSettings _pictureSettings;
|
PictureSettings _pictureSettings;
|
||||||
bool _needToProcess = false;
|
bool _needToProcess = false;
|
||||||
|
|
||||||
|
void InitDecodeTables();
|
||||||
void InitConversionMatrix(double hueShift, double saturationShift);
|
void InitConversionMatrix(double hueShift, double saturationShift);
|
||||||
|
|
||||||
void RgbToYiq(double r, double g, double b, double &y, double &i, double &q);
|
void RgbToYiq(double r, double g, double b, double &y, double &i, double &q);
|
||||||
|
|
Loading…
Add table
Reference in a new issue