Pass unitsize per sample chunk.
authorUwe Hermann <uwe@hermann-uwe.de>
Thu, 20 Aug 2015 17:36:12 +0000 (19:36 +0200)
committerUwe Hermann <uwe@hermann-uwe.de>
Thu, 20 Aug 2015 18:20:34 +0000 (20:20 +0200)
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.

instance.c
libsigrokdecode-internal.h
libsigrokdecode.h
session.c

index f99cd684e8d7afc1610168fe3ff1a1130c319aac..bfe9142860d76829ce2f609ddbf1bd23fbe312f1 100644 (file)
@@ -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,
index e9aef649b93697e430cc3586c2298b9c613e3c7c..926036374c1a9511c4086be544c7a0bdbd730687 100644 (file)
@@ -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);
 
index 0aed0f3ee7ce5f5473563372cfd3d810a1d2ade5..9d403dd497d3b246dfc469f3fda7b4b9be36b370 100644 (file)
@@ -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,
index 8b8866046b3224f3b39542f65f63049acb5205d4..703c7ead104e737a50ea341cc68736f7c7f146e2 100644 (file)
--- 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;
        }