@camstack/system 1.2.260 → 1.2.262
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1587,23 +1587,64 @@ var PIXEL_FORMAT = "yuv420p";
|
|
|
1587
1587
|
*/
|
|
1588
1588
|
var GOP_SECONDS = 1;
|
|
1589
1589
|
/**
|
|
1590
|
-
* `-analyzeduration` / `-probesize`,
|
|
1590
|
+
* `-analyzeduration` / `-probesize`, as small as ffmpeg allows.
|
|
1591
1591
|
*
|
|
1592
|
-
*
|
|
1593
|
-
*
|
|
1594
|
-
*
|
|
1595
|
-
*
|
|
1596
|
-
*
|
|
1592
|
+
* ## The probes are SEQUENTIAL, and this is what the tile skew was
|
|
1593
|
+
*
|
|
1594
|
+
* The sentence that used to be here said the probes are "PARALLEL inputs of one
|
|
1595
|
+
* child". They are not. ffmpeg opens its inputs one after another and each open
|
|
1596
|
+
* BLOCKS in `avformat_find_stream_info` until its budget is spent — so input 0
|
|
1597
|
+
* is already connected and receiving while ffmpeg is still opening input 1, its
|
|
1598
|
+
* frames pile up, and `overlay` (which pairs inputs BY PTS) marries input 0's
|
|
1599
|
+
* oldest frame to input 1's newest. The lag is fixed for the life of the child:
|
|
1600
|
+
* both tiles then advance one frame per output frame, so nothing ever closes it.
|
|
1601
|
+
* The FIRST cell is the most behind; the last is live.
|
|
1602
|
+
*
|
|
1603
|
+
* Reproduced in one command on 2026-09-18 — two sources hstacked, one frame,
|
|
1604
|
+
* reading the cameras' own burnt-in clocks out of the composed picture:
|
|
1605
|
+
*
|
|
1606
|
+
* ```
|
|
1607
|
+
* 13:11:21 | 13:11:23 two seconds, and the earlier input is the late one
|
|
1608
|
+
* ```
|
|
1609
|
+
*
|
|
1610
|
+
* ## Why the old numbers cost seconds
|
|
1611
|
+
*
|
|
1612
|
+
* `-probesize` is a BYTE budget, and 1 MB of a 640x360 sub-stream is tens of
|
|
1613
|
+
* seconds of video — so `-analyzeduration 1s` never got the chance to stop it
|
|
1614
|
+
* and each open ran until the byte budget filled. Zero and 32 make the probe
|
|
1615
|
+
* return from the SDP, which already declares the codec, without reading media.
|
|
1616
|
+
*
|
|
1617
|
+
* Measured on this hub, the two sources of the live grid, three runs each,
|
|
1618
|
+
* production input args otherwise identical — time to the first composed frame,
|
|
1619
|
+
* and the skew read off the two burnt-in clocks in that frame:
|
|
1620
|
+
*
|
|
1621
|
+
* ```
|
|
1622
|
+
* 1 s / 1 MB 8986, 9728, 9712 ms skew 5 s, 5 s, 4 s
|
|
1623
|
+
* 0 / 32 2281, 2270, 2304 ms skew 1 s, 1 s, 0 s
|
|
1624
|
+
* ```
|
|
1625
|
+
*
|
|
1626
|
+
* The same numbers are the ~9 s cold start the operator had accepted: it was a
|
|
1627
|
+
* SUM of the opens, never the wait for the slowest source.
|
|
1628
|
+
*
|
|
1629
|
+
* Checked before shipping, because a probe that reads nothing has to survive
|
|
1630
|
+
* what it is not told: h264, h265 and a derived (`mid-to-low`) source all open
|
|
1631
|
+
* with `rc=0`, a 20 s run produces 200 frames of 200 either way (so the pacing
|
|
1632
|
+
* this file already lost once is untouched), and the skew is still 0 at 25 s
|
|
1633
|
+
* into a run — it is set at start-up and does not drift.
|
|
1634
|
+
*
|
|
1635
|
+
* What remains is the spread in when each source's first key frame arrives, and
|
|
1636
|
+
* a `/muted` dial waits for the next IDR. That spread is small here; if it ever
|
|
1637
|
+
* is not, the answer is to start the inputs from a join point we hold, NOT to
|
|
1638
|
+
* re-time the inputs (see `useWallclockTimestamps` below).
|
|
1597
1639
|
*/
|
|
1598
|
-
var ANALYZE_DURATION_US =
|
|
1599
|
-
var PROBE_SIZE_BYTES =
|
|
1640
|
+
var ANALYZE_DURATION_US = 0;
|
|
1641
|
+
var PROBE_SIZE_BYTES = 32;
|
|
1600
1642
|
function inputPlanFor(source) {
|
|
1601
1643
|
return {
|
|
1602
1644
|
url: source.url,
|
|
1603
1645
|
rtspTransport: "tcp",
|
|
1604
1646
|
fflags: ["+discardcorrupt"],
|
|
1605
1647
|
lowDelay: true,
|
|
1606
|
-
useWallclockTimestamps: true,
|
|
1607
1648
|
analyzeDurationUs: ANALYZE_DURATION_US,
|
|
1608
1649
|
probeSizeBytes: PROBE_SIZE_BYTES
|
|
1609
1650
|
};
|
|
@@ -1582,23 +1582,64 @@ var PIXEL_FORMAT = "yuv420p";
|
|
|
1582
1582
|
*/
|
|
1583
1583
|
var GOP_SECONDS = 1;
|
|
1584
1584
|
/**
|
|
1585
|
-
* `-analyzeduration` / `-probesize`,
|
|
1585
|
+
* `-analyzeduration` / `-probesize`, as small as ffmpeg allows.
|
|
1586
1586
|
*
|
|
1587
|
-
*
|
|
1588
|
-
*
|
|
1589
|
-
*
|
|
1590
|
-
*
|
|
1591
|
-
*
|
|
1587
|
+
* ## The probes are SEQUENTIAL, and this is what the tile skew was
|
|
1588
|
+
*
|
|
1589
|
+
* The sentence that used to be here said the probes are "PARALLEL inputs of one
|
|
1590
|
+
* child". They are not. ffmpeg opens its inputs one after another and each open
|
|
1591
|
+
* BLOCKS in `avformat_find_stream_info` until its budget is spent — so input 0
|
|
1592
|
+
* is already connected and receiving while ffmpeg is still opening input 1, its
|
|
1593
|
+
* frames pile up, and `overlay` (which pairs inputs BY PTS) marries input 0's
|
|
1594
|
+
* oldest frame to input 1's newest. The lag is fixed for the life of the child:
|
|
1595
|
+
* both tiles then advance one frame per output frame, so nothing ever closes it.
|
|
1596
|
+
* The FIRST cell is the most behind; the last is live.
|
|
1597
|
+
*
|
|
1598
|
+
* Reproduced in one command on 2026-09-18 — two sources hstacked, one frame,
|
|
1599
|
+
* reading the cameras' own burnt-in clocks out of the composed picture:
|
|
1600
|
+
*
|
|
1601
|
+
* ```
|
|
1602
|
+
* 13:11:21 | 13:11:23 two seconds, and the earlier input is the late one
|
|
1603
|
+
* ```
|
|
1604
|
+
*
|
|
1605
|
+
* ## Why the old numbers cost seconds
|
|
1606
|
+
*
|
|
1607
|
+
* `-probesize` is a BYTE budget, and 1 MB of a 640x360 sub-stream is tens of
|
|
1608
|
+
* seconds of video — so `-analyzeduration 1s` never got the chance to stop it
|
|
1609
|
+
* and each open ran until the byte budget filled. Zero and 32 make the probe
|
|
1610
|
+
* return from the SDP, which already declares the codec, without reading media.
|
|
1611
|
+
*
|
|
1612
|
+
* Measured on this hub, the two sources of the live grid, three runs each,
|
|
1613
|
+
* production input args otherwise identical — time to the first composed frame,
|
|
1614
|
+
* and the skew read off the two burnt-in clocks in that frame:
|
|
1615
|
+
*
|
|
1616
|
+
* ```
|
|
1617
|
+
* 1 s / 1 MB 8986, 9728, 9712 ms skew 5 s, 5 s, 4 s
|
|
1618
|
+
* 0 / 32 2281, 2270, 2304 ms skew 1 s, 1 s, 0 s
|
|
1619
|
+
* ```
|
|
1620
|
+
*
|
|
1621
|
+
* The same numbers are the ~9 s cold start the operator had accepted: it was a
|
|
1622
|
+
* SUM of the opens, never the wait for the slowest source.
|
|
1623
|
+
*
|
|
1624
|
+
* Checked before shipping, because a probe that reads nothing has to survive
|
|
1625
|
+
* what it is not told: h264, h265 and a derived (`mid-to-low`) source all open
|
|
1626
|
+
* with `rc=0`, a 20 s run produces 200 frames of 200 either way (so the pacing
|
|
1627
|
+
* this file already lost once is untouched), and the skew is still 0 at 25 s
|
|
1628
|
+
* into a run — it is set at start-up and does not drift.
|
|
1629
|
+
*
|
|
1630
|
+
* What remains is the spread in when each source's first key frame arrives, and
|
|
1631
|
+
* a `/muted` dial waits for the next IDR. That spread is small here; if it ever
|
|
1632
|
+
* is not, the answer is to start the inputs from a join point we hold, NOT to
|
|
1633
|
+
* re-time the inputs (see `useWallclockTimestamps` below).
|
|
1592
1634
|
*/
|
|
1593
|
-
var ANALYZE_DURATION_US =
|
|
1594
|
-
var PROBE_SIZE_BYTES =
|
|
1635
|
+
var ANALYZE_DURATION_US = 0;
|
|
1636
|
+
var PROBE_SIZE_BYTES = 32;
|
|
1595
1637
|
function inputPlanFor(source) {
|
|
1596
1638
|
return {
|
|
1597
1639
|
url: source.url,
|
|
1598
1640
|
rtspTransport: "tcp",
|
|
1599
1641
|
fflags: ["+discardcorrupt"],
|
|
1600
1642
|
lowDelay: true,
|
|
1601
|
-
useWallclockTimestamps: true,
|
|
1602
1643
|
analyzeDurationUs: ANALYZE_DURATION_US,
|
|
1603
1644
|
probeSizeBytes: PROBE_SIZE_BYTES
|
|
1604
1645
|
};
|