MediaCodec 编码H264 编码一帧后dequeueOutputBuffer为-1的问题

在用android MediaCodec编码h264的时候,会遇到,dequeueOutputBuffer在成功获取到config帧(sps pps)及第一个I帧后,dequeueOutputBuffer然后结果一直为-1的情况,


在我用的三星note3及小米3都是这样的,解决方案如下:

关键在下面这个函数的第四个参数上,就是时间戳,这个参数一定要填写,可以类似的这么简单的算一下:

long timepts = 1000000*count / 20;

mediaCodec.queueInputBuffer(inputBufferIndex, 0, input.length, timepts, 0);


然后就解决了~


dequeueOutputBuffer 结果正常了,可以继续编码了~

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
在Android中,可以使用MediaCodec API来进行H.264编码。下面是一个简单的示例代码,演示如何使用MediaCodec API编码图像数据。 首先,需要创建一个MediaCodec对象并配置它的参数: ```java MediaCodec codec = MediaCodec.createEncoderByType("video/avc"); MediaFormat format = MediaFormat.createVideoFormat("video/avc", width, height); format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate); format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate); format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iFrameInterval); codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); Surface inputSurface = codec.createInputSurface(); ``` 其中,`width`和`height`分别是图像的宽度和高度,`bitRate`是比特率,`frameRate`是帧率,`iFrameInterval`是关键帧间隔。`COLOR_FormatSurface`表明使用Surface作为输入源。 然后,可以开始编码图像数据。这里假设已经将图像数据绘制到了Surface上: ```java codec.start(); while (!isEOS) { int inputIndex = codec.dequeueInputBuffer(-1); if (inputIndex >= 0) { ByteBuffer inputBuffer = codec.getInputBuffer(inputIndex); inputBuffer.clear(); if (/* 判断是否为最后一帧 */) { codec.queueInputBuffer(inputIndex, 0, /*图像数据大小*/, /*时间戳*/, MediaCodec.BUFFER_FLAG_END_OF_STREAM); isEOS = true; } else { // 将图像数据复制到inputBuffer中 codec.queueInputBuffer(inputIndex, 0, /*图像数据大小*/, /*时间戳*/, 0); } } int outputIndex = codec.dequeueOutputBuffer(info, TIMEOUT_US); if (outputIndex >= 0) { ByteBuffer outputBuffer = codec.getOutputBuffer(outputIndex); // 对outputBuffer中的数据进行处理,例如将它写入文件或网络 codec.releaseOutputBuffer(outputIndex, false); } else if (outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { // 处理编码器输出格式变化的情况 MediaFormat newFormat = codec.getOutputFormat(); } } codec.stop(); codec.release(); ``` 在上面的代码中,使用`dequeueInputBuffer()`获取一个输入缓冲区,并将图像数据复制到该缓冲区中。然后,使用`queueInputBuffer()`将缓冲区提交给编码器进行编码。如果已经到达最后一帧,需要将`BUFFER_FLAG_END_OF_STREAM`标志设置为true,表示输入流结束。 使用`dequeueOutputBuffer()`获取一个输出缓冲区,并对该缓冲区中的数据进行处理。处理完成后,使用`releaseOutputBuffer()`将缓冲区释放,同时指示编码器是否需要渲染这一帧。 最后,使用`stop()`和`release()`方法停止和释放编码器。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值