h264-v4l2m2m: Add pixel format quirk for pi4

h264-v4l2m2m
Andri Yngvason 2024-03-16 16:50:23 +00:00
parent ddf023fd3a
commit 87b308f15f
1 changed files with 30 additions and 2 deletions

View File

@ -42,6 +42,8 @@ struct h264_encoder_v4l2m2m {
uint32_t format; uint32_t format;
int quality; // TODO: Can we affect the quality? int quality; // TODO: Can we affect the quality?
char driver[16];
int fd; int fd;
struct aml_handler* handler; struct aml_handler* handler;
@ -172,6 +174,23 @@ static uint32_t v4l2_format_from_drm(const uint32_t* formats,
#undef TRY_FORMAT #undef TRY_FORMAT
} }
// This driver mixes up pixel formats...
static uint32_t v4l2_format_from_drm_bcm2835(const uint32_t* formats,
size_t n_formats, uint32_t drm_format)
{
switch (drm_format) {
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888:
return V4L2_PIX_FMT_RGBA32;
case DRM_FORMAT_BGRX8888:
case DRM_FORMAT_BGRA8888:
// TODO: This could also be ABGR, based on how this driver
// behaves
return V4L2_PIX_FMT_BGR32;
}
return 0;
}
static int set_src_fmt(struct h264_encoder_v4l2m2m* self) static int set_src_fmt(struct h264_encoder_v4l2m2m* self)
{ {
int rc; int rc;
@ -180,7 +199,12 @@ static int set_src_fmt(struct h264_encoder_v4l2m2m* self)
size_t n_formats = get_supported_formats(self, supported_formats, size_t n_formats = get_supported_formats(self, supported_formats,
ARRAY_LENGTH(supported_formats)); ARRAY_LENGTH(supported_formats));
uint32_t format = v4l2_format_from_drm(supported_formats, n_formats, uint32_t format;
if (strcmp(self->driver, "bcm2835-codec") == 0)
format = v4l2_format_from_drm_bcm2835(supported_formats,
n_formats, self->format);
else
format = v4l2_format_from_drm(supported_formats, n_formats,
self->format); self->format);
if (!format) { if (!format) {
nvnc_log(NVNC_LOG_DEBUG, "Failed to find a proper pixel format"); nvnc_log(NVNC_LOG_DEBUG, "Failed to find a proper pixel format");
@ -507,6 +531,10 @@ static struct h264_encoder* h264_encoder_v4l2m2m_create(uint32_t width,
if (self->fd < 0) if (self->fd < 0)
goto failure; goto failure;
struct v4l2_capability cap = { 0 };
ioctl(self->fd, VIDIOC_QUERYCAP, &cap);
strncpy(self->driver, (const char*)cap.driver, sizeof(self->driver));
if (set_src_fmt(self) < 0) if (set_src_fmt(self) < 0)
goto failure; goto failure;