From 42f1d874ba19b23d457ff254d61c9e757555f3a9 Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Tue, 3 Nov 2026 16:56:48 +0100 Subject: [PATCH] openvidu-test-e2e: stop the picture check failing encoder artifacts The picture check of the Egress Pro tests (countBrokenPictures) failed publisherCongestionVp9Test locally in 2 of 4 pion runs, and once with mediasoup, on frames that had arrived whole. A trace of every VP9 packet the egress received (rtpvp9depay at trace level) showed each of them written with every frame it predicts from. The flaws were the encoder's: white flashes drawn only in part under the 250 kbit/s cap, with 64x64 blocks of the dark frame before them left in place, and once a dark seam 1 px wide through the bar. A row with flash white (three pixels in a row at FLASH_WHITE, 250, or more) is now part of a flash and not checked, and bright stretches at most BAR_SEAM_PX (2) apart are one stretch of the bar. Co-Authored-By: Claude Opus 5.5 --- .../e2e/OpenViduTestAppE2eEgressProTest.java | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eEgressProTest.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eEgressProTest.java index 522d4cc0c..bf2f22b6c 100644 --- a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eEgressProTest.java +++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eEgressProTest.java @@ -144,6 +144,11 @@ public class OpenViduTestAppE2eEgressProTest extends AbstractOpenViduTestappE2eT private static final double BAR_WINDOW_S = 0.5; // Width of the luma row the bar is read from, whatever the frame size private static final int BAR_ROW_WIDTH = 640; + // A pixel of the row this bright is flash white: nothing else on the canvas is + private static final int FLASH_WHITE = 250; + // Bright stretches of the row this many pixels apart or less are one stretch + // of the bar: the encoder can leave a darker seam through it + private static final int BAR_SEAM_PX = 2; // A/V offset drift allowed between the start and the end of a long recording private static final double MAX_AV_DRIFT_MS = 40; // The SDK egress's sync engine places a track by its arrival time until it has @@ -4609,7 +4614,11 @@ public class OpenViduTestAppE2eEgressProTest extends AbstractOpenViduTestappE2eT if (edge != null) { s.bar.add(new double[] { time, edge / BAR_ROW_WIDTH * BAR_PERIOD_MS }); } - barRuns.add(new Object[] { time, brightRuns(row) }); + // a row with flash white is part of a flash: one the encoder, short of + // bits, only partly drew, leaving blocks of the dark frame before it + if (!showsFlashWhite(row)) { + barRuns.add(new Object[] { time, brightRuns(row) }); + } } previousLuma = luma; previousTime = time; @@ -4671,10 +4680,23 @@ public class OpenViduTestAppE2eEgressProTest extends AbstractOpenViduTestappE2eT return null; } + /** Whether a luma row has three pixels in a row at FLASH_WHITE or more. */ + private static boolean showsFlashWhite(int[] row) { + int white = 0; + for (int value : row) { + white = value >= FLASH_WHITE ? white + 1 : 0; + if (white >= 3) { + return true; + } + } + return false; + } + /** * The stretches of a luma row, of 3 pixels or more, brighter than halfway * between the background (the median) and the brightest pixel, as [start, - * width]; null if nothing stands out of the background. + * width]; null if nothing stands out of the background. Stretches at most + * BAR_SEAM_PX apart are one. */ private static List brightRuns(int[] row) { int[] sorted = row.clone(); @@ -4693,7 +4715,12 @@ public class OpenViduTestAppE2eEgressProTest extends AbstractOpenViduTestappE2eT start = x; } else if (!bright && start >= 0) { if (x - start >= 3) { - runs.add(new int[] { start, x - start }); + int[] last = runs.isEmpty() ? null : runs.get(runs.size() - 1); + if (last != null && start - (last[0] + last[1]) <= BAR_SEAM_PX) { + last[1] = x - last[0]; + } else { + runs.add(new int[] { start, x - start }); + } } start = -1; }