Reputation: 8978
I have a problem with the outputBuffer
inside my onOutputBufferAvailable()
callback method. Everytime this callback method is called I check the outputBuffer
using outputBuffer.hasRemaining
method and this is always return false
.
codec.setCallback(new MediaCodec.Callback() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
int rounds = extractor.readSampleData(inputBuffer,0);
if(rounds > 0) {
long currentT = extractor.getSampleTime();
Log.i("CurrentT", String.valueOf(currentT/(1000*1000)));
codec.queueInputBuffer(inputBufferId, 0, rounds, 0, 0);
extractor.advance();
} else {
// EOS
codec.queueInputBuffer(inputBufferId, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
Log.i("EOS","=-1");
}
}
@Override
public void onError(@NonNull MediaCodec mediaCodec, @NonNull MediaCodec.CodecException e) {
Log.i("error", "e");
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, MediaCodec.BufferInfo info) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
Log.i("has", String.valueOf(outputBuffer.hasRemaining()));
if (outputBuffer.hasRemaining()) {
b = outputBuffer.get();
Log.i("i", String.valueOf(b));
BAOS.write(b);
outputBuffer.clear();
} else {
array= BAOS.toByteArray();
codec.stop();
codec.release();
}
codec.releaseOutputBuffer(outputBufferId, false);
}
@Override
public void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
// mOutputFormat = format; // option B
}
});
Upvotes: 0
Views: 2271
Reputation: 8978
The main reason of the problem was wrong MediaCodec
mode; wasMediaCodec.createByCodecName(...)
, should be codec = MediaCodec.createDecoderByType("audio/mpeg")
. After unsuccesfull tries getting byte using get()
I finally ended up with get(byte[] dst)
method. Working code below.
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, MediaCodec.BufferInfo info) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
byte[] b = new byte[outputBuffer.remaining()];
outputBuffer.get(b);
for(i=0;i< b.length;i++) {
BAOS.write(b[i]);
}
outputBuffer.clear();
codec.releaseOutputBuffer(outputBufferId, false);
if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
array=BAOS.toByteArray();
Log.i("array", String.valueOf(array.length));
FileTools fl = new FileTools();
fl.WriteFile(array);
codec.stop();
codec.release();
}
}
Upvotes: 0
Reputation: 13317
The position/limit markers on the ByteBuffers aren't updated by MediaCodec, you need to check the MediaCodec.BufferInfo object that you got to know the position and length of the actual payload data.
Upvotes: 1