Skip to content

gst: Always set the smart resize and crop when configuring - #82

Merged
naushir merged 1 commit into
raspberrypi:mainfrom
steventhegeek:gst-always-set-smart-resize
Nov 4, 2026
Merged

naushir merged 1 commit into
raspberrypi:mainfrom
steventhegeek:gst-always-set-smart-resize

Conversation

@steventhegeek

Copy link
Copy Markdown
Contributor

After pispconvert is reconfigured with new input caps but the same output size, the Back End runs with the resampler disabled. The output is then an unscaled, wrongly tiled crop of the input (shifted in vertical chunks and zoomed in), and it stays that way until the output size or crop changes.

Cause

In gst_pisp_convert_configure():

  1. global.rgb_enables = PISP_BE_RGB_ENABLE_INPUT; followed by SetGlobal() clears the downscale/resample enables.
  2. The backend only re-enables them in BackEnd::updateSmartResize(), when the smart resize (or crop) is dirty.
  3. SetSmartResize() was skipped when the output size equalled applied_smart_resize, so nothing re-enabled the resampler after a reconfigure at the same output size.

The pisp_be_tiles_config written to pispbe-config shows it. For the same 3840x2160 → 2560x1440 conversion, global.rgb_enables is 0x48203 on the first configure and 0x40203 (no RESAMPLE0) after the reconfigure, and the tiles differ.

How to reproduce

Pi 5, Trixie, libpisp / gstreamer1.0-pispconvert 1.7.0-1, GStreamer 1.26.2. Feed one pispconvert, through a concat, at a fixed output size:

  • a 3840x2160 H.265 clip (v4l2slh265dec, DMA_DRM NV12:0x0700000000000004, zero-copy input), then
  • a 3840x2160 H.264 clip (avdec_h264, I420, memcpy input),

into pispconvert ! video/x-raw(memory:DMABuf),format=DMA_DRM,drm-format=NV12,width=2560,height=1440 ! kmssink.

The second clip comes out wrong, and so does the same pair in the other order. Each clip is fine on its own, and after a change of output size or crop. A caps change of only the frame rate (4K60 → 4K25 H.265) triggers it too.

Fix

Always call SetSmartResize() when configuring. With the change, rgb_enables stays 0x48203 after the reconfigure, and both orders come out right. I checked frames captured at kmssink and watched the output on a 2560x1440 screen.

clang-format (22.1.3) is clean.

@naushir naushir left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change looks good, only a couple of minor things to address.

Comment thread src/gst/gstpispconvert.cpp Outdated
self->priv->applied_smart_resize[i] = smart_resize;
}
self->priv->backend->SetSmartResize(i, smart_resize);
self->priv->applied_smart_resize[i] = smart_resize;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think applied_smart_resize is used any more? If so, could you delete it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, nothing reads it now. Removed, along with its declaration.

Comment thread src/gst/gstpispconvert.cpp Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we might want to do the same thing here as with smart_reisize below?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, SetCrop() is now called on every configure and applied_crop is gone too. The crop does not hit the same problem as far as I can see: it lives in be_config_extra_ and SetGlobal() does not reset it, and a format change already sets retile_. But setting it every time keeps the two consistent and drops the cache. Re-tested the same-size switches in both orders, plus a cropped stream (1024x608 coded, 1024x600 shown) in between: all correct.

gst_pisp_convert_configure() resets rgb_enables to the input and output
enables, and the backend only re-enables the downscale and resample blocks
in updateSmartResize() when the smart resize is dirty. SetSmartResize() was
skipped when the output size had not changed, so after any reconfigure at
the same output size the resampler was left disabled and the output was an
unscaled, wrongly tiled crop of the input.

This shows when the input caps change but the output size does not, for
example a tiled NV12 (SAND128) stream from v4l2slh265dec followed by an
I420 stream of the same size from avdec_h264, in either order, or a change
of frame rate only. The config sent to the backend has rgb_enables 0x48203
on the first configure and 0x40203 (no RESAMPLE0) after the reconfigure.

Always call SetSmartResize() so the resampler is re-enabled on every
configure. Call SetCrop() every time as well for consistency, and drop the
now unused applied_smart_resize and applied_crop caches.

Signed-off-by: StevenTheGeek <steventhegeek@gmail.com>
@steventhegeek
steventhegeek force-pushed the gst-always-set-smart-resize branch from e5e154d to 161ebd1 Compare November 4, 2026 00:06
@steventhegeek steventhegeek changed the title gst: Always set the smart resize when configuring gst: Always set the smart resize and crop when configuring Nov 4, 2026
@naushir

naushir commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

Thanks, now merging.

@naushir
naushir merged commit 45d7255 into raspberrypi:main Nov 4, 2026
2 checks passed

This branch was successfully deployed

1 active deployment
camera-test — 161ebd13 Deployed Nov 4, 2026 by steventhegeek via trigger-camera-tests #26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants