Skip to content

Commit

Permalink
[android] Turn SbDecodeTargetPrivate to interface (#4610)
Browse files Browse the repository at this point in the history
The SbDecodeTargetPrivate class on Android TV used to hold a ref-counted
data. Now it's abstracted into a ref-counted interface into
starboard/shared/starboard/decode_target, and the android derived class
DecodeTarget simply holds the data directly.
    
This has the following benefits:
1. The DecodeTarget is not a class, and its member variables are
properly encapsulated.
2. Since SbDecodeTargetPrivate is now an interface, this allows us to
have multiple implementation of it in the same Starboard binary.
3. The implementation of DecodeTarget is also simplified as there is one
less level of indirection (i.e. the nested class Data is removed).

b/327287075
  • Loading branch information
xiaomings authored Dec 18, 2024
1 parent a2deb5c commit 1f79302
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 151 deletions.
10 changes: 6 additions & 4 deletions starboard/android/shared/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ static_library("starboard_platform") {
"//starboard/shared/starboard/audio_sink/stub_audio_sink_type.h",
"//starboard/shared/starboard/command_line.cc",
"//starboard/shared/starboard/command_line.h",
"//starboard/shared/starboard/decode_target/decode_target_get_info.cc",
"//starboard/shared/starboard/decode_target/decode_target_internal.cc",
"//starboard/shared/starboard/decode_target/decode_target_internal.h",
"//starboard/shared/starboard/decode_target/decode_target_release.cc",
"//starboard/shared/starboard/drm/drm_close_session.cc",
"//starboard/shared/starboard/drm/drm_destroy_system.cc",
"//starboard/shared/starboard/drm/drm_generate_session_update_request.cc",
Expand Down Expand Up @@ -189,10 +193,8 @@ static_library("starboard_platform") {
"configuration_public.h",
"crash_handler.cc",
"crash_handler.h",
"decode_target_get_info.cc",
"decode_target_internal.cc",
"decode_target_internal.h",
"decode_target_release.cc",
"decode_target.cc",
"decode_target.h",
"drm_create_system.cc",
"drm_system.cc",
"drm_system.h",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/android/shared/decode_target_internal.h"
#include "starboard/android/shared/decode_target.h"

#include <android/native_window_jni.h>
#include <jni.h>
Expand All @@ -28,6 +28,9 @@

using starboard::android::shared::JniEnvExt;

namespace starboard {
namespace android {
namespace shared {
namespace {

jobject CreateSurfaceTexture(int gl_texture_id) {
Expand Down Expand Up @@ -61,17 +64,30 @@ void RunOnContextRunner(void* context) {

} // namespace

SbDecodeTargetPrivate::SbDecodeTargetPrivate(
SbDecodeTargetGraphicsContextProvider* provider) {
DecodeTarget::DecodeTarget(SbDecodeTargetGraphicsContextProvider* provider) {
std::function<void()> closure =
std::bind(&SbDecodeTargetPrivate::CreateOnContextRunner, this);
std::bind(&DecodeTarget::CreateOnContextRunner, this);
SbDecodeTargetRunInGlesContext(provider, &RunOnContextRunner, &closure);
}

SbDecodeTargetPrivate::SbDecodeTargetPrivate(const SbDecodeTargetPrivate& that)
: data(that.data) {}
bool DecodeTarget::GetInfo(SbDecodeTargetInfo* out_info) {
SB_DCHECK(out_info);

void SbDecodeTargetPrivate::CreateOnContextRunner() {
*out_info = info_;
}

DecodeTarget::~DecodeTarget() {
ANativeWindow_release(native_window_);

JniEnvExt* env = JniEnvExt::Get();
env->DeleteGlobalRef(surface_);
env->DeleteGlobalRef(surface_texture_);

glDeleteTextures(1, &info_.planes[0].texture);
SB_DCHECK(glGetError() == GL_NO_ERROR);
}

void DecodeTarget::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
Expand All @@ -88,44 +104,34 @@ void SbDecodeTargetPrivate::CreateOnContextRunner() {
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);
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);
surface_ = CreateSurfaceFromSurfaceTexture(surface_texture_);

data->native_window =
ANativeWindow_fromSurface(JniEnvExt::Get(), data->surface);
native_window_ = ANativeWindow_fromSurface(JniEnvExt::Get(), 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;
info_.format = kSbDecodeTargetFormat1PlaneRGBA;
info_.is_opaque = true;
info_.width = 0;
info_.height = 0;
info_.planes[0].texture = texture;
info_.planes[0].gl_texture_target = GL_TEXTURE_EXTERNAL_OES;
info_.planes[0].width = 0;
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;
info_.planes[0].content_region.left = 0;
info_.planes[0].content_region.right = 0;
info_.planes[0].content_region.top = 0;
info_.planes[0].content_region.bottom = 0;

GL_CALL(glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0));
}

SbDecodeTargetPrivate::Data::~Data() {
ANativeWindow_release(native_window);

JniEnvExt* env = JniEnvExt::Get();
env->DeleteGlobalRef(surface);
env->DeleteGlobalRef(surface_texture);

glDeleteTextures(1, &info.planes[0].texture);
SB_DCHECK(glGetError() == GL_NO_ERROR);
}
} // namespace shared
} // namespace android
} // namespace starboard
68 changes: 68 additions & 0 deletions starboard/android/shared/decode_target.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2024 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_H_
#define STARBOARD_ANDROID_SHARED_DECODE_TARGET_H_

#include <GLES2/gl2.h>
#include <android/native_window.h>
#include <jni.h>

#include "starboard/decode_target.h"
#include "starboard/shared/starboard/decode_target/decode_target_internal.h"

namespace starboard {
namespace android {
namespace shared {

class DecodeTarget final : public SbDecodeTargetPrivate {
public:
explicit DecodeTarget(SbDecodeTargetGraphicsContextProvider* provider);

bool GetInfo(SbDecodeTargetInfo* out_info) final;

jobject surface_texture() const { return surface_texture_; }
jobject surface() const { return surface_; }

void set_dimension(int width, int height) {
info_.planes[0].width = width;
info_.planes[0].height = height;
info_.width = width;
info_.height = height;
}

void set_content_region(
const SbDecodeTargetInfoContentRegion& content_region) {
info_.planes[0].content_region = content_region;
}

private:
~DecodeTarget() final;

void CreateOnContextRunner();

// Java objects which wrap the texture. We hold on to global references
// to these objects.
jobject surface_texture_;
jobject surface_;
ANativeWindow* native_window_;

SbDecodeTargetInfo info_;
};

} // namespace shared
} // namespace android
} // namespace starboard

#endif // STARBOARD_ANDROID_SHARED_DECODE_TARGET_H_
54 changes: 0 additions & 54 deletions starboard/android/shared/decode_target_internal.h

This file was deleted.

Loading

0 comments on commit 1f79302

Please sign in to comment.