Skip to content

Commit

Permalink
Android: Fix MediaCodec SurfaceTexture scaling for non-square pixels
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-kendall committed Mar 21, 2019
1 parent a4f29cd commit 9821f03
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 21 deletions.
15 changes: 14 additions & 1 deletion mythtv/libs/libmythtv/mythmediacodecinterop.cpp
Expand Up @@ -30,12 +30,18 @@ MythMediaCodecInterop::MythMediaCodecInterop(MythRenderOpenGL* Context)
m_colourSpaceInitialised(false),
m_surface(),
m_surfaceTexture(),
m_surfaceListener()
m_surfaceListener(),
m_textureTransform(nullptr),
m_transform()
{
jfloatArray transform = QAndroidJniEnvironment()->NewFloatArray(16);
m_textureTransform = jfloatArray(QAndroidJniEnvironment()->NewGlobalRef(transform));
QAndroidJniEnvironment()->DeleteLocalRef(transform);
}

MythMediaCodecInterop::~MythMediaCodecInterop()
{
QAndroidJniEnvironment()->DeleteGlobalRef(m_textureTransform);
}

void* MythMediaCodecInterop::GetSurface(void)
Expand Down Expand Up @@ -161,5 +167,12 @@ vector<MythVideoTexture*> MythMediaCodecInterop::Acquire(MythRenderOpenGL *Conte

// Update texture
m_surfaceTexture.callMethod<void>("updateTexImage");

// Retrieve and set transform
m_surfaceTexture.callMethod<void>("getTransformMatrix", "([F)V", m_textureTransform);
QAndroidJniEnvironment()->GetFloatArrayRegion(m_textureTransform, 0, 16, m_transform.data());
m_openglTextures[DUMMY_INTEROP_ID][0]->m_transform = &m_transform;
m_openglTextures[DUMMY_INTEROP_ID][0]->m_flip = false;

return m_openglTextures[DUMMY_INTEROP_ID];
}
2 changes: 2 additions & 0 deletions mythtv/libs/libmythtv/mythmediacodecinterop.h
Expand Up @@ -32,6 +32,8 @@ class MythMediaCodecInterop : public MythOpenGLInterop
QAndroidJniObject m_surface;
QAndroidJniObject m_surfaceTexture;
QAndroidJniObject m_surfaceListener;
jfloatArray m_textureTransform;
QMatrix4x4 m_transform;
};

#endif // MYTHMEDIACODECINTEROP_H
12 changes: 12 additions & 0 deletions mythtv/libs/libmythtv/openglvideo.cpp
Expand Up @@ -265,6 +265,8 @@ bool OpenGLVideo::CreateVideoShader(VideoShaderType Type, QString Deinterlacer)
if ((Default == Type) || (!format_is_yuv(m_outputType)))
{
fragment = DefaultFragmentShader;
if (FMT_MEDIACODEC == m_inputType)
vertex = MediaCodecVertexShader;
}
// no interlaced shaders yet
else if ((Progressive == Type) || (Interlaced == Type) || Deinterlacer.isEmpty())
Expand Down Expand Up @@ -581,6 +583,16 @@ void OpenGLVideo::PrepareFrame(VideoFrame *Frame, bool TopFieldFirst, FrameScanT
{
SetupFrameFormat(newsourcetype, newtargettype, newsize, newtargettexture);
}

// Set the texture transform for mediacodec
if (FMT_MEDIACODEC == m_inputType)
{
if (inputtextures[0]->m_transform && m_shaders[Default])
{
m_render->EnableShaderProgram(m_shaders[Default]);
m_shaders[Default]->setUniformValue("u_transform", *inputtextures[0]->m_transform);
}
}
}
else
{
Expand Down
52 changes: 32 additions & 20 deletions mythtv/libs/libmythtv/openglvideoshaders.h
@@ -1,6 +1,38 @@
#ifndef OPENGLVIDEOSHADERS_H
#define OPENGLVIDEOSHADERS_H

static const QString DefaultVertexShader =
"attribute highp vec2 a_position;\n"
"attribute highp vec2 a_texcoord0;\n"
"varying highp vec2 v_texcoord0;\n"
"uniform highp mat4 u_projection;\n"
"void main()\n"
"{\n"
" gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n"
" v_texcoord0 = a_texcoord0;\n"
"}\n";

static const QString DefaultFragmentShader =
"uniform sampler2D s_texture0;\n"
"varying highp vec2 v_texcoord0;\n"
"void main(void)\n"
"{\n"
" highp vec4 color = texture2D(s_texture0, v_texcoord0);\n"
" gl_FragColor = vec4(color.rgb, 1.0);\n"
"}\n";

static const QString MediaCodecVertexShader =
"attribute highp vec2 a_position;\n"
"attribute highp vec2 a_texcoord0;\n"
"varying highp vec2 v_texcoord0;\n"
"uniform highp mat4 u_projection;\n"
"uniform highp mat4 u_transform;\n"
"void main()\n"
"{\n"
" gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n"
" v_texcoord0 = (u_transform * vec4(a_texcoord0, 0.0, 1.0)).xy;\n"
"}\n";

#define SAMPLE_NV12 "\
highp vec3 sampleNV12(in sampler2D texture1, in sampler2D texture2, highp vec2 texcoord)\n\
{\n\
Expand Down Expand Up @@ -93,17 +125,6 @@ SAMPLE_NV12
" gl_FragColor = vec4(current, 1.0) * m_colourMatrix;\n"
"}\n"};

static const QString DefaultVertexShader =
"attribute highp vec2 a_position;\n"
"attribute highp vec2 a_texcoord0;\n"
"varying highp vec2 v_texcoord0;\n"
"uniform highp mat4 u_projection;\n"
"void main()\n"
"{\n"
" gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n"
" v_texcoord0 = a_texcoord0;\n"
"}\n";

static const QString SelectColumn =
" if (fract(v_texcoord0.x * m_frameData.y) < 0.5)\n"
" yuva = yuva.rabg;\n";
Expand Down Expand Up @@ -275,15 +296,6 @@ static const QString BicubicShader =
" gl_FragColor = mix(tex00, tex10, parmx.z);\n"
"}\n";

static const QString DefaultFragmentShader =
"uniform sampler2D s_texture0;\n"
"varying highp vec2 v_texcoord0;\n"
"void main(void)\n"
"{\n"
" highp vec4 color = texture2D(s_texture0, v_texcoord0);\n"
" gl_FragColor = vec4(color.rgb, 1.0);\n"
"}\n";

static const QString SampleYV12 =
"highp vec3 sampleYVU(in sampler2D texture1, in sampler2D texture2, in sampler2D texture3, highp vec2 texcoord)\n"
"{\n"
Expand Down

0 comments on commit 9821f03

Please sign in to comment.