我试图将我的手机相机输出转换为.h264 es格式,但MediaCodec编码器在第一帧后卡在TRY_AGAIN_LATER输出缓冲区状态。相机预览被设置为NV21。
这是相机到编码器:
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
private long timestamp=0;
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
byte[] buffer = new byte[data.length];
encode(data);
}
});
编码器初始化:
private void initCodec() {
try {
mBufferInfo = new MediaCodec.BufferInfo();
mMediaCodec = MediaCodec.createEncoderByType("video/avc");
} catch (IOException e) {
e.printStackTrace();
}
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc",
1920,
1080);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 125000);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
mMediaCodec.configure(mediaFormat,
null,
null,
MediaCodec.CONFIGURE_FLAG_ENCODE);
mMediaCodec.start();
}
编码器本身:
private synchronized void encode(byte[] data) {
inputBuffers = mMediaCodec.getInputBuffers();// here changes
outputBuffers = mMediaCodec.getOutputBuffers();
int inputBufferIndex = mMediaCodec.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(data);
mMediaCodec.queueInputBuffer(inputBufferIndex, 0, data.length, 0, 0);
} else {
return;
}
int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(mBufferInfo, 10000);
do {
if (outputBufferIndex >= 0) {
ByteBuffer outBuffer = outputBuffers[outputBufferIndex];
System.out.println("buffer info-->" + mBufferInfo.offset + "--"
+ mBufferInfo.size + "--" + mBufferInfo.flags + "--"
+ mBufferInfo.presentationTimeUs);
byte[] outData = new byte[mBufferInfo.size];
outBuffer.get(outData);
if (mBufferInfo.offset != 0) {
byte[] offsettedData;
offsettedData = Arrays.copyOfRange(outData, mBufferInfo.offset, outData.length-1);
pushFrame(offsettedData, offsettedData.length);
} else {
pushFrame(outData, outData.length);
}
mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mMediaCodec.dequeueOutputBuffer(mBufferInfo,
0);
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = mMediaCodec.getOutputBuffers();
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat format = mMediaCodec.getOutputFormat();
}
} while (outputBufferIndex >= 0);
}
为什么输出缓冲区停留在try_again_later(-1)上?所有输入数据似乎都是有效的(来自相机)。