Skip to content
This repository
Browse code

jni: Add a templated helper for retrieving jobjectArrays.

This takes care of ensuring global references, and skips a copy by using
emplace_back rather than push_back.
  • Loading branch information...
commit 157e32a438d738aad5ada56d0ddda8f29fd21e3b 1 parent 5757df4
authored August 20, 2013 S. Davilla committed August 23, 2013
38  xbmc/android/jni/MediaCodec.cpp
@@ -164,44 +164,14 @@ const CJNIMediaFormat CJNIMediaCodec::getOutputFormat()
164 164
 
165 165
 std::vector<CJNIByteBuffer> CJNIMediaCodec::getInputBuffers()
166 166
 {
167  
-  jhobjectArray oByteBuffers = call_method<jhobjectArray>(m_object,
168  
-    "getInputBuffers", "()[Ljava/nio/ByteBuffer;");
169  
-
170  
-  JNIEnv *env = xbmc_jnienv();
171  
-  jsize size = env->GetArrayLength(oByteBuffers.get());
172  
-
173  
-  CJNIByteBuffers buffers;
174  
-  buffers.reserve(size);
175  
-
176  
-  for (int i = 0; i < size; i++)
177  
-  {
178  
-    jobject j_object = env->GetObjectArrayElement(oByteBuffers.get(), i);
179  
-    CJNIByteBuffer buffer = CJNIByteBuffer(jhobject(xbmc_jnienv()->NewGlobalRef(j_object)));
180  
-    buffers.push_back(buffer);
181  
-  }
182  
-
183  
-  return buffers;
  167
+  return jcast<CJNIByteBuffers>(call_method<jhobjectArray>(m_object,
  168
+    "getInputBuffers", "()[Ljava/nio/ByteBuffer;"));
184 169
 }
185 170
 
186 171
 std::vector<CJNIByteBuffer> CJNIMediaCodec::getOutputBuffers()
187 172
 {
188  
-  jhobjectArray oByteBuffers = call_method<jhobjectArray>(m_object,
189  
-    "getOutputBuffers", "()[Ljava/nio/ByteBuffer;");
190  
-
191  
-  JNIEnv *env = xbmc_jnienv();
192  
-  jsize size = env->GetArrayLength(oByteBuffers.get());
193  
-
194  
-  CJNIByteBuffers buffers;
195  
-  buffers.reserve(size);
196  
-
197  
-  for (int i = 0; i < size; i++)
198  
-  {
199  
-    jobject j_object = env->GetObjectArrayElement(oByteBuffers.get(), i);
200  
-    CJNIByteBuffer buffer = CJNIByteBuffer(jhobject(xbmc_jnienv()->NewGlobalRef(j_object)));
201  
-    buffers.push_back(buffer);
202  
-  }
203  
-
204  
-  return buffers;
  173
+  return jcast<CJNIByteBuffers>(call_method<jhobjectArray>(m_object,
  174
+    "getOutputBuffers", "()[Ljava/nio/ByteBuffer;"));
205 175
 }
206 176
 
207 177
 int CJNIMediaCodec::getInputBufferSize()
35  xbmc/android/jni/jutils/jutils-details.hpp
@@ -71,6 +71,12 @@ struct jcast_helper<std::vector<std::string>, jobjectArray>
71 71
     static std::vector<std::string> cast(jobjectArray const &v);
72 72
 };
73 73
 
  74
+template <typename T>
  75
+struct jcast_helper<std::vector<T>, jobjectArray>
  76
+{
  77
+    static std::vector<T> cast(jobjectArray const &v);
  78
+};
  79
+
74 80
 template <>
75 81
 struct jcast_helper<jhstring, std::string>
76 82
 {
@@ -101,6 +107,35 @@ struct jcast_helper<std::vector<std::string>, jhobjectArray>
101 107
     }
102 108
 };
103 109
 
  110
+template <typename T>
  111
+struct jcast_helper<std::vector<T>, jhobjectArray>
  112
+{
  113
+    static std::vector<T> cast(jhobjectArray const &v)
  114
+    {
  115
+        return jcast_helper<std::vector<T>, jobjectArray>::cast(v);
  116
+    }
  117
+};
  118
+
  119
+
  120
+template <typename T>
  121
+std::vector<T> jcast_helper<std::vector<T>, jobjectArray>::cast(jobjectArray const &v)
  122
+{
  123
+  JNIEnv *env = xbmc_jnienv();
  124
+  jsize size = 0;
  125
+  if(v)
  126
+    size = env->GetArrayLength(v);
  127
+
  128
+  std::vector<T> vec;
  129
+  vec.reserve(size);
  130
+
  131
+  for (int i = 0; i < size; i++)
  132
+  {
  133
+    jhobject element = (jhobject)env->GetObjectArrayElement(v, i);
  134
+    vec.emplace_back(element);
  135
+  }
  136
+  return vec;
  137
+}
  138
+
104 139
 
105 140
 } // namespace details
106 141
 

2 notes on commit 157e32a

Cory Fields
Owner

Heh, you beat me to this by seconds. Docs updated after your push.

davilla
Collaborator

There's a problem here. While it does handle the creation phase of the life time, The death phase will result in a spew of ;

D/dalvikvm(13490): Attempt to remove invalid index 10d (bottom=0d top=4d)
W/dalvikvm(13490): JNI WARNING: DeleteLocalRef(0x22800029) failed to find entry

because the jhobject really belongs to the original array element and we just have a vec.emplace_back copy.

Please sign in to comment.
Something went wrong with that request. Please try again.