Skip to content

Conversation

ngphibang
Copy link
Contributor

  • Add a size field into video_format struct.
  • Video receiver drivers now need to set the format's size to expose to application. Application should base on the format size to allocate buffers. The caps' min/max_line_count fields (which are needed only for HWs that cannot support the whole image frame) can hence be dropped.

@avolmat-st
Copy link

It seems to me that currently there is a hole if a sensor provides a compressed format (ex: OV5640 which is capable, from a HW point of view, to provide JPEG data).
In such case, a receiver should not check base its calculation on the width, video_bits_per_pixel and height but rather directly on the size value provided by the source itself since, in case of compressed data there is just no way to figure out what could be size. The best entity to estimate this is the producer of the data, right ?

So, if the video_bits_per_pixel reports a non zero value, a receiver can estimate the pitch and size (as done in this PR), however if the video_bits_per_pixel is zero (as it would be in case of JPEG), then we cannot apply this calculation and need to get this from another way. (either from the sensor itself, since it could estimate it itself, knowing the quality settings etc etc, or by a rather simple estimation in each receiver, but not based on the video_bits_per_pixel).

@decsny decsny removed their request for review October 8, 2025 13:36
@ngphibang
Copy link
Contributor Author

ngphibang commented Oct 8, 2025

It seems to me that currently there is a hole if a sensor provides a compressed format (ex: OV5640 which is capable, from a HW point of view, to provide JPEG data)...

Yes, we should distinguish uncompressed vs compressed formats (can be based on fmt->pitch or video_bits_per_pixel).
For compressed formats, the size will be an estimate for the worse case as described in the fmt->field size. But the estimation will be added later when support for compressed image in sensors are added (e.g. ov5640).

Will update.

@avolmat-st
Copy link

It seems to me that currently there is a hole if a sensor provides a compressed format (ex: OV5640 which is capable, from a HW point of view, to provide JPEG data)...

Yes, we should distinguish uncompressed vs compressed formats (can be based on fmt->pitch or video_bits_per_pixel). For compressed formats, the size will be an estimate for the worse case as described in the fmt->field size. Will update.

Yes. Cannot be done on the pitch value I think since pitch is related to the way it is organized into memory, which is not applicable for sensors (which do not write themselves into memory). Hence my proposal to look at video_bits_per_pixel.
It is assume that sensor would not set the pitch. For uncompressed format, sensor do not need to set fmt.size, however for compressed format they will have to set fmt.size to give a worst case frame size.

Copy link
Contributor

@josuah josuah left a comment

Choose a reason for hiding this comment

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

https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/video/video_shell.c
This has a print statement for logging the max count

https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/video/video_emul_rx.c
This will be needing some conversion too, useful for testing this change on CI.

This sounds like a better solution than what I proposed here IMHO #92884 (comment)

avolmat-st
avolmat-st previously approved these changes Oct 9, 2025
Copy link

@avolmat-st avolmat-st left a comment

Choose a reason for hiding this comment

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

Thanks @ngphibang. All good to me.

@ngphibang ngphibang force-pushed the add_fmt_size branch 3 times, most recently from 73736a2 to ffea025 Compare October 10, 2025 07:27
@ngphibang
Copy link
Contributor Author

Dropped caps' min_line_count in the recently merged VENC driver.

@ngphibang ngphibang added this to the v4.3.0 milestone Oct 10, 2025
@ngphibang
Copy link
Contributor Author

Added 4.3 milestone as #95862 was merged which requires drivers to set format size

@josuah josuah requested a review from avolmat-st October 10, 2025 09:25
josuah
josuah previously approved these changes Oct 10, 2025
return -EINVAL;
}

fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;
Copy link
Contributor

Choose a reason for hiding this comment

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

Good idea to also set the pitch.

* For compressed formats, it gives a rough estimate size of a complete
* compressed frame.
*
* @param fmt The video format

Choose a reason for hiding this comment

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

What about

@param fmt Pointer to video format struct

so that we use same wording as for other helpers.

return -EINVAL;
}

fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;

Choose a reason for hiding this comment

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

This fmt->pitch could be done within the default case since it doesn't make sense for the JPEG part for which this will always lead to 0. Thus what about setting fmt->pitch = 0 for JPEG instead ?

fmt->size = fmt->width * fmt->height * 2;
return 0;
default:
if (fmt->pitch != 0) {
Copy link

@avolmat-st avolmat-st Oct 10, 2025

Choose a reason for hiding this comment

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

Doing the opposite test, aka if (fmt->pitch == 0) { return -ENOSUP; } would allow to have less { } { } and keep the expected behavior code with less indentation.

Aka something like:

        switch (fmt->pixelformat) {
        case VIDEO_PIX_FMT_JPEG:
                /* Rough estimate for the worst case (quality = 100) */
                fmt->pitch = 0;
                fmt->size = fmt->width * fmt->height * 2;
                break;
        default:
                /* Uncompressed format */
                fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;
                if (fmt->pitch == 0) {
                        return -ENOTSUP;
                }
                fmt->size = fmt->pitch * fmt->height;
                break;
        }

        return 0;

Copy link

@avolmat-st avolmat-st Oct 10, 2025

Choose a reason for hiding this comment

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

Oups, noticed break were missing here ;) Updated.

}

/* Cache the format selected locally to use it for getting the size of the buffer */
fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;

Choose a reason for hiding this comment

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

To be replaced by video_estimate_fmt_size call ?

break;
}

fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;

Choose a reason for hiding this comment

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

To be replaced by video_estimate_fmt_size ?

return ret;
}

fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;

Choose a reason for hiding this comment

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

Use video_estimate_fmt_size ?

return -EIO;
}

fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;

Choose a reason for hiding this comment

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

Use video_estimate_fmt_size ?

return ret;
}

fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;

Choose a reason for hiding this comment

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

Use video_estimate_fmt_size ?


*fmt = data->fmt;

fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;

Choose a reason for hiding this comment

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

Use video_estimate_fmt_size ?

@ngphibang ngphibang force-pushed the add_fmt_size branch 2 times, most recently from 3b29e74 to da0ba92 Compare October 10, 2025 13:22
/* Rough estimate for the worst case (quality = 100) */
fmt->pitch = 0;
fmt->size = fmt->width * fmt->height * 2;
return 0;

Choose a reason for hiding this comment

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

return 0 at the end of the function seems better to me since currently a rapid look is showing that nothing is returned.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It returns for all cases and the compiler does not complain. I think if we return at the end, we need to do "break;" and this will take more lines, just that.

Choose a reason for hiding this comment

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

Yeah I wasn't pointing that a return was missing, I am only pointing that this feel as if there were a return missing at the end since this is a non void function which finish with

     }
}

I'd feel better to have in such case only one return.


/* Cache the format selected locally to use it for getting the size of the buffer */
fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;
ret = video_estimate_fmt_size(fmt);

Choose a reason for hiding this comment

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

Ok for this part. However I think similar one is missing in the init function of this driver since doing a get_fmt without a set first will lead just read copy the fmt structure initialized during the init, into which only pitch is set. Hence video_estimate_fmt_size can simply be called during the _init function instead of the existing fmt->pitch set.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it lacks a call in init(), will add it, but we still need to call video_estimate_fmt_size() in each set_format() because the call in init() is only for the default format.

Choose a reason for hiding this comment

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

Yes agree. I just used this part to comment since I couldn't point the _init section of course ;)

}

fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE;
video_estimate_fmt_size(fmt);

Choose a reason for hiding this comment

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

Ok. However it seems to me that video_estimate_fmt_size call is missing the in get_fmt function, in case of CONFIG_VIDEO_MCUX_MIPI_CSI2RX is not defined. In such situation result of the video_get_format from the source device is returned straight.

Add a helper to estimate format size and pitch.

Signed-off-by: Phi Bang Nguyen <[email protected]>
Receiver drivers now need to set the format's size to expose it to
the application.

Application should base on the format size to allocate buffers. The
caps' min/max_line_count (which are needed only for HWs that cannot
support the whole image frame) can hence be dropped.

Signed-off-by: Phi Bang Nguyen <[email protected]>
The mipid02 is just a bridge driver which does not deal with memory so
should not expose caps' min_vbuf_count.

Signed-off-by: Phi Bang Nguyen <[email protected]>
Mention some dropped fields in the video_caps structure and the buffer
allocation size for application.

Signed-off-by: Phi Bang Nguyen <[email protected]>
Mention a new video_estimate_fmt_size helper.

Signed-off-by: Phi Bang Nguyen <[email protected]>
Copy link

@avolmat-st avolmat-st left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks a lot.

Copy link

@avolmat-st
Copy link

Regarding the new issue reported, we might want to add more compressed format in the future in this generic helper so I propose to not take it into account.

@cfriedt cfriedt merged commit c1a27a1 into zephyrproject-rtos:main Oct 10, 2025
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Samples Samples area: USB Universal Serial Bus area: Video Video subsystem platform: ESP32 Espressif ESP32 platform: NXP NXP platform: Renesas RA Renesas Electronics Corporation, RA platform: STM32 ST Micro STM32 Release Notes To be mentioned in the release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants