GPUOpen-LibrariesAndSDKs / AMF

The Advanced Media Framework (AMF) SDK provides developers with optimal access to AMD devices for multimedia processing
Other
609 stars 152 forks source link

[Question]: NV12 to RGBA conversion #511

Open martin19 opened 1 week ago

martin19 commented 1 week ago

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.

MikhailAMD commented 1 week ago

Definitely you can.

  1. You need to select D3D11 device and pass to AMF via AMFContext::InitDX11(). Or NULL to use default device. Probably you already did so.
  2. 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)
  3. 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);
  4. If you see failures, enable detailed AMF tracing and share the log.
martin19 commented 1 week ago

@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.

MikhailAMD commented 1 week ago

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.

martin19 commented 1 week ago

Does it mean I can display the result texture directly via directx? think this would be the fastest path.

MikhailAMD commented 1 week ago

Sure: (ID3D11Texture2D*)surface->GetPlaneAt(0)->GetNative(). Don't forget about serializing access to ID3D11DeviceContext if you use multithreading: AMFDX11Locker locker(context);