Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# History

## [0.65.3] - 2026-08-22

`video0.size` with a non-native aspect no longer stalls VENC on Star6E.

- **Keep-aspect precrop is now 16-px aligned.**
`pipeline_common_compute_precrop()` aligned the keep-aspect crop to 2 px;
the VIF/VPE capture window needs aligned geometry, and an unaligned crop
is accepted by every MI_* call and then VPE silently emits nothing — the
daemon sat at "waiting for encoder data" forever. Reproduced on Star6E
with imx415 1472x816@120 -> 1280x720 (crop 1450x816@x=10); 1280x704
(crop 1472x808@y=4, full width) streamed immediately. Sizes and offsets
are now floored to 16 px, a superset of the stab crop path's width/8 +
x/16 rule; the crop aspect can differ from the target by at most
16/size (0.74 % in the case above), which the scaler absorbs.

## [0.65.2] - 2026-08-15

CV610 gets a scaler, one mode table instead of five copies of it, and a
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.65.2
0.65.3
5 changes: 4 additions & 1 deletion include/pipeline_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ int pipeline_common_cap_exposure_for_fps(uint32_t fps,

/** Compute crop rectangle for the VIF/SCL stage.
* keep_aspect = true → center-crop the sensor to the aspect ratio of
* image_w x image_h with 2-pixel alignment.
* image_w x image_h. Sizes and offsets are floored
* to 16 px (VIF/VPE silently produce nothing for an
* unaligned window), so the crop aspect may differ
* from the target by up to 16/size.
* keep_aspect = false → return the full sensor area; image_w/image_h are
* ignored and the downstream scaler will stretch. */
PipelinePrecropRect pipeline_common_compute_precrop(uint32_t sensor_w,
Expand Down
23 changes: 19 additions & 4 deletions src/pipeline_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,31 @@ PipelinePrecropRect pipeline_common_compute_precrop(uint32_t sensor_w,
sensor_ar = (uint64_t)sensor_w * image_h;
image_ar = (uint64_t)image_w * sensor_h;

/* The VIF/VPE capture window needs aligned geometry; an unaligned
* crop is accepted by every MI_* call and then VPE silently emits
* nothing. Observed 2026-08-22 on Star6E, imx415 1472x816: the
* 2-px-aligned 1450x816@x=10 crop for 1280x720 left VENC waiting
* forever, while 1280x704 (1472x808@y=4 — full width, x=0) streamed.
* The stab crop path (star6e_framing_stab.c) has always used
* width & ~7 with x & ~15 and is known good; 16 on every size and
* offset is a superset of that and of the working case, and
* 1440x816@x=16 for 1280x720 is device-verified.
*
* Flooring to 16 changes the crop aspect by at most 16/size — under
* 1.2 % at 1280-class output, 0.74 % in the case above — which the
* downstream scaler absorbs invisibly. Rounding to nearest would
* halve that but replace a hardware-verified geometry with an
* unverified one. */
if (sensor_ar > image_ar) {
rect.h = (uint16_t)sensor_h;
rect.w = (uint16_t)((sensor_h * image_w / image_h) & ~1u);
rect.x = (uint16_t)(((sensor_w - rect.w) / 2) & ~1u);
rect.w = (uint16_t)((sensor_h * image_w / image_h) & ~15u);
rect.x = (uint16_t)(((sensor_w - rect.w) / 2) & ~15u);
rect.y = 0;
} else if (sensor_ar < image_ar) {
rect.w = (uint16_t)sensor_w;
rect.h = (uint16_t)((sensor_w * image_h / image_w) & ~1u);
rect.h = (uint16_t)((sensor_w * image_h / image_w) & ~15u);
rect.x = 0;
rect.y = (uint16_t)(((sensor_h - rect.h) / 2) & ~1u);
rect.y = (uint16_t)(((sensor_h - rect.h) / 2) & ~15u);
}

return rect;
Expand Down
23 changes: 23 additions & 0 deletions tests/test_pipeline_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,29 @@ int test_pipeline_common(void)
CHECK("precrop matched-AR x", rect.x == 0);
CHECK("precrop matched-AR y", rect.y == 0);

/* compute_precrop: sizes and offsets must be 16-px aligned. imx415
* 1472x816 -> 1280x720 is the case that stalled VENC on Star6E: the
* ideal 1450x816@x=10 crop is accepted by every MI_* call and then
* VPE emits nothing. 1440x816@x=16 is the device-verified result. */
rect = pipeline_common_compute_precrop(1472, 816, 1280, 720, true);
CHECK("precrop 1472x816->16:9 w", rect.w == 1440);
CHECK("precrop 1472x816->16:9 h", rect.h == 816);
CHECK("precrop 1472x816->16:9 x", rect.x == 16);
CHECK("precrop 1472x816->16:9 y", rect.y == 0);
CHECK("precrop 1472x816->16:9 w aligned", (rect.w & 15) == 0);
CHECK("precrop 1472x816->16:9 x aligned", (rect.x & 15) == 0);
CHECK("precrop 1472x816->16:9 fits", rect.x + rect.w <= 1472);

/* Same constraint on the letterbox axis: 1472x816 -> 1280x704.
* Flooring h to 800 and y to 0 leaves the window 8 px above centre,
* the cost of 16-px offsets. */
rect = pipeline_common_compute_precrop(1472, 816, 1280, 704, true);
CHECK("precrop 1472x816->1280x704 w", rect.w == 1472);
CHECK("precrop 1472x816->1280x704 h", rect.h == 800);
CHECK("precrop 1472x816->1280x704 x", rect.x == 0);
CHECK("precrop 1472x816->1280x704 y", rect.y == 0);
CHECK("precrop 1472x816->1280x704 fits", rect.y + rect.h <= 816);

/* compute_precrop: keep_aspect=false short-circuits to full sensor
* regardless of image_w/image_h. This is what isp.keepAspect=false
* gives us. */
Expand Down
Loading