我的来源来自 FFmpeg,它是 YCbCr 平面格式(YUV420P,I420),
由于某些原因,我需要将其转换为 YCbCr 打包格式(NV12),
它必须通过 WIC YCbCr API 来完成,我该怎么做?
为什么选择 WIC?Libyuv 更直接,可能表现更好。
https://code.google.com/p/libyuv/
特征:
使用点、双线性或框过滤器缩放 YUV 以准备压缩内容。
从网络摄像头格式转换为 YUV。
从 YUV 转换为渲染/效果的格式。
旋转 90/180/270 度以适应纵向模式下的移动设备。
针对 x86/x64 上的 SSE2/SSSE3/AVX2 进行了优化。
接口:
/ Convert NV12 to I420.
LIBYUV_API
int NV12ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_uv, int src_stride_uv,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height);
// Convert NV21 to I420.
LIBYUV_API
int NV21ToI420(const uint8* src_y, int src_stride_y,
const uint8* src_vu, int src_stride_vu,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height);
我不确定 WIC 是否是处理它的正确 API。来自 Media Foundation 的可独立使用的Color Converter DSP肯定会负责转换。它使用 SIMD 指令进行了很好的优化,并且自 Windows Vista 时代以来就存在于核心操作系统中。
FFmpeg 的 libswscale 也做同样的事情。像这样的库和 API 可能会根据内部实现更好或更差地处理特定方向。NV12 有可能在 libswscale 中没有很好地实现。
同时,I420 到 NV12 是一个非常简单的转换方向,您可以使用一次屏幕代码和 SIMD 内部函数来实现它,并且非常有效。