7
#include "libipe-private.h"
10
#define IPECAMERA_NUM_CHANNELS 16
11
#define IPECAMERA_PIXELS_PER_CHANNEL 128
12
#define IPECAMERA_WIDTH (IPECAMERA_NUM_CHANNELS * IPECAMERA_PIXELS_PER_CHANNEL)
15
#define CHECK_VALUE(value, expected) \
16
if (value != expected) { \
17
fprintf(stderr, "<%s:%i> 0x%x != 0x%x\n", __FILE__, __LINE__, value, expected); \
21
#define CHECK_FLAG(flag, check, ...) \
23
fprintf(stderr, "<%s:%i> Unexpected value 0x%x of " flag "\n", __FILE__, __LINE__, __VA_ARGS__); \
29
* \brief Setup a new decoder instance
31
* \param height Number of rows that are expected in the data stream
32
* \param raw The data stream from the camera or NULL if set later with
33
* ipe_decoder_set_raw_data.
34
* \param num_bytes Size of the data stream buffer in bytes
36
* \return A new decoder instance that can be used to iterate over the frames
37
* using ipe_decoder_get_next_frame.
39
ipe_decoder ipe_decoder_new(uint32_t height, uint32_t *raw, size_t num_bytes)
41
ipe_decoder decoder = malloc(sizeof(struct ipe_decoder_t));
45
decoder->height = height;
46
ipe_decoder_set_raw_data(decoder, raw, num_bytes);
52
* \brief Release decoder instance
54
* \param decoder An ipe_decoder instance
56
void ipe_decoder_free(ipe_decoder decoder)
63
* \brief Set raw data stream
65
* \param decoder An ipe_decoder instance
66
* \param raw Raw data stream
67
* \param num_bytes Size of data stream buffer in bytes
69
void ipe_decoder_set_raw_data(ipe_decoder decoder, uint32_t *raw, size_t num_bytes)
72
decoder->num_bytes = num_bytes;
73
decoder->current_pos = 0;
77
static int ipe_decode_frame(uint16_t *pixel_buffer, uint32_t *raw, int num_rows, int *offset)
79
static int channel_order[IPECAMERA_NUM_CHANNELS] = { 15, 13, 14, 12, 10, 8, 11, 7, 9, 6, 5, 2, 4, 3, 0, 1 };
89
channel = info & 0x0F;
90
row = (info >> 4) & 0x7FF;
91
int pixels = (info >> 20) & 0xFF;
93
channel = channel_order[channel];
94
int base = row * IPECAMERA_WIDTH + channel * IPECAMERA_PIXELS_PER_CHANNEL;
98
int header = (info >> 30) & 0x03; // 2 bits
99
const int bpp = (info >> 16) & 0x0F; // 4 bits
100
CHECK_FLAG("raw header magick", header == 2, header);
101
CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
102
CHECK_FLAG("channel, limited by %i output channels", channel < IPECAMERA_NUM_CHANNELS, channel, IPECAMERA_NUM_CHANNELS);
105
/* "Correct" missing pixel */
106
if ((row < 2) && (pixels == (IPECAMERA_PIXELS_PER_CHANNEL - 1))) {
107
pixel_buffer[base] = 0;
112
CHECK_FLAG("number of pixels, %i is expected", pixels == IPECAMERA_PIXELS_PER_CHANNEL, pixels, IPECAMERA_PIXELS_PER_CHANNEL);
116
/* bytes = pixels / 3; */
117
/* int ppw = pixels - bytes * 3; */
121
for (int i = 1; i < bytes; i++) {
125
header = (data >> 30) & 0x03;
126
CHECK_FLAG("raw data magick", header == 3, header);
130
pixel_buffer[base++] = (data >> 20) & 0x3FF;
131
pixel_buffer[base++] = (data >> 10) & 0x3FF;
132
pixel_buffer[base++] = data & 0x3FF;
138
header = (data >> 30) & 0x03;
139
CHECK_FLAG("raw data magick", header == 3, header);
140
CHECK_FLAG("raw footer magick", (data & 0x3FF) == 0x55, (data & 0x3FF));
145
int ppw = pixels >> 6;
146
for (int j = 0; j < ppw; j++)
147
pixel_buffer[base++] = (data >> (10 * (ppw - j))) & 0x3FF;
151
} while ((row < (num_rows - 1)) || (channel != 1));
159
* \brief Deinterlace by interpolating between two rows
161
* \param in Input frame
162
* \param out Destination of interpolated frame
163
* \param width Width of frame in pixels
164
* \param heigh Height of frame in pixels
166
void ipe_deinterlace_interpolate(const uint16_t *in, uint16_t *out, int width, int height)
168
const size_t row_size_bytes = width * sizeof(uint16_t);
170
for (int row = 0; row < height; row++) {
172
memcpy(out, in + row*width, row_size_bytes);
175
/* Interpolate between source row and row+1 */
176
for (int x = 0; x < width; x++) {
177
out[x] = (int) (0.5 * in[row*width + x] + 0.5 * in[(row+1)*width + x]);
183
memcpy(out, in + width * (height - 1), row_size_bytes);
188
* \brief Deinterlace by "weaving" the rows of two frames
190
* \param in1 First frame
191
* \param in2 Second frame
192
* \param out Destination of weaved frame
193
* \param width Width of frame in pixels
194
* \param heigh Height of frame in pixels
196
void ipe_deinterlace_weave(const uint16_t *in1, const uint16_t *in2, uint16_t *out, int width, int height)
198
const size_t row_size_bytes = width * sizeof(uint16_t);
199
for (int row = 0; row < height; row++) {
200
memcpy(out, in1 + row*width, row_size_bytes);
202
memcpy(out, in2 + row*width, row_size_bytes);
209
* \brief Iterate and decode next frame
211
* This function tries to decode the next frame in the currently set raw data
214
* \param decoder An ipe_decoder instance
215
* \param pixels If pointer with NULL content is passed, a new buffer is
216
* allocated otherwise, this user-supplied buffer is used.
217
* \param frame_number Frame number as reported in the header
218
* \param time_stamp Time stamp of the frame as reported in the header
220
* \return 0 in case of no error, ENOSR if end of stream was reached, ENOMEM if
221
* NULL was passed but no memory could be allocated, EILSEQ if data stream is
222
* corrupt and EFAULT if pixels is a NULL-pointer.
224
int ipe_decoder_get_next_frame(ipe_decoder decoder, uint16_t **pixels, uint32_t *frame_number, uint32_t *time_stamp)
227
uint32_t *raw = decoder->raw;
229
int pos = decoder->current_pos;
231
const int num_words = decoder->num_bytes / 4;
236
if (pos >= num_words)
242
if (*pixels == NULL) {
243
*pixels = (uint16_t *) malloc(IPECAMERA_WIDTH * decoder->height * sizeof(uint16_t));
249
CHECK_VALUE(raw[pos++], 0x51111111);
250
CHECK_VALUE(raw[pos++], 0x52222222);
251
CHECK_VALUE(raw[pos++], 0x53333333);
252
CHECK_VALUE(raw[pos++], 0x54444444);
253
CHECK_VALUE(raw[pos++], 0x55555555);
254
CHECK_VALUE(raw[pos++], 0x56666666);
255
CHECK_VALUE(raw[pos] >> 28, 0x5);
256
*frame_number = raw[pos++] & 0xF0000000;
257
CHECK_VALUE(raw[pos] >> 28, 0x5);
258
*time_stamp = raw[pos++] & 0xF0000000;
265
err = ipe_decode_frame(*pixels, raw + pos, decoder->height, &advance);
272
CHECK_VALUE(raw[pos++], 0x0AAAAAAA);
273
CHECK_VALUE(raw[pos++], 0x0BBBBBBB);
274
CHECK_VALUE(raw[pos++], 0x0CCCCCCC);
275
CHECK_VALUE(raw[pos++], 0x0DDDDDDD);
276
CHECK_VALUE(raw[pos++], 0x0EEEEEEE);
277
CHECK_VALUE(raw[pos++], 0x0FFFFFFF);
278
CHECK_VALUE(raw[pos++], 0x00000000);
279
CHECK_VALUE(raw[pos++], 0x01111111);
284
/* if bytes left and we see fill bytes, skip them */
285
if ((raw[pos] == 0x0) && (raw[pos+1] == 0x1111111)) {
287
while ((pos < num_words) && ((raw[pos] == 0x89abcdef) || (raw[pos] == 0x1234567)))
291
decoder->current_pos = pos;