From 518b40f3af7090405ec5ab141feeecf42183aa8a Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Sun, 20 Jul 2025 05:32:12 +0200 Subject: device: Target resolution of 720p on libcamera devices Most cameras needing the fallback path are provided by libcamera, which does not yet provide framerates. At the same time many such cameras support very high resolutions - often in the 4K category - and are paired with rather weak CPUs. Examples for this are popular mobile phones such as the PinePhone Pro or the OnePlus6. In order to archive a somewhat stable FPS count in such scenarios, target a resolution of 720p as a compromise of quality and performance. --- plugins/rtp/src/device.vala | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'plugins/rtp') diff --git a/plugins/rtp/src/device.vala b/plugins/rtp/src/device.vala index 17803c6c..ce89c8ee 100644 --- a/plugins/rtp/src/device.vala +++ b/plugins/rtp/src/device.vala @@ -401,17 +401,46 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object { } if (best_index == -1) { // No caps in first round, try without framerate + int target_pixel_count = 1280 * 720; + double target_pixel_ratio = 16.0 / 9.0; + double best_diversion_factor = 0.0; + for (int i = 0; i < device.caps.get_size(); i++) { unowned Gst.Structure? that = device.caps.get_structure(i); unowned Gst.CapsFeatures? features = device.caps.get_features(i); if (!that.has_name("video/x-raw") || !features.contains("memory:SystemMemory")) continue; int width = 0, height = 0; - if (!that.has_field("width") || !that.get_int("width", out width)) continue; - if (!that.has_field("height") || !that.get_int("height", out height)) continue; - if (best_width < width || best_width == width && best_height < height) { + if (!that.has_field("width") || !that.get_int("width", out width) || width == 0) continue; + if (!that.has_field("height") || !that.get_int("height", out height) || height == 0) continue; + + int pixel_count = width * height; + double pixel_count_diversion_factor; + if (pixel_count > target_pixel_count) + pixel_count_diversion_factor = (double)pixel_count / target_pixel_count; + else + pixel_count_diversion_factor = (double)target_pixel_count / pixel_count; + + double pixel_ratio; + if (width > height) + pixel_ratio = (double)width / height; + else + pixel_ratio = (double)height / width; + + double ratio_diversion_factor; + if (pixel_ratio > target_pixel_ratio) + ratio_diversion_factor = pixel_ratio / target_pixel_ratio; + else + ratio_diversion_factor = target_pixel_ratio / pixel_ratio; + + // 1.0 is the best possible value. Any diversion from + // target_pixel_count or target_pixel_ratio increases it. + double diversion_factor = pixel_count_diversion_factor * ratio_diversion_factor; + + if (best_index == -1 || diversion_factor < best_diversion_factor) { + best_index = i; best_width = width; best_height = height; - best_index = i; + best_diversion_factor = diversion_factor; } } } -- cgit v1.3