Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VideoPlayer: OpenGL - do colorspace conversion in linear RGB #13481

Merged
merged 2 commits into from Feb 6, 2018
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Next

VideoPlayer: OpenGL - do colorspace conversion in linear RGB

  • Loading branch information...
FernetMenta committed Feb 4, 2018
commit ea2ac93cd89235ed52f4e862acfcbbb94f3db026
@@ -33,6 +33,9 @@ varying vec2 m_cordV;
uniform vec2 m_step;
uniform mat4 m_yuvmat;
uniform float m_stretch;
uniform mat3 m_primMat;
uniform float m_gammaDstInv;
uniform float m_gammaSrc;
uniform float m_alpha;

vec2 stretch(vec2 pos)
@@ -118,5 +121,15 @@ vec4 process()

#endif

#if defined(XBMC_COL_CONVERSION)
rgb.r = pow(rgb.r, m_gammaSrc);
rgb.g = pow(rgb.g, m_gammaSrc);
rgb.b = pow(rgb.b, m_gammaSrc);
rgb.rgb = m_primMat * rgb.rgb;
rgb.r = pow(rgb.r, m_gammaDstInv);
rgb.g = pow(rgb.g, m_gammaDstInv);
rgb.b = pow(rgb.b, m_gammaDstInv);
#endif

return rgb;
}
@@ -12,6 +12,9 @@ uniform vec2 m_step;
uniform mat4 m_yuvmat;
uniform float m_stretch;
uniform float m_alpha;
uniform mat3 m_primMat;
uniform float m_gammaDstInv;
uniform float m_gammaSrc;
in vec2 m_cordY;
in vec2 m_cordU;
in vec2 m_cordV;
@@ -92,5 +95,15 @@ vec4 process()

#endif

#if defined(XBMC_COL_CONVERSION)
rgb.r = pow(rgb.r, m_gammaSrc);
rgb.g = pow(rgb.g, m_gammaSrc);
rgb.b = pow(rgb.b, m_gammaSrc);
rgb.rgb = m_primMat * rgb.rgb;
rgb.r = pow(rgb.r, m_gammaDstInv);
rgb.g = pow(rgb.g, m_gammaDstInv);
rgb.b = pow(rgb.b, m_gammaDstInv);
#endif

return rgb;
}
@@ -13,6 +13,9 @@ uniform mat4 m_yuvmat;
uniform float m_stretch;
uniform float m_alpha;
uniform sampler1D m_kernelTex;
uniform mat3 m_primMat;
uniform float m_gammaDstInv;
uniform float m_gammaSrc;
in vec2 m_cordY;
in vec2 m_cordU;
in vec2 m_cordV;
@@ -104,5 +107,14 @@ vec4 process()
rgb.a = m_alpha;
#endif

#if defined(XBMC_COL_CONVERSION)
rgb.r = pow(rgb.r, m_gammaSrc);
rgb.g = pow(rgb.g, m_gammaSrc);
rgb.b = pow(rgb.b, m_gammaSrc);
rgb.rgb = m_primMat * rgb.rgb;
rgb.r = pow(rgb.r, m_gammaDstInv);
rgb.g = pow(rgb.g, m_gammaDstInv);
rgb.b = pow(rgb.b, m_gammaDstInv);
#endif
return rgb;
}
@@ -250,9 +250,8 @@ bool CLinuxRendererGL::Configure(const VideoPicture &picture, float fps, unsigne
m_iFlags = GetFlagsChromaPosition(picture.chroma_position) |
GetFlagsStereoMode(picture.stereoMode);

m_srcPrimaries = static_cast<AVColorPrimaries>(picture.color_primaries);
m_srcColSpace = static_cast<AVColorSpace>(picture.color_space);
m_srcFullRange = picture.color_range == 1;
m_srcPrimaries = GetSrcPrimaries(static_cast<AVColorPrimaries>(picture.color_primaries),
picture.iWidth, picture.iHeight);

// Calculate the input frame aspect ratio.
CalculateFrameAspectRatio(picture.iDisplayWidth, picture.iDisplayHeight);
@@ -321,11 +320,10 @@ void CLinuxRendererGL::AddVideoPicture(const VideoPicture &picture, int index, d
buf.videoBuffer = picture.videoBuffer;
buf.videoBuffer->Acquire();
buf.loaded = false;

m_srcPrimaries = static_cast<AVColorPrimaries>(picture.color_primaries);
m_srcColSpace = static_cast<AVColorSpace>(picture.color_space);
m_srcFullRange = picture.color_range == 1;
m_srcBits = picture.colorBits;
buf.m_srcPrimaries = static_cast<AVColorPrimaries>(picture.color_primaries);
buf.m_srcColSpace = static_cast<AVColorSpace>(picture.color_space);
buf.m_srcFullRange = picture.color_range == 1;
buf.m_srcBits = picture.colorBits;
}

void CLinuxRendererGL::ReleaseBuffer(int idx)
@@ -917,6 +915,7 @@ void CLinuxRendererGL::LoadShaders(int field)
{
m_pYUVShader = new YUV2RGBFilterShader4(m_textureTarget == GL_TEXTURE_RECTANGLE_ARB,
shaderFormat, m_nonLinStretch,
AVColorPrimaries::AVCOL_PRI_BT709, m_srcPrimaries,
m_scalingMethod, out);
if (!m_cmsOn)
m_pYUVShader->SetConvertFullColorRange(m_fullRange);
@@ -940,7 +939,8 @@ void CLinuxRendererGL::LoadShaders(int field)
if (!m_pYUVShader)
{
m_pYUVShader = new YUV2RGBProgressiveShader(m_textureTarget == GL_TEXTURE_RECTANGLE_ARB, shaderFormat,
m_nonLinStretch && m_renderQuality == RQ_SINGLEPASS, out);
m_nonLinStretch && m_renderQuality == RQ_SINGLEPASS,
AVColorPrimaries::AVCOL_PRI_BT709, m_srcPrimaries, out);

if (!m_cmsOn)
m_pYUVShader->SetConvertFullColorRange(m_fullRange);
@@ -1052,8 +1052,16 @@ bool CLinuxRendererGL::Render(DWORD flags, int renderBuffer)

void CLinuxRendererGL::RenderSinglePass(int index, int field)
{
YUVBUFFER &buf = m_buffers[index];
YUVPLANE (&planes)[YuvImage::MAX_PLANES] = m_buffers[index].fields[field];

AVColorPrimaries srcPrim = GetSrcPrimaries(buf.m_srcPrimaries, buf.image.width, buf.image.height);
if (srcPrim != m_srcPrimaries)
{
m_srcPrimaries = srcPrim;
m_reloadShaders = true;
}

if (m_reloadShaders)
{
LoadShaders(field);
@@ -1080,8 +1088,7 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field)
m_pYUVShader->SetContrast(m_videoSettings.m_Contrast * 0.02f);
m_pYUVShader->SetWidth(planes[0].texwidth);
m_pYUVShader->SetHeight(planes[0].texheight);
m_pYUVShader->SetColSpace(m_srcColSpace, m_srcPrimaries, m_srcBits, !m_srcFullRange,
m_srcTextureBits, AVCOL_PRI_BT709);
m_pYUVShader->SetColParams(buf.m_srcColSpace, buf.m_srcBits, !buf.m_srcFullRange, buf.m_srcTextureBits);

//disable non-linear stretch when a dvd menu is shown, parts of the menu are rendered through the overlay renderer
//having non-linear stretch on breaks the alignment
@@ -1197,8 +1204,16 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field)

void CLinuxRendererGL::RenderToFBO(int index, int field, bool weave /*= false*/)
{
YUVBUFFER &buf = m_buffers[index];
YUVPLANE (&planes)[YuvImage::MAX_PLANES] = m_buffers[index].fields[field];

AVColorPrimaries srcPrim = GetSrcPrimaries(buf.m_srcPrimaries, buf.image.width, buf.image.height);
if (srcPrim != m_srcPrimaries)
{
m_srcPrimaries = srcPrim;
m_reloadShaders = true;
}

if (m_reloadShaders)
{
m_reloadShaders = 0;
@@ -1255,8 +1270,7 @@ void CLinuxRendererGL::RenderToFBO(int index, int field, bool weave /*= false*/)
m_pYUVShader->SetWidth(planes[0].texwidth);
m_pYUVShader->SetHeight(planes[0].texheight);
m_pYUVShader->SetNonLinStretch(1.0);
m_pYUVShader->SetColSpace(m_srcColSpace, m_srcPrimaries, m_srcBits, !m_srcFullRange,
m_srcTextureBits, AVCOL_PRI_BT709);
m_pYUVShader->SetColParams(buf.m_srcColSpace, buf.m_srcBits, !buf.m_srcFullRange, buf.m_srcTextureBits);

if (field == FIELD_TOP)
m_pYUVShader->SetField(1);
@@ -1791,6 +1805,7 @@ bool CLinuxRendererGL::CreateYV12Texture(int index)
/* since we also want the field textures, pitch must be texture aligned */
unsigned p;

YUVBUFFER &buf = m_buffers[index];
YuvImage &im = m_buffers[index].image;
GLuint *pbo = m_buffers[index].pbo;

@@ -1804,24 +1819,24 @@ bool CLinuxRendererGL::CreateYV12Texture(int index)
switch (m_format)
{
case AV_PIX_FMT_YUV420P16:
m_srcTextureBits = 16;
buf.m_srcTextureBits = 16;
break;
case AV_PIX_FMT_YUV420P14:
m_srcTextureBits = 14;
buf.m_srcTextureBits = 14;
break;
case AV_PIX_FMT_YUV420P12:
m_srcTextureBits = 12;
buf.m_srcTextureBits = 12;
break;
case AV_PIX_FMT_YUV420P10:
m_srcTextureBits = 10;
buf.m_srcTextureBits = 10;
break;
case AV_PIX_FMT_YUV420P9:
m_srcTextureBits = 9;
buf.m_srcTextureBits = 9;
break;
default:
break;
}
if (m_srcTextureBits > 8)
if (buf.m_srcTextureBits > 8)
im.bpp = 2;
else
im.bpp = 1;
@@ -2687,3 +2702,15 @@ void CLinuxRendererGL::DeleteCLUT()
}
}

AVColorPrimaries CLinuxRendererGL::GetSrcPrimaries(AVColorPrimaries srcPrimaries, unsigned int width, unsigned int height)
{
AVColorPrimaries ret = srcPrimaries;
if (ret == AVCOL_PRI_UNSPECIFIED)
{
if (width > 1024 || height >= 600)
ret = AVCOL_PRI_BT709;
else
ret = AVCOL_PRI_BT470BG;
}
return ret;
}
@@ -132,6 +132,7 @@ class CLinuxRendererGL : public CBaseRenderer
virtual void LoadShaders(int field=FIELD_FULL);
void SetTextureFilter(GLenum method);
void UpdateVideoFilter();
AVColorPrimaries GetSrcPrimaries(AVColorPrimaries srcPrimaries, unsigned int width, unsigned int height);

// textures
virtual bool UploadTexture(int index);
@@ -213,6 +214,12 @@ class CLinuxRendererGL : public CBaseRenderer

CVideoBuffer *videoBuffer;
bool loaded;

AVColorPrimaries m_srcPrimaries;
AVColorSpace m_srcColSpace;
int m_srcBits = 8;
int m_srcTextureBits = 8;
bool m_srcFullRange;
};

// YV12 decoder textures
@@ -233,10 +240,6 @@ class CLinuxRendererGL : public CBaseRenderer
unsigned int m_ditherDepth;
bool m_fullRange;
AVColorPrimaries m_srcPrimaries;
AVColorSpace m_srcColSpace;
int m_srcBits = 8;
int m_srcTextureBits = 8;
bool m_srcFullRange;

// clear colour for "black" bars
float m_clearColour;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.