summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ufodecode-private.h3
-rw-r--r--src/ufodecode.c101
-rw-r--r--src/ufodecode.h76
3 files changed, 102 insertions, 78 deletions
diff --git a/src/ufodecode-private.h b/src/ufodecode-private.h
index 4d0eb9b..c948ae8 100644
--- a/src/ufodecode-private.h
+++ b/src/ufodecode-private.h
@@ -3,13 +3,12 @@
#include <stdbool.h>
-struct ufo_decoder_t {
+struct _UfoDecoder {
int32_t height;
uint32_t width;
uint32_t *raw;
size_t num_bytes;
uint32_t current_pos;
- uint32_t old_time_stamp;
};
diff --git a/src/ufodecode.c b/src/ufodecode.c
index efb7970..dd32695 100644
--- a/src/ufodecode.c
+++ b/src/ufodecode.c
@@ -69,20 +69,19 @@ typedef struct {
* \return A new decoder instance that can be used to iterate over the frames
* using ufo_decoder_get_next_frame.
*/
-ufo_decoder
+UfoDecoder *
ufo_decoder_new (int32_t height, uint32_t width, uint32_t *raw, size_t num_bytes)
{
if (width % IPECAMERA_PIXELS_PER_CHANNEL)
return NULL;
- ufo_decoder decoder = malloc(sizeof(struct ufo_decoder_t));
+ UfoDecoder *decoder = malloc(sizeof(UfoDecoder));
if (decoder == NULL)
return NULL;
decoder->width = width;
decoder->height = height;
- decoder->old_time_stamp = 0;
ufo_decoder_set_raw_data(decoder, raw, num_bytes);
return decoder;
}
@@ -90,10 +89,10 @@ ufo_decoder_new (int32_t height, uint32_t width, uint32_t *raw, size_t num_bytes
/**
* \brief Release decoder instance
*
- * \param decoder An ufo_decoder instance
+ * \param decoder An UfoDecoder instance
*/
void
-ufo_decoder_free(ufo_decoder decoder)
+ufo_decoder_free(UfoDecoder *decoder)
{
free(decoder);
}
@@ -101,12 +100,12 @@ ufo_decoder_free(ufo_decoder decoder)
/**
* \brief Set raw data stream
*
- * \param decoder An ufo_decoder instance
+ * \param decoder An UfoDecoder instance
* \param raw Raw data stream
* \param num_bytes Size of data stream buffer in bytes
*/
void
-ufo_decoder_set_raw_data(ufo_decoder decoder, uint32_t *raw, size_t num_bytes)
+ufo_decoder_set_raw_data(UfoDecoder *decoder, uint32_t *raw, size_t num_bytes)
{
decoder->raw = raw;
decoder->num_bytes = num_bytes;
@@ -114,9 +113,8 @@ ufo_decoder_set_raw_data(ufo_decoder decoder, uint32_t *raw, size_t num_bytes)
}
static int
-ufo_decode_frame_channels_v0(ufo_decoder decoder,
+ufo_decode_frame_channels_v0(UfoDecoder *decoder,
uint16_t *pixel_buffer,
- uint16_t *cmask,
uint32_t *raw,
size_t num_words,
size_t *offset)
@@ -159,9 +157,6 @@ ufo_decode_frame_channels_v0(ufo_decoder decoder,
CHECK_FLAG("row number, only %i rows requested", row < num_rows, row, num_rows);
CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
CHECK_FLAG("channel, limited by %zu output channels", channel < cpl, channel, cpl);
- CHECK_FLAG("channel (line %i), duplicate entry",
- (!cmask) || (cmask[row] & (1<<channel_order[channel])) == 0,
- channel_order[channel], row);
#endif
if ((row > num_rows) || (channel > cpl) || (pixels > IPECAMERA_PIXELS_PER_CHANNEL))
@@ -170,9 +165,6 @@ ufo_decode_frame_channels_v0(ufo_decoder decoder,
channel = channel_order[channel];
int base = row * IPECAMERA_WIDTH + channel * IPECAMERA_PIXELS_PER_CHANNEL;
- if (cmask)
- cmask[row] |= (1 << channel);
-
/* "Correct" missing pixel */
if ((row < 2) && (pixels == (IPECAMERA_PIXELS_PER_CHANNEL - 1))) {
pixel_buffer[base] = 0;
@@ -259,9 +251,8 @@ ufo_decode_frame_channels_v0(ufo_decoder decoder,
}
static int
-ufo_decode_frame_channels_v4(ufo_decoder decoder,
+ufo_decode_frame_channels_v4(UfoDecoder *decoder,
uint16_t *pixel_buffer,
- uint16_t *cmask,
uint32_t *raw,
size_t num_words,
size_t num_rows,
@@ -307,9 +298,6 @@ ufo_decode_frame_channels_v4(ufo_decoder decoder,
CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
CHECK_FLAG("channel, limited by %zu output channels", channel < channels_per_row, channel, channels_per_row);
- CHECK_FLAG("channel (line %i), duplicate entry",
- (!cmask) || (cmask[row] & (1 << channel_order[channel])) == 0,
- channel_order[channel], row);
#endif
if ((channel > channels_per_row) || (pixels > IPECAMERA_PIXELS_PER_CHANNEL))
@@ -318,9 +306,6 @@ ufo_decode_frame_channels_v4(ufo_decoder decoder,
channel = channel_order[channel];
int base = row * IPECAMERA_WIDTH + channel * IPECAMERA_PIXELS_PER_CHANNEL;
- if (cmask)
- cmask[row] |= (1 << channel);
-
/* "Correct" missing pixel */
if ((row < 2) && (pixels == (IPECAMERA_PIXELS_PER_CHANNEL - 1))) {
pixel_buffer[base] = 0;
@@ -407,9 +392,8 @@ ufo_decode_frame_channels_v4(ufo_decoder decoder,
}
static int
-ufo_decode_frame_channels_v5(ufo_decoder decoder,
+ufo_decode_frame_channels_v5(UfoDecoder *decoder,
uint16_t *pixel_buffer,
- uint16_t *cmask,
uint32_t *raw,
size_t num_words,
size_t num_rows,
@@ -549,25 +533,21 @@ void ufo_deinterlace_weave(const uint16_t *in1, const uint16_t *in2, uint16_t *o
*
* This function tries to decode the supplied data
*
- * \param decoder An ufo_decoder instance
+ * \param decoder An UfoDecoder instance
* \param raw Raw data stream
* \param num_bytes Size of data stream buffer in bytes
* \param pixels If pointer with NULL content is passed, a new buffer is
* allocated otherwise, this user-supplied buffer is used.
* \param frame_number Frame number as reported in the header
* \param time_stamp Time stamp of the frame as reported in the header
- * \paran cmask Change-mask
*
* \return number of decoded bytes or 0 in case of error
*/
-size_t ufo_decoder_decode_frame(ufo_decoder decoder,
- uint32_t *raw,
- size_t num_bytes,
- uint16_t *pixels,
- uint32_t *num_rows,
- uint32_t *frame_number,
- uint32_t *time_stamp,
- uint16_t *cmask)
+size_t ufo_decoder_decode_frame(UfoDecoder *decoder,
+ uint32_t *raw,
+ size_t num_bytes,
+ uint16_t *pixels,
+ UfoDecoderMeta *meta)
{
int err = 0;
size_t pos = 0;
@@ -591,19 +571,22 @@ size_t ufo_decoder_decode_frame(ufo_decoder decoder,
case 0:
CHECK_VALUE(raw[pos++], 0x56666666);
CHECK_VALUE(raw[pos] >> 28, 0x5);
- *frame_number = raw[pos++] & 0xFFFFFFF;
+ meta->frame_number = raw[pos++] & 0xFFFFFFF;
CHECK_VALUE(raw[pos] >> 28, 0x5);
- *time_stamp = raw[pos++] & 0xFFFFFFF;
+ meta->time_stamp = raw[pos++] & 0xFFFFFFF;
break;
case 4:
case 5:
CHECK_VALUE(raw[pos] >> 28, 0x5);
- rows_per_frame = raw[pos] & 0x7FF;
+ meta->cmosis_start_address = (raw[pos] >> 21) & 0x1FF;
+ meta->n_skipped_rows = (raw[pos] >> 15) & 0x3F;
+ meta->n_rows = rows_per_frame = raw[pos] & 0x7FF;
pos++;
- *frame_number = raw[pos++] & 0x1FFFFFF;
+
+ meta->frame_number = raw[pos++] & 0x1FFFFFF;
CHECK_VALUE(raw[pos] >> 24, 0x50);
- *time_stamp = raw[pos++] & 0xFFFFFF;
+ meta->time_stamp = raw[pos++] & 0xFFFFFF;
break;
default:
@@ -616,13 +599,13 @@ size_t ufo_decoder_decode_frame(ufo_decoder decoder,
#else
switch (version) {
case 0:
- *frame_number = raw[pos + 6] & 0xFFFFFFF;
- *time_stamp = raw[pos + 7] & 0xFFFFFFF;
+ meta->frame_number = raw[pos + 6] & 0xFFFFFFF;
+ meta->time_stamp = raw[pos + 7] & 0xFFFFFFF;
break;
case 4:
case 5:
- *frame_number = raw[pos + 6] & 0x1FFFFFF;
- *time_stamp = raw[pos + 7] & 0xFFFFFF;
+ meta->frame_number = raw[pos + 6] & 0x1FFFFFF;
+ meta->time_stamp = raw[pos + 7] & 0xFFFFFF;
break;
default:
fprintf(stderr, "Unsupported data format detected\n");
@@ -632,17 +615,15 @@ size_t ufo_decoder_decode_frame(ufo_decoder decoder,
pos += 8;
#endif
- *num_rows = rows_per_frame;
-
switch (version) {
case 0:
- err = ufo_decode_frame_channels_v0(decoder, pixels, cmask, raw + pos, num_words - pos - 8, &advance);
+ err = ufo_decode_frame_channels_v0(decoder, pixels, raw + pos, num_words - pos - 8, &advance);
break;
case 4:
- err = ufo_decode_frame_channels_v4(decoder, pixels, cmask, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
+ err = ufo_decode_frame_channels_v4(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
break;
case 5:
- err = ufo_decode_frame_channels_v5(decoder, pixels, cmask, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
+ err = ufo_decode_frame_channels_v5(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
break;
default:
break;
@@ -655,10 +636,11 @@ size_t ufo_decoder_decode_frame(ufo_decoder decoder,
#ifdef CHECKS
CHECK_VALUE(raw[pos++], 0x0AAAAAAA);
+
+ meta->status1.bits = raw[pos++];
+ meta->status2.bits = raw[pos++];
+ meta->status3.bits = raw[pos++];
pos++;
- pos++; /* 0x840dffff expected */
- pos++; /* 0x0f001001 expected */
- pos++; /* 0x28000111 explains problems if status2 is wrong */
pos++;
CHECK_VALUE(raw[pos++], 0x00000000);
CHECK_VALUE(raw[pos++], 0x01111111);
@@ -678,24 +660,20 @@ size_t ufo_decoder_decode_frame(ufo_decoder decoder,
* This function tries to decode the next frame in the currently set raw data
* stream.
*
- * \param decoder An ufo_decoder instance
+ * \param decoder An UfoDecoder instance
* \param pixels If pointer with NULL content is passed, a new buffer is
* allocated otherwise, this user-supplied buffer is used.
* \param num_rows Number of actual decoded rows
* \param frame_number Frame number as reported in the header
* \param time_stamp Time stamp of the frame as reported in the header
- * \paran cmask Change-mask
*
* \return 0 in case of no error, EIO if end of stream was reached, ENOMEM if
* NULL was passed but no memory could be allocated, EILSEQ if data stream is
* corrupt and EFAULT if pixels is a NULL-pointer.
*/
-int ufo_decoder_get_next_frame(ufo_decoder decoder,
- uint16_t **pixels,
- uint32_t *num_rows,
- uint32_t *frame_number,
- uint32_t *time_stamp,
- uint16_t *cmask)
+int ufo_decoder_get_next_frame(UfoDecoder *decoder,
+ uint16_t **pixels,
+ UfoDecoderMeta *meta)
{
uint32_t *raw = decoder->raw;
size_t pos = decoder->current_pos;
@@ -720,8 +698,7 @@ int ufo_decoder_get_next_frame(ufo_decoder decoder,
while ((pos < num_words) && (raw[pos] != 0x51111111))
pos++;
- advance = ufo_decoder_decode_frame(decoder, raw + pos, decoder->num_bytes -
- pos, *pixels, num_rows, frame_number, time_stamp, cmask);
+ advance = ufo_decoder_decode_frame(decoder, raw + pos, decoder->num_bytes - pos, *pixels, meta);
/*
* On error, advance is 0 but we have to advance at least a bit to net get
diff --git a/src/ufodecode.h b/src/ufodecode.h
index bce17ec..38ea85a 100644
--- a/src/ufodecode.h
+++ b/src/ufodecode.h
@@ -3,34 +3,82 @@
#include <inttypes.h>
-typedef struct ufo_decoder_t *ufo_decoder;
+typedef struct _UfoDecoder UfoDecoder;
+
+typedef struct {
+ unsigned dummy1:2;
+ unsigned fsm_master_readout:4;
+ unsigned dummy2:4;
+ unsigned fsm_daq:4;
+ unsigned pixel_full:1;
+ unsigned control_lock:1;
+ unsigned data_lock:16;
+} UfoDecoderStatus1;
+
+typedef struct {
+ unsigned end_of_frames:1;
+ unsigned busy_or:1;
+ unsigned busy_ddr:1;
+ unsigned busy_interl:1;
+ unsigned error_status:4; /* What the heck? */
+ unsigned data_fifo_read_count:10;
+ unsigned data_fifo_full:1;
+ unsigned data_fifo_empty:1;
+ unsigned dummy:2;
+ unsigned ddr_fifo_write_count:8;
+ unsigned ddr_fifo_full:1;
+ unsigned ddr_fifo_empty:1;
+} UfoDecoderStatus2;
+
+typedef struct {
+ unsigned dummy:2;
+ unsigned row_counter:10;
+ unsigned pixel_counter:8;
+ unsigned ddr_read:4;
+ unsigned ddr_write:4;
+ unsigned ddr_arbiter:4;
+} UfoDecoderStatus3;
+
+typedef struct {
+ uint32_t frame_number;
+ uint32_t time_stamp;
+ uint32_t n_rows;
+ uint8_t n_skipped_rows;
+ uint16_t cmosis_start_address;
+ union {
+ uint32_t bits;
+ UfoDecoderStatus1 desc;
+ } status1;
+ union {
+ uint32_t bits;
+ UfoDecoderStatus2 desc;
+ } status2;
+ union {
+ uint32_t bits;
+ UfoDecoderStatus3 desc;
+ } status3;
+} UfoDecoderMeta;
#ifdef __cplusplus
extern "C" {
#endif
-ufo_decoder ufo_decoder_new (int32_t height,
+UfoDecoder *ufo_decoder_new (int32_t height,
uint32_t width,
uint32_t *raw,
size_t num_bytes);
-void ufo_decoder_free (ufo_decoder decoder);
-size_t ufo_decoder_decode_frame (ufo_decoder decoder,
+void ufo_decoder_free (UfoDecoder *decoder);
+size_t ufo_decoder_decode_frame (UfoDecoder *decoder,
uint32_t *raw,
size_t num_bytes,
uint16_t *pixels,
- uint32_t *num_rows,
- uint32_t *frame_number,
- uint32_t *time_stamp,
- uint16_t *cmask);
-void ufo_decoder_set_raw_data (ufo_decoder decoder,
+ UfoDecoderMeta *meta);
+void ufo_decoder_set_raw_data (UfoDecoder *decoder,
uint32_t *raw,
size_t num_bytes);
-int ufo_decoder_get_next_frame (ufo_decoder decoder,
+int ufo_decoder_get_next_frame (UfoDecoder *decoder,
uint16_t **pixels,
- uint32_t *num_rows,
- uint32_t *frame_number,
- uint32_t *time_stamp,
- uint16_t *cmask);
+ UfoDecoderMeta *meta_data);
void ufo_deinterlace_interpolate (const uint16_t *frame_in,
uint16_t *frame_out,
int width,