X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=pv%2Fdata%2Fdecodesignal.cpp;h=593af02fdd796348aac72d3b621fa13239cffa3f;hb=cbb2e4da8042495531b406f745ee9d9e20448ef6;hp=10ef7d1a0b7a5538af7aad9c93c526c43bc9584f;hpb=b2b18d3aabf497666c3cff76d0c6663623539e36;p=pulseview.git diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp index 10ef7d1a..593af02f 100644 --- a/pv/data/decodesignal.cpp +++ b/pv/data/decodesignal.cpp @@ -76,7 +76,7 @@ const vector< shared_ptr >& DecodeSignal::decoder_stack() const return stack_; } -void DecodeSignal::stack_decoder(const srd_decoder *decoder) +void DecodeSignal::stack_decoder(const srd_decoder *decoder, bool restart_decode) { assert(decoder); @@ -101,7 +101,8 @@ void DecodeSignal::stack_decoder(const srd_decoder *decoder) decoder_stacked((void*)dec.get()); - begin_decode(); + if (restart_decode) + begin_decode(); } void DecodeSignal::remove_decoder(int index) @@ -235,12 +236,11 @@ void DecodeSignal::begin_decode() (srd_decoder_annotation_row *)l->data; assert(ann_row); - const Row row(row_index++, decc, ann_row); + const Row row(row_index++, dec.get(), ann_row); for (const GSList *ll = ann_row->ann_classes; ll; ll = ll->next) - class_rows_[make_pair(decc, - GPOINTER_TO_INT(ll->data))] = row; + class_rows_[make_pair(decc, GPOINTER_TO_INT(ll->data))] = row; } } @@ -442,15 +442,13 @@ int64_t DecodeSignal::get_decoded_sample_count(uint32_t segment_id, int64_t result = 0; - try { - const DecodeSegment *segment = &(segments_.at(segment_id)); - if (include_processing) - result = segment->samples_decoded_incl; - else - result = segment->samples_decoded_excl; - } catch (out_of_range&) { - // Do nothing - } + if (segment_id >= segments_.size()) + return result; + + if (include_processing) + result = segments_[segment_id].samples_decoded_incl; + else + result = segments_[segment_id].samples_decoded_excl; return result; } @@ -472,20 +470,37 @@ vector DecodeSignal::get_rows(bool visible_only) const int row_index = 0; // Add a row for the decoder if it doesn't have a row list if (!decc->annotation_rows) - rows.emplace_back(row_index++, decc); + rows.emplace_back(row_index++, dec.get()); // Add the decoder rows for (const GSList *l = decc->annotation_rows; l; l = l->next) { const srd_decoder_annotation_row *const ann_row = (srd_decoder_annotation_row *)l->data; assert(ann_row); - rows.emplace_back(row_index++, decc, ann_row); + rows.emplace_back(row_index++, dec.get(), ann_row); } } return rows; } +uint64_t DecodeSignal::get_annotation_count(const decode::Row &row, + uint32_t segment_id) const +{ + if (segment_id >= segments_.size()) + return 0; + + const DecodeSegment *segment = &(segments_.at(segment_id)); + const map *rows = + &(segment->annotation_rows); + + const auto iter = rows->find(row); + if (iter != rows->end()) + return (*iter).second.get_annotation_count(); + + return 0; +} + void DecodeSignal::get_annotation_subset( vector &dest, const decode::Row &row, uint32_t segment_id, uint64_t start_sample, @@ -493,18 +508,15 @@ void DecodeSignal::get_annotation_subset( { lock_guard lock(output_mutex_); - try { - const DecodeSegment *segment = &(segments_.at(segment_id)); - const map *rows = - &(segment->annotation_rows); + if (segment_id >= segments_.size()) + return; - const auto iter = rows->find(row); - if (iter != rows->end()) - (*iter).second.get_annotation_subset(dest, - start_sample, end_sample); - } catch (out_of_range&) { - // Do nothing - } + const DecodeSegment *segment = &(segments_.at(segment_id)); + const map *rows = &(segment->annotation_rows); + + const auto iter = rows->find(row); + if (iter != rows->end()) + (*iter).second.get_annotation_subset(dest, start_sample, end_sample); } void DecodeSignal::get_annotation_subset( @@ -513,7 +525,7 @@ void DecodeSignal::get_annotation_subset( { // Note: We put all vectors and lists on the heap, not the stack - const vector rows = get_rows(true); + const vector rows = get_rows(); // Use forward_lists for faster merging forward_list *all_ann_list = new forward_list(); @@ -535,8 +547,11 @@ void DecodeSignal::get_annotation_subset( } uint32_t DecodeSignal::get_binary_data_chunk_count(uint32_t segment_id, - const Decoder* dec, uint8_t bin_class_id) const + const Decoder* dec, uint32_t bin_class_id) const { + if (segments_.size() == 0) + return 0; + try { const DecodeSegment *segment = &(segments_.at(segment_id)); @@ -551,7 +566,7 @@ uint32_t DecodeSignal::get_binary_data_chunk_count(uint32_t segment_id, } void DecodeSignal::get_binary_data_chunk(uint32_t segment_id, - const Decoder* dec, uint8_t bin_class_id, uint32_t chunk_id, + const Decoder* dec, uint32_t bin_class_id, uint32_t chunk_id, const vector **dest, uint64_t *size) { try { @@ -568,8 +583,8 @@ void DecodeSignal::get_binary_data_chunk(uint32_t segment_id, } } -void DecodeSignal::get_binary_data_chunks_merged(uint32_t segment_id, - const Decoder* dec, uint8_t bin_class_id, uint64_t start_sample, +void DecodeSignal::get_merged_binary_data_chunks_by_sample(uint32_t segment_id, + const Decoder* dec, uint32_t bin_class_id, uint64_t start_sample, uint64_t end_sample, vector *dest) const { assert(dest != nullptr); @@ -609,6 +624,63 @@ void DecodeSignal::get_binary_data_chunks_merged(uint32_t segment_id, } } +void DecodeSignal::get_merged_binary_data_chunks_by_offset(uint32_t segment_id, + const data::decode::Decoder* dec, uint32_t bin_class_id, uint64_t start, + uint64_t end, vector *dest) const +{ + assert(dest != nullptr); + + try { + const DecodeSegment *segment = &(segments_.at(segment_id)); + + const DecodeBinaryClass* bin_class = nullptr; + for (const DecodeBinaryClass& bc : segment->binary_classes) + if ((bc.decoder == dec) && (bc.info->bin_class_id == bin_class_id)) + bin_class = &bc; + + // Determine overall size before copying to resize dest vector only once + uint64_t size = 0; + uint64_t offset = 0; + for (const DecodeBinaryDataChunk& chunk : bin_class->chunks) { + if (offset >= start) + size += chunk.data.size(); + offset += chunk.data.size(); + if (offset >= end) + break; + } + dest->resize(size); + + offset = 0; + uint64_t dest_offset = 0; + for (const DecodeBinaryDataChunk& chunk : bin_class->chunks) { + if (offset >= start) { + memcpy(dest->data() + dest_offset, chunk.data.data(), chunk.data.size()); + dest_offset += chunk.data.size(); + } + offset += chunk.data.size(); + if (offset >= end) + break; + } + } catch (out_of_range&) { + // Do nothing + } +} + +const DecodeBinaryClass* DecodeSignal::get_binary_data_class(uint32_t segment_id, + const data::decode::Decoder* dec, uint32_t bin_class_id) const +{ + try { + const DecodeSegment *segment = &(segments_.at(segment_id)); + + for (const DecodeBinaryClass& bc : segment->binary_classes) + if ((bc.decoder == dec) && (bc.info->bin_class_id == bin_class_id)) + return &bc; + } catch (out_of_range&) { + // Do nothing + } + + return nullptr; +} void DecodeSignal::save_settings(QSettings &settings) const { @@ -1313,7 +1385,7 @@ void DecodeSignal::create_decode_segment() int row_index = 0; // Add a row for the decoder if it doesn't have a row list if (!decc->annotation_rows) - (segments_.back().annotation_rows)[Row(row_index++, decc)] = + (segments_.back().annotation_rows)[Row(row_index++, dec.get())] = decode::RowData(); // Add the decoder rows @@ -1322,21 +1394,20 @@ void DecodeSignal::create_decode_segment() (srd_decoder_annotation_row *)l->data; assert(ann_row); - const Row row(row_index++, decc, ann_row); + const Row row(row_index++, dec.get(), ann_row); // Add a new empty row data object - (segments_.back().annotation_rows)[row] = - decode::RowData(); + (segments_.back().annotation_rows)[row] = decode::RowData(); } } // Prepare our binary output classes for (const shared_ptr& dec : stack_) { - uint8_t n = dec->get_binary_class_count(); + uint32_t n = dec->get_binary_class_count(); - for (uint8_t i = 0; i < n; i++) + for (uint32_t i = 0; i < n; i++) segments_.back().binary_classes.push_back( - {dec.get(), dec->get_binary_class(i), vector()}); + {dec.get(), dec->get_binary_class(i), deque()}); } } @@ -1372,7 +1443,9 @@ void DecodeSignal::annotation_callback(srd_proto_data *pdata, void *decode_signa row_iter = ds->segments_.at(ds->current_segment_id_).annotation_rows.find((*r).second); else { // Failing that, use the decoder as a key - row_iter = ds->segments_.at(ds->current_segment_id_).annotation_rows.find(Row(0, decc)); + for (const shared_ptr& dec : ds->decoder_stack()) + if (dec->decoder() == decc) + row_iter = ds->segments_.at(ds->current_segment_id_).annotation_rows.find(Row(0, dec.get())); } if (row_iter == ds->segments_.at(ds->current_segment_id_).annotation_rows.end()) { @@ -1411,7 +1484,7 @@ void DecodeSignal::binary_callback(srd_proto_data *pdata, void *decode_signal) DecodeBinaryClass* bin_class = nullptr; for (DecodeBinaryClass& bc : segment->binary_classes) - if ((bc.decoder->decoder() == decc) && (bc.info->bin_class_id == pdb->bin_class)) + if ((bc.decoder->decoder() == decc) && (bc.info->bin_class_id == (uint32_t)pdb->bin_class)) bin_class = &bc; if (!bin_class) {