为什么JNI的GetByteArrayElements不保留像素跨度?

0 人关注

我需要把一个YUV_420_8888的图像从Android传到C++中进行处理。所以,我把图像平面,转换为 ByteArray ,然后把它们发送到C++函数。

val yBuffer: ByteBuffer = image.planes[0].buffer            
val uBuffer: ByteBuffer = image.planes[1].buffer
val vBuffer: ByteBuffer = image.planes[2].buffer
val yByteArray = ByteArray(yBuffer.remaining())
val uByteArray = ByteArray(uBuffer.remaining())
val vByteArray = ByteArray(vBuffer.remaining())
yBuffer.get(yByteArray)
uBuffer.get(uByteArray)
vBuffer.get(vByteArray)
return NativeCppClass::process(yByteArray, uByteArray, vByteArray)

替换代码2】平面的像素跨度为1。uv平面的像素跨度为2。当我看uByteArrayvByteArray时,它们在查看同一个内存块,其中v平面在u平面之前开始。更特别的是,它们看起来像这样,比如说。

vByteArray = [0, 1, 2, 3, 4, 5, 6]
uByteArray =    [1, 2, 3, 4, 5, 6, 7]

在此基础上,我希望我们有以下的声明。为了便于参考,我们把它叫做(*)

uByteArray.begin - vByteArray.begin = 1; // begin is just a way to express the starting point of a byte array

我也有一个ByteArray_JNI,将ByteArray从Kotlin转换成一个叫做CppByteArray的类。它们看起来像这样。

class ByteArray_JNI {
public:
    using CppType = CppByteArray;
    using JniType = jbyteArray;
    using Boxed = ByteArray_JNI;
   static CppType toCpp(JNIEnv *jniEnv, JniType byteArray) { 
      return CppType{byteArray, jniEnv};
class CppByteArray {
public: 
    CppByteArray(jbyteArray data, JNIEnv *env) : array_(env, data) {
        jboolean copied = false;
        buffer_ = (uint8_t *)env->GetByteArrayElements(data, &copied);
        // copied out param is false at this stage, so no copy
        size_ = env->GetArrayLength(data);
    const uint8_t* data() const {
      return buffer_; 
private: 
    djinni::GlobalRef<jbyteArray> array_;
    uint8_t *buffer_ = nullptr;
    jsize size_ = 0;

然而,上面的语句(*)在C++里面是不正确的。

class NativeCppClass {
public:
    static CppByteArray process(CppByteArray &&y_array, CppByteArray &&u_array, CppByteArray &&v_array) {
          auto u_begin = u_array.data(); 
          auto v_begin = v_array.data();
          // u_begin - v_begin = 462848 (not 1 as expected). My image has dimensions 1280x720, just in case it is related to the number 462848. 
         return something;