AMediaCodec_queueInputBuffer 使用时间戳调整 的demo
时间: 2024-03-05 18:53:10 浏览: 135
以下是一个使用时间戳调整的 AMediaCodec_queueInputBuffer demo:
```java
// 创建 MediaCodec
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);
MediaCodec encoder = MediaCodec.createEncoderByType("video/avc");
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
Surface inputSurface = encoder.createInputSurface();
encoder.start();
// 创建 MediaMuxer
MediaMuxer muxer = new MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// 初始化时间戳
long lastPresentationTimeUs = 0;
// 循环编码每一帧
while (hasFrame()) {
// 获取输入缓冲区
int inputBufferIndex = encoder.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
// 获取输入缓冲区
ByteBuffer inputBuffer = encoder.getInputBuffer(inputBufferIndex);
inputBuffer.clear();
// 获取数据
Frame frame = getFrame();
// 将数据放入输入缓冲区
inputBuffer.put(frame.getData());
// 调整时间戳
long presentationTimeUs = frame.getPresentationTimeUs();
if (lastPresentationTimeUs > 0 && presentationTimeUs < lastPresentationTimeUs) {
presentationTimeUs = lastPresentationTimeUs;
}
lastPresentationTimeUs = presentationTimeUs;
// 将缓冲区提交给 MediaCodec
encoder.queueInputBuffer(inputBufferIndex, 0, frame.getData().length, presentationTimeUs, 0);
}
// 获取输出缓冲区
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);
while (outputBufferIndex >= 0) {
// 获取输出缓冲区
ByteBuffer outputBuffer = encoder.getOutputBuffer(outputBufferIndex);
// 写入 MediaMuxer
muxer.writeSampleData(trackIndex, outputBuffer, bufferInfo);
// 释放输出缓冲区
encoder.releaseOutputBuffer(outputBufferIndex, false);
// 获取下一个输出缓冲区
outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, 0);
}
}
// 释放资源
encoder.stop();
encoder.release();
muxer.stop();
muxer.release();
```
在这个 demo 中,每次调用 `MediaCodec.queueInputBuffer()` 时,都会传入一个时间戳参数 `presentationTimeUs`,表示当前帧的显示时间戳。如果当前帧的时间戳比上一帧的时间戳小,就将当前帧的时间戳设置为上一帧的时间戳。这样可以避免由于时间戳错误导致的视频播放卡顿或者花屏等问题。
阅读全文