多个手机出现抖动问题,请问怎么解决
Zhangxd77 opened this issue · comments
在华为、荣耀、OPPO这几个手机里都出现了视频抖动,
平滑的录制的,但是预播放时候就是画面抖了,请问怎么解决,谢谢
修改RecordUtil.encodeVideo()方法可以解決抖动,但是解决不了时长变长的问题
private void encodeVideo(byte[] nv21) throws IOException {
/* if (checkMaxFrame()) {
currFrame--;
return;
}*/
byte[] nv12 = new byte[nv21.length];
byte[] yuvI420 = new byte[nv21.length];
byte[] tempYuvI420 = new byte[nv21.length];
LibyuvUtil.convertNV21ToI420(nv21, yuvI420, videoWidth, videoHeight);
LibyuvUtil.compressI420(yuvI420, videoWidth, videoHeight, tempYuvI420, videoWidth, videoHeight, rotation, isFrontCamera);
LibyuvUtil.convertI420ToNV12(tempYuvI420, nv12, videoWidth, videoHeight);
//得到编码器的输入和输出流, 输入流写入源数据 输出流读取编码后的数据
//得到要使用的缓存序列角标
int inputIndex = videoMediaCodec.dequeueInputBuffer(TIMEOUT_USEC);
if (inputIndex >= 0) {
ByteBuffer inputBuffer = videoMediaCodec.getInputBuffer(inputIndex);
inputBuffer.clear();
//把要编码的数据添加进去
inputBuffer.put(nv12);
//塞到编码序列中, 等待MediaCodec编码
//videoMediaCodec.queueInputBuffer(inputIndex, 0, nv12.length, System.nanoTime() / 1000, 0);
videoMediaCodec.queueInputBuffer(inputIndex, 0, nv12.length, System.currentTimeMillis(), 0);
}
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
//读取MediaCodec编码后的数据
int outputIndex = videoMediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
// boolean keyFrame = false;
while (outputIndex >= 0) {
ByteBuffer outputBuffer = videoMediaCodec.getOutputBuffer(outputIndex);
byte[] h264 = new byte[bufferInfo.size];
//这步就是编码后的h264数据了
outputBuffer.get(h264);
switch (bufferInfo.flags) {
case MediaCodec.BUFFER_FLAG_CODEC_CONFIG://视频信息
configByte = new byte[bufferInfo.size];
configByte = h264;
break;
case MediaCodec.BUFFER_FLAG_KEY_FRAME://关键帧
frameBuffer.put(configByte);
frameBuffer.put(h264);
keyFrame = true;
break;
default://正常帧
frameBuffer.put(h264);
break;
}
//数据写入本地成功 通知MediaCodec释放data
videoMediaCodec.releaseOutputBuffer(outputIndex, false);
//读取下一次编码数据
outputIndex = videoMediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
}
if (frameBuffer.position() > 0) {
byte[] frameByte = new byte[frameBuffer.position()];
frameBuffer.flip();
frameBuffer.get(frameByte);
frameBuffer.clear();
//主要是这里
/* while (keyFrame && checkMinFrame()) {
currFrame++;
videoOut.write(frameByte, 0, frameByte.length);
videoOut.flush();
}*/
currFrame++;
videoOut.write(frameByte, 0, frameByte.length);
videoOut.flush();
}
}
不好意思,用您这个替换后,
是不会抖动了,但是画面出现类似马赛克效果,而且很虚
机型是oppo a5