Surfaceview / TextureView для субтитров альфа не работает - PullRequest
0 голосов
/ 27 мая 2018

Цель : попытка собрать видеоплеер с субтитрами для Android.Видео может иметь низкое разрешение, но субтитры должны соответствовать разрешению телефона (например, если видео имеет разрешение 720p, субтитры должны отображаться с размером экрана, скажем, 1080p).

Проблема : Визуализацияна Textureview или Surfaceview не видно сквозь то, где вы могли бы смешать его с фоновыми представлениями. Я использую FFMPEG для рендеринга кадра, скажем, в 720p, но телефонное устройство имеет разрешение 1080p.Мне нужно отобразить субтитры, разрешение которых отличается от разрешения субтитров, поэтому смешивание пикселей затруднено.

Сначала я попытался масштабировать кадр (AVFrame) с помощью sws_convert, но каждый кадр занимал 80 мс, так что это не вариант (так какэто работает программное обеспечение).

Затем я попробовал два вида поверхности, один для видео и один для субтитров, где видео будет 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 альфа (поэтому должно быть невидимым), но оно показано.Если я изменю его на желтый с альфа 0, он будет виден, но не правильный цвет.Если я поменяю на белый с 1 альфа, он будет белым и непрозрачным.Если я использую черный с альфа 0xCC, он невидим, только если альфа 0xFF, то он виден как черный.Кажется, нет прозрачности, хотя я добавил его в SurfaceHolder.Почему это так?Я могу добавить больше кода, если это необходимо.

Это мой единственный вариант сделать то, что я хочу, чтобы отобразить кадр как текстуру в OpenGL и (GLSurfaceView), изменить размер изображения до разрешения телефона и смешать альфа-субтитры с кадромв качестве текстуры?

Заранее спасибо.

...