- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我使用 mediaCodec 解码 AMR 文件时,它会输出一个字节缓冲区,但是当我尝试将字节缓冲区转换为 double 组时,应用程序崩溃了。
我尝试从字节缓冲区中取出一个字节,应用程序也崩溃了。对字节缓冲区的任何操作都会导致我的应用程序崩溃。
decoder.start();
inputBuffers = decoder.getInputBuffers();
outputBuffers = decoder.getOutputBuffers();
end_of_input_file = false;
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
ByteBuffer data = readData(info);
int samplesRead = info.size;
byte[] bytesArray = new byte[data.remaining()];
bytesArray = getByteArrayFromByteBuffer(data);
here the app crashes.
这是 readData 方法:
private ByteBuffer readData(MediaCodec.BufferInfo info) {
if (decoder == null)
return null;
for (;;) {
// Read data from the file into the codec.
if (!end_of_input_file) {
int inputBufferIndex = decoder.dequeueInputBuffer(10000);
if (inputBufferIndex >= 0) {
int size = mExtractor.readSampleData(inputBuffers[inputBufferIndex], 0);
if (size < 0) {
// End Of File
decoder.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
end_of_input_file = true;
} else {
decoder.queueInputBuffer(inputBufferIndex, 0, size, mExtractor.getSampleTime(), 0);
mExtractor.advance();
}
}
}
// Read the output from the codec.
if (outputBufferIndex >= 0)
// Ensure that the data is placed at the start of the buffer
outputBuffers[outputBufferIndex].position(0);
outputBufferIndex = decoder.dequeueOutputBuffer(info, 10000);
if (outputBufferIndex >= 0) {
// Handle EOF
if (info.flags != 0) {
decoder.stop();
decoder.release();
decoder = null;
return null;
}
// Release the buffer so MediaCodec can use it again.
// The data should stay there until the next time we are called.
decoder.releaseOutputBuffer(outputBufferIndex, false);
return outputBuffers[outputBufferIndex];
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
// This usually happens once at the start of the file.
outputBuffers = decoder.getOutputBuffers();
}
}
}
这是 getByteArrayFromByteBuffer 方法:
private static byte[] getByteArrayFromByteBuffer(ByteBuffer byteBuffer) {
byte[] bytesArray = new byte[byteBuffer.remaining()];
byteBuffer.get(bytesArray, 0, bytesArray.length);
return bytesArray;
}
````
I would like to get the output of the decoder into a double array.
最佳答案
您的代码中有两个错误/误解。
第一期:
// Read the output from the codec.
if (outputBufferIndex >= 0)
// Ensure that the data is placed at the start of the buffer
outputBuffers[outputBufferIndex].position(0);
outputBufferIndex = decoder.dequeueOutputBuffer(info, 10000);
在调用dequeueOutputBuffer
之前,你无法知道它将返回什么输出缓冲区。即使这样,您也无法控制编解码器将其输出放置在缓冲区中的位置。解码器将从可用缓冲区中选择一个缓冲区,并将输出数据放置在该缓冲区中所需的任何位置。 (实际上它几乎总是在开始处。)
如果您想在输出缓冲区内以任何特定方式设置位置/限制,请在 dequeueOutputBuffer 将其返回给您之后执行此操作。
只需删除整个 if 语句和position() 调用即可。
第二个错误,这是真正的主要问题:
// Release the buffer so MediaCodec can use it again.
// The data should stay there until the next time we are called.
decoder.releaseOutputBuffer(outputBufferIndex, false);
return outputBuffers[outputBufferIndex];
只有在 dequeueOutputBuffer
返回缓冲区后,您才可以接触和使用 outputBuffers 中的缓冲区,直到通过 releaseOutputBuffer
将其返回给解码器为止。正如您的评论所说,在 releaseOutputBuffers
之后,MediaCodec 可以再次使用它。您的 ByteBuffer 变量只是对编解码器可以写入新输出的相同数据的引用 - 它还不是这里的副本。因此,在使用完 ByteBuffer 对象之前,您无法调用releaseOutputBuffer。
奖励积分:在使用 ByteBuffer 之前,最好为其设置位置/限制,如下所示:
outputBuffers[outputBufferIndex].position(info.offset);
outputBuffers[outputBufferIndex].limit(info.offset + info.size);
一些解码器隐式地执行此操作,但不一定是全部。
关于java - Bytebuffor 操作在从小 amr 文件中提取原始数据时导致 Android 应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56100282/
我是一名优秀的程序员,十分优秀!