Settle the render window on the time selection and delete the experiment that proved it

The millisecond floor lives in the custom-bounds field, not the engine, so
RENDER_BOUNDSFLAG=2 is now the only bounds mode: the two-position type, the
console verdict and the STARTPOS/ENDPOS drift probe all go. capture.cpp 697 -> 622.
This commit is contained in:
2026-08-02 16:55:12 -04:00
parent d85e50c143
commit 8331df2e91
14 changed files with 205 additions and 862 deletions
+28 -82
View File
@@ -111,12 +111,8 @@ static void testLabelsSeparateExactlyWhatTheRenderSeparates() {
// --- tail: TailMode -> RENDER_* mapping (docs/product/capture-tail.md) --------
// The tail assertions below are about the MODE's mapping; the one value that also
// depends on the bounds channel has its own test, so they all pin the channel that
// every shipped capture rendered on.
static TailRenderSettings tailFor(TailMode mode, double manualTailMs) {
return tailRenderSettingsFor(mode, manualTailMs,
RenderBoundsChannel::CustomTimeBounds);
return tailRenderSettingsFor(mode, manualTailMs);
}
static void testTailNoneIsExactBounds() {
@@ -136,11 +132,11 @@ static void testTailNoneIsExactBounds() {
}
static void testTailAutoIsSurgicalTrim() {
// Auto -> custom-bounds tail bit, 8 s cap, SURGICAL normalize (ONLY &32768), and
// the -72 dB TRIMEND ratio. The disable-all bit must NOT be set (it is semantically
// opposed to trim — this assertion catches a regression to the None normalize).
// Auto -> the time-selection tail bit, 8 s cap, SURGICAL normalize (ONLY &32768),
// and the -72 dB TRIMEND ratio. The disable-all bit must NOT be set (it is
// semantically opposed to trim — this catches a regression to the None normalize).
TailRenderSettings t = tailFor(TailMode::Auto, 0.0);
CHECK(t.tailFlag == kTailFlagCustomBounds); // &1
CHECK(t.tailFlag == kTailFlagTimeSelection); // &4
CHECK(t.tailMs == kMaxTailMs); // 8000
CHECK(t.normalize == kNormalizeTrimEnd); // exactly 32768, nothing else
CHECK((t.normalize & kNormalizeDisableAll) == 0); // disable-all is NOT set
@@ -161,11 +157,11 @@ static void testAutoTrimRatioDerivesFromDb() {
}
static void testTailManualFixedNoTrim() {
// Manual -> custom-bounds tail, the requested ms (within cap), disable-all
// Manual -> the time-selection tail bit, the requested ms (within cap), disable-all
// normalize (no trim). A Manual capture is a fixed tail, so it keeps today's
// disable-all exactly like the no-tail path.
TailRenderSettings t = tailFor(TailMode::Manual, 2500.0);
CHECK(t.tailFlag == kTailFlagCustomBounds);
CHECK(t.tailFlag == kTailFlagTimeSelection);
CHECK(t.tailMs == 2500.0);
CHECK(t.normalize == kNormalizeDisableAll);
CHECK(t.trimEnd == 0.0);
@@ -181,59 +177,29 @@ static void testTailManualClampsToCap() {
CHECK(tailFor(TailMode::Manual, -50.0).tailMs == 0.0);
}
// --- bounds channel: RENDER_BOUNDSFLAG mode + the tail bit it drags along ------
// --- bounds mode: RENDER_BOUNDSFLAG + the tail bit paired with it ---------------
static void testEachChannelNamesItsOwnBoundsFlagMode() {
// The two RENDER_BOUNDSFLAG values, as literals from the SDK header — 0 = custom
// time bounds, 2 = time selection. Pinned as numbers so a renumbering of the enum
// cannot silently point a capture at "entire project" or "selected media items".
CHECK(renderBoundsFlagFor(RenderBoundsChannel::CustomTimeBounds) == 0);
CHECK(renderBoundsFlagFor(RenderBoundsChannel::TimeSelection) == 2);
static void testTheBoundsModeIsTheTimeSelectionAndItsTailBitIsPairedWithIt() {
// Literals from the SDK header, pinned as numbers so neither can drift onto
// another bounds mode's value: RENDER_BOUNDSFLAG 2 = time selection (~3042), and
// RENDER_TAILFLAG's bits are keyed per bounds mode, &4 = time selection (~3047).
// The custom-bounds pair (0 / &1) is DELIBERATELY absent — that mode floors the
// window to the millisecond (render_settings.h) and must not come back.
CHECK(kRenderBoundsTimeSelection == 2);
CHECK(kTailFlagTimeSelection == 4);
CHECK(kTailFlagNone == 0);
}
static void testTailBitFollowsTheBoundsChannel() {
// RENDER_TAILFLAG's bits are per-bounds-mode: &1 covers custom time bounds, &4
// covers the time selection. A tail set under the other channel's bit renders no
// tail at all, which is why the mapping takes the channel rather than trusting a
// caller to OR the right one in.
CHECK(tailFlagBitFor(RenderBoundsChannel::CustomTimeBounds) == 1);
CHECK(tailFlagBitFor(RenderBoundsChannel::TimeSelection) == 4);
static void testEveryTailModeSetsTheBitTheBoundsModeReads() {
// A tail set under a different bounds mode's bit renders no tail at all, so both
// tail-bearing modes must carry &4 — a fix applied to Auto alone would leave
// Manual silently tailless.
for (TailMode mode : {TailMode::Auto, TailMode::Manual})
CHECK(tailRenderSettingsFor(mode, 2500.0).tailFlag == kTailFlagTimeSelection);
// Both tail-bearing modes follow it — a fix applied to Auto alone would leave
// Manual rendering under a bit the bounds mode does not read.
for (TailMode mode : {TailMode::Auto, TailMode::Manual}) {
CHECK(tailRenderSettingsFor(mode, 2500.0,
RenderBoundsChannel::CustomTimeBounds)
.tailFlag == kTailFlagCustomBounds);
CHECK(tailRenderSettingsFor(mode, 2500.0,
RenderBoundsChannel::TimeSelection)
.tailFlag == kTailFlagTimeSelection);
}
}
static void testNoneSetsNoTailBitOnEitherChannel() {
// None is exact bounds on every channel: no tail bit, so no channel's bit either.
CHECK(tailRenderSettingsFor(TailMode::None, 5000.0,
RenderBoundsChannel::CustomTimeBounds)
.tailFlag == kTailFlagNone);
CHECK(tailRenderSettingsFor(TailMode::None, 5000.0,
RenderBoundsChannel::TimeSelection)
.tailFlag == kTailFlagNone);
}
static void testTheChannelLabelNamesTheModeAndItsStore() {
// The console verdict is read by someone deciding which channel to keep, so the
// label has to name both the mode number and where the window actually went.
const std::string custom = renderBoundsChannelLabel(RenderBoundsChannel::CustomTimeBounds);
CHECK(custom.find("RENDER_BOUNDSFLAG=0") != std::string::npos);
CHECK(custom.find("RENDER_STARTPOS") != std::string::npos);
const std::string ts = renderBoundsChannelLabel(RenderBoundsChannel::TimeSelection);
CHECK(ts.find("RENDER_BOUNDSFLAG=2") != std::string::npos);
CHECK(ts.find("GetSet_LoopTimeRange") != std::string::npos);
// Two channels that read alike in the console would make the experiment unreadable.
CHECK(custom != ts);
// None is exact bounds: no tail bit at all, whatever ms it is handed.
CHECK(tailRenderSettingsFor(TailMode::None, 5000.0).tailFlag == kTailFlagNone);
CHECK(tailRenderSettingsFor(TailMode::None, 0.0).tailFlag == kTailFlagNone);
}
// --- realtimeRecordWindowEnd: the T2 record-window extension -----------------
@@ -384,23 +350,6 @@ static void testMultiTrackStemRenderIsNamedForRefusal() {
CHECK(!isMultiTrackStemRender(sourceModeForScope(CaptureScope::Item, true), 2));
}
static void testSourceBypassesBoundsChannelOnlyForContentDerivedSources() {
// SelectedItems (&32) and RazorArea (&4096) derive their bounds from the
// selected items'/areas' own extents -- RENDER_BOUNDSFLAG is never consulted, so
// a bounds-channel verdict is not evidence for either (the regression this
// predicate exists to catch: RunBatchCaptureItems always renders through
// SelectedItems, so this false-EXACT would fire on every batch-item capture).
CHECK(sourceBypassesBoundsChannel(SourceMode::SelectedItems));
CHECK(sourceBypassesBoundsChannel(SourceMode::RazorArea));
// Every other source is genuinely time-bounded through RENDER_STARTPOS/ENDPOS or
// the time selection, so the channel IS the evidence for these.
CHECK(!sourceBypassesBoundsChannel(SourceMode::MasterMix));
CHECK(!sourceBypassesBoundsChannel(SourceMode::TimeSelection));
CHECK(!sourceBypassesBoundsChannel(SourceMode::SelectedTracks));
CHECK(!sourceBypassesBoundsChannel(SourceMode::Realtime));
}
static void testRefusalMessagesAreSiblingsWithDistinctExits() {
const std::string item = multiTrackRefusalMessage(CaptureScope::Item);
const std::string track = multiTrackRefusalMessage(CaptureScope::Track);
@@ -528,10 +477,8 @@ int main() {
testAutoTrimRatioDerivesFromDb();
testTailManualFixedNoTrim();
testTailManualClampsToCap();
testEachChannelNamesItsOwnBoundsFlagMode();
testTailBitFollowsTheBoundsChannel();
testNoneSetsNoTailBitOnEitherChannel();
testTheChannelLabelNamesTheModeAndItsStore();
testTheBoundsModeIsTheTimeSelectionAndItsTailBitIsPairedWithIt();
testEveryTailModeSetsTheBitTheBoundsModeReads();
testRealtimeWindowNoneIsExact();
testRealtimeWindowAutoAddsCap();
testRealtimeWindowManualAddsClampedLength();
@@ -543,7 +490,6 @@ int main() {
testScopeSourceModes();
testRangedItemScopeRendersTimeBounded();
testMultiTrackStemRenderIsNamedForRefusal();
testSourceBypassesBoundsChannelOnlyForContentDerivedSources();
testRefusalMessagesAreSiblingsWithDistinctExits();
testRefusalMessagesMatchGoldenLiterals();
testRangeInference();