summaryrefslogtreecommitdiff
path: root/src/ipa/raspberrypi/md_parser.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipa/raspberrypi/md_parser.hpp')
-rw-r--r--src/ipa/raspberrypi/md_parser.hpp178
1 files changed, 105 insertions, 73 deletions
diff --git a/src/ipa/raspberrypi/md_parser.hpp b/src/ipa/raspberrypi/md_parser.hpp
index c9db62c0..e3e27385 100644
--- a/src/ipa/raspberrypi/md_parser.hpp
+++ b/src/ipa/raspberrypi/md_parser.hpp
@@ -6,107 +6,137 @@
*/
#pragma once
+#include <initializer_list>
+#include <map>
+#include <optional>
#include <stdint.h>
-/* Camera metadata parser class. Usage as shown below.
+#include <libcamera/base/span.h>
-Setup:
-
-Usually the metadata parser will be made as part of the CamHelper class so
-application code doesn't have to worry which to kind to instantiate. But for
-the sake of example let's suppose we're parsing imx219 metadata.
-
-MdParser *parser = new MdParserImx219(); // for example
-parser->SetBitsPerPixel(bpp);
-parser->SetLineLengthBytes(pitch);
-parser->SetNumLines(2);
-
-Note 1: if you don't know how many lines there are, you can use SetBufferSize
-instead to limit the total buffer size.
-
-Note 2: if you don't know the line length, you can leave the line length unset
-(or set to zero) and the parser will hunt for the line start instead. In this
-case SetBufferSize *must* be used so that the parser won't run off the end of
-the buffer.
-
-Then on every frame:
-
-if (parser->Parse(data) != MdParser::OK)
- much badness;
-unsigned int exposure_lines, gain_code
-if (parser->GetExposureLines(exposure_lines) != MdParser::OK)
- exposure was not found;
-if (parser->GetGainCode(parser, gain_code) != MdParser::OK)
- gain code was not found;
-
-(Note that the CamHelper class converts to/from exposure lines and time,
-and gain_code / actual gain.)
-
-If you suspect your embedded data may have changed its layout, change any line
-lengths, number of lines, bits per pixel etc. that are different, and
-then:
-
-parser->Reset();
-
-before calling Parse again. */
+/*
+ * Camera metadata parser class. Usage as shown below.
+ *
+ * Setup:
+ *
+ * Usually the metadata parser will be made as part of the CamHelper class so
+ * application code doesn't have to worry which kind to instantiate. But for
+ * the sake of example let's suppose we're parsing imx219 metadata.
+ *
+ * MdParser *parser = new MdParserSmia({ expHiReg, expLoReg, gainReg });
+ * parser->SetBitsPerPixel(bpp);
+ * parser->SetLineLengthBytes(pitch);
+ * parser->SetNumLines(2);
+ *
+ * Note 1: if you don't know how many lines there are, the size of the input
+ * buffer is used as a limit instead.
+ *
+ * Note 2: if you don't know the line length, you can leave the line length unset
+ * (or set to zero) and the parser will hunt for the line start instead.
+ *
+ * Then on every frame:
+ *
+ * RegisterMap registers;
+ * if (parser->Parse(buffer, registers) != MdParser::OK)
+ * much badness;
+ * Metadata metadata;
+ * CamHelper::PopulateMetadata(registers, metadata);
+ *
+ * (Note that the CamHelper class converts to/from exposure lines and time,
+ * and gain_code / actual gain.)
+ *
+ * If you suspect your embedded data may have changed its layout, change any line
+ * lengths, number of lines, bits per pixel etc. that are different, and
+ * then:
+ *
+ * parser->Reset();
+ *
+ * before calling Parse again.
+ */
namespace RPiController {
-// Abstract base class from which other metadata parsers are derived.
+/* Abstract base class from which other metadata parsers are derived. */
class MdParser
{
public:
- // Parser status codes:
- // OK - success
- // NOTFOUND - value such as exposure or gain was not found
- // ERROR - all other errors
+ using RegisterMap = std::map<uint32_t, uint32_t>;
+
+ /*
+ * Parser status codes:
+ * OK - success
+ * NOTFOUND - value such as exposure or gain was not found
+ * ERROR - all other errors
+ */
enum Status {
OK = 0,
NOTFOUND = 1,
ERROR = 2
};
- MdParser() : reset_(true) {}
- virtual ~MdParser() {}
- void Reset() { reset_ = true; }
- void SetBitsPerPixel(int bpp) { bits_per_pixel_ = bpp; }
- void SetNumLines(unsigned int num_lines) { num_lines_ = num_lines; }
- void SetLineLengthBytes(unsigned int num_bytes)
+
+ MdParser()
+ : reset_(true), bits_per_pixel_(0), num_lines_(0), line_length_bytes_(0)
{
- line_length_bytes_ = num_bytes;
}
- void SetBufferSize(unsigned int num_bytes)
+
+ virtual ~MdParser() = default;
+
+ void Reset()
+ {
+ reset_ = true;
+ }
+
+ void SetBitsPerPixel(int bpp)
+ {
+ bits_per_pixel_ = bpp;
+ }
+
+ void SetNumLines(unsigned int num_lines)
{
- buffer_size_bytes_ = num_bytes;
+ num_lines_ = num_lines;
}
- virtual Status Parse(void *data) = 0;
- virtual Status GetExposureLines(unsigned int &lines) = 0;
- virtual Status GetGainCode(unsigned int &gain_code) = 0;
+
+ void SetLineLengthBytes(unsigned int num_bytes)
+ {
+ line_length_bytes_ = num_bytes;
+ }
+
+ virtual Status Parse(libcamera::Span<const uint8_t> buffer,
+ RegisterMap &registers) = 0;
protected:
bool reset_;
int bits_per_pixel_;
unsigned int num_lines_;
unsigned int line_length_bytes_;
- unsigned int buffer_size_bytes_;
};
-// This isn't a full implementation of a metadata parser for SMIA sensors,
-// however, it does provide the findRegs method which will prove useful and make
-// it easier to implement parsers for other SMIA-like sensors (see
-// md_parser_imx219.cpp for an example).
+/*
+ * This isn't a full implementation of a metadata parser for SMIA sensors,
+ * however, it does provide the findRegs method which will prove useful and make
+ * it easier to implement parsers for other SMIA-like sensors (see
+ * md_parser_imx219.cpp for an example).
+ */
-class MdParserSmia : public MdParser
+class MdParserSmia final : public MdParser
{
public:
- MdParserSmia() : MdParser() {}
-
-protected:
- // Note that error codes > 0 are regarded as non-fatal; codes < 0
- // indicate a bad data buffer. Status codes are:
- // PARSE_OK - found all registers, much happiness
- // MISSING_REGS - some registers found; should this be a hard error?
- // The remaining codes are all hard errors.
+ MdParserSmia(std::initializer_list<uint32_t> registerList);
+
+ MdParser::Status Parse(libcamera::Span<const uint8_t> buffer,
+ RegisterMap &registers) override;
+
+private:
+ /* Maps register address to offset in the buffer. */
+ using OffsetMap = std::map<uint32_t, std::optional<uint32_t>>;
+
+ /*
+ * Note that error codes > 0 are regarded as non-fatal; codes < 0
+ * indicate a bad data buffer. Status codes are:
+ * PARSE_OK - found all registers, much happiness
+ * MISSING_REGS - some registers found; should this be a hard error?
+ * The remaining codes are all hard errors.
+ */
enum ParseStatus {
PARSE_OK = 0,
MISSING_REGS = 1,
@@ -116,8 +146,10 @@ protected:
BAD_LINE_END = -4,
BAD_PADDING = -5
};
- ParseStatus findRegs(unsigned char *data, uint32_t regs[],
- int offsets[], unsigned int num_regs);
+
+ ParseStatus findRegs(libcamera::Span<const uint8_t> buffer);
+
+ OffsetMap offsets_;
};
} // namespace RPi