2424#include " base/android/jni_string.h"
2525#include " base/android/scoped_java_ref.h"
2626#include " starboard/android/shared/audio_output_manager.h"
27- #include " starboard/android/shared/jni_utils.h"
2827#include " starboard/android/shared/media_common.h"
2928#include " starboard/android/shared/media_drm_bridge.h"
3029#include " starboard/android/shared/starboard_bridge.h"
@@ -43,6 +42,8 @@ namespace {
4342using base::android::AttachCurrentThread;
4443using base::android::ConvertJavaStringToUTF8;
4544using base::android::ConvertUTF8ToJavaString;
45+ using base::android::JavaParamRef;
46+ using base::android::ScopedJavaGlobalRef;
4647using base::android::ScopedJavaLocalRef;
4748
4849// https://developer.android.com/reference/android/view/Display.HdrCapabilities.html#HDR_TYPE_HDR10
@@ -62,47 +63,20 @@ bool EndsWith(const std::string& str, const std::string& suffix) {
6263}
6364
6465Range ConvertJavaRangeToRange (JNIEnv* env, jobject j_range) {
65- struct RangeJniCache {
66- jmethodID get_upper_method = nullptr ;
67- jmethodID get_lower_method = nullptr ;
68- jmethodID int_value_method = nullptr ;
69- };
70-
71- static std::once_flag once_flag;
72- static RangeJniCache cache;
73-
74- std::call_once (once_flag, [env]() {
75- jclass range_class = env->FindClass (" android/util/Range" );
76- SB_CHECK (range_class);
77-
78- cache.get_upper_method =
79- env->GetMethodID (range_class, " getUpper" , " ()Ljava/lang/Comparable;" );
80- SB_CHECK (cache.get_upper_method );
81-
82- cache.get_lower_method =
83- env->GetMethodID (range_class, " getLower" , " ()Ljava/lang/Comparable;" );
84- SB_CHECK (cache.get_lower_method );
85- env->DeleteLocalRef (range_class);
86-
87- jclass integer_class = env->FindClass (" java/lang/Integer" );
88- SB_CHECK (integer_class);
89-
90- cache.int_value_method = env->GetMethodID (integer_class, " intValue" , " ()I" );
91- SB_CHECK (cache.int_value_method );
92- env->DeleteLocalRef (integer_class);
93- });
94-
95- jobject j_upper_comparable =
96- env->CallObjectMethod (j_range, cache.get_upper_method );
97- jint j_upper_int =
98- env->CallIntMethod (j_upper_comparable, cache.int_value_method );
99-
100- jobject j_lower_comparable =
101- env->CallObjectMethod (j_range, cache.get_lower_method );
102- jint j_lower_int =
103- env->CallIntMethod (j_lower_comparable, cache.int_value_method );
104-
105- return Range (j_lower_int, j_upper_int);
66+ const auto j_range_ref = JavaParamRef<jobject>(env, j_range);
67+ return Range (Java_MediaCodecUtil_getRangeLower (env, j_range_ref),
68+ Java_MediaCodecUtil_getRangeUpper (env, j_range_ref));
69+ }
70+
71+ template <typename GetRangeFunc>
72+ Range GetRange (JNIEnv* env,
73+ const base::android::JavaRef<jobject>& j_capabilities,
74+ GetRangeFunc get_range_func) {
75+ SB_CHECK (env);
76+ SB_CHECK (j_capabilities);
77+ ScopedJavaLocalRef<jobject> j_range = get_range_func (env, j_capabilities);
78+ SB_CHECK (j_range);
79+ return ConvertJavaRangeToRange (env, j_range.obj ());
10680}
10781
10882void ConvertStringToLowerCase (std::string* str) {
@@ -191,37 +165,16 @@ AudioCodecCapability::AudioCodecCapability(
191165 JNIEnv* env,
192166 ScopedJavaLocalRef<jobject>& j_codec_info,
193167 ScopedJavaLocalRef<jobject>& j_audio_capabilities)
194- : CodecCapability(env, j_codec_info) {
195- SB_CHECK (env);
168+ : CodecCapability(env, j_codec_info),
169+ supported_bitrates_([env, &j_audio_capabilities] {
170+ Range supported_bitrates =
171+ GetRange (env, j_audio_capabilities,
172+ &Java_MediaCodecUtil_getAudioBitrateRange);
173+ // Overwrite the lower bound to 0.
174+ supported_bitrates.minimum = 0 ;
175+ return supported_bitrates;
176+ }()) {
196177 SB_CHECK (j_codec_info);
197- SB_CHECK (j_audio_capabilities);
198-
199- struct AudioCapabilitiesJniCache {
200- jmethodID get_bitrate_range_method;
201- };
202-
203- static std::once_flag once_flag;
204- static AudioCapabilitiesJniCache cache;
205-
206- std::call_once (once_flag, [env]() {
207- jclass audio_capabilities_class =
208- env->FindClass (" android/media/MediaCodecInfo$AudioCapabilities" );
209- SB_CHECK (audio_capabilities_class);
210-
211- cache.get_bitrate_range_method = env->GetMethodID (
212- audio_capabilities_class, " getBitrateRange" , " ()Landroid/util/Range;" );
213- SB_CHECK (cache.get_bitrate_range_method );
214- env->DeleteLocalRef (audio_capabilities_class);
215- });
216-
217- ScopedJavaLocalRef<jobject> j_bitrate_range (
218- env, env->CallObjectMethod (j_audio_capabilities.obj (),
219- cache.get_bitrate_range_method ));
220- SB_CHECK (j_bitrate_range);
221- supported_bitrates_ = ConvertJavaRangeToRange (env, j_bitrate_range.obj ());
222-
223- // Overwrite the lower bound to 0.
224- supported_bitrates_.minimum = 0 ;
225178}
226179
227180bool AudioCodecCapability::IsBitrateSupported (int bitrate) const {
@@ -236,110 +189,37 @@ VideoCodecCapability::VideoCodecCapability(
236189 is_software_decoder_(
237190 Java_CodecCapabilityInfo_isSoftware (env, j_codec_info)),
238191 is_hdr_capable_(Java_CodecCapabilityInfo_isHdrCapable(env, j_codec_info)),
239- j_video_capabilities_(env, j_video_capabilities.obj()) {
240- struct VideoCapabilitiesJniCache {
241- jmethodID get_supported_widths_method;
242- jmethodID get_supported_heights_method;
243- jmethodID get_bitrate_range_method;
244- jmethodID get_supported_frame_rates_method;
245- };
246-
247- static std::once_flag once_flag;
248- static VideoCapabilitiesJniCache cache;
249-
250- std::call_once (once_flag, [env]() {
251- jclass video_capabilities_class =
252- env->FindClass (" android/media/MediaCodecInfo$VideoCapabilities" );
253- SB_CHECK (video_capabilities_class);
254-
255- cache.get_supported_widths_method =
256- env->GetMethodID (video_capabilities_class, " getSupportedWidths" ,
257- " ()Landroid/util/Range;" );
258- SB_CHECK (cache.get_supported_widths_method );
259-
260- cache.get_supported_heights_method =
261- env->GetMethodID (video_capabilities_class, " getSupportedHeights" ,
262- " ()Landroid/util/Range;" );
263- SB_CHECK (cache.get_supported_heights_method );
264-
265- cache.get_bitrate_range_method = env->GetMethodID (
266- video_capabilities_class, " getBitrateRange" , " ()Landroid/util/Range;" );
267- SB_CHECK (cache.get_bitrate_range_method );
268-
269- cache.get_supported_frame_rates_method =
270- env->GetMethodID (video_capabilities_class, " getSupportedFrameRates" ,
271- " ()Landroid/util/Range;" );
272- SB_CHECK (cache.get_supported_frame_rates_method );
273- env->DeleteLocalRef (video_capabilities_class);
274- });
275-
276- ScopedJavaLocalRef<jobject> j_width_range (
277- env, env->CallObjectMethod (j_video_capabilities_.obj (),
278- cache.get_supported_widths_method ));
279- SB_CHECK (j_width_range);
280- supported_widths_ = ConvertJavaRangeToRange (env, j_width_range.obj ());
281-
282- ScopedJavaLocalRef<jobject> j_height_range (
283- env, env->CallObjectMethod (j_video_capabilities_.obj (),
284- cache.get_supported_heights_method ));
285- SB_CHECK (j_height_range);
286- supported_heights_ = ConvertJavaRangeToRange (env, j_height_range.obj ());
287-
288- ScopedJavaLocalRef<jobject> j_bitrate_range (
289- env, env->CallObjectMethod (j_video_capabilities_.obj (),
290- cache.get_bitrate_range_method ));
291- SB_CHECK (j_bitrate_range);
292- supported_bitrates_ = ConvertJavaRangeToRange (env, j_bitrate_range.obj ());
293-
294- ScopedJavaLocalRef<jobject> j_frame_rate_range (
295- env, env->CallObjectMethod (j_video_capabilities_.obj (),
296- cache.get_supported_frame_rates_method ));
297- SB_CHECK (j_frame_rate_range);
298- supported_frame_rates_ =
299- ConvertJavaRangeToRange (env, j_frame_rate_range.obj ());
300- }
301-
302- VideoCodecCapability::~VideoCodecCapability () {}
192+ j_video_capabilities_(env, j_video_capabilities.obj()),
193+ supported_widths_(GetRange(env,
194+ j_video_capabilities_,
195+ &Java_MediaCodecUtil_getVideoWidthRange)),
196+ supported_heights_(GetRange(env,
197+ j_video_capabilities_,
198+ &Java_MediaCodecUtil_getVideoHeightRange)),
199+ supported_bitrates_(GetRange(env,
200+ j_video_capabilities_,
201+ &Java_MediaCodecUtil_getVideoBitrateRange)),
202+ supported_frame_rates_(
203+ GetRange (env,
204+ j_video_capabilities_,
205+ &Java_MediaCodecUtil_getVideoFrameRateRange)) {}
206+ VideoCodecCapability::~VideoCodecCapability () = default ;
303207
304208bool VideoCodecCapability::IsBitrateSupported (int bitrate) const {
305209 return supported_bitrates_.Contains (bitrate);
306210}
307211
308212bool VideoCodecCapability::AreResolutionAndRateSupported (int frame_width,
309213 int frame_height,
310- int fps) {
214+ int fps) const {
311215 JNIEnv* env = AttachCurrentThread ();
312- struct AreResolutionAndRateSupportedJniCache {
313- jmethodID are_size_and_rate_supported_method;
314- jmethodID is_size_supported_method;
315- };
316-
317- static std::once_flag once_flag;
318- static AreResolutionAndRateSupportedJniCache cache;
319-
320- std::call_once (once_flag, [env]() {
321- jclass video_capabilities_class =
322- env->FindClass (" android/media/MediaCodecInfo$VideoCapabilities" );
323- SB_CHECK (video_capabilities_class);
324-
325- cache.are_size_and_rate_supported_method = env->GetMethodID (
326- video_capabilities_class, " areSizeAndRateSupported" , " (IID)Z" );
327- SB_CHECK (cache.are_size_and_rate_supported_method );
328-
329- cache.is_size_supported_method =
330- env->GetMethodID (video_capabilities_class, " isSizeSupported" , " (II)Z" );
331- SB_CHECK (cache.is_size_supported_method );
332- env->DeleteLocalRef (video_capabilities_class);
333- });
334-
335216 if (frame_width != 0 && frame_height != 0 && fps != 0 ) {
336- return env-> CallBooleanMethod (
337- j_video_capabilities_. obj (), cache. are_size_and_rate_supported_method ,
338- frame_width, frame_height, static_cast <jdouble>(fps));
217+ return Java_MediaCodecUtil_areSizeAndRateSupported (
218+ env, j_video_capabilities_, frame_width, frame_height ,
219+ static_cast <jdouble>(fps));
339220 } else if (frame_width != 0 && frame_height != 0 ) {
340- return env->CallBooleanMethod (j_video_capabilities_.obj (),
341- cache.is_size_supported_method , frame_width,
342- frame_height);
221+ return Java_MediaCodecUtil_isSizeSupported (env, j_video_capabilities_,
222+ frame_width, frame_height);
343223 }
344224 if (frame_width != 0 && !supported_widths_.Contains (frame_width)) {
345225 return false ;
0 commit comments