summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libcamera/base/log.h1
-rw-r--r--include/libcamera/ipa/ipa_interface.h4
-rw-r--r--meson.build1
-rw-r--r--src/apps/cam/main.cpp4
-rw-r--r--src/apps/common/dng_writer.cpp210
-rw-r--r--src/apps/qcam/main.cpp4
-rw-r--r--src/ipa/libipa/exposure_mode_helper.cpp9
-rw-r--r--src/ipa/libipa/matrix.cpp4
-rw-r--r--src/ipa/rpi/controller/rpi/awb.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/ccm.cpp6
-rw-r--r--src/ipa/rpi/controller/rpi/contrast.cpp4
-rw-r--r--src/libcamera/device_enumerator_sysfs.cpp2
-rw-r--r--src/libcamera/pipeline/rpi/vc4/vc4.cpp2
-rw-r--r--src/py/libcamera/py_color_space.cpp2
-rw-r--r--src/py/libcamera/py_controls_generated.cpp.in2
-rw-r--r--src/py/libcamera/py_enums.cpp2
-rw-r--r--src/py/libcamera/py_formats_generated.cpp.in2
-rw-r--r--src/py/libcamera/py_geometry.cpp2
-rw-r--r--src/py/libcamera/py_main.cpp8
-rw-r--r--src/py/libcamera/py_main.h10
-rw-r--r--src/py/libcamera/py_properties_generated.cpp.in2
-rw-r--r--src/py/libcamera/py_transform.cpp2
-rw-r--r--src/v4l2/v4l2_compat.cpp73
-rw-r--r--test/gstreamer/gstreamer_test.cpp6
-rw-r--r--test/gstreamer/meson.build7
-rw-r--r--test/ipc/unixsocket.cpp4
-rw-r--r--utils/tuning/libtuning/image.py2
27 files changed, 303 insertions, 74 deletions
diff --git a/include/libcamera/base/log.h b/include/libcamera/base/log.h
index b5775e49..df27df03 100644
--- a/include/libcamera/base/log.h
+++ b/include/libcamera/base/log.h
@@ -48,6 +48,7 @@ private:
extern const LogCategory &_LOG_CATEGORY(name)();
#define LOG_DEFINE_CATEGORY(name) \
+LOG_DECLARE_CATEGORY(name) \
const LogCategory &_LOG_CATEGORY(name)() \
{ \
/* The instance will be deleted by the Logger destructor. */ \
diff --git a/include/libcamera/ipa/ipa_interface.h b/include/libcamera/ipa/ipa_interface.h
index b93f1a15..53cf5377 100644
--- a/include/libcamera/ipa/ipa_interface.h
+++ b/include/libcamera/ipa/ipa_interface.h
@@ -33,8 +33,8 @@ public:
virtual ~IPAInterface() = default;
};
-} /* namespace libcamera */
-
extern "C" {
libcamera::IPAInterface *ipaCreate();
}
+
+} /* namespace libcamera */
diff --git a/meson.build b/meson.build
index 0ef4cdaa..2acd8c3e 100644
--- a/meson.build
+++ b/meson.build
@@ -95,6 +95,7 @@ if cc.has_header_symbol('stdlib.h', 'secure_getenv', prefix : '#define _GNU_SOUR
endif
common_arguments = [
+ '-Wmissing-declarations',
'-Wshadow',
'-include', meson.current_build_dir() / 'config.h',
]
diff --git a/src/apps/cam/main.cpp b/src/apps/cam/main.cpp
index 4f87f200..460dbc81 100644
--- a/src/apps/cam/main.cpp
+++ b/src/apps/cam/main.cpp
@@ -344,12 +344,16 @@ std::string CamApp::cameraName(const Camera *camera)
return name;
}
+namespace {
+
void signalHandler([[maybe_unused]] int signal)
{
std::cout << "Exiting" << std::endl;
CamApp::instance()->quit();
}
+} /* namespace */
+
int main(int argc, char **argv)
{
CamApp app;
diff --git a/src/apps/common/dng_writer.cpp b/src/apps/common/dng_writer.cpp
index 59f1fa23..9241f23f 100644
--- a/src/apps/common/dng_writer.cpp
+++ b/src/apps/common/dng_writer.cpp
@@ -126,7 +126,9 @@ struct Matrix3d {
float m[9];
};
-void packScanlineSBGGR8(void *output, const void *input, unsigned int width)
+namespace {
+
+void packScanlineRaw8(void *output, const void *input, unsigned int width)
{
const uint8_t *in = static_cast<const uint8_t *>(input);
uint8_t *out = static_cast<uint8_t *>(output);
@@ -134,7 +136,66 @@ void packScanlineSBGGR8(void *output, const void *input, unsigned int width)
std::copy(in, in + width, out);
}
-void packScanlineSBGGR10P(void *output, const void *input, unsigned int width)
+void packScanlineRaw10(void *output, const void *input, unsigned int width)
+{
+ const uint16_t *in = static_cast<const uint16_t *>(input);
+ uint8_t *out = static_cast<uint8_t *>(output);
+
+ for (unsigned int i = 0; i < width; i += 4) {
+ *out++ = (in[0] & 0x3fc) >> 2;
+ *out++ = (in[0] & 0x003) << 6 | (in[1] & 0x3f0) >> 4;
+ *out++ = (in[1] & 0x00f) << 4 | (in[2] & 0x3c0) >> 6;
+ *out++ = (in[2] & 0x03f) << 2 | (in[3] & 0x300) >> 8;
+ *out++ = (in[3] & 0x0ff);
+ in += 4;
+ }
+}
+
+void packScanlineRaw12(void *output, const void *input, unsigned int width)
+{
+ const uint16_t *in = static_cast<const uint16_t *>(input);
+ uint8_t *out = static_cast<uint8_t *>(output);
+
+ for (unsigned int i = 0; i < width; i += 2) {
+ *out++ = (in[0] & 0xff0) >> 4;
+ *out++ = (in[0] & 0x00f) << 4 | (in[1] & 0xf00) >> 8;
+ *out++ = (in[1] & 0x0ff);
+ in += 2;
+ }
+}
+
+void packScanlineRaw16(void *output, const void *input, unsigned int width)
+{
+ const uint16_t *in = static_cast<const uint16_t *>(input);
+ uint16_t *out = static_cast<uint16_t *>(output);
+
+ std::copy(in, in + width, out);
+}
+
+/* Thumbnail function for raw data with each pixel aligned to 16bit. */
+void thumbScanlineRaw(const FormatInfo &info, void *output, const void *input,
+ unsigned int width, unsigned int stride)
+{
+ const uint16_t *in = static_cast<const uint16_t *>(input);
+ const uint16_t *in2 = static_cast<const uint16_t *>(input) + stride / 2;
+ uint8_t *out = static_cast<uint8_t *>(output);
+
+ /* Shift down to 8. */
+ unsigned int shift = info.bitsPerSample - 8;
+
+ /* Simple averaging that produces greyscale RGB values. */
+ for (unsigned int x = 0; x < width; x++) {
+ uint16_t value = (in[0] + in[1] + in2[0] + in2[1]) >> 2;
+ value = value >> shift;
+ *out++ = value;
+ *out++ = value;
+ *out++ = value;
+ in += 16;
+ in2 += 16;
+ }
+}
+
+void packScanlineRaw10_CSI2P(void *output, const void *input, unsigned int width)
{
const uint8_t *in = static_cast<const uint8_t *>(input);
uint8_t *out = static_cast<uint8_t *>(output);
@@ -150,7 +211,7 @@ void packScanlineSBGGR10P(void *output, const void *input, unsigned int width)
}
}
-void packScanlineSBGGR12P(void *output, const void *input, unsigned int width)
+void packScanlineRaw12_CSI2P(void *output, const void *input, unsigned int width)
{
const uint8_t *in = static_cast<const uint8_t *>(input);
uint8_t *out = static_cast<uint8_t *>(output);
@@ -164,7 +225,7 @@ void packScanlineSBGGR12P(void *output, const void *input, unsigned int width)
}
}
-void thumbScanlineSBGGRxxP(const FormatInfo &info, void *output,
+void thumbScanlineRaw_CSI2P(const FormatInfo &info, void *output,
const void *input, unsigned int width,
unsigned int stride)
{
@@ -282,78 +343,150 @@ void thumbScanlineIPU3([[maybe_unused]] const FormatInfo &info, void *output,
}
}
-static const std::map<PixelFormat, FormatInfo> formatInfo = {
+const std::map<PixelFormat, FormatInfo> formatInfo = {
{ formats::SBGGR8, {
.bitsPerSample = 8,
.pattern = { CFAPatternBlue, CFAPatternGreen, CFAPatternGreen, CFAPatternRed },
- .packScanline = packScanlineSBGGR8,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw8,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SGBRG8, {
.bitsPerSample = 8,
.pattern = { CFAPatternGreen, CFAPatternBlue, CFAPatternRed, CFAPatternGreen },
- .packScanline = packScanlineSBGGR8,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw8,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SGRBG8, {
.bitsPerSample = 8,
.pattern = { CFAPatternGreen, CFAPatternRed, CFAPatternBlue, CFAPatternGreen },
- .packScanline = packScanlineSBGGR8,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw8,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SRGGB8, {
.bitsPerSample = 8,
.pattern = { CFAPatternRed, CFAPatternGreen, CFAPatternGreen, CFAPatternBlue },
- .packScanline = packScanlineSBGGR8,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw8,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
+ } },
+ { formats::SBGGR10, {
+ .bitsPerSample = 10,
+ .pattern = { CFAPatternBlue, CFAPatternGreen, CFAPatternGreen, CFAPatternRed },
+ .packScanline = packScanlineRaw10,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SGBRG10, {
+ .bitsPerSample = 10,
+ .pattern = { CFAPatternGreen, CFAPatternBlue, CFAPatternRed, CFAPatternGreen },
+ .packScanline = packScanlineRaw10,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SGRBG10, {
+ .bitsPerSample = 10,
+ .pattern = { CFAPatternGreen, CFAPatternRed, CFAPatternBlue, CFAPatternGreen },
+ .packScanline = packScanlineRaw10,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SRGGB10, {
+ .bitsPerSample = 10,
+ .pattern = { CFAPatternRed, CFAPatternGreen, CFAPatternGreen, CFAPatternBlue },
+ .packScanline = packScanlineRaw10,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SBGGR12, {
+ .bitsPerSample = 12,
+ .pattern = { CFAPatternBlue, CFAPatternGreen, CFAPatternGreen, CFAPatternRed },
+ .packScanline = packScanlineRaw12,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SGBRG12, {
+ .bitsPerSample = 12,
+ .pattern = { CFAPatternGreen, CFAPatternBlue, CFAPatternRed, CFAPatternGreen },
+ .packScanline = packScanlineRaw12,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SGRBG12, {
+ .bitsPerSample = 12,
+ .pattern = { CFAPatternGreen, CFAPatternRed, CFAPatternBlue, CFAPatternGreen },
+ .packScanline = packScanlineRaw12,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SRGGB12, {
+ .bitsPerSample = 12,
+ .pattern = { CFAPatternRed, CFAPatternGreen, CFAPatternGreen, CFAPatternBlue },
+ .packScanline = packScanlineRaw12,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SBGGR16, {
+ .bitsPerSample = 16,
+ .pattern = { CFAPatternBlue, CFAPatternGreen, CFAPatternGreen, CFAPatternRed },
+ .packScanline = packScanlineRaw16,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SGBRG16, {
+ .bitsPerSample = 16,
+ .pattern = { CFAPatternGreen, CFAPatternBlue, CFAPatternRed, CFAPatternGreen },
+ .packScanline = packScanlineRaw16,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SGRBG16, {
+ .bitsPerSample = 16,
+ .pattern = { CFAPatternGreen, CFAPatternRed, CFAPatternBlue, CFAPatternGreen },
+ .packScanline = packScanlineRaw16,
+ .thumbScanline = thumbScanlineRaw,
+ } },
+ { formats::SRGGB16, {
+ .bitsPerSample = 16,
+ .pattern = { CFAPatternRed, CFAPatternGreen, CFAPatternGreen, CFAPatternBlue },
+ .packScanline = packScanlineRaw16,
+ .thumbScanline = thumbScanlineRaw,
} },
{ formats::SBGGR10_CSI2P, {
.bitsPerSample = 10,
.pattern = { CFAPatternBlue, CFAPatternGreen, CFAPatternGreen, CFAPatternRed },
- .packScanline = packScanlineSBGGR10P,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw10_CSI2P,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SGBRG10_CSI2P, {
.bitsPerSample = 10,
.pattern = { CFAPatternGreen, CFAPatternBlue, CFAPatternRed, CFAPatternGreen },
- .packScanline = packScanlineSBGGR10P,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw10_CSI2P,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SGRBG10_CSI2P, {
.bitsPerSample = 10,
.pattern = { CFAPatternGreen, CFAPatternRed, CFAPatternBlue, CFAPatternGreen },
- .packScanline = packScanlineSBGGR10P,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw10_CSI2P,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SRGGB10_CSI2P, {
.bitsPerSample = 10,
.pattern = { CFAPatternRed, CFAPatternGreen, CFAPatternGreen, CFAPatternBlue },
- .packScanline = packScanlineSBGGR10P,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw10_CSI2P,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SBGGR12_CSI2P, {
.bitsPerSample = 12,
.pattern = { CFAPatternBlue, CFAPatternGreen, CFAPatternGreen, CFAPatternRed },
- .packScanline = packScanlineSBGGR12P,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw12_CSI2P,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SGBRG12_CSI2P, {
.bitsPerSample = 12,
.pattern = { CFAPatternGreen, CFAPatternBlue, CFAPatternRed, CFAPatternGreen },
- .packScanline = packScanlineSBGGR12P,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw12_CSI2P,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SGRBG12_CSI2P, {
.bitsPerSample = 12,
.pattern = { CFAPatternGreen, CFAPatternRed, CFAPatternBlue, CFAPatternGreen },
- .packScanline = packScanlineSBGGR12P,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw12_CSI2P,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SRGGB12_CSI2P, {
.bitsPerSample = 12,
.pattern = { CFAPatternRed, CFAPatternGreen, CFAPatternGreen, CFAPatternBlue },
- .packScanline = packScanlineSBGGR12P,
- .thumbScanline = thumbScanlineSBGGRxxP,
+ .packScanline = packScanlineRaw12_CSI2P,
+ .thumbScanline = thumbScanlineRaw_CSI2P,
} },
{ formats::SBGGR10_IPU3, {
.bitsPerSample = 16,
@@ -381,6 +514,8 @@ static const std::map<PixelFormat, FormatInfo> formatInfo = {
} },
};
+} /* namespace */
+
int DNGWriter::write(const char *filename, const Camera *camera,
const StreamConfiguration &config,
const ControlList &metadata,
@@ -522,6 +657,23 @@ int DNGWriter::write(const char *filename, const Camera *camera,
TIFFWriteDirectory(tif);
+ /*
+ * Workaround for a bug introduced in libtiff version 4.5.1 and no fix
+ * released. In these versions the CFA* tags were missing in the field
+ * info.
+ * Introduced by: https://gitlab.com/libtiff/libtiff/-/commit/738e04099b13192bb1f654e74e9b5829313f3161
+ * Fixed by: https://gitlab.com/libtiff/libtiff/-/commit/49856998c3d82e65444b47bb4fb11b7830a0c2be
+ */
+ if (!TIFFFindField(tif, TIFFTAG_CFAREPEATPATTERNDIM, TIFF_ANY)) {
+ static const TIFFFieldInfo infos[] = {
+ { TIFFTAG_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, FIELD_CUSTOM,
+ 1, 0, const_cast<char *>("CFARepeatPatternDim") },
+ { TIFFTAG_CFAPATTERN, -1, -1, TIFF_BYTE, FIELD_CUSTOM,
+ 1, 1, const_cast<char *>("CFAPattern") },
+ };
+ TIFFMergeFieldInfo(tif, infos, 2);
+ }
+
/* Create a new IFD for the RAW image. */
const uint16_t cfaRepeatPatternDim[] = { 2, 2 };
const uint8_t cfaPlaneColor[] = {
diff --git a/src/apps/qcam/main.cpp b/src/apps/qcam/main.cpp
index 9846fba5..d0bde141 100644
--- a/src/apps/qcam/main.cpp
+++ b/src/apps/qcam/main.cpp
@@ -21,6 +21,8 @@
using namespace libcamera;
+namespace {
+
void signalHandler([[maybe_unused]] int signal)
{
qInfo() << "Exiting";
@@ -52,6 +54,8 @@ OptionsParser::Options parseOptions(int argc, char *argv[])
return options;
}
+} /* namespace */
+
int main(int argc, char **argv)
{
QApplication app(argc, argv);
diff --git a/src/ipa/libipa/exposure_mode_helper.cpp b/src/ipa/libipa/exposure_mode_helper.cpp
index 683a564a..7703becc 100644
--- a/src/ipa/libipa/exposure_mode_helper.cpp
+++ b/src/ipa/libipa/exposure_mode_helper.cpp
@@ -166,7 +166,7 @@ ExposureModeHelper::splitExposure(utils::Duration exposure) const
return { minShutter_, minGain_, exposure / (minShutter_ * minGain_) };
utils::Duration shutter;
- double stageGain;
+ double stageGain = 1.0;
double gain;
for (unsigned int stage = 0; stage < gains_.size(); stage++) {
@@ -201,12 +201,9 @@ ExposureModeHelper::splitExposure(utils::Duration exposure) const
* From here on all we can do is max out the shutter time, followed by
* the analogue gain. If we still haven't achieved the target we send
* the rest of the exposure time to digital gain. If we were given no
- * stages to use then set stageGain to 1.0 so that shutter time is maxed
- * before gain touched at all.
+ * stages to use then the default stageGain of 1.0 is used so that
+ * shutter time is maxed before gain is touched at all.
*/
- if (gains_.empty())
- stageGain = 1.0;
-
shutter = clampShutter(exposure / clampGain(stageGain));
gain = clampGain(exposure / shutter);
diff --git a/src/ipa/libipa/matrix.cpp b/src/ipa/libipa/matrix.cpp
index 7f000382..8346f0d3 100644
--- a/src/ipa/libipa/matrix.cpp
+++ b/src/ipa/libipa/matrix.cpp
@@ -122,8 +122,6 @@ namespace ipa {
* \return Matrix sum of matrices \a m1 and \a m2
*/
-} /* namespace ipa */
-
#ifndef __DOXYGEN__
/*
* The YAML data shall be a list of numerical values. Its size shall be equal
@@ -146,4 +144,6 @@ bool matrixValidateYaml(const YamlObject &obj, unsigned int size)
}
#endif /* __DOXYGEN__ */
+} /* namespace ipa */
+
} /* namespace libcamera */
diff --git a/src/ipa/rpi/controller/rpi/awb.cpp b/src/ipa/rpi/controller/rpi/awb.cpp
index 003c8fa1..f45525bc 100644
--- a/src/ipa/rpi/controller/rpi/awb.cpp
+++ b/src/ipa/rpi/controller/rpi/awb.cpp
@@ -122,7 +122,7 @@ int AwbConfig::read(const libcamera::YamlObject &params)
}
if (priors.empty()) {
LOG(RPiAwb, Error) << "AwbConfig: no AWB priors configured";
- return ret;
+ return -EINVAL;
}
}
if (params.contains("modes")) {
diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp
index e673964c..aefa580c 100644
--- a/src/ipa/rpi/controller/rpi/ccm.cpp
+++ b/src/ipa/rpi/controller/rpi/ccm.cpp
@@ -113,8 +113,10 @@ void Ccm::initialise()
{
}
+namespace {
+
template<typename T>
-static bool getLocked(Metadata *metadata, std::string const &tag, T &value)
+bool getLocked(Metadata *metadata, std::string const &tag, T &value)
{
T *ptr = metadata->getLocked<T>(tag);
if (ptr == nullptr)
@@ -149,6 +151,8 @@ Matrix applySaturation(Matrix const &ccm, double saturation)
return Y2RGB * S * RGB2Y * ccm;
}
+} /* namespace */
+
void Ccm::prepare(Metadata *imageMetadata)
{
bool awbOk = false, luxOk = false;
diff --git a/src/ipa/rpi/controller/rpi/contrast.cpp b/src/ipa/rpi/controller/rpi/contrast.cpp
index 9b37943a..fe866a54 100644
--- a/src/ipa/rpi/controller/rpi/contrast.cpp
+++ b/src/ipa/rpi/controller/rpi/contrast.cpp
@@ -94,6 +94,8 @@ void Contrast::prepare(Metadata *imageMetadata)
imageMetadata->set("contrast.status", status_);
}
+namespace {
+
ipa::Pwl computeStretchCurve(Histogram const &histogram,
ContrastConfig const &config)
{
@@ -153,6 +155,8 @@ ipa::Pwl applyManualContrast(ipa::Pwl const &gammaCurve, double brightness,
return newGammaCurve;
}
+} /* namespace */
+
void Contrast::process(StatisticsPtr &stats,
[[maybe_unused]] Metadata *imageMetadata)
{
diff --git a/src/libcamera/device_enumerator_sysfs.cpp b/src/libcamera/device_enumerator_sysfs.cpp
index fc33ba52..7866885c 100644
--- a/src/libcamera/device_enumerator_sysfs.cpp
+++ b/src/libcamera/device_enumerator_sysfs.cpp
@@ -33,7 +33,7 @@ int DeviceEnumeratorSysfs::init()
int DeviceEnumeratorSysfs::enumerate()
{
struct dirent *ent;
- DIR *dir;
+ DIR *dir = nullptr;
static const char * const sysfs_dirs[] = {
"/sys/subsystem/media/devices",
diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp
index 4a89e35f..e5b6ef2b 100644
--- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp
+++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp
@@ -802,7 +802,7 @@ void Vc4CameraData::ispInputDequeue(FrameBuffer *buffer)
void Vc4CameraData::ispOutputDequeue(FrameBuffer *buffer)
{
RPi::Stream *stream = nullptr;
- unsigned int index;
+ unsigned int index = 0;
if (!isRunning())
return;
diff --git a/src/py/libcamera/py_color_space.cpp b/src/py/libcamera/py_color_space.cpp
index 5201121a..fd5a5dab 100644
--- a/src/py/libcamera/py_color_space.cpp
+++ b/src/py/libcamera/py_color_space.cpp
@@ -12,6 +12,8 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
+#include "py_main.h"
+
namespace py = pybind11;
using namespace libcamera;
diff --git a/src/py/libcamera/py_controls_generated.cpp.in b/src/py/libcamera/py_controls_generated.cpp.in
index 8d282ce5..26d5a104 100644
--- a/src/py/libcamera/py_controls_generated.cpp.in
+++ b/src/py/libcamera/py_controls_generated.cpp.in
@@ -11,6 +11,8 @@
#include <pybind11/pybind11.h>
+#include "py_main.h"
+
namespace py = pybind11;
class PyControls
diff --git a/src/py/libcamera/py_enums.cpp b/src/py/libcamera/py_enums.cpp
index e25689c6..ca6aeb86 100644
--- a/src/py/libcamera/py_enums.cpp
+++ b/src/py/libcamera/py_enums.cpp
@@ -9,6 +9,8 @@
#include <pybind11/pybind11.h>
+#include "py_main.h"
+
namespace py = pybind11;
using namespace libcamera;
diff --git a/src/py/libcamera/py_formats_generated.cpp.in b/src/py/libcamera/py_formats_generated.cpp.in
index a3f7f94d..c5fb9063 100644
--- a/src/py/libcamera/py_formats_generated.cpp.in
+++ b/src/py/libcamera/py_formats_generated.cpp.in
@@ -11,6 +11,8 @@
#include <pybind11/pybind11.h>
+#include "py_main.h"
+
namespace py = pybind11;
class PyFormats
diff --git a/src/py/libcamera/py_geometry.cpp b/src/py/libcamera/py_geometry.cpp
index 5c2aeac4..c7e30360 100644
--- a/src/py/libcamera/py_geometry.cpp
+++ b/src/py/libcamera/py_geometry.cpp
@@ -14,6 +14,8 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
+#include "py_main.h"
+
namespace py = pybind11;
using namespace libcamera;
diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
index bce08218..ab33f38a 100644
--- a/src/py/libcamera/py_main.cpp
+++ b/src/py/libcamera/py_main.cpp
@@ -85,14 +85,6 @@ PYBIND11_DECLARE_HOLDER_TYPE(T, PyCameraSmartPtr<T>)
*/
static std::weak_ptr<PyCameraManager> gCameraManager;
-void init_py_color_space(py::module &m);
-void init_py_controls_generated(py::module &m);
-void init_py_enums(py::module &m);
-void init_py_formats_generated(py::module &m);
-void init_py_geometry(py::module &m);
-void init_py_properties_generated(py::module &m);
-void init_py_transform(py::module &m);
-
PYBIND11_MODULE(_libcamera, m)
{
init_py_enums(m);
diff --git a/src/py/libcamera/py_main.h b/src/py/libcamera/py_main.h
index 5bb5f2d1..4d594326 100644
--- a/src/py/libcamera/py_main.h
+++ b/src/py/libcamera/py_main.h
@@ -7,8 +7,18 @@
#include <libcamera/base/log.h>
+#include <pybind11/pybind11.h>
+
namespace libcamera {
LOG_DECLARE_CATEGORY(Python)
}
+
+void init_py_color_space(pybind11::module &m);
+void init_py_controls_generated(pybind11::module &m);
+void init_py_enums(pybind11::module &m);
+void init_py_formats_generated(pybind11::module &m);
+void init_py_geometry(pybind11::module &m);
+void init_py_properties_generated(pybind11::module &m);
+void init_py_transform(pybind11::module &m);
diff --git a/src/py/libcamera/py_properties_generated.cpp.in b/src/py/libcamera/py_properties_generated.cpp.in
index e3802b81..d28f1ab8 100644
--- a/src/py/libcamera/py_properties_generated.cpp.in
+++ b/src/py/libcamera/py_properties_generated.cpp.in
@@ -11,6 +11,8 @@
#include <pybind11/pybind11.h>
+#include "py_main.h"
+
namespace py = pybind11;
class PyProperties
diff --git a/src/py/libcamera/py_transform.cpp b/src/py/libcamera/py_transform.cpp
index f3a0bfaf..768260ff 100644
--- a/src/py/libcamera/py_transform.cpp
+++ b/src/py/libcamera/py_transform.cpp
@@ -12,6 +12,8 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
+#include "py_main.h"
+
namespace py = pybind11;
using namespace libcamera;
diff --git a/src/v4l2/v4l2_compat.cpp b/src/v4l2/v4l2_compat.cpp
index 8e2b7e92..66468bf3 100644
--- a/src/v4l2/v4l2_compat.cpp
+++ b/src/v4l2/v4l2_compat.cpp
@@ -7,12 +7,15 @@
#include "v4l2_compat_manager.h"
+#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
+#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <unistd.h>
#include <libcamera/base/utils.h>
@@ -28,71 +31,97 @@ using namespace libcamera;
va_end(ap); \
}
+namespace {
+
+/*
+ * Determine if the flags require a further mode arguments that needs to be
+ * parsed from va_args.
+ */
+bool needs_mode(int flags)
+{
+ return (flags & O_CREAT) || ((flags & O_TMPFILE) == O_TMPFILE);
+}
+
+} /* namespace */
+
extern "C" {
LIBCAMERA_PUBLIC int open(const char *path, int oflag, ...)
{
mode_t mode = 0;
- if (oflag & O_CREAT || oflag & O_TMPFILE)
+ if (needs_mode(oflag))
extract_va_arg(mode_t, mode, oflag);
return V4L2CompatManager::instance()->openat(AT_FDCWD, path,
oflag, mode);
}
-/* _FORTIFY_SOURCE redirects open to __open_2 */
-LIBCAMERA_PUBLIC int __open_2(const char *path, int oflag)
-{
- return open(path, oflag);
-}
-
#ifndef open64
LIBCAMERA_PUBLIC int open64(const char *path, int oflag, ...)
{
mode_t mode = 0;
- if (oflag & O_CREAT || oflag & O_TMPFILE)
+ if (needs_mode(oflag))
extract_va_arg(mode_t, mode, oflag);
return V4L2CompatManager::instance()->openat(AT_FDCWD, path,
oflag | O_LARGEFILE, mode);
}
-
-LIBCAMERA_PUBLIC int __open64_2(const char *path, int oflag)
-{
- return open(path, oflag);
-}
#endif
LIBCAMERA_PUBLIC int openat(int dirfd, const char *path, int oflag, ...)
{
mode_t mode = 0;
- if (oflag & O_CREAT || oflag & O_TMPFILE)
+ if (needs_mode(oflag))
extract_va_arg(mode_t, mode, oflag);
return V4L2CompatManager::instance()->openat(dirfd, path, oflag, mode);
}
-LIBCAMERA_PUBLIC int __openat_2(int dirfd, const char *path, int oflag)
-{
- return openat(dirfd, path, oflag);
-}
-
#ifndef openat64
LIBCAMERA_PUBLIC int openat64(int dirfd, const char *path, int oflag, ...)
{
mode_t mode = 0;
- if (oflag & O_CREAT || oflag & O_TMPFILE)
+ if (needs_mode(oflag))
extract_va_arg(mode_t, mode, oflag);
return V4L2CompatManager::instance()->openat(dirfd, path,
oflag | O_LARGEFILE, mode);
}
+#endif
-LIBCAMERA_PUBLIC int __openat64_2(int dirfd, const char *path, int oflag)
+/*
+ * _FORTIFY_SOURCE redirects open* to __open*_2. Disable the
+ * -Wmissing-declarations warnings, as the functions won't be declared if
+ * _FORTIFY_SOURCE is not in use.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-declarations"
+
+LIBCAMERA_PUBLIC int __open_2(const char *path, int oflag)
+{
+ assert(!needs_mode(oflag));
+ return open(path, oflag);
+}
+
+LIBCAMERA_PUBLIC int __open64_2(const char *path, int oflag)
{
+ assert(!needs_mode(oflag));
+ return open64(path, oflag);
+}
+
+LIBCAMERA_PUBLIC int __openat_2(int dirfd, const char *path, int oflag)
+{
+ assert(!needs_mode(oflag));
return openat(dirfd, path, oflag);
}
-#endif
+
+LIBCAMERA_PUBLIC int __openat64_2(int dirfd, const char *path, int oflag)
+{
+ assert(!needs_mode(oflag));
+ return openat64(dirfd, path, oflag);
+}
+
+#pragma GCC diagnostic pop
LIBCAMERA_PUBLIC int dup(int oldfd)
{
diff --git a/test/gstreamer/gstreamer_test.cpp b/test/gstreamer/gstreamer_test.cpp
index e8119b85..a15fef0e 100644
--- a/test/gstreamer/gstreamer_test.cpp
+++ b/test/gstreamer/gstreamer_test.cpp
@@ -9,12 +9,17 @@
#include <libcamera/base/utils.h>
+#if HAVE_ASAN
+#include <sanitizer/asan_interface.h>
+#endif
+
#include "gstreamer_test.h"
#include "test.h"
using namespace std;
+#if HAVE_ASAN
extern "C" {
const char *__asan_default_options()
{
@@ -26,6 +31,7 @@ const char *__asan_default_options()
return "detect_leaks=false";
}
}
+#endif
GstreamerTest::GstreamerTest(unsigned int numStreams)
: pipeline_(nullptr), libcameraSrc_(nullptr)
diff --git a/test/gstreamer/meson.build b/test/gstreamer/meson.build
index f3ba5a23..37ad125e 100644
--- a/test/gstreamer/meson.build
+++ b/test/gstreamer/meson.build
@@ -11,8 +11,15 @@ gstreamer_tests = [
]
gstreamer_dep = dependency('gstreamer-1.0', required : true)
+gstreamer_test_args = []
+
+if asan_enabled
+ gstreamer_test_args += ['-D', 'HAVE_ASAN=1']
+endif
+
foreach test : gstreamer_tests
exe = executable(test['name'], test['sources'], 'gstreamer_test.cpp',
+ cpp_args : gstreamer_test_args,
dependencies : [libcamera_private, gstreamer_dep],
link_with : test_libraries,
include_directories : test_includes_internal)
diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp
index f44ab9c9..2546882d 100644
--- a/test/ipc/unixsocket.cpp
+++ b/test/ipc/unixsocket.cpp
@@ -34,6 +34,8 @@ using namespace libcamera;
using namespace std;
using namespace std::chrono_literals;
+namespace {
+
int calculateLength(int fd)
{
lseek(fd, 0, 0);
@@ -43,6 +45,8 @@ int calculateLength(int fd)
return size;
}
+} /* namespace */
+
class UnixSocketTestSlave
{
public:
diff --git a/utils/tuning/libtuning/image.py b/utils/tuning/libtuning/image.py
index e2181b11..6ff60ec1 100644
--- a/utils/tuning/libtuning/image.py
+++ b/utils/tuning/libtuning/image.py
@@ -79,7 +79,7 @@ class Image:
# is R, then G, then G, then B.
bayer_case = {
'0 1 1 2': (lt.Color.R, lt.Color.GR, lt.Color.GB, lt.Color.B),
- '1 2 0 1': (lt.Color.GB, lt.Color.R, lt.Color.B, lt.Color.GR),
+ '1 2 0 1': (lt.Color.GB, lt.Color.B, lt.Color.R, lt.Color.GR),
'2 1 1 0': (lt.Color.B, lt.Color.GB, lt.Color.GR, lt.Color.R),
'1 0 2 1': (lt.Color.GR, lt.Color.R, lt.Color.B, lt.Color.GB)
}