const double DecodeSignal::DecodeMargin = 1.0;
const double DecodeSignal::DecodeThreshold = 0.2;
-const int64_t DecodeSignal::DecodeChunkLength = 10 * 1024 * 1024;
-const unsigned int DecodeSignal::DecodeNotifyPeriod = 1024;
+const int64_t DecodeSignal::DecodeChunkLength = 256 * 1024;
mutex DecodeSignal::global_srd_mutex_;
logic_mux_data_invalid_(false),
start_time_(0),
samplerate_(0),
- annotation_count_(0),
samples_decoded_(0),
frame_complete_(false)
{
DecodeSignal::~DecodeSignal()
{
- if (decode_thread_.joinable()) {
- decode_interrupt_ = true;
- decode_input_cond_.notify_one();
- decode_thread_.join();
- }
-
- if (logic_mux_thread_.joinable()) {
- logic_mux_interrupt_ = true;
- logic_mux_cond_.notify_one();
- logic_mux_thread_.join();
- }
-
- stop_srd_session();
+ reset_decode();
}
const vector< shared_ptr<Decoder> >& DecodeSignal::decoder_stack() const
void DecodeSignal::reset_decode()
{
+ if (decode_thread_.joinable()) {
+ decode_interrupt_ = true;
+ decode_input_cond_.notify_one();
+ decode_thread_.join();
+ }
+
+ if (logic_mux_thread_.joinable()) {
+ logic_mux_interrupt_ = true;
+ logic_mux_cond_.notify_one();
+ logic_mux_thread_.join();
+ }
+
stop_srd_session();
- annotation_count_ = 0;
frame_complete_ = false;
samples_decoded_ = 0;
error_message_ = QString();
+
rows_.clear();
class_rows_.clear();
+
+ logic_mux_data_.reset();
+ logic_mux_data_invalid_ = true;
}
void DecodeSignal::begin_decode()
return;
}
+ // Make sure that all assigned channels still provide logic data
+ // (can happen when a converted signal was assigned but the
+ // conversion removed in the meanwhile)
+ for (data::DecodeChannel &ch : channels_)
+ if (ch.assigned_signal && !(ch.assigned_signal->logic_data() != nullptr))
+ ch.assigned_signal = nullptr;
+
// Check that all decoders have the required channels
for (const shared_ptr<decode::Decoder> &dec : stack_)
if (!dec->have_required_channels()) {
// TODO Restore decoder stack, channel mapping and decoder options
}
-uint64_t DecodeSignal::inc_annotation_count()
-{
- return (annotation_count_++);
-}
-
void DecodeSignal::update_channel_list()
{
vector<data::DecodeChannel> prev_channels = channels_;
} while (processed_samples < samples_to_process);
}
- if (session_.get_capture_state() != Session::Stopped) {
+ if (samples_to_process == 0) {
// Wait for more input
unique_lock<mutex> logic_mux_lock(logic_mux_mutex_);
logic_mux_cond_.wait(logic_mux_lock);
}
- } while ((session_.get_capture_state() != Session::Stopped) && !logic_mux_interrupt_);
+ } while (!logic_mux_interrupt_);
// No more input data and session is stopped, let the decode thread
// process any pending data, terminate and release the global SRD mutex
samplerate_valid = true;
}
- // Wait until input data is available or an interrupt was requested
- unique_lock<mutex> input_wait_lock(input_mutex_);
- decode_input_cond_.wait(input_wait_lock);
+ if (!samplerate_valid) {
+ // Wait until input data is available or an interrupt was requested
+ unique_lock<mutex> input_wait_lock(input_mutex_);
+ decode_input_cond_.wait(input_wait_lock);
+ }
} while (!samplerate_valid && !decode_interrupt_);
}
lock_guard<mutex> lock(output_mutex_);
samples_decoded_ = chunk_end;
}
+
+ // Notify the frontend that we processed some data and
+ // possibly have new annotations as well
+ new_annotations();
}
}
decode_data(abs_start_samplenum, sample_count);
abs_start_samplenum += sample_count;
}
- } while (error_message_.isEmpty() && (sample_count > 0));
+ } while (error_message_.isEmpty() && (sample_count > 0) && !decode_interrupt_);
- if (error_message_.isEmpty()) {
- // Make sure all annotations are known to the frontend
- new_annotations();
+ if (error_message_.isEmpty() && !decode_interrupt_) {
+ if (sample_count == 0)
+ decode_finished();
// Wait for new input data or an interrupt was requested
unique_lock<mutex> input_wait_lock(input_mutex_);
void DecodeSignal::connect_input_notifiers()
{
// Disconnect the notification slot from the previous set of signals
+ disconnect(this, SLOT(on_data_cleared()));
disconnect(this, SLOT(on_data_received()));
// Connect the currently used signals to our slot
if (!ch.assigned_signal)
continue;
- shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
- connect(logic_data.get(), SIGNAL(samples_added(QObject*, uint64_t, uint64_t)),
+ const data::SignalBase *signal = ch.assigned_signal;
+ connect(signal, SIGNAL(samples_cleared()),
+ this, SLOT(on_data_cleared()));
+ connect(signal, SIGNAL(samples_added(QObject*, uint64_t, uint64_t)),
this, SLOT(on_data_received()));
}
}
// Add the annotation
(*row_iter).second.push_annotation(a);
-
- // Notify the frontend every DecodeNotifyPeriod annotations
- if (ds->inc_annotation_count() % DecodeNotifyPeriod == 0)
- ds->new_annotations();
}
void DecodeSignal::on_capture_state_changed(int state)
begin_decode();
}
+void DecodeSignal::on_data_cleared()
+{
+ reset_decode();
+}
+
void DecodeSignal::on_data_received()
{
- logic_mux_cond_.notify_one();
+ if (!logic_mux_thread_.joinable())
+ begin_decode();
+ else
+ logic_mux_cond_.notify_one();
}
} // namespace data