Android WebRTC能否直接发送NV12格式YUV帧而无需转420 planar?
结论
可以无需提前将NV12转换为I420格式,直接使用WebRTC原生能力完成NV12帧的推流,不需要走CPU手动格式转换路线。
具体实现方案
- WebRTC Android SDK 原生提供了
org.webrtc.NV12Buffer类,专门用于封装NV12格式的原始数据,你无需手动做格式转换,直接将摄像头输出的NV12 ByteBuffer、实际宽高、Y分量步长、UV分量步长传入构造实例即可。 - 构造完成的
NV12Buffer可以直接封装进VideoFrame,传入采集观察者CapturerObserver的onFrameCaptured方法,WebRTC底层会自动处理后续的编码、推流逻辑,内部实现均为Native层优化后的代码,性能远高于Java层手动循环转换。
示例代码
// 入参说明: // nv12Buf:摄像头输出的NV12格式ByteBuffer // width:帧宽度,height:帧高度 // strideY:Y分量行步长(多数摄像头输出步长≥宽度,需取摄像头实际返回值) // strideUV:UV分量行步长 // rotation:帧旋转角度 // timestampNs:帧时间戳(单位纳秒) NV12Buffer nv12Buffer = new NV12Buffer( width, height, strideY, strideUV, nv12Buf.slice(), nv12Buf.position(strideY * height), () -> { /* 自定义buffer回收逻辑,无特殊需求可传null */ } ); VideoFrame videoFrame = new VideoFrame(nv12Buffer, rotation, timestampNs); // 传入采集观察者 capturerObserver.onFrameCaptured(videoFrame); // 用完释放frame,避免内存泄漏 videoFrame.release();
低版本WebRTC兼容方案
如果你使用的WebRTC版本没有内置NV12Buffer,也不要使用Java多层for循环做转换,推荐接入libyuv库做格式转换,其Native层优化后的NV12ToI420接口性能是Java纯循环实现的10~30倍,完全可以满足1080P 30帧的场景需求。
内容的提问来源于stack exchange,提问作者Mete
相关产品推荐
相关产品推荐

