[Question]: How to only capture the 1/2 monitor by AMFDisplayCapture?
When using AMFDisplayCapture to capture screen with two monitor, can not only capture the first or second monitor, it always capture all monitor together.
xrandr output
xrandr
Screen 0: minimum 320 x 200, current 2624 x 900, maximum 16384 x 16384
DisplayPort-0 disconnected (normal left inverted right x axis y axis)
DisplayPort-1 connected primary 1600x900+0+0 (normal left inverted right x axis y axis) 410mm x 256mm
1440x900 59.89 + 74.98
1280x1024 75.02 60.02
1280x960 60.00
1280x800 59.81
1152x864 75.00
1280x720 59.89
1024x768 75.03 70.07 60.00
832x624 74.55
800x600 72.19 75.00 60.32 56.25
640x480 75.00 72.81 66.67 59.94
720x400 70.08
HDMI-A-0 disconnected (normal left inverted right x axis y axis)
HDMI-A-1 connected 1024x768+1600+0 (normal left inverted right x axis y axis) 256mm x 192mm
1024x768 60.00*+
1920x1080 60.00 59.94
1280x1024 85.02 60.02
1440x900 74.98 59.90
1280x960 60.00
1360x768 60.02
1280x800 59.91
1280x720 60.00 59.94
800x600 60.00
720x480 60.00 59.94
640x480 60.00
OS: Ubuntu 22.04.1 5.15.0-46 Display Adapter: AMD RX 470 Amd Driver: amdgpu-install_22.20.50200-1_all.deb
init code
res = g_AMFFactory.GetFactory()->CreateComponent(m_pContext, AMFDisplayCapture, &m_pDisplayCapture);
CHECK_AMF_ERROR_RETURN(res, "AMFCreateComponent AMFDisplayCapture failed");
res = m_pDisplayCapture->SetProperty(AMF_DISPLAYCAPTURE_MONITOR_INDEX, 0); // or 1
CHECK_AMF_ERROR_RETURN(res, "Failed to set monitor ID");
res = m_pDisplayCapture->SetProperty(AMF_DISPLAYCAPTURE_CURRENT_TIME_INTERFACE, m_pCurrentTime);
CHECK_AMF_ERROR_RETURN(res, "Failed to set current time interface");
res = m_pDisplayCapture->SetProperty(AMF_DISPLAYCAPTURE_FRAMERATE, AMFConstructRate(30, 1));
CHECK_AMF_ERROR_RETURN(res, "Failed to set frame rate");
res = m_pDisplayCapture->SetProperty(AMF_DISPLAYCAPTURE_MODE, AMF_DISPLAYCAPTURE_MODE_KEEP_FRAMERATE);
CHECK_AMF_ERROR_RETURN(res, "Failed to set CAPTURE_MODE");
res = m_pDisplayCapture->Init(amf::AMF_SURFACE_UNKNOWN, 0, 0);
m_pDisplayCapture->GetProperty(AMF_DISPLAYCAPTURE_RESOLUTION, &m_CurrResolution);
m_pDisplayCapture->GetProperty(AMF_DISPLAYCAPTURE_DESKTOP_RECT, &m_CurrDesktopRect);
the RESOLUTION always: 2624x900
the DESKTOP_RECT always: 2624x900
How to only capture the first monitor or second monitor, and get the RESOLUTION or DESKTOP_RECT to DisplayPort-1 1600x900
When the app gets captured surface could you please check values of the surface->GetPlane(0)->GetOffsetX(), GetOffsety(), GetWidth(), GetHeight()?
get the captured surface: width, height
m_pDisplayCapture->QueryOutput(&data);
amf::AMFSurfacePtr pSurfPtr(data);
LOG("capture surface: %d %d %dx%d",
pSurfPtr->GetPlane(amf::AMF_PLANE_UNKNOWN)->GetOffsetX(),
pSurfPtr->GetPlane(amf::AMF_PLANE_UNKNOWN)->GetOffsetY(),
pSurfPtr->GetPlane(amf::AMF_PLANE_UNKNOWN)->GetWidth(),
pSurfPtr->GetPlane(amf::AMF_PLANE_UNKNOWN)->GetHeight());
log: capture surface: 0 0 1600x900
It seams that it only can be get the RESOLUTION by surface property? Have any way to get the captured RESOLUTION after m_pDisplayCapture->Init() and before m_pDisplayCapture->QueryOutput(&data) to call m_pEncoder->Init() ?
I understand the issue. We will need to fix AMF_DISPLAYCAPTURE_RESOLUTION. It will come with driver update.
so good
Few things to explain:
- In your setup compositor allocates a single surface for both monitors and AMF applies the correct cropping. In our testing Wayland compositor allocated different surfaces for each monitor.
- AMF Capture component just provides direct access to the compositor surfaces, it doesn't change or copy data.
- If you want to encode the captured surface directly you should know that encoder supports cropping only at right/bottom area. If cropping happens at left/top area you would have to copy surface by surface->Duplicate() function or use AMF color converter which respects all cropping.