diff --git a/starboard/android/shared/BUILD.gn b/starboard/android/shared/BUILD.gn index 2801ca2a6b8..0acc55f11d5 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 9773b935c6d..00000000000 --- 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 3f32621b95a..00000000000 --- 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 957fb1daf17..b5ab91a57a0 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 512b7ee02d0..6f1d4b6ecdc 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 f56c7c06c2d..5d7b3e9f6bb 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; } }