Android MediaCodec输出缓冲区始终为空
我的Android MediaCodec输出缓冲区始终为空,android,android-mediacodec,mediaextractor,Android,Android Mediacodec,Mediaextractor,我的onOutputBufferAvailable()回调方法中的outputBuffer有问题。每次调用此回调方法时,我都使用outputBuffer.hasraining方法检查outputBuffer,该方法始终返回false codec.setCallback(new MediaCodec.Callback() { @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Over
onOutputBufferAvailable()
回调方法中的outputBuffer
有问题。每次调用此回调方法时,我都使用outputBuffer.hasraining
方法检查outputBuffer
,该方法始终返回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
}
});
MediaCodec未更新ByteBuffers上的位置/限制标记,您需要检查MediaCodec.BufferInfo对象,以了解实际有效负载数据的位置和长度。问题的主要原因是错误的
MediaCodec
模式;wasMediaCodec.createByCodecName(…)
,应该是codec=MediaCodec.createDecoderByType(“音频/mpeg”)
。在尝试使用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();
}
}
@RequiresApi(api=Build.VERSION\u CODES.LOLLIPOP)
@凌驾
public void onOutputBufferAvailable(MediaCodec mc、int outputBufferId、MediaCodec.BufferInfo){
ByteBuffer outputBuffer=codec.getOutputBuffer(outputBufferId);
byte[]b=新字节[outputBuffer.remaining()];
outputBuffer.get(b);
对于(i=0;i
你是说presentationTimeUs()
来获取实际位置吗?不是,我是说读取MediaCodec.BufferInfo中的偏移量
和大小
字段。然而,getOutputBuffer()
的文档似乎记录了它已经自动设置:“返回缓冲区的位置和限制设置为有效的输出数据”不知道为什么,但我的info.offset
始终为0info.size
为4608。是的,偏移量几乎总是零。无论如何,因为MediaCodec已经设置了它,所以如果您使用getOutputBuffer()
,这与此无关。只有在使用较旧的(API 21之前)方法时才需要它,在这些方法中,您可以提前调用getOutputBuffers()
,以获取ByteBuffer
对象的数组。然后需要将偏移量/大小应用于现有的ByteBuffer
对象。这是不正确的:info.flags==MediaCodec.BUFFER\u FLAG\u END\u OF\u STREAM info.flags指的是多个标志。无法将\u流的缓冲区\u标志\u结束\u与此进行比较。必须使用流的info.flags和MediaCodec.BUFFER\u FLAG\u END\u