unity3d - IllegalStateException when reading from ShortBuffer in Unity Android -
i'm working on game in unity, need raw audio data media buffer. following code being used jar plugin in unity. it's working on android 4.x without problems. when try run on android 5.0.1 or 5.1, following exception, when try open aac or m4a files. suggestions?
this function, read audio buffer:
public short[] readnextsamples() { if (sawoutputeos) { return new short[0]; } int res; while (true) { res = codec.dequeueoutputbuffer(info, ktimeoutus); if (res >= 0) { if (info.size > 0) { break; } else { codec.releaseoutputbuffer(res, false); if ((info.flags & mediacodec.buffer_flag_end_of_stream)!= 0) { sawoutputeos = true; return new short[0]; } } } } int outputbufindex = res; bytebuffer buf = codecoutputbuffers[outputbufindex]; int samplesize = info.size / 2; short[] samplevalues = new short[samplesize]; shortbuffer shbuf = buf.asshortbuffer(); try { shbuf.get(samplevalues, 0, samplesize); } catch (exception e) { //the exception being thrown here e.printstacktrace(); } codec.releaseoutputbuffer(outputbufindex, false); if ((info.flags & mediacodec.buffer_flag_end_of_stream) != 0) { sawoutputeos = true; } return samplevalues; }
the exception:
06-04 16:18:01.188: w/system.err(20884): java.lang.illegalstateexception: buffer inaccessible 06-04 16:18:01.188: w/system.err(20884): @ java.nio.directbytebuffer.checkisaccessible(directbytebuffer.java:551) 06-04 16:18:01.188: w/system.err(20884): @ java.nio.directbytebuffer.get(directbytebuffer.java:155) 06-04 16:18:01.188: w/system.err(20884): @ java.nio.bytebufferasshortbuffer.get(bytebufferasshortbuffer.java:103) 06-04 16:18:01.190: w/system.err(20884): @ com.pocketgames.musiverse.mediadecoder.readnextsamples(mediadecoder.java:112) 06-04 16:18:01.190: w/system.err(20884): @ com.unity3d.player.reflectionhelper.nativeproxyinvoke(native method) 06-04 16:18:01.190: w/system.err(20884): @ com.unity3d.player.reflectionhelper.a(unknown source) 06-04 16:18:01.190: w/system.err(20884): @ com.unity3d.player.reflectionhelper$1.invoke(unknown source) 06-04 16:18:01.190: w/system.err(20884): @ java.lang.reflect.proxy.invoke(proxy.java:397) 06-04 16:18:01.190: w/system.err(20884): @ $proxy0.run(unknown source) 06-04 16:18:01.191: w/system.err(20884): @ java.lang.thread.run(thread.java:818)
basically should use api level dependent code. think might have figured out. sake of documenting, should use
bytebuffer buf = codecoutputbuffers[outputbufindex];
for api level < 21
and
bytebuffer buf = codec.getoutputbuffer(outputbufindex);
for api level >= 21.
the code this:
final int version = build.version.sdk_int; bytebuffer buf; if (version >= 21) { buf = codec.getoutputbuffer(outputbufindex); } else { buf = codecoutputbuffers[outputbufindex]; }
if @ source code of mediacodec
class, code getoutputbuffer
is:
@nullable public bytebuffer getoutputbuffer(int index) { bytebuffer newbuffer = getbuffer(false /* input */, index); synchronized(mbufferlock) { invalidatebytebuffer(mcachedoutputbuffers, index); mdequeuedoutputbuffers.put(index, newbuffer); } return newbuffer; }
so, error related acquiring lock mbufferlock
might required implementation of mediacodec
api level >= 21 , hence error related inaccessibility. hope helps.
Comments
Post a Comment