gpt4 book ai didi

android - MediaCodec 缓冲区下溢 excel

转载 作者:行者123 更新时间:2023-11-29 17:53:14 25 4
gpt4 key购买 nike

我有一个 h264 流,想在 Android 4.1.2 中使用 MediaCodec 解码

流可以使用 ffmpeg 解码,但它很慢,所以我想使用 MediaCodec。手机是三星 Galaxy S3

单击按钮,将启动一个新 Activity 。

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

test = new SurfaceView(getApplicationContext());
test.getHolder().addCallback(this);
setContentView(test);
}

在回调中

public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
//codedBuffer = new byte[1536000];
if(wt == null){
wt = new RenderThread(arg0.getSurface());
wt.start();
}

}

RenderThread在哪里

public void run() {
formatIn = MediaFormat.createVideoFormat("video/avc", 480, 800);
coder = MediaCodec.createDecoderByType("video/avc");
if(formatIn != null)
coder.configure(formatIn, mSurface, null, 0);
coder.start();
ByteBuffer[] inputBuffers = coder.getInputBuffers();
ByteBuffer[] outputBuffers = coder.getOutputBuffers();
mBufferInfo = new BufferInfo();
while(!Thread.interrupted()){

while(waitForStream){
Thread.yield();
}
if(!EOS ){

int inBufIndex = coder.dequeueInputBuffer(10000);
if(inBufIndex != -1){
ByteBuffer buffer = inputBuffers[inBufIndex];
buffer.put(receivebuffer,0,size);
coder.queueInputBuffer(inBufIndex, 0, size, 0,0);
}
int outBufIndex = coder.dequeueOutputBuffer(mBufferInfo, 10000);
switch (outBufIndex) {
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED");
outputBuffers = coder.getOutputBuffers();
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
Log.d("DecodeActivity", "New format " );
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
Log.d("DecodeActivity", "dequeueOutputBuffer timed out!");
break;
default:
// ByteBuffer buffer = outputBuffers[outBufIndex];
// buffer.get(decodedBuffer);
coder.releaseOutputBuffer(outBufIndex, true);
}
}

decodedBuffer 是一个字节[1536000]

更新后的错误日志为

02-03 05:53:20.065: I/OMXClient(12333): Using client-side OMX mux.
02-03 05:53:20.145: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.170: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.195: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.215: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.270: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.290: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.295: E/SpannableStringBuilder(12333): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
02-03 05:53:20.295: E/SpannableStringBuilder(12333): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
02-03 05:53:20.310: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.330: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.355: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.375: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.395: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.410: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.420: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.425: D/DecodeActivity(12333): New format
02-03 05:53:20.485: D/DecodeActivity(12333): dequeueOutputBuffer timed out!
02-03 05:53:20.605: W/dalvikvm(12333): threadid=15: thread exiting with uncaught exception (group=0x40de32a0)
02-03 05:53:20.605: E/AndroidRuntime(12333): FATAL EXCEPTION: Thread-658
02-03 05:53:20.605: E/AndroidRuntime(12333): java.nio.BufferOverflowException
02-03 05:53:20.605: E/AndroidRuntime(12333): at java.nio.Buffer.checkPutBounds(Buffer.java:189)
02-03 05:53:20.605: E/AndroidRuntime(12333): at java.nio.ReadWriteDirectByteBuffer.put(ReadWriteDirectByteBuffer.java:100)
02-03 05:53:20.605: E/AndroidRuntime(12333): at java.nio.ByteBuffer.put(ByteBuffer.java:712)

最佳答案

因为这是一个 get() 调用,我假设你在这里失败了:

ByteBuffer buffer = outputBuffers[outBufIndex];
buffer.get(decodedBuffer);

如果您查看 CTS EncodeDecodeTest ,它适用于原始 YUV 数据,您会看到一个额外的位:

ByteBuffer outputFrame = decoderOutputBuffers[decoderStatus];
outputFrame.position(info.offset);
outputFrame.limit(info.offset + info.size);

MediaCodec 代码不会读取或更新 ByteBuffer 状态,因此您必须明确地执行此操作。这也适用于输入端。

EncodeDecodeTest 的缓冲区到缓冲区和缓冲区到表面部分将与 API 16 配合使用,并且有助于检查。表面对表面测试需要 API 18。

您会发现一件事是测试不会将缓冲区内容提取到固定大小的数组中,因为帧的解码大小是静态不可知的。您需要知道输出的颜色格式,这会因设备而异。您还会发现 checkFrame() 在某些设备上完全放弃,因为它不理解帧格式。

如果您可以解码到 Surface,您的代码就可以像 checkSurfaceFrame() 那样工作,您不必关心缓冲区格式,因为 OpenGL ES 会完成所有工作。另见 ExtractMpegFramesTest .

关于android - MediaCodec 缓冲区下溢 excel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21460113/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com