diff options
| author | Robert Mader <robert.mader@collabora.com> | 2025-07-20 05:32:12 +0200 |
|---|---|---|
| committer | Marvin W <git@larma.de> | 2025-10-06 21:23:22 +0200 |
| commit | 518b40f3af7090405ec5ab141feeecf42183aa8a (patch) | |
| tree | acc339b9b1e814c88734838b138be35b31cc44e2 | |
| parent | e801d44b8472bf72ac04ed1c8faf6bd856f25def (diff) | |
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.
| -rw-r--r-- | plugins/rtp/src/device.vala | 37 |
1 files changed, 33 insertions, 4 deletions
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; } } } |
