X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=pv%2Fdata%2Fdecodesignal.cpp;h=2f14914529e2fcf348ab0a0d1cede95f62769af0;hb=c0c3e62a897ae31592855da7fbd0a6d0444c2581;hp=9b40540c7032b058f988f8cb8d903d6763b3d97f;hpb=c526a8fd78952bedc767f64009e0511b2f940f75;p=pulseview.git
diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp
index 9b40540c..2f149145 100644
--- a/pv/data/decodesignal.cpp
+++ b/pv/data/decodesignal.cpp
@@ -17,6 +17,7 @@
* along with this program; if not, see .
*/
+#include
#include
#include
@@ -78,14 +79,19 @@ const vector< shared_ptr >& DecodeSignal::decoder_stack() const
void DecodeSignal::stack_decoder(const srd_decoder *decoder)
{
assert(decoder);
- const shared_ptr dec = make_shared(decoder);
- stack_.push_back(dec);
+ // Set name if this decoder is the first in the list or the name is unchanged
+ const srd_decoder* prev_dec =
+ stack_.empty() ? nullptr : stack_.back()->decoder();
+ const QString prev_dec_name =
+ prev_dec ? QString::fromUtf8(prev_dec->name) : QString();
- // Set name if this decoder is the first in the list
- if (stack_.size() == 1)
+ if ((stack_.empty()) || ((stack_.size() > 0) && (name() == prev_dec_name)))
set_name(QString::fromUtf8(decoder->name));
+ const shared_ptr dec = make_shared(decoder);
+ stack_.push_back(dec);
+
// Include the newly created decode channels in the channel lists
update_channel_list();
@@ -200,12 +206,12 @@ void DecodeSignal::begin_decode()
// 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_)
+ 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 &dec : stack_)
+ for (const shared_ptr& dec : stack_)
if (!dec->have_required_channels()) {
set_error_message(tr("One or more required channels "
"have not been specified"));
@@ -214,7 +220,7 @@ void DecodeSignal::begin_decode()
// Map out all the annotation classes
int row_index = 0;
- for (const shared_ptr &dec : stack_) {
+ for (const shared_ptr& dec : stack_) {
assert(dec);
const srd_decoder *const decc = dec->decoder();
assert(dec->decoder());
@@ -295,7 +301,7 @@ void DecodeSignal::auto_assign_signals(const shared_ptr dec)
bool new_assignment = false;
// Try to auto-select channels that don't have signals assigned yet
- for (data::DecodeChannel &ch : channels_) {
+ for (data::DecodeChannel& ch : channels_) {
// If a decoder is given, auto-assign only its channels
if (dec && (ch.decoder_ != dec))
continue;
@@ -307,7 +313,7 @@ void DecodeSignal::auto_assign_signals(const shared_ptr dec)
ch_name = ch_name.replace(QRegExp("[-_.]"), " ");
shared_ptr match;
- for (shared_ptr s : session_.signalbases()) {
+ for (const shared_ptr& s : session_.signalbases()) {
if (!s->enabled())
continue;
@@ -344,7 +350,7 @@ void DecodeSignal::auto_assign_signals(const shared_ptr dec)
void DecodeSignal::assign_signal(const uint16_t channel_id, const SignalBase *signal)
{
- for (data::DecodeChannel &ch : channels_)
+ for (data::DecodeChannel& ch : channels_)
if (ch.id == channel_id) {
ch.assigned_signal = signal;
logic_mux_data_invalid_ = true;
@@ -365,7 +371,7 @@ int DecodeSignal::get_assigned_signal_count() const
void DecodeSignal::set_initial_pin_state(const uint16_t channel_id, const int init_state)
{
- for (data::DecodeChannel &ch : channels_)
+ for (data::DecodeChannel& ch : channels_)
if (ch.id == channel_id)
ch.initial_pin_state = init_state;
@@ -405,7 +411,7 @@ int64_t DecodeSignal::get_working_sample_count(uint32_t segment_id) const
int64_t count = std::numeric_limits::max();
bool no_signals_assigned = true;
- for (const data::DecodeChannel &ch : channels_)
+ for (const data::DecodeChannel& ch : channels_)
if (ch.assigned_signal) {
no_signals_assigned = false;
@@ -444,15 +450,15 @@ int64_t DecodeSignal::get_decoded_sample_count(uint32_t segment_id,
return result;
}
-vector DecodeSignal::visible_rows() const
+vector DecodeSignal::get_rows(bool visible_only) const
{
lock_guard lock(output_mutex_);
vector rows;
- for (const shared_ptr &dec : stack_) {
+ for (const shared_ptr& dec : stack_) {
assert(dec);
- if (!dec->shown())
+ if (visible_only && !dec->shown())
continue;
const srd_decoder *const decc = dec->decoder();
@@ -502,7 +508,7 @@ void DecodeSignal::get_annotation_subset(
{
// Note: We put all vectors and lists on the heap, not the stack
- const vector rows = visible_rows();
+ const vector rows = get_rows(true);
// Use forward_lists for faster merging
forward_list *all_ann_list = new forward_list();
@@ -523,6 +529,61 @@ void DecodeSignal::get_annotation_subset(
delete all_ann_list;
}
+uint32_t DecodeSignal::get_binary_data_chunk_count(uint32_t segment_id) const
+{
+ uint32_t count = 0;
+
+ try {
+ const DecodeSegment *segment = &(segments_.at(segment_id));
+ count = segment->binary_data.size();
+ } catch (out_of_range&) {
+ // Do nothing
+ }
+
+ return count;
+}
+
+void DecodeSignal::get_binary_data_chunk(uint32_t segment_id, uint32_t chunk_id,
+ const vector **dest, uint64_t *size)
+{
+ try {
+ const DecodeSegment *segment = &(segments_.at(segment_id));
+ if (dest)
+ *dest = &(segment->binary_data.at(chunk_id).data);
+ if (size)
+ *size = segment->binary_data.at(chunk_id).data.size();
+ } catch (out_of_range&) {
+ // Do nothing
+ }
+}
+
+void DecodeSignal::get_binary_data_chunks_merged(uint32_t segment_id,
+ uint64_t start_sample, uint64_t end_sample, vector *dest) const
+{
+ assert(dest != nullptr);
+
+ try {
+ const DecodeSegment *segment = &(segments_.at(segment_id));
+
+ // Determine overall size before copying to resize dest vector only once
+ uint64_t size = 0;
+ for (const DecodeBinaryData& d : segment->binary_data)
+ if ((d.sample >= start_sample) && (d.sample < end_sample))
+ size += d.data.size();
+ dest->reserve(size);
+
+ uint64_t index = 0;
+ for (const DecodeBinaryData& d : segment->binary_data)
+ if ((d.sample >= start_sample) && (d.sample < end_sample)) {
+ memcpy(dest->data() + index, d.data.data(), d.data.size());
+ index += d.data.size();
+ }
+ } catch (out_of_range&) {
+ // Do nothing
+ }
+}
+
+
void DecodeSignal::save_settings(QSettings &settings) const
{
SignalBase::save_settings(settings);
@@ -531,10 +592,11 @@ void DecodeSignal::save_settings(QSettings &settings) const
// Save decoder stack
int decoder_idx = 0;
- for (shared_ptr decoder : stack_) {
+ for (const shared_ptr& decoder : stack_) {
settings.beginGroup("decoder" + QString::number(decoder_idx++));
settings.setValue("id", decoder->decoder()->id);
+ settings.setValue("shown", decoder->shown());
// Save decoder options
const map& options = decoder->options();
@@ -544,7 +606,7 @@ void DecodeSignal::save_settings(QSettings &settings) const
// Note: decode::Decoder::options() returns only the options
// that differ from the default. See binding::Decoder::getter()
int i = 0;
- for (auto option : options) {
+ for (auto& option : options) {
settings.beginGroup("option" + QString::number(i));
settings.setValue("name", QString::fromStdString(option.first));
GlobalSettings::store_gvariant(settings, option.second);
@@ -603,6 +665,7 @@ void DecodeSignal::restore_settings(QSettings &settings)
make_shared(dec);
stack_.push_back(decoder);
+ decoder->show(settings.value("shown", true).toBool());
// Restore decoder options that differ from their default
int options = settings.value("options").toInt();
@@ -644,7 +707,7 @@ void DecodeSignal::restore_settings(QSettings &settings)
QString assigned_signal_name = settings.value("assigned_signal_name").toString();
- for (shared_ptr signal : signalbases)
+ for (const shared_ptr& signal : signalbases)
if (signal->name() == assigned_signal_name)
channel->assigned_signal = signal.get();
@@ -673,7 +736,7 @@ uint32_t DecodeSignal::get_input_segment_count() const
uint64_t count = std::numeric_limits::max();
bool no_signals_assigned = true;
- for (const data::DecodeChannel &ch : channels_)
+ for (const data::DecodeChannel& ch : channels_)
if (ch.assigned_signal) {
no_signals_assigned = false;
@@ -693,7 +756,7 @@ uint32_t DecodeSignal::get_input_samplerate(uint32_t segment_id) const
{
double samplerate = 0;
- for (const data::DecodeChannel &ch : channels_)
+ for (const data::DecodeChannel& ch : channels_)
if (ch.assigned_signal) {
const shared_ptr logic_data = ch.assigned_signal->logic_data();
if (!logic_data || logic_data->logic_segments().empty())
@@ -719,7 +782,7 @@ void DecodeSignal::update_channel_list()
uint16_t id = 0;
// Copy existing entries, create new as needed
- for (shared_ptr decoder : stack_) {
+ for (shared_ptr& decoder : stack_) {
const srd_decoder* srd_d = decoder->decoder();
const GSList *l;
@@ -729,7 +792,7 @@ void DecodeSignal::update_channel_list()
bool ch_added = false;
// Copy but update ID if this channel was in the list before
- for (data::DecodeChannel &ch : prev_channels)
+ for (data::DecodeChannel& ch : prev_channels)
if (ch.pdch_ == pdch) {
ch.id = id++;
channels_.push_back(ch);
@@ -752,7 +815,7 @@ void DecodeSignal::update_channel_list()
bool ch_added = false;
// Copy but update ID if this channel was in the list before
- for (data::DecodeChannel &ch : prev_channels)
+ for (data::DecodeChannel& ch : prev_channels)
if (ch.pdch_ == pdch) {
ch.id = id++;
channels_.push_back(ch);
@@ -777,8 +840,8 @@ void DecodeSignal::update_channel_list()
} else {
// Same number but assignment may still differ, so compare all channels
for (size_t i = 0; i < channels_.size(); i++) {
- const data::DecodeChannel &p_ch = prev_channels[i];
- const data::DecodeChannel &ch = channels_[i];
+ const data::DecodeChannel& p_ch = prev_channels[i];
+ const data::DecodeChannel& ch = channels_[i];
if ((p_ch.pdch_ != ch.pdch_) ||
(p_ch.assigned_signal != ch.assigned_signal)) {
@@ -798,7 +861,7 @@ void DecodeSignal::commit_decoder_channels()
for (shared_ptr dec : stack_) {
vector channel_list;
- for (data::DecodeChannel &ch : channels_)
+ for (data::DecodeChannel& ch : channels_)
if (ch.decoder_ == dec)
channel_list.push_back(&ch);
@@ -807,7 +870,7 @@ void DecodeSignal::commit_decoder_channels()
// Channel bit IDs must be in sync with the channel's apperance in channels_
int id = 0;
- for (data::DecodeChannel &ch : channels_)
+ for (data::DecodeChannel& ch : channels_)
if (ch.assigned_signal)
ch.bit_id = id++;
}
@@ -824,7 +887,7 @@ void DecodeSignal::mux_logic_samples(uint32_t segment_id, const int64_t start, c
vector signal_in_bytepos;
vector signal_in_bitpos;
- for (data::DecodeChannel &ch : channels_)
+ for (data::DecodeChannel& ch : channels_)
if (ch.assigned_signal) {
const shared_ptr logic_data = ch.assigned_signal->logic_data();
@@ -1110,7 +1173,7 @@ void DecodeSignal::start_srd_session()
if (samplerate)
srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE,
g_variant_new_uint64(samplerate));
- for (const shared_ptr &dec : stack_)
+ for (const shared_ptr& dec : stack_)
dec->apply_all_options();
srd_session_start(srd_session_);
@@ -1123,7 +1186,7 @@ void DecodeSignal::start_srd_session()
// Create the decoders
srd_decoder_inst *prev_di = nullptr;
- for (const shared_ptr &dec : stack_) {
+ for (const shared_ptr& dec : stack_) {
srd_decoder_inst *const di = dec->create_decoder_inst(srd_session_);
if (!di) {
@@ -1147,6 +1210,9 @@ void DecodeSignal::start_srd_session()
srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_ANN,
DecodeSignal::annotation_callback, this);
+ srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_BINARY,
+ DecodeSignal::binary_callback, this);
+
srd_session_start(srd_session_);
// We just recreated the srd session, so all stack changes are applied now
@@ -1170,7 +1236,7 @@ void DecodeSignal::terminate_srd_session()
if (samplerate)
srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE,
g_variant_new_uint64(samplerate));
- for (const shared_ptr &dec : stack_)
+ for (const shared_ptr& dec : stack_)
dec->apply_all_options();
}
}
@@ -1183,7 +1249,7 @@ void DecodeSignal::stop_srd_session()
srd_session_ = nullptr;
// Mark the decoder instances as non-existant since they were deleted
- for (const shared_ptr &dec : stack_)
+ for (const shared_ptr& dec : stack_)
dec->invalidate_decoder_inst();
}
}
@@ -1195,7 +1261,7 @@ void DecodeSignal::connect_input_notifiers()
disconnect(this, SLOT(on_data_received()));
// Connect the currently used signals to our slot
- for (data::DecodeChannel &ch : channels_) {
+ for (data::DecodeChannel& ch : channels_) {
if (!ch.assigned_signal)
continue;
@@ -1213,7 +1279,7 @@ void DecodeSignal::create_decode_segment()
segments_.emplace_back(DecodeSegment());
// Add annotation classes
- for (const shared_ptr &dec : stack_) {
+ for (const shared_ptr& dec : stack_) {
assert(dec);
const srd_decoder *const decc = dec->decoder();
assert(dec->decoder());
@@ -1252,19 +1318,19 @@ void DecodeSignal::annotation_callback(srd_proto_data *pdata, void *decode_signa
lock_guard lock(ds->output_mutex_);
- // Find the row
+ // Get the decoder and the annotation data
assert(pdata->pdo);
assert(pdata->pdo->di);
const srd_decoder *const decc = pdata->pdo->di->decoder;
assert(decc);
- const srd_proto_data_annotation *const pda =
- (const srd_proto_data_annotation*)pdata->data;
+ const srd_proto_data_annotation *const pda = (const srd_proto_data_annotation*)pdata->data;
assert(pda);
+ // Find the row
auto row_iter = ds->segments_.at(ds->current_segment_id_).annotation_rows.end();
- // Try looking up the sub-row of this class
+ // Try finding a better row match than the default by looking up the sub-row of this class
const auto format = pda->ann_class;
const auto r = ds->class_rows_.find(make_pair(decc, format));
if (r != ds->class_rows_.end())
@@ -1285,6 +1351,32 @@ void DecodeSignal::annotation_callback(srd_proto_data *pdata, void *decode_signa
(*row_iter).second.emplace_annotation(pdata, &((*row_iter).first));
}
+void DecodeSignal::binary_callback(srd_proto_data *pdata, void *decode_signal)
+{
+ assert(pdata);
+ assert(decode_signal);
+
+ DecodeSignal *const ds = (DecodeSignal*)decode_signal;
+ assert(ds);
+
+ if (ds->decode_interrupt_)
+ return;
+
+ const srd_proto_data_binary *const pdb = (const srd_proto_data_binary*)pdata->data;
+ assert(pdb);
+
+ DecodeSegment* segment = &(ds->segments_.at(ds->current_segment_id_));
+
+ segment->binary_data.emplace_back();
+ DecodeBinaryData* bin_data = &(segment->binary_data.back());
+
+ bin_data->sample = pdata->start_sample;
+ bin_data->data.reserve(pdb->size);
+ memcpy(bin_data->data.data(), pdb->data, pdb->size);
+
+ ds->new_binary_data(ds->current_segment_id_);
+}
+
void DecodeSignal::on_capture_state_changed(int state)
{
// If a new acquisition was started, we need to start decoding from scratch