Skip to content

Commit

Permalink
Fix black borders on Huawei devices when rendering alpha video. (#471)
Browse files Browse the repository at this point in the history
Co-authored-by: fusionxu <fusionxu@tencent.com>
  • Loading branch information
FusionXu and fusionxu committed Aug 12, 2022
1 parent 24970bd commit 4db8dd6
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/platform/android/GPUDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ GPUDecoder::~GPUDecoder() {
}

bool GPUDecoder::initDecoder(JNIEnv* env, const VideoFormat& format) {
videoSurface = VideoSurface::Make(format.width, format.height);
videoSurface = VideoSurface::Make(format.width, format.height, format.hasAlpha);
if (videoSurface == nullptr) {
return false;
}
Expand Down
21 changes: 13 additions & 8 deletions src/platform/android/VideoSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ void VideoSurface::InitJNI(JNIEnv* env, const std::string& className) {
VideoSurface_release = env->GetMethodID(VideoSurfaceClass.get(), "release", "()V");
}

OESTexture::OESTexture(const tgfx::GLSampler& glSampler, int width, int height)
: GLTexture(width, height, tgfx::ImageOrigin::TopLeft) {
OESTexture::OESTexture(const tgfx::GLSampler& glSampler, int width, int height, bool hasAlpha)
: GLTexture(width, height, tgfx::ImageOrigin::TopLeft), hasAlpha(hasAlpha) {
sampler = glSampler;
}

Expand All @@ -55,7 +55,7 @@ void OESTexture::setTextureSize(int width, int height) {
}

void OESTexture::computeTransform() {
if (textureWidth == 0 || textureHeight == 0) {
if (textureWidth == 0 || textureHeight == 0 || hasAlpha) {
return;
}
// https://cs.android.com/android/platform/superproject/+/master:frameworks/native/libs/nativedisplay/surfacetexture/SurfaceTexture.cpp;l=275;drc=master;bpv=0;bpt=1
Expand All @@ -79,6 +79,10 @@ void OESTexture::computeTransform() {
}

tgfx::Point OESTexture::getTextureCoord(float x, float y) const {
if (hasAlpha) {
// 如果有 alpha 通道,不需要缩小纹素,解决华为设备上的黑边问题
return {x / static_cast<float>(textureWidth), y / static_cast<float>(textureHeight)};
}
return {x / static_cast<float>(width()) * sx + tx, y / static_cast<float>(height()) * sy + ty};
}

Expand All @@ -89,7 +93,7 @@ void OESTexture::onReleaseGPU() {
}
}

std::shared_ptr<VideoSurface> VideoSurface::Make(int width, int height) {
std::shared_ptr<VideoSurface> VideoSurface::Make(int width, int height, bool hasAlpha) {
auto env = JNIEnvironment::Current();
if (env == nullptr) {
return nullptr;
Expand All @@ -99,11 +103,12 @@ std::shared_ptr<VideoSurface> VideoSurface::Make(int width, int height) {
if (surface.empty()) {
return nullptr;
}
return std::shared_ptr<VideoSurface>(new VideoSurface(env, surface.get(), width, height));
return std::shared_ptr<VideoSurface>(
new VideoSurface(env, surface.get(), width, height, hasAlpha));
}

VideoSurface::VideoSurface(JNIEnv* env, jobject surface, int width, int height)
: width(width), height(height) {
VideoSurface::VideoSurface(JNIEnv* env, jobject surface, int width, int height, bool hasAlpha)
: width(width), height(height), hasAlpha(hasAlpha) {
videoSurface.reset(env, surface);
}

Expand Down Expand Up @@ -145,7 +150,7 @@ std::shared_ptr<tgfx::Texture> VideoSurface::makeTexture(tgfx::Context* context)
if (oesTexture == nullptr) {
auto textureWidth = env->CallIntMethod(videoSurface.get(), VideoSurface_videoWidth);
auto textureHeight = env->CallIntMethod(videoSurface.get(), VideoSurface_videoHeight);
oesTexture = tgfx::Resource::Wrap(context, new OESTexture(glInfo, width, height));
oesTexture = tgfx::Resource::Wrap(context, new OESTexture(glInfo, width, height, hasAlpha));
oesTexture->setTextureSize(textureWidth, textureHeight);
oesTexture->attachedSurface.reset(env, videoSurface.get());
}
Expand Down
8 changes: 5 additions & 3 deletions src/platform/android/VideoSurface.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
namespace pag {
class OESTexture : public tgfx::GLTexture {
public:
OESTexture(const tgfx::GLSampler& sampler, int width, int height);
OESTexture(const tgfx::GLSampler& sampler, int width, int height, bool hasAlpha);

tgfx::Point getTextureCoord(float x, float y) const override;

Expand All @@ -37,6 +37,7 @@ class OESTexture : public tgfx::GLTexture {

int textureWidth = 0;
int textureHeight = 0;
bool hasAlpha = false;
// 持有 Java 的 Surface,确保即使 GPUDecoder 提前释放也能正常被使用。
Global<jobject> attachedSurface;
float sx = 1.0f;
Expand All @@ -51,7 +52,7 @@ class VideoSurface {
public:
static void InitJNI(JNIEnv* env, const std::string& className);

static std::shared_ptr<VideoSurface> Make(int width, int height);
static std::shared_ptr<VideoSurface> Make(int width, int height, bool hasAlpha = false);

~VideoSurface();

Expand All @@ -67,12 +68,13 @@ class VideoSurface {
Global<jobject> videoSurface;
int width = 0;
int height = 0;
bool hasAlpha = false;
uint32_t deviceID = 0;
tgfx::GLSampler glInfo = {};
std::shared_ptr<OESTexture> oesTexture = nullptr;
mutable std::atomic_bool hasPendingTextureImage = {false};

VideoSurface(JNIEnv* env, jobject surface, int width, int height);
VideoSurface(JNIEnv* env, jobject surface, int width, int height, bool hasAlpha);
bool attachToContext(JNIEnv* env, tgfx::Context* context);
bool updateTexImage(JNIEnv* env);
};
Expand Down
1 change: 1 addition & 0 deletions src/rendering/sequences/VideoSequenceDemuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ VideoSequenceDemuxer::VideoSequenceDemuxer(std::shared_ptr<File> file, VideoSequ
: file(std::move(file)), sequence(sequence) {
format.width = sequence->getVideoWidth();
format.height = sequence->getVideoHeight();
format.hasAlpha = sequence->alphaStartX + sequence->alphaStartY > 0;
for (auto& header : sequence->headers) {
auto bytes = tgfx::Data::MakeWithoutCopy(header->data(), header->length());
format.headers.push_back(std::move(bytes));
Expand Down
1 change: 1 addition & 0 deletions src/rendering/video/VideoFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct VideoFormat {
tgfx::YUVColorRange colorRange = tgfx::YUVColorRange::MPEG;
int width = 0;
int height = 0;
bool hasAlpha = false;
int64_t duration = 0;
float frameRate = 0.0;
int maxReorderSize = 4;
Expand Down

0 comments on commit 4db8dd6

Please sign in to comment.