public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
From: Rivka S <s0533160580@gmail.com>
To: linux-media@vger.kernel.org
Cc: Rivka S <s0533160580@gmail.com>
Subject: [PATCH] utils: fwht: support resolution changes
Date: Thu, 26 Mar 2026 10:12:12 +0200	[thread overview]
Message-ID: <20260326081211.26562-2-s0533160580@gmail.com> (raw)

The FWHT decoder currently fails when the resolution changes
between frames.

Instead of returning -EINVAL, update the internal state to match
the new resolution.

When a resolution change is detected:
- Update visible width and height from the frame header
- Recalculate coded dimensions
- Update stride and reference stride
- Reset GOP-related state

Also recompute dependent values such as dst_chroma_stride,
ref_chroma_stride and dst_size after updating the state.

On the userspace side, ensure the destination buffer is large enough
for the updated frame size and reallocate it if needed.

This allows decoding streams with dynamic resolution changes.

Tested using a custom FWHT decoding script.

Signed-off-by: Rivka Sabo <s0533160580@gmail.com>
---
 utils/common/codec-v4l2-fwht.c | 29 ++++++++++++++++++++++-------
 utils/qvidcap/capture.cpp      | 15 ++++++++++++---
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/utils/common/codec-v4l2-fwht.c b/utils/common/codec-v4l2-fwht.c
index 0c83678f..f45b06c3 100644
--- a/utils/common/codec-v4l2-fwht.c
+++ b/utils/common/codec-v4l2-fwht.c
@@ -288,9 +288,9 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
 	const struct v4l2_fwht_pixfmt_info *info;
 	unsigned int hdr_width_div, hdr_height_div;
 	struct fwht_raw_frame dst_rf;
-	unsigned int dst_chroma_stride = state->stride;
-	unsigned int ref_chroma_stride = state->ref_stride;
-	unsigned int dst_size = state->stride * state->coded_height;
+	unsigned int dst_chroma_stride;
+	unsigned int ref_chroma_stride;
+	unsigned int dst_size;
 	unsigned int ref_size;
 
 	if (!state->info)
@@ -309,10 +309,25 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
 	    state->header.magic2 != FWHT_MAGIC2)
 		return -EINVAL;
 
-	/* TODO: support resolution changes */
-	if (ntohl(state->header.width)  != state->visible_width ||
-	    ntohl(state->header.height) != state->visible_height)
-		return -EINVAL;
+	if (ntohl(state->header.width) != state->visible_width ||
+	    ntohl(state->header.height) != state->visible_height) {
+		state->visible_width = ntohl(state->header.width);
+		state->visible_height = ntohl(state->header.height);
+		state->coded_width = vic_round_dim(
+			state->visible_width + (info->width_div - 1),
+			info->width_div);
+		state->coded_height = vic_round_dim(
+			state->visible_height + (info->height_div - 1),
+			info->height_div);
+		state->stride = state->coded_width * info->bytesperline_mult;
+		state->ref_stride = state->stride;
+		state->gop_cnt = 0;
+		state->ref_frame_ts = 0;
+	}
+
+	dst_chroma_stride = state->stride;
+	ref_chroma_stride = state->ref_stride;
+	dst_size = state->stride * state->coded_height;
 
 	flags = ntohl(state->header.flags);
 
diff --git a/utils/qvidcap/capture.cpp b/utils/qvidcap/capture.cpp
index 6b41933e..8fff20c8 100644
--- a/utils/qvidcap/capture.cpp
+++ b/utils/qvidcap/capture.cpp
@@ -1337,9 +1337,18 @@ void CaptureWin::sockReadEvent()
 			offset += n;
 			sz -= n;
 		}
-		if (is_fwht)
-			fwht_decompress(m_ctx, dst, data_size, m_curData[p], m_curSize[p]);
-		else
+		if (is_fwht) {
+			__u32 needed_out = m_v4l_fmt.g_sizeimage(p);
+
+			if (!m_curData[p] || m_curSize[p] < needed_out) {
+				delete[] m_curData[p];
+				m_curData[p] = new __u8[needed_out];
+				m_curSize[p] = needed_out;
+			}
+
+			fwht_decompress(m_ctx, dst, data_size, m_curData[p],
+					m_curSize[p]);
+		} else
 			rle_decompress(dst, size, data_size,
 				       rle_calc_bpl(m_v4l_fmt.g_bytesperline(p), m_v4l_fmt.g_pixelformat()));
 	}
-- 
2.43.0


                 reply	other threads:[~2026-03-26  8:12 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260326081211.26562-2-s0533160580@gmail.com \
    --to=s0533160580@gmail.com \
    --cc=linux-media@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox