PatrickSCLin
PatrickSCLin

Reputation: 1449

How to convert YCbCr planar format to packed format by WIC for UWP?

my source is from FFmpeg, it's a YCbCr planar format (YUV420P, I420),

for some reasons, I need to convert it to YCbCr packed format (NV12),

and it have to do it by WIC YCbCr APIs, how to I do ?

Upvotes: 0

Views: 1550

Answers (2)

Roman Ryltsov
Roman Ryltsov

Reputation: 69734

I am not sure WIC is the right API to handle it. Color Converter DSP, a piece from Media Foundation which can be used standalone, will definitely take care of the conversion. It's well optimized using SIMD instructions, and exists in core OS since Windows Vista times.

FFmpeg's libswscale does the same thing too. Libraries and API like these might process specific direction better or worse depending on internal implementation. There is a chance NV12 is not well implemented in libswscale.

In the same time I420 to NV12 is a very simple conversion direction and you can implement it, and pretty efficiently, using once screen of code and SIMD intrinsic functions.

Upvotes: 0

9dan
9dan

Reputation: 4282

Why WIC? Libyuv is more straight forward and probably perform better.

https://code.google.com/p/libyuv/

Feature:

Scale YUV to prepare content for compression, with point, bilinear or box filter.
Convert to YUV from webcam formats.
Convert from YUV to formats for rendering/effects.
Rotate by 90/180/270 degrees to adjust for mobile devices in portrait mode.
Optimized for SSE2/SSSE3/AVX2 on x86/x64.

API:

/ 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);

Upvotes: 1

Related Questions