diff options
author | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2011-12-12 02:57:56 +0100 |
---|---|---|
committer | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2011-12-12 02:57:56 +0100 |
commit | 1ba46e0dd6192d9b879633dc5895c5910d0315cf (patch) | |
tree | 53f1317f67b9aff7901180a2cbaac9c4f4318802 /src/ufodecode.c | |
parent | 3d1bb6a8ddc5074059b37f0954faca7f9f42fda2 (diff) | |
download | libufodecode-1ba46e0dd6192d9b879633dc5895c5910d0315cf.tar.gz libufodecode-1ba46e0dd6192d9b879633dc5895c5910d0315cf.tar.bz2 libufodecode-1ba46e0dd6192d9b879633dc5895c5910d0315cf.tar.xz libufodecode-1ba46e0dd6192d9b879633dc5895c5910d0315cf.zip |
Introduce thread-safe ufo_decoder_decode_frame function
Diffstat (limited to 'src/ufodecode.c')
-rw-r--r-- | src/ufodecode.c | 100 |
1 files changed, 69 insertions, 31 deletions
diff --git a/src/ufodecode.c b/src/ufodecode.c index 5b8b874..0f1d068 100644 --- a/src/ufodecode.c +++ b/src/ufodecode.c @@ -86,7 +86,7 @@ void ufo_decoder_set_raw_data(ufo_decoder decoder, uint32_t *raw, size_t num_byt decoder->current_pos = 0; } -static int ufo_decode_frame(ufo_decoder decoder, uint16_t *pixel_buffer, uint16_t *cmask, uint32_t *raw, size_t num_words, int *offset) +static int ufo_decode_frame_channels(ufo_decoder decoder, uint16_t *pixel_buffer, uint16_t *cmask, uint32_t *raw, size_t num_words, size_t *offset) { static int channel_order[IPECAMERA_NUM_CHANNELS] = { 15, 13, 14, 12, 10, 8, 11, 7, 9, 6, 5, 2, 4, 3, 0, 1 }; static int channel_size = (2 + IPECAMERA_PIXELS_PER_CHANNEL / 3); @@ -279,46 +279,33 @@ void ufo_deinterlace_weave(const uint16_t *in1, const uint16_t *in2, uint16_t *o } + /** - * \brief Iterate and decode next frame + * \brief Decodes frame * - * This function tries to decode the next frame in the currently set raw data - * stream. + * This function tries to decode the supplied data * * \param decoder An ufo_decoder 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 0 in case of no error, ENOSR 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. + * \return number of decoded bytes or 0 in case of error */ -int ufo_decoder_get_next_frame(ufo_decoder decoder, uint16_t **pixels, uint32_t *frame_number, uint32_t *time_stamp, uint16_t *cmask) +size_t ufo_decoder_decode_frame(ufo_decoder decoder, uint32_t *raw, size_t num_bytes, uint16_t *pixels, uint32_t *frame_number, uint32_t *time_stamp, uint16_t *cmask) { - uint32_t *raw = decoder->raw; int err = 0; - size_t pos = decoder->current_pos; - int advance; - const size_t num_words = decoder->num_bytes / 4; - - if (pixels == NULL) - return EFAULT; - - if (pos >= num_words) - return ENOSR; - - if (num_words < 16) - return EILSEQ; + size_t pos = 0; + size_t advance; + const size_t num_words = num_bytes / 4; - if (*pixels == NULL) { - *pixels = (uint16_t *) malloc(IPECAMERA_WIDTH * decoder->height * sizeof(uint16_t)); - if (*pixels == NULL) - return ENOMEM; - } + if ((pixels == NULL)||(num_words < 16)) + return 0; #ifdef DEBUG CHECK_VALUE(raw[pos++], 0x51111111); @@ -331,17 +318,15 @@ int ufo_decoder_get_next_frame(ufo_decoder decoder, uint16_t **pixels, uint32_t *frame_number = raw[pos++] & 0xFFFFFFF; CHECK_VALUE(raw[pos] >> 28, 0x5); *time_stamp = raw[pos++] & 0xFFFFFFF; - if (err) - return EILSEQ; + if (err) return 0; #else *frame_number = raw[pos + 6] & 0xFFFFFFF; *time_stamp = raw[pos + 7] & 0xFFFFFFF; pos += 8; #endif - err = ufo_decode_frame(decoder, *pixels, cmask, raw + pos, num_words - pos - 8, &advance); - if (err) - return EILSEQ; + err = ufo_decode_frame_channels(decoder, pixels, cmask, raw + pos, num_words - pos - 8, &advance); + if (err) return 0; pos += advance; @@ -360,10 +345,63 @@ int ufo_decoder_get_next_frame(ufo_decoder decoder, uint16_t **pixels, uint32_t CHECK_VALUE(raw[pos++], 0x0FFFFFFF); CHECK_VALUE(raw[pos++], 0x00000000); CHECK_VALUE(raw[pos++], 0x01111111); + + if (err) return 0; #else pos += 8; #endif + return pos; +} + + + +/** + * \brief Iterate and decode next frame + * + * This function tries to decode the next frame in the currently set raw data + * stream. + * + * \param decoder An ufo_decoder instance + * \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 0 in case of no error, ENOSR 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 *frame_number, uint32_t *time_stamp, uint16_t *cmask) +{ + + uint32_t *raw = decoder->raw; + size_t pos = decoder->current_pos; + size_t advance; + const size_t num_words = decoder->num_bytes / 4; + + if (pixels == NULL) + return 0; + + if (pos >= num_words) + return ENOSR; + + if (num_words < 16) + return EILSEQ; + + if (*pixels == NULL) { + *pixels = (uint16_t *) malloc(IPECAMERA_WIDTH * decoder->height * sizeof(uint16_t)); + if (*pixels == NULL) + return ENOMEM; + } + + advance = ufo_decoder_decode_frame(decoder, raw + pos * 4, decoder->num_bytes - pos * 4, *pixels, frame_number, time_stamp, cmask); + if (!advance) + return EILSEQ; + + pos += advance; + /* if bytes left and we see fill bytes, skip them */ if (((pos + 2) < num_words) && ((raw[pos] == 0x0) && (raw[pos+1] == 0x1111111))) { pos += 2; |