session_(session),
srd_session_(nullptr),
logic_mux_data_invalid_(false),
+ stack_config_changed_(true),
current_segment_id_(0)
{
connect(&session_, SIGNAL(capture_state_changed(int)),
// Include the newly created decode channels in the channel lists
update_channel_list();
+ stack_config_changed_ = true;
auto_assign_signals(dec);
commit_decoder_channels();
begin_decode();
stack_.erase(iter);
// Update channels and decoded data
+ stack_config_changed_ = true;
update_channel_list();
begin_decode();
}
void DecodeSignal::reset_decode()
{
+ if (stack_config_changed_)
+ stop_srd_session();
+ else
+ terminate_srd_session();
+
if (decode_thread_.joinable()) {
decode_interrupt_ = true;
decode_input_cond_.notify_one();
logic_mux_thread_.join();
}
- stop_srd_session();
-
class_rows_.clear();
current_segment_id_ = 0;
segments_.clear();
if (new_assignment) {
logic_mux_data_invalid_ = true;
+ stack_config_changed_ = true;
commit_decoder_channels();
channels_updated();
}
logic_mux_data_invalid_ = true;
}
+ stack_config_changed_ = true;
commit_decoder_channels();
channels_updated();
begin_decode();
if (ch.id == channel_id)
ch.initial_pin_state = init_state;
+ stack_config_changed_ = true;
channels_updated();
-
begin_decode();
}
}
// Update the internal structures
+ stack_config_changed_ = true;
update_channel_list();
commit_decoder_channels();
}
}
} while (error_message_.isEmpty() && !decode_interrupt_);
+
+ // Potentially reap decoders when the application no longer is
+ // interested in their (pending) results.
+ if (decode_interrupt_)
+ terminate_srd_session();
}
void DecodeSignal::start_srd_session()
{
uint64_t samplerate;
- if (srd_session_)
- stop_srd_session();
+ if (srd_session_) {
+ // When a decoder stack was created before, re-use it
+ // for the next stream of input data, after terminating
+ // potentially still executing operations, and resetting
+ // internal state. Skip the rather expensive (teardown
+ // and) construction of another decoder stack.
+
+ // TODO Reduce redundancy, use a common code path for
+ // the meta/cb/start sequence?
+ terminate_srd_session();
+ srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE,
+ g_variant_new_uint64(segments_.at(current_segment_id_).samplerate));
+ srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_ANN,
+ DecodeSignal::annotation_callback, this);
+ srd_session_start(srd_session_);
+ return;
+ }
// Create the session
srd_session_new(&srd_session_);
DecodeSignal::annotation_callback, this);
srd_session_start(srd_session_);
+
+ // We just recreated the srd session, so all stack changes are applied now
+ stack_config_changed_ = false;
+}
+
+void DecodeSignal::terminate_srd_session()
+{
+ // Call the "terminate and reset" routine for the decoder stack
+ // (if available). This does not harm those stacks which already
+ // have completed their operation, and reduces response time for
+ // those stacks which still are processing data while the
+ // application no longer wants them to.
+ if (srd_session_)
+ srd_session_terminate_reset(srd_session_);
}
void DecodeSignal::stop_srd_session()