MediaCodec outputBuffer始终是空的
问题描述:
我的outputBuffer
在我的onOutputBufferAvailable()
回调方法中有问题。每次调用此回调方法时,我使用outputBuffer.hasRemaining
方法检查outputBuffer
并始终返回false
。MediaCodec outputBuffer始终是空的
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
}
});
答
问题的主要原因是错误的MediaCodec
模式;是MediaCodec.createByCodecName(...)
,应该是codec = MediaCodec.createDecoderByType("audio/mpeg")
。在unsuccesfull尝试获取字节使用get()
我终于结束了get(byte[] dst)
方法。下面的工作代码。
@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();
}
}
答
位置/上的ByteBuffers限制标志不被MediaCodec更新,你需要检查你必须知道实际的有效载荷数据的位置和长度MediaCodec.BufferInfo对象。
您的意思是'presentationTimeUs()'获取实际位置? – Kristopher
不,我的意思是读取MediaCodec.BufferInfo中的'offset'和'size'字段。然而,'getOutputBuffer()'的文档似乎并没有记录它已经自动设置:“返回的缓冲区的位置和限制被设置为有效的输出数据” – mstorsjo
不知道为什么,但我的信息。偏移量“始终是0.”info.size“是4608. – Kristopher