用于字幕alpha的Surfaceview / TextureView不起作用

时间:2018-05-27 05:26:51

标签: android video ffmpeg android-ndk surfaceview

目标:尝试为Android制作带字幕的视频播放器。视频可以是低分辨率但字幕应该是手机的分辨率(如果视频是720p,则字幕应该渲染到屏幕尺寸为1080p)。

问题在Textureview或Surfaceview上渲染无法通过哪里可以看到它与背景视图混合。我正在使用FFMPEG渲染帧720p,但电话设备是1080p。我需要显示分辨率不同于字幕分辨率的字幕,因此难以进行像素混合。

我首先尝试使用sws_convert缩放帧(AVFrame),但每帧占用80ms因此不是一个选项(因为它正在运行软件)。

然后我尝试了两个表面视图,一个用于视频,一个用于字幕,其中视频为720p,字幕SurfaceView为1080p,然后视频可扩展到手机大小。这里的问题是字幕不是半透明的。黑色不透明度0将是透明的,但是具有α0的白色仍然是白色。这是为什么?

//Code from Java, the view that extends FrameLayout
public VideoView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    mVideoSurface = new SurfaceView(context);
    mSubtitlesSurface = new SurfaceView(context);
    addView(mVideoSurface);
    addView(mSubtitlesSurface);
    mVideoSurface.getHolder().addCallback(mSurfaceCallback);
    mSubtitlesSurface.getHolder().addCallback(mSurfaceCallback);
    mSubtitlesSurface.setZOrderMediaOverlay(true);
    mSubtitlesSurface.getHolder().setFormat(PixelFormat.TRANSLUCENT);
    //etc
}

最终我尝试作为测试来为字幕表面视图(C ++)渲染一个正方形

// Render the video frame, now render the subtitle frame
ANativeWindow_Buffer buffer;
ANativeWindow_setBuffersGeometry(subWindow, width, height, WINDOW_FORMAT_RGBA_8888);
if ((ret = ANativeWindow_lock(subWindow, &buffer, NULL)) < 0) {
    return ret;
}
for (int j = height/2; j < height/2 + 100; j++) {
    for (int i = width/2; i < width/2 + 100; i++) {
        uint8_t * d =  (uint8_t*)buffer.bits + j * (buffer.stride * 4) + i * 4;
        d[0] = 0xff;
        d[1] = 0xff;
        d[2] = 0xFF;
        d[3] = 0;           /* alpha */

    }
}
ANativeWindow_unlockAndPost(subWindow);

因此,上面的代码应该在图像中呈现一个带有0 alpha的白色方块(因此应该是不可见的),但它会显示出来。如果我用alpha 0将其更改为黄色,它将是可见的,但不是正确的颜色。如果我用1 alpha变为白色,则为白色且不透明。如果我使用带有alpha 0xCC的黑色,它是不可见的,只有当alpha为0xFF时它才会显示为黑色。即使我将它添加到SurfaceHolder,似乎没有半透明性。为什么会这样?如果需要,我可以添加更多代码。

我唯一的选择就是在OpenGL和(GLSurfaceView)中将帧渲染为纹理,将图像大小调整为手机分辨率并将alpha字幕作为纹理混合到帧上?

提前致谢。

0 个答案:

没有答案