在Android中,将YUV数据绘制到表面的最佳方法是什么?

在Android中,将YUV数据绘制到表面的最佳方法是什么?,android,yuv,hardware-acceleration,Android,Yuv,Hardware Acceleration,我需要以特定的方式播放视频。这就是为什么我需要“预解码”一些帧,并保留它,稍后再显示。我使用MediaCodec对视频帧进行解码。输出缓冲区是YUV(420)格式,问题是,以后在屏幕上显示它们的最佳方式是什么 复制codec.GetOutputBuffer()的输出还是保留code.GetOutputImage()的输出更好 是否有一种硬件加速的方式可以将YUV转换为RGB作为Java函数 如何有效地将数据绘制到曲面上 有必要进行转换吗?难道不可能直接(以任何形式,如ByteBuffer或Ima

我需要以特定的方式播放视频。这就是为什么我需要“预解码”一些帧,并保留它,稍后再显示。我使用MediaCodec对视频帧进行解码。输出缓冲区是YUV(420)格式,问题是,以后在屏幕上显示它们的最佳方式是什么

  • 复制codec.GetOutputBuffer()的输出还是保留code.GetOutputImage()的输出更好
  • 是否有一种硬件加速的方式可以将YUV转换为RGB作为Java函数
  • 如何有效地将数据绘制到曲面上
  • 有必要进行转换吗?难道不可能直接(以任何形式,如ByteBuffer或Image等)将YUV数据绘制到更新的(>=8.0)Android版本上吗
  • mp4编解码器不能被指示生成RGB输出而不是YUV,对吗
  • 我浏览了大量类似(或相同)的问题,但大多数问题都是老问题,我只是看到一些手动YUV到RGB转换,这对我来说太慢了。我希望新的安卓版本能让情况稍微好一点;)


    谢谢您的建议。

    从rgb转换为yuv并将其转换回rgb的着色器示例。 为了简单起见,我将2个相邻的rgba像素转换为yuv,并以(y1y2uv)格式将其保存为1个像素。这不是一个有效的例子,但我希望它能让你进入正确的方向

    // From rgb to yuv
    companion object {
        val FRAGMENT_SHADER = "" +
            "precision highp float;\n" +
            "varying vec2 textureCoordinate;\n" +
            " \n" +
            "uniform sampler2D inputImageTexture;\n" +
            "uniform float step;\n" +
            "const vec3 multiplier = vec3(0.299, 0.587, 0.114);\n" +
            " \n" +
            "void main()\n" +
            "{\n" +
            "     vec4 first= texture2D(inputImageTexture, textureCoordinate);\n" +
            "     float y1 = clamp(dot(multiplier, first.rgb), 0.0, 1.0);\n" +
            "     vec2 secondCoord = textureCoordinate;\n" +
            "     secondCoord.x = secondCoord.x + step;\n" +
            "     vec4 second= texture2D(inputImageTexture, secondCoord);\n" +
            "     float y2 = clamp(dot(multiplier, second.rgb), 0.0, 1.0);\n" +
            "     vec3 rgbAve = mix(first.rgb, second.rgb, 0.5);\n" +
            "     float yAve = 0.5 * (y1 + y2);\n" +
            "     float u = clamp((rgbAve.b - yAve) * 0.565 + 0.5, 0.0, 1.0);\n" +
            "     float v = clamp((rgbAve.r - yAve) * 0.713 + 0.5, 0.0, 1.0);\n" +
            "     gl_FragColor.r = y1;\n" +
            "     gl_FragColor.g = y2;\n" +
            "     gl_FragColor.b = u;\n" +
            "     gl_FragColor.a = v;\n" +
            "}"
    }
    
    // From yuv to rgb
    companion object {
        val FRAGMENT_SHADER = "" +
            "precision highp float;\n" +
            "varying vec2 textureCoordinate;\n" +
            " \n" +
            "uniform sampler2D inputImageTexture;\n" +
            "uniform float step;\n" +
            " \n" +
            "void main()\n" +
            "{\n" +
            "     vec2 secondCoord = textureCoordinate;\n" +
            "     float correction = secondCoord.x - 2.0 * step * floor(secondCoord.x / (2.0 * step));\n" +
            "     correction = clamp((correction - (step/2.0))/ (step/2.0), 0.0, 1.0);\n" +
            "     secondCoord.x = secondCoord.x - (correction * step);\n" +
            "     vec4 yuv = texture2D(inputImageTexture, secondCoord);\n" +
            "     yuv.r = (1.0 - correction) * yuv.r + correction * yuv.g;\n" +
            "     yuv.g = yuv.b - 0.5;\n" +
            "     yuv.b = yuv.a - 0.5;\n" +
            "     gl_FragColor.r = clamp(yuv.r + 1.403 * yuv.b, 0.0, 1.0);\n" +
            "     gl_FragColor.g = clamp(yuv.r - 0.344 * yuv.g - 0.714 * yuv.b, 0.0, 1.0);\n" +
            "     gl_FragColor.b = clamp(yuv.r + 1.770 * yuv.g, 0.0, 1.0);\n" +
            "     gl_FragColor.a = 1.0;\n" +
            "}"
    }
    

    使用opengl将其绘制到曲面上如何?我在上一个项目中也做过类似的工作,我将视频解码成surface,将其转换成yuv并缓存在opengl纹理中,然后在屏幕上显示时再转换回rgb。所有这些都可以使用片段着色器完成。我没有使用opengl的经验,但这听起来是个好主意!有没有这样的解决方案的例子?我是否很清楚颜色空间转换可以通过硬件(着色器)以某种方式完成?我找到了一些如何使用着色器的示例(如)。我遗漏了一件重要的事情,那就是你的着色器代码。非常感谢。