X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=pv%2Fdata%2Fdecodesignal.cpp;h=ecdacdefa6ec09d53c6a1e8b343b40e6f661e96b;hb=f228f00ed2c11ce4c9c36e0b758132a075e251da;hp=df385be8d99ce397ed9aba327247f37e0176983b;hpb=ce0b6a40ca6f804fd6ae7dcce2bbe163848819aa;p=pulseview.git diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp index df385be..ecdacde 100644 --- a/pv/data/decodesignal.cpp +++ b/pv/data/decodesignal.cpp @@ -56,6 +56,7 @@ DecodeSignal::DecodeSignal(pv::Session &session) : 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)), @@ -64,7 +65,7 @@ DecodeSignal::DecodeSignal(pv::Session &session) : DecodeSignal::~DecodeSignal() { - reset_decode(); + reset_decode(true); } const vector< shared_ptr >& DecodeSignal::decoder_stack() const @@ -86,6 +87,7 @@ void DecodeSignal::stack_decoder(const srd_decoder *decoder) // 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(); @@ -105,6 +107,7 @@ void DecodeSignal::remove_decoder(int index) stack_.erase(iter); // Update channels and decoded data + stack_config_changed_ = true; update_channel_list(); begin_decode(); } @@ -127,9 +130,12 @@ bool DecodeSignal::toggle_decoder_visibility(int index) return state; } -void DecodeSignal::reset_decode() +void DecodeSignal::reset_decode(bool shutting_down) { - terminate_srd_session(); + if (stack_config_changed_ || shutting_down) + stop_srd_session(); + else + terminate_srd_session(); if (decode_thread_.joinable()) { decode_interrupt_ = true; @@ -143,8 +149,6 @@ void DecodeSignal::reset_decode() logic_mux_thread_.join(); } - stop_srd_session(); - class_rows_.clear(); current_segment_id_ = 0; segments_.clear(); @@ -152,15 +156,16 @@ void DecodeSignal::reset_decode() logic_mux_data_.reset(); logic_mux_data_invalid_ = true; - error_message_ = QString(); + if (!error_message_.isEmpty()) { + error_message_ = QString(); + qDebug().noquote().nospace() << name() << ": Error cleared"; + } decode_reset(); } void DecodeSignal::begin_decode() { - terminate_srd_session(); - if (decode_thread_.joinable()) { decode_interrupt_ = true; decode_input_cond_.notify_one(); @@ -176,14 +181,14 @@ void DecodeSignal::begin_decode() reset_decode(); if (stack_.size() == 0) { - error_message_ = tr("No decoders"); + set_error_message(tr("No decoders")); return; } assert(channels_.size() > 0); if (get_assigned_signal_count() == 0) { - error_message_ = tr("There are no channels assigned to this decoder"); + set_error_message(tr("There are no channels assigned to this decoder")); return; } @@ -197,8 +202,8 @@ void DecodeSignal::begin_decode() // Check that all decoders have the required channels for (const shared_ptr &dec : stack_) if (!dec->have_required_channels()) { - error_message_ = tr("One or more required channels " - "have not been specified"); + set_error_message(tr("One or more required channels " + "have not been specified")); return; } @@ -236,7 +241,7 @@ void DecodeSignal::begin_decode() connect_input_notifiers(); if (get_input_segment_count() == 0) { - error_message_ = tr("No input data"); + set_error_message(tr("No input data")); return; } @@ -287,6 +292,7 @@ void DecodeSignal::auto_assign_signals(const shared_ptr dec) if (new_assignment) { logic_mux_data_invalid_ = true; + stack_config_changed_ = true; commit_decoder_channels(); channels_updated(); } @@ -300,6 +306,7 @@ void DecodeSignal::assign_signal(const uint16_t channel_id, const SignalBase *si logic_mux_data_invalid_ = true; } + stack_config_changed_ = true; commit_decoder_channels(); channels_updated(); begin_decode(); @@ -318,8 +325,8 @@ void DecodeSignal::set_initial_pin_state(const uint16_t channel_id, const int in if (ch.id == channel_id) ch.initial_pin_state = init_state; + stack_config_changed_ = true; channels_updated(); - begin_decode(); } @@ -571,12 +578,19 @@ void DecodeSignal::restore_settings(QSettings &settings) } // Update the internal structures + stack_config_changed_ = true; update_channel_list(); commit_decoder_channels(); begin_decode(); } +void DecodeSignal::set_error_message(QString msg) +{ + error_message_ = msg; + qDebug().noquote().nospace() << name() << ": " << msg; +} + uint32_t DecodeSignal::get_input_segment_count() const { uint64_t count = std::numeric_limits::max(); @@ -890,7 +904,7 @@ void DecodeSignal::decode_data( if (srd_session_send(srd_session_, i, chunk_end, chunk, data_size, unit_size) != SRD_OK) { - error_message_ = tr("Decoder reported an error"); + set_error_message(tr("Decoder reported an error")); delete[] chunk; break; } @@ -965,9 +979,8 @@ void DecodeSignal::decode_proc() segments_.at(current_segment_id_).samplerate = input_segment->samplerate(); segments_.at(current_segment_id_).start_time = input_segment->start_time(); - // Reset decoder state - stop_srd_session(); - start_srd_session(); + // Reset decoder state but keep the decoder stack intact + terminate_srd_session(); } else { // All segments have been processed decode_finished(); @@ -989,6 +1002,8 @@ void DecodeSignal::start_srd_session() { uint64_t samplerate; + // If there were stack changes, the session has been destroyed by now, so if + // it hasn't been destroyed, we can just reset and re-use it if (srd_session_) { // When a decoder stack was created before, re-use it // for the next stream of input data, after terminating @@ -1017,7 +1032,7 @@ void DecodeSignal::start_srd_session() srd_decoder_inst *const di = dec->create_decoder_inst(srd_session_); if (!di) { - error_message_ = tr("Failed to create decoder instance"); + set_error_message(tr("Failed to create decoder instance")); srd_session_destroy(srd_session_); srd_session_ = nullptr; return; @@ -1039,6 +1054,9 @@ void DecodeSignal::start_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() @@ -1058,6 +1076,10 @@ void DecodeSignal::stop_srd_session() // Destroy the session srd_session_destroy(srd_session_); srd_session_ = nullptr; + + // Mark the decoder instances as non-existant since they were deleted + for (const shared_ptr &dec : stack_) + dec->invalidate_decoder_inst(); } }