INFO_OUTPUT_BUFFERS_CHANGED通过getOutputBuffers取出来的数据应该如何编码成MP4代码例子
时间: 2023-10-05 09:05:31 浏览: 138
dcm.rar_XILINX DCM ip_dcm_xilinx DCM_原语代码_时钟管理模块
下面是一个使用MediaCodec和MediaMuxer将H.264编码数据编码成MP4文件的代码示例:
```java
private MediaCodec mEncoder;
private MediaMuxer mMuxer;
private int mTrackIndex;
private boolean mMuxerStarted;
// 初始化编码器和复用器
private void initEncoder() throws IOException {
MediaFormat format = MediaFormat.createVideoFormat("video/avc", mWidth, mHeight);
format.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
format.setInteger(MediaFormat.KEY_FRAME_RATE, mFrameRate);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, mIFrameInterval);
mEncoder = MediaCodec.createEncoderByType("video/avc");
mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
Surface surface = mEncoder.createInputSurface();
mEncoder.start();
mMuxer = new MediaMuxer(mOutputFile.getAbsolutePath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
mTrackIndex = -1;
mMuxerStarted = false;
}
// 编码数据
private void encodeData() {
while (mEncoding) {
int index = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_US);
if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
// 编解码器输出缓冲区状态已更改
continue;
}
if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// 编解码器输出格式已更改,添加轨道到复用器
MediaFormat format = mEncoder.getOutputFormat();
mTrackIndex = mMuxer.addTrack(format);
mMuxer.start();
mMuxerStarted = true;
continue;
}
if (index < 0) {
// 没有可用输出缓冲区
continue;
}
ByteBuffer outputBuffer = mEncoder.getOutputBuffer(index);
if (outputBuffer == null) {
mEncoder.releaseOutputBuffer(index, false);
continue;
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
// 编码器配置数据,忽略
mBufferInfo.size = 0;
}
if (mBufferInfo.size != 0) {
outputBuffer.position(mBufferInfo.offset);
outputBuffer.limit(mBufferInfo.offset + mBufferInfo.size);
if (mMuxerStarted) {
mMuxer.writeSampleData(mTrackIndex, outputBuffer, mBufferInfo);
}
}
mEncoder.releaseOutputBuffer(index, false);
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
break;
}
}
if (mMuxerStarted) {
mMuxer.stop();
mMuxer.release();
mMuxerStarted = false;
}
mEncoder.stop();
mEncoder.release();
}
```
在上面的代码中,initEncoder方法用于初始化编码器和复用器,encodeData方法用于编码数据。在encodeData方法中,我们先使用dequeueOutputBuffer方法获取输出缓冲区的索引。如果输出缓冲区的索引大于等于0,则使用getOutputBuffer方法获取输出缓冲区,并从中读取实际的编码数据。然后,将读取的数据写入到MP4文件中。如果返回的输出缓冲区索引大于等于0,使用releaseOutputBuffer方法释放输出缓冲区。最后,如果已经写入了编码数据,则使用MediaMuxer将数据写入到MP4文件中。
阅读全文