From fc163a7d163d5dce1cedaeffb99ad411ae98bbf6 Mon Sep 17 00:00:00 2001 From: xiaomings Date: Tue, 17 Dec 2024 15:24:37 -0800 Subject: [PATCH] [android] Refactor SbDecodeTarget creation (#4598) Move the creation of the SbDecodeTargetPrivate from the function DecodeTargetCreate() into the ctor of SbDecodeTargetPrivate. Also no longer pass parameters (format, width, and height) with preset values. There is no other functionality changes. b/327287075 --- starboard/android/shared/BUILD.gn | 2 - .../android/shared/decode_target_create.cc | 147 ------------------ .../android/shared/decode_target_create.h | 34 ---- .../android/shared/decode_target_internal.cc | 101 ++++++++++++ .../android/shared/decode_target_internal.h | 7 + starboard/android/shared/video_decoder.cc | 8 +- 6 files changed, 111 insertions(+), 188 deletions(-) delete mode 100644 starboard/android/shared/decode_target_create.cc delete mode 100644 starboard/android/shared/decode_target_create.h diff --git a/starboard/android/shared/BUILD.gn b/starboard/android/shared/BUILD.gn index 2801ca2a6b8b..0acc55f11d5c 100644 --- a/starboard/android/shared/BUILD.gn +++ b/starboard/android/shared/BUILD.gn @@ -189,8 +189,6 @@ static_library("starboard_platform") { "configuration_public.h", "crash_handler.cc", "crash_handler.h", - "decode_target_create.cc", - "decode_target_create.h", "decode_target_get_info.cc", "decode_target_internal.cc", "decode_target_internal.h", diff --git a/starboard/android/shared/decode_target_create.cc b/starboard/android/shared/decode_target_create.cc deleted file mode 100644 index 9773b935c6df..000000000000 --- a/starboard/android/shared/decode_target_create.cc +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2017 The Cobalt Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "starboard/android/shared/decode_target_create.h" - -#include -#include - -#include -#include -#include - -#include "starboard/android/shared/decode_target_internal.h" -#include "starboard/android/shared/jni_env_ext.h" -#include "starboard/decode_target.h" -#include "starboard/shared/gles/gl_call.h" - -using starboard::android::shared::JniEnvExt; - -namespace starboard { -namespace android { -namespace shared { - -namespace { -jobject CreateSurfaceTexture(int gl_texture_id) { - JniEnvExt* env = JniEnvExt::Get(); - - jobject local_surface_texture = env->NewObjectOrAbort( - "dev/cobalt/media/VideoSurfaceTexture", "(I)V", gl_texture_id); - - jobject global_surface_texture = - env->ConvertLocalRefToGlobalRef(local_surface_texture); - - return global_surface_texture; -} - -jobject CreateSurfaceFromSurfaceTexture(jobject surface_texture) { - JniEnvExt* env = JniEnvExt::Get(); - - jobject local_surface = env->NewObjectOrAbort( - "android/view/Surface", "(Landroid/graphics/SurfaceTexture;)V", - surface_texture); - - jobject global_surface = env->ConvertLocalRefToGlobalRef(local_surface); - - return global_surface; -} - -struct CreateParams { - int width; - int height; - SbDecodeTargetFormat format; - - SbDecodeTarget decode_target_out; -}; - -void CreateWithContextRunner(void* context) { - CreateParams* params = static_cast(context); - - // Setup the GL texture that Android's MediaCodec library will target with - // the decoder. We don't call glTexImage2d() on it, Android will handle - // the creation of the content when SurfaceTexture::updateTexImage() is - // called. - GLuint texture; - GL_CALL(glGenTextures(1, &texture)); - GL_CALL(glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture)); - GL_CALL(glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, - GL_LINEAR)); - GL_CALL(glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, - GL_LINEAR)); - GL_CALL(glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_EDGE)); - GL_CALL(glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_EDGE)); - - SbDecodeTarget decode_target = new SbDecodeTargetPrivate; - decode_target->data = new SbDecodeTargetPrivate::Data; - - // Wrap the GL texture in an Android SurfaceTexture object. - decode_target->data->surface_texture = CreateSurfaceTexture(texture); - - // We will also need an Android Surface object in order to obtain a - // ANativeWindow object that we can pass into the AMediaCodec library. - decode_target->data->surface = - CreateSurfaceFromSurfaceTexture(decode_target->data->surface_texture); - - decode_target->data->native_window = - ANativeWindow_fromSurface(JniEnvExt::Get(), decode_target->data->surface); - - // Setup our publicly accessible decode target information. - decode_target->data->info.format = params->format; - decode_target->data->info.is_opaque = true; - decode_target->data->info.width = params->width; - decode_target->data->info.height = params->height; - decode_target->data->info.planes[0].texture = texture; - decode_target->data->info.planes[0].gl_texture_target = - GL_TEXTURE_EXTERNAL_OES; - decode_target->data->info.planes[0].width = params->width; - decode_target->data->info.planes[0].height = params->height; - - // These values will be initialized when SbPlayerGetCurrentFrame() is called. - decode_target->data->info.planes[0].content_region.left = 0; - decode_target->data->info.planes[0].content_region.right = 0; - decode_target->data->info.planes[0].content_region.top = 0; - decode_target->data->info.planes[0].content_region.bottom = 0; - - GL_CALL(glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0)); - - params->decode_target_out = decode_target; -} - -} // namespace - -SbDecodeTarget DecodeTargetCreate( - SbDecodeTargetGraphicsContextProvider* provider, - SbDecodeTargetFormat format, - int width, - int height) { - SB_DCHECK(format == kSbDecodeTargetFormat1PlaneRGBA); - if (format != kSbDecodeTargetFormat1PlaneRGBA) { - return kSbDecodeTargetInvalid; - } - - CreateParams params; - params.width = width; - params.height = height; - params.format = format; - params.decode_target_out = kSbDecodeTargetInvalid; - - SbDecodeTargetRunInGlesContext(provider, &CreateWithContextRunner, ¶ms); - return params.decode_target_out; -} - -} // namespace shared -} // namespace android -} // namespace starboard diff --git a/starboard/android/shared/decode_target_create.h b/starboard/android/shared/decode_target_create.h deleted file mode 100644 index 3f32621b95a3..000000000000 --- a/starboard/android/shared/decode_target_create.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2017 The Cobalt Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef STARBOARD_ANDROID_SHARED_DECODE_TARGET_CREATE_H_ -#define STARBOARD_ANDROID_SHARED_DECODE_TARGET_CREATE_H_ - -#include "starboard/decode_target.h" - -namespace starboard { -namespace android { -namespace shared { - -SbDecodeTarget DecodeTargetCreate( - SbDecodeTargetGraphicsContextProvider* provider, - SbDecodeTargetFormat format, - int width, - int height); - -} // namespace shared -} // namespace android -} // namespace starboard - -#endif // STARBOARD_ANDROID_SHARED_DECODE_TARGET_CREATE_H_ diff --git a/starboard/android/shared/decode_target_internal.cc b/starboard/android/shared/decode_target_internal.cc index 957fb1daf172..b5ab91a57a0f 100644 --- a/starboard/android/shared/decode_target_internal.cc +++ b/starboard/android/shared/decode_target_internal.cc @@ -14,10 +14,111 @@ #include "starboard/android/shared/decode_target_internal.h" +#include +#include + +#include +#include +#include + +#include + #include "starboard/android/shared/jni_env_ext.h" +#include "starboard/shared/gles/gl_call.h" using starboard::android::shared::JniEnvExt; +namespace { + +jobject CreateSurfaceTexture(int gl_texture_id) { + JniEnvExt* env = JniEnvExt::Get(); + + jobject local_surface_texture = env->NewObjectOrAbort( + "dev/cobalt/media/VideoSurfaceTexture", "(I)V", gl_texture_id); + + jobject global_surface_texture = + env->ConvertLocalRefToGlobalRef(local_surface_texture); + + return global_surface_texture; +} + +jobject CreateSurfaceFromSurfaceTexture(jobject surface_texture) { + JniEnvExt* env = JniEnvExt::Get(); + + jobject local_surface = env->NewObjectOrAbort( + "android/view/Surface", "(Landroid/graphics/SurfaceTexture;)V", + surface_texture); + + jobject global_surface = env->ConvertLocalRefToGlobalRef(local_surface); + + return global_surface; +} + +void RunOnContextRunner(void* context) { + std::function* closure = static_cast*>(context); + (*closure)(); +} + +} // namespace + +SbDecodeTargetPrivate::SbDecodeTargetPrivate( + SbDecodeTargetGraphicsContextProvider* provider) { + std::function closure = + std::bind(&SbDecodeTargetPrivate::CreateOnContextRunner, this); + SbDecodeTargetRunInGlesContext(provider, &RunOnContextRunner, &closure); +} + +SbDecodeTargetPrivate::SbDecodeTargetPrivate(const SbDecodeTargetPrivate& that) + : data(that.data) {} + +void SbDecodeTargetPrivate::CreateOnContextRunner() { + // Setup the GL texture that Android's MediaCodec library will target with + // the decoder. We don't call glTexImage2d() on it, Android will handle + // the creation of the content when SurfaceTexture::updateTexImage() is + // called. + GLuint texture; + GL_CALL(glGenTextures(1, &texture)); + GL_CALL(glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture)); + GL_CALL(glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, + GL_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, + GL_LINEAR)); + GL_CALL(glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, + GL_CLAMP_TO_EDGE)); + GL_CALL(glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, + GL_CLAMP_TO_EDGE)); + + data = new SbDecodeTargetPrivate::Data; + + // Wrap the GL texture in an Android SurfaceTexture object. + data->surface_texture = CreateSurfaceTexture(texture); + + // We will also need an Android Surface object in order to obtain a + // ANativeWindow object that we can pass into the AMediaCodec library. + data->surface = CreateSurfaceFromSurfaceTexture(data->surface_texture); + + data->native_window = + ANativeWindow_fromSurface(JniEnvExt::Get(), data->surface); + + // Setup our publicly accessible decode target information. + data->info.format = kSbDecodeTargetFormat1PlaneRGBA; + data->info.is_opaque = true; + data->info.width = 0; + data->info.height = 0; + data->info.planes[0].texture = texture; + data->info.planes[0].gl_texture_target = GL_TEXTURE_EXTERNAL_OES; + data->info.planes[0].width = 0; + data->info.planes[0].height = 0; + + // These values will be initialized when SbPlayerGetCurrentFrame() is called. + data->info.planes[0].content_region.left = 0; + data->info.planes[0].content_region.right = 0; + data->info.planes[0].content_region.top = 0; + data->info.planes[0].content_region.bottom = 0; + + GL_CALL(glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0)); +} + SbDecodeTargetPrivate::Data::~Data() { ANativeWindow_release(native_window); diff --git a/starboard/android/shared/decode_target_internal.h b/starboard/android/shared/decode_target_internal.h index 512b7ee02d01..6f1d4b6ecdcf 100644 --- a/starboard/android/shared/decode_target_internal.h +++ b/starboard/android/shared/decode_target_internal.h @@ -23,6 +23,10 @@ #include "starboard/decode_target.h" struct SbDecodeTargetPrivate { + explicit SbDecodeTargetPrivate( + SbDecodeTargetGraphicsContextProvider* provider); + SbDecodeTargetPrivate(const SbDecodeTargetPrivate& that); + class Data : public starboard::RefCounted { public: Data() {} @@ -42,6 +46,9 @@ struct SbDecodeTargetPrivate { }; starboard::scoped_refptr data; + + private: + void CreateOnContextRunner(); }; #endif // STARBOARD_ANDROID_SHARED_DECODE_TARGET_INTERNAL_H_ diff --git a/starboard/android/shared/video_decoder.cc b/starboard/android/shared/video_decoder.cc index f56c7c06c2de..5d7b3e9f6bb7 100644 --- a/starboard/android/shared/video_decoder.cc +++ b/starboard/android/shared/video_decoder.cc @@ -22,7 +22,6 @@ #include #include -#include "starboard/android/shared/decode_target_create.h" #include "starboard/android/shared/decode_target_internal.h" #include "starboard/android/shared/jni_env_ext.h" #include "starboard/android/shared/jni_utils.h" @@ -685,8 +684,7 @@ bool VideoDecoder::InitializeCodec(const VideoStreamInfo& video_stream_info, // done behind the scenes, the acquired texture is not actually backed // by texture data until updateTexImage() is called on it. SbDecodeTarget decode_target = - DecodeTargetCreate(decode_target_graphics_context_provider_, - kSbDecodeTargetFormat1PlaneRGBA, 0, 0); + new SbDecodeTargetPrivate(decode_target_graphics_context_provider_); if (!SbDecodeTargetIsValid(decode_target)) { *error_message = "Could not acquire a decode target from provider."; SB_LOG(ERROR) << *error_message; @@ -1064,8 +1062,8 @@ SbDecodeTarget VideoDecoder::GetCurrentDecodeTarget() { } if (first_texture_received_) { - SbDecodeTarget out_decode_target = new SbDecodeTargetPrivate; - out_decode_target->data = decode_target_->data; + SbDecodeTarget out_decode_target = + new SbDecodeTargetPrivate(*decode_target_); return out_decode_target; } }