From: Uwe Hermann Date: Thu, 20 Aug 2015 17:36:12 +0000 (+0200) Subject: Pass unitsize per sample chunk. X-Git-Tag: libsigrokdecode-0.4.0~92 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=cda2d36cfeed3f921252ffa95377529d6bdc074b;p=libsigrokdecode.git Pass unitsize per sample chunk. Don't pass unitsize to srd_inst_channel_set_all(), have that only set the channel map. Instead, srd_session_send() now has a parameter for the unitsize which is passed with every new chunk to be decoded. This is in preparation to fix issues with devices or files which have a unitsize != 1 and where the "guessed" unitsize based on the number of channels is not correct. This also allows for (potential) future changes where every chunk can indeed have a different unitsize. This fixes (parts of) bug #352. --- diff --git a/instance.c b/instance.c index f99cd68..bfe9142 100644 --- a/instance.c +++ b/instance.c @@ -187,16 +187,13 @@ static gint compare_channel_id(const struct srd_channel *pdch, * @param new_channels A GHashTable of channels to set. Key is channel name, * value is the channel number. Samples passed to this * instance will be arranged in this order. - * @param unit_size Number of bytes per sample in the data stream to be passed - * to the decoder. The highest channel index specified in the - * channel map must lie within a sample unit. * * @return SRD_OK upon success, a (negative) error code otherwise. * - * @since 0.3.0 + * @since 0.4.0 */ SRD_API int srd_inst_channel_set_all(struct srd_decoder_inst *di, - GHashTable *new_channels, int unit_size) + GHashTable *new_channels) { GVariant *channel_val; GList *l; @@ -205,9 +202,8 @@ SRD_API int srd_inst_channel_set_all(struct srd_decoder_inst *di, int *new_channelmap, new_channelnum, num_required_channels, i; char *channel_id; - srd_dbg("Setting channels for instance %s with list of %d channels, " - "unitsize %d.", di->inst_id, g_hash_table_size(new_channels), - unit_size); + srd_dbg("Setting channels for instance %s with list of %d channels.", + di->inst_id, g_hash_table_size(new_channels)); if (g_hash_table_size(new_channels) == 0) /* No channels provided. */ @@ -240,12 +236,6 @@ SRD_API int srd_inst_channel_set_all(struct srd_decoder_inst *di, return SRD_ERR_ARG; } new_channelnum = g_variant_get_int32(channel_val); - if (new_channelnum >= 8 * unit_size) { - srd_err("Channel index %d not within data unit (%d bit).", - new_channelnum, 8 * unit_size); - g_free(new_channelmap); - return SRD_ERR_ARG; - } if (!(sl = g_slist_find_custom(di->decoder->channels, channel_id, (GCompareFunc)compare_channel_id))) { /* Fall back on optional channels. */ @@ -262,7 +252,6 @@ SRD_API int srd_inst_channel_set_all(struct srd_decoder_inst *di, srd_dbg("Setting channel mapping: %s (index %d) = channel %d.", pdch->id, pdch->order, new_channelnum); } - di->data_unitsize = unit_size; srd_dbg("Final channel map:"); num_required_channels = g_slist_length(di->decoder->channels); @@ -342,7 +331,6 @@ SRD_API struct srd_decoder_inst *srd_inst_new(struct srd_session *sess, g_malloc(sizeof(int) * di->dec_num_channels); for (i = 0; i < di->dec_num_channels; i++) di->dec_channelmap[i] = i; - di->data_unitsize = (di->dec_num_channels + 7) / 8; /* * Will be used to prepare a sample at every iteration * of the instance's decode() method. @@ -543,20 +531,23 @@ SRD_PRIV int srd_inst_start(struct srd_decoder_inst *di) * set, relative to the start of capture. * @param inbuf The buffer to decode. Must not be NULL. * @param inbuflen Length of the buffer. Must be > 0. + * @param unitsize The number of bytes per sample. * * @return SRD_OK upon success, a (negative) error code otherwise. * * @private * - * @since 0.1.0 + * @since 0.4.0 */ SRD_PRIV int srd_inst_decode(const struct srd_decoder_inst *di, uint64_t start_samplenum, uint64_t end_samplenum, - const uint8_t *inbuf, uint64_t inbuflen) + const uint8_t *inbuf, uint64_t inbuflen, uint64_t unitsize) { PyObject *py_res; srd_logic *logic; + ((struct srd_decoder_inst *)di)->data_unitsize = unitsize; + srd_dbg("Calling decode(), start sample %" PRIu64 ", end sample %" PRIu64 " (%" PRIu64 " samples, %" PRIu64 " bytes, unitsize = " "%d), instance %s.", start_samplenum, end_samplenum, diff --git a/libsigrokdecode-internal.h b/libsigrokdecode-internal.h index e9aef64..9260363 100644 --- a/libsigrokdecode-internal.h +++ b/libsigrokdecode-internal.h @@ -61,7 +61,7 @@ SRD_PRIV struct srd_decoder_inst *srd_inst_find_by_obj( const GSList *stack, SRD_PRIV int srd_inst_start(struct srd_decoder_inst *di); SRD_PRIV int srd_inst_decode(const struct srd_decoder_inst *di, uint64_t start_samplenum, uint64_t end_samplenum, - const uint8_t *inbuf, uint64_t inbuflen); + const uint8_t *inbuf, uint64_t inbuflen, uint64_t unitsize); SRD_PRIV void srd_inst_free(struct srd_decoder_inst *di); SRD_PRIV void srd_inst_free_all(struct srd_session *sess, GSList *stack); diff --git a/libsigrokdecode.h b/libsigrokdecode.h index 0aed0f3..9d403dd 100644 --- a/libsigrokdecode.h +++ b/libsigrokdecode.h @@ -277,7 +277,7 @@ SRD_API int srd_session_metadata_set(struct srd_session *sess, int key, GVariant *data); SRD_API int srd_session_send(struct srd_session *sess, uint64_t start_samplenum, uint64_t end_samplenum, - const uint8_t *inbuf, uint64_t inbuflen); + const uint8_t *inbuf, uint64_t inbuflen, uint64_t unitsize); SRD_API int srd_session_destroy(struct srd_session *sess); SRD_API int srd_pd_output_callback_add(struct srd_session *sess, int output_type, srd_pd_output_callback cb, void *cb_data); @@ -295,7 +295,7 @@ SRD_API int srd_decoder_unload_all(void); SRD_API int srd_inst_option_set(struct srd_decoder_inst *di, GHashTable *options); SRD_API int srd_inst_channel_set_all(struct srd_decoder_inst *di, - GHashTable *channels, int unit_size); + GHashTable *channels); SRD_API struct srd_decoder_inst *srd_inst_new(struct srd_session *sess, const char *id, GHashTable *options); SRD_API int srd_inst_stack(struct srd_session *sess, diff --git a/session.c b/session.c index 8b88660..703c7ea 100644 --- a/session.c +++ b/session.c @@ -212,23 +212,24 @@ SRD_API int srd_session_metadata_set(struct srd_session *sess, int key, * in channel order, in the least amount of space possible. The default * channel set consists of all required channels + all optional channels. * - * The size of a sample in inbuf is the unit size passed to - * srd_inst_channel_set_all(). If no channel map has been configured, it is - * the minimum number of bytes needed to store the default channels. + * The size of a sample in inbuf is 'unitsize' bytes. If no channel map + * has been configured, it is the minimum number of bytes needed to store + * the default channels. * * @param sess The session to use. * @param start_samplenum The sample number of the first sample in this chunk. * @param end_samplenum The sample number of the last sample in this chunk. * @param inbuf Pointer to sample data. * @param inbuflen Length in bytes of the buffer. + * @param unitsize The number of bytes per sample. * * @return SRD_OK upon success, a (negative) error code otherwise. * - * @since 0.3.0 + * @since 0.4.0 */ SRD_API int srd_session_send(struct srd_session *sess, uint64_t start_samplenum, uint64_t end_samplenum, - const uint8_t *inbuf, uint64_t inbuflen) + const uint8_t *inbuf, uint64_t inbuflen, uint64_t unitsize) { GSList *d; int ret; @@ -240,7 +241,7 @@ SRD_API int srd_session_send(struct srd_session *sess, for (d = sess->di_list; d; d = d->next) { if ((ret = srd_inst_decode(d->data, start_samplenum, - end_samplenum, inbuf, inbuflen)) != SRD_OK) + end_samplenum, inbuf, inbuflen, unitsize)) != SRD_OK) return ret; }