6

I had some problems about encoding/decoding audio in my wrapper code, I debugged my code and finally found out that SetByteArrayRegion does not work as expected. Here we go:

// incoming parameters => jbyteArray jencoded
jbyte encoded[320]; //
... // fill encoded with 'encodedSize' number of bytes
int i;
for (i = 0; i < encodedSize; i++) {
    fprintf(encodeDbg, "%02X ", (unsigned char)(encoded[i]));
}
fprintf(encodeDbg, "\n");
fflush(encodeDbg);
(*env)->SetByteArrayRegion(env, jencoded, 0, encodedSize, encoded);
jbyte* encoded_test = (*env)->GetByteArrayElements(env, jencoded, NULL);
for (i = 0; i < encodedSize; i++) {
    fprintf(encodeDbg, "%02X ", (unsigned char)(encoded_test[i]));
}
fprintf(encodeDbg, "\n");
fflush(encodeDbg);
(*env)->ReleaseByteArrayElements(env, jencoded, encoded_test, JNI_ABORT);

The values in encoded and jencoded (i.e. encoded_test) do not match! After calling this procedure multiple times, the content of encodeDbg file is as follows:

 08 40 64 6A 6A 00 00 00 61 16 0D 2B 2D 7C F1 EF 8B D0 AE D3 21 39 
 D0 F4 40 1B 00 00 00 00 16 00 00 00 00 F3 40 1B 8B D0 AE D3 21 39 

 08 40 64 6A 6A 00 00 00 74 DB F7 02 23 18 01 86 8E 6D 4A 56 9E 9C 64 41 43 E8 09 
 D0 F4 40 1B 00 00 00 00 1B 00 00 00 00 F3 40 1B 8E 6D 4A 56 9E 9C 64 41 43 E8 09 

 08 40 64 6A 6A 00 00 00 D5 A4 A3 5E A3 DC B1 3B 2D 3D 6C 4C A4 
 D0 F4 40 1B 00 00 00 00 15 00 00 00 00 F3 40 1B 2D 3D 6C 4C A4 

 08 40 64 6A 6A 00 00 00 AC 59 7A 0E 3D A1 50 43 57 20 58 41 5F 5C 74 88 22 1B 5D 
 D0 F4 40 1B 00 00 00 00 1B 00 00 00 00 F3 40 1B 57 20 58 41 5F 5C 74 88 22 1B 5D 

 08 40 64 6A 6A 00 00 00 73 33 13 51 56 77 BF 41 93 0A 61 9C 57 30 A3 DB B9 80 
 D0 F4 40 1B 00 00 00 00 1A 00 00 00 00 F3 40 1B 93 0A 61 9C 57 30 A3 DB B9 80 

 08 40 64 6A 6A 00 00 00 9C 05 BB 57 32 9B 14 2B 9E A1 87 DF EF 55 7F 4E B5 FD C2 
 D0 F4 40 1B 00 00 00 00 1B 00 00 00 00 F3 40 1B 9E A1 87 DF EF 55 7F 4E B5 FD C2 

 08 40 64 6A 6A 00 00 00 03 4C 7F ED 08 28 18 5D E1 23 D9 7C DD E8 27 BC 46 12 FA 0D 0E 56 29 C2 14 58 
 D0 F4 40 1B 00 00 00 00 22 00 00 00 00 F3 40 1B E1 23 D9 7C DD E8 27 BC 46 12 FA 0D 0E 56 29 C2 14 58 

 08 40 64 6A 6A 00 00 00 77 09 3F 7E 57 78 53 64 E2 39 74 6B E1 E5 AB 2C EB C4 D7 FE 80 
 D0 F4 40 1B 00 00 00 00 1D 00 00 00 00 F3 40 1B E2 39 74 6B E1 E5 AB 2C EB C4 D7 FE 80 

There is a problem with the first 16 bytes, while the rest is of the array is ok. Any suggestion is highly appreciated.

EDIT:

I compile the JNI part (C stuff) on linux (with mingw), and copy the dll to Windows, where I run the Java application. May this cross platform operations cause the problem? Do I need to add some extra flag/parameter to the compiler or linker?

SECOND EDIT:

I slightly changed the code to see the contents of encoded after SetByteArrayRegion call. The code and the output is as following:

// incoming parameters => jbyteArray jencoded
jbyte encoded[320]; //
... // fill encoded with 'encodedSize' number of bytes
int i;
for (i = 0; i < encodedSize; i++) {
    fprintf(encodeDbg, "%02X ", (unsigned char)(encoded[i]));
}
fprintf(encodeDbg, "\n");
fflush(encodeDbg);
(*env)->SetByteArrayRegion(env, jencoded, 0, encodedSize, encoded);
jbyte* encoded_test = (*env)->GetByteArrayElements(env, jencoded, NULL);
for (i = 0; i < encodedSize; i++) {
    fprintf(encodeDbg, "%02X ", (unsigned char)(encoded_test[i]));
}
fprintf(encodeDbg, "\n");
for (i = 0; i < encodedSize; i++) {
    fprintf(encodeDbg, "%02X ", (unsigned char)(encoded[i]));
}
fprintf(encodeDbg, "\n\n");
fflush(encodeDbg);
(*env)->ReleaseByteArrayElements(env, jencoded, encoded_test, JNI_ABORT);

Sample output:

08 40 64 6A 6A 00 00 00 61 16 0D 2B 2D 7C F1 EF 8B D0 AE D3 21 39 
20 F1 07 1B 00 00 00 00 16 00 00 00 50 EF 07 1B 8B D0 AE D3 21 39 
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 2C 

08 40 64 6A 6A 00 00 00 74 DB F7 02 23 18 01 86 8E 6D 4A 56 9E 9C 64 41 43 E8 09 
20 F1 07 1B 00 00 00 00 1B 00 00 00 50 EF 07 1B 8E 6D 4A 56 9E 9C 64 41 43 E8 09 
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 2C F0 76 B0 18 64 

08 40 64 6A 6A 00 00 00 D5 A4 A3 5E A3 DC B1 3B 2D 3D 6C 4C A4 
20 F1 07 1B 00 00 00 00 15 00 00 00 50 EF 07 1B 2D 3D 6C 4C A4 
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 

08 40 64 6A 6A 00 00 00 AC 59 7A 0E 3D A1 50 43 57 20 58 41 5F 5C 74 88 22 1B 5D 
20 F1 07 1B 00 00 00 00 1B 00 00 00 50 EF 07 1B 57 20 58 41 5F 5C 74 88 22 1B 5D 
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 2C F0 76 B0 18 64 

08 40 64 6A 6A 00 00 00 73 33 13 51 56 77 BF 41 93 0A 61 9C 57 30 A3 DB B9 80 
20 F1 07 1B 00 00 00 00 1A 00 00 00 50 EF 07 1B 93 0A 61 9C 57 30 A3 DB B9 80 
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 2C F0 76 B0 18 

08 40 64 6A 6A 00 00 00 4B 2D C9 D8 69 E5 B9 BE 2F 77 13 0F 89 E6 A3 52 89 8E 96 CC 
20 F1 07 1B 00 00 00 00 1C 00 00 00 50 EF 07 1B 2F 77 13 0F 89 E6 A3 52 89 8E 96 CC 
20 F1 07 1B 5C F2 07 1B 20 72 F1 76 AC BF CA B0 FE FF FF FF F6 2C F0 76 B0 18 64 6A 
Ramazan
  • 989
  • 3
  • 14
  • 26
  • What are the values of `jencodedOffset`, `jpcmLength` and `encodedSize`? *"the first 16 bytes are always correct, but there is a problem with the first 16 bytes."* What do you mean? They can't both be correct and also have a problem. What's the problem? – Radiodef May 11 '15 at 17:18
  • @Radiodef edited the question to make it clear. – Ramazan May 11 '15 at 17:34
  • @Radiodef `jencodedOffset` is always 0, and `jpcmLength` is always 320. I have already changed the code in the question to these values. (I checked it with `fprintf` also, so there is no problem with it.) – Ramazan May 11 '15 at 17:45
  • Okay, I see that now, thanks. – Radiodef May 11 '15 at 17:49
  • What happens if you define `jbyteArray jencoded =(*env)->NewByteArray(env, size);` in your native code directly? Does it work in this case? – j.holetzeck May 11 '15 at 19:19
  • What does `(*env)->GetArrayLength(env, jencoded);` return? – Andrew Henle May 11 '15 at 19:22
  • @j.holetzeck `jencoded` is the method parameter, i.e. it is the `byte[]` sent from `Java`. So it is already properly initialized. – Ramazan May 12 '15 at 08:53
  • @AndrewHenle `jencoded` is of length 320. – Ramazan May 12 '15 at 08:54
  • OK. What contents are visible to the Java code after the JNI call returns? The correct values or the corrupted ones? – Andrew Henle May 12 '15 at 10:09
  • @AndrewHenle unfortunately the corrupted ones are visible. This is the cause of all problem... – Ramazan May 12 '15 at 10:26
  • Does the C array `encoded` contain uncorrupted data **after** the call to `SetByteArrayRegion()`? – Andrew Henle May 12 '15 at 10:34
  • @AndrewHenle good point.. Updated the question. – Ramazan May 12 '15 at 10:51
  • 1
    That `FE FF FF FF` is -2 as a little-endian 32-bit two's-complement signed integer. As a first guess, I'd say you have some serious stack corruption going on. – Andrew Henle May 12 '15 at 11:24
  • @AndrewHenle Then you say the problem is probably because of misconfigured cross compilation. Do you have any suggestion? – Ramazan May 12 '15 at 11:50
  • @Ramazan - I don't know enough about your code or cross compilation setup to know. It sounds possible. Does the code work when run without cross compiling? – Andrew Henle May 12 '15 at 21:59

0 Answers0