[Question]: NV12 to RGBA conversion
Hello,
I'm integrating AMF encoder and decoder into a screen-sharing app. Currently I'm decoding to NV12 format via amf and converting to RGBA in RAM/software and blitting everything to screen via QImage.
Is there any way to accelerate this - get RGBA directly from the decoder, converting or displaying via directx? Writing a converter ( amf::AMF_SURFACE_NV12 -> amf::AMF_SURFACE_RGBA) gives me AMF_INVALID_FORMAT when calling converter->Init.
Definitely you can.
- You need to select D3D11 device and pass to AMF via AMFContext::InitDX11(). Or NULL to use default device. Probably you already did so.
- Native decode fromat for 8-bit streams is NV12. You can use internal color converter inside decoder to convert. Pass the required format to decoder->Init(AMF_SURFACE_R8G8B8A8 , width, height)
- If you want combine color conversion with scaling or have more control over conversion, aspect ratio etc, you can use separate color coverter component. See SimpleConverter sample: res = converter->SetProperty(AMF_VIDEO_CONVERTER_MEMORY_TYPE, AMF_MEMORY_DX11); res = converter->SetProperty(AMF_VIDEO_CONVERTER_OUTPUT_FORMAT, formatOut); res = converter->SetProperty(AMF_VIDEO_CONVERTER_OUTPUT_SIZE, ::AMFConstructSize(widthOut, heightOut)); res = converter->Init(formatIn, widthIn, heightIn);
- If you see failures, enable detailed AMF tracing and share the log.
@MikhailAMD it works like you've described it (i use amf::AMF_SURFACE_RGBA). Thank you.
The output horizontal pitch for 1920x1080 video is 2048 so I'll need to crop the result before displaying it.
Video memory is always allocated with horizontal alignment so pitch could be present,. But if you consume it in GPU, it doesn't matter, as D3D11 texture in this case will be 1920x1080. If you map to system memory, yes, you will see pitch.
Does it mean I can display the result texture directly via directx? think this would be the fastest path.
Sure: (ID3D11Texture2D*)surface->GetPlaneAt(0)->GetNative(). Don't forget about serializing access to ID3D11DeviceContext if you use multithreading: AMFDX11Locker locker(context);