The open imaging DSP library
Loading...
Searching...
No Matches
operation.h
1/* SPDX-License-Identifier: Apache-2.0 */
7#ifndef MPIX_OP_H
8#define MPIX_OP_H
9
10#include <assert.h>
11#include <stdint.h>
12
13#include <mpix/formats.h>
14#include <mpix/port.h>
15#include <mpix/ring.h>
16#include <mpix/types.h>
17#include <mpix/pipeline.h>
18
28#define MPIX_REGISTER_OP(name, ...) MPIX_REGISTER_NB(name, ## __VA_ARGS__, P_NB)
29#define MPIX_REGISTER_NB(name, ...) enum { __VA_ARGS__ }; const size_t mpix_params_nb_##name = P_NB
30
31/* Declaration of all the parameter numbers defined in the operation files */
32#define MPIX_OP_PARAMS_NB(X, x) extern const size_t mpix_params_nb_##x;
33MPIX_FOR_EACH_OP(MPIX_OP_PARAMS_NB)
34
35/* Declaration of all the functions to add an operation to a pipeline */
36#define MPIX_OP_ADD(X, x) int mpix_add_##x(struct mpix_image *img, const int32_t *params);
37MPIX_FOR_EACH_OP(MPIX_OP_ADD)
38
39/* Declaration of all the functions to run an operation of a pipeline */
40#define MPIX_OP_RUN(X, x) int mpix_run_##x(struct mpix_base_op *op);
41MPIX_FOR_EACH_OP(MPIX_OP_RUN)
42
43
44#define MPIX_OP_INPUT_LINES(...) { int e = mpix_op_input_lines(__VA_ARGS__); if (e) return e; }
45
47#define MPIX_OP_INPUT_BYTES(...) { int e = mpix_op_input_bytes(__VA_ARGS__); if (e) return e; }
48
50#define MPIX_OP_INPUT_DONE(...) { int e = mpix_op_input_done(__VA_ARGS__); if (e) return e; }
51
53#define MPIX_OP_INPUT_PEEK(...) { int e = mpix_op_input_peek(__VA_ARGS__); if (e) return e; }
54
56#define MPIX_OP_INPUT_FLUSH(...) { int e = mpix_op_input_flush(__VA_ARGS__); if (e) return e; }
57
59#define MPIX_OP_OUTPUT_LINE(...) { int e = mpix_op_output_line(__VA_ARGS__); if (e) return e; }
60
62#define MPIX_OP_OUTPUT_DONE(...) { int e = mpix_op_output_done(__VA_ARGS__); if (e) return e; }
63
65#define MPIX_OP_OUTPUT_PEEK(...) { int e = mpix_op_output_peek(__VA_ARGS__); if (e) return e; }
66
68#define MPIX_OP_OUTPUT_FLUSH(...) { int e = mpix_op_output_flush(__VA_ARGS__); if (e) return e; }
69
70static inline int mpix_op_input_lines(struct mpix_base_op *op, const uint8_t **src, size_t num)
71{
72 /* Reset the peek position to clear any previous call from this function */
73 mpix_ring_reset_peek(&op->ring);
74
75 /* Fill every line into */
76 for (size_t i = 0; i < num; i++) {
77 src[i] = mpix_ring_peek(&op->ring, mpix_format_pitch(&op->fmt));
78 if (src[i] == NULL) return -EAGAIN;
79 }
80
81 return 0;
82}
83
84static inline int mpix_op_input_bytes(struct mpix_base_op *op, const uint8_t **src, size_t bytes)
85{
86 /* Read out the specified amount of data without clearing it from the buffer */
87 *src = mpix_ring_peek(&op->ring, bytes);
88
89 return (*src == NULL) ? -EAGAIN : 0;
90}
91
92static inline int mpix_op_input_done(struct mpix_base_op *op, size_t lines)
93{
94 /* Shift the line counter forward */
95 op->line_offset += lines;
96
97 /* Clear the requested number of lines from the input buffer */
98 const uint8_t *src = mpix_ring_read(&op->ring, mpix_format_pitch(&op->fmt) * lines);
99
100 return (src == NULL) ? -EIO : 0;
101}
102
103static inline int mpix_op_input_peek(struct mpix_base_op *op, const uint8_t **src, size_t *sz)
104{
105 /* Query the utilized buffer size */
106 *sz = mpix_ring_used_size(&op->ring);
107
108 /* Read this amount of data without clearing it out from the input buffer */
109 *src = mpix_ring_peek(&op->ring, *sz);
110
111 return (*src == NULL) ? -EIO : 0;
112}
113
114static inline int mpix_op_input_flush(struct mpix_base_op *op, size_t bytes)
115{
116 /* Clear out the specified number of bytes from the input buffer */
117 const uint8_t *src = mpix_ring_read(&op->ring, bytes);
118
119 return (src == NULL) ? -EIO : 0;
120}
121
122static inline void mpix_op_input_all(struct mpix_base_op *op, const uint8_t **src, size_t *sz)
123{
124 /* Query the utilized buffer size */
125 *sz = mpix_ring_used_size(&op->ring);
126
127 /* Read this amount of data and clear it out from the input buffer */
128 *src = mpix_ring_read(&op->ring, *sz);
129
130 /* Reset the ring buffer */
131 op->ring.head = op->ring.tail = op->ring.peek = 0;
132}
133
134static inline int mpix_op_output_peek(struct mpix_base_op *op, uint8_t **dst, size_t *sz)
135{
136 if (op->next == NULL) return -ENODEV;
137
138 /* Get the entire available buffer without clearing it */
139 *sz = mpix_ring_free_size(&op->next->ring);
140 *dst = &op->next->ring.buffer[op->next->ring.head];
141
142 return (*dst == NULL) ? -EIO : 0;
143}
144
145static inline int mpix_op_output_done(struct mpix_base_op *op)
146{
147 if (op->next == NULL) return -ENODEV;
148
149 /* Stop the counter of the current pipeline */
151
152 /* Run the rest of the pipeline */
153 int err = mpix_pipeline_run_once(op->next);
154
155 /* Start the counter again when resuming to his element */
157
158 return err;
159}
160
161static inline int mpix_op_output_line(struct mpix_base_op *op, uint8_t **dst)
162{
163 if (op->next == NULL) return -ENODEV;
164
165 /* Get one line from the output buffer */
166 *dst = mpix_ring_write(&op->next->ring, mpix_format_pitch(&op->next->fmt));
167
168 return (*dst == NULL) ? -ENOBUFS : 0;
169}
170
171static inline int mpix_op_output_flush(struct mpix_base_op *op, size_t bytes)
172{
173 if (op->next == NULL) return -ENODEV;
174
175 /* Clear out the specified number of bytes from the output buffer */
176 uint8_t *dst = mpix_ring_write(&op->next->ring, bytes);
177
178 return (dst == NULL) ? -ENOBUFS : 0;
179}
180
188static inline void *mpix_op_append(struct mpix_image *img, enum mpix_op_type op_type, size_t op_sz,
189 size_t buf_sz)
190{
191 struct mpix_base_op *op;
192
193 op = mpix_port_alloc(op_sz);
194 if (op == NULL) {
195 return NULL;
196 }
197 memset(op, 0x00, op_sz);
198
199 op->type = op_type;
200 op->fmt = img->fmt;
201 op->ring.size = buf_sz;
202
203 if (img->last_op != NULL) {
204 img->last_op->next = op;
205 }
206 if (img->first_op == NULL) {
207 img->first_op = op;
208 }
209 img->last_op = op;
210
211 return op;
212}
213
214#endif
static size_t mpix_format_pitch(const struct mpix_format *fmt)
Get the pitch for a given pixel format.
Definition formats.h:601
static void * mpix_op_append(struct mpix_image *img, enum mpix_op_type op_type, size_t op_sz, size_t buf_sz)
Allocate a new operation and add it to an image pipeline.
Definition operation.h:188
uint32_t mpix_port_get_uptime_us(void)
Get the uptime in microsecond, used to compute performance statistics.
void * mpix_port_alloc(size_t size)
Allocate a buffer to use with libmpix.
mpix_op_type
MPIX operation type identifying an operation family.
Definition types.h:21
One step of a line operation pipeline.
Definition types.h:111
struct mpix_base_op * next
Definition types.h:113
uint16_t line_offset
Definition types.h:119
struct mpix_ring ring
Definition types.h:121
uint32_t total_time_us
Definition types.h:125
uint32_t start_time_us
Definition types.h:123
enum mpix_op_type type
Definition types.h:115
struct mpix_format fmt
Definition types.h:117
Represent the image currently being processed.
Definition types.h:136
struct mpix_base_op * first_op
Definition types.h:138
struct mpix_base_op * last_op
Definition types.h:140
struct mpix_format fmt
Definition types.h:146
size_t peek
Definition types.h:96
uint8_t * buffer
Definition types.h:88
size_t head
Definition types.h:92
size_t size
Definition types.h:90
size_t tail
Definition types.h:94