diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp index baef9ce1..0e813d38 100644 --- a/pv/data/decodesignal.cpp +++ b/pv/data/decodesignal.cpp @@ -398,7 +398,8 @@ int64_t DecodeSignal::get_working_sample_count(uint32_t segment_id) const return (no_signals_assigned ? 0 : count); } -int64_t DecodeSignal::get_decoded_sample_count(uint32_t segment_id) const +int64_t DecodeSignal::get_decoded_sample_count(uint32_t segment_id, + bool include_processing) const { lock_guard decode_lock(output_mutex_); @@ -406,7 +407,10 @@ int64_t DecodeSignal::get_decoded_sample_count(uint32_t segment_id) const try { const DecodeSegment *segment = &(segments_.at(segment_id)); - result = segment->samples_decoded; + if (include_processing) + result = segment->samples_decoded_incl; + else + result = segment->samples_decoded_excl; } catch (out_of_range&) { // Do nothing } @@ -919,11 +923,10 @@ void DecodeSignal::decode_data( const int64_t chunk_end = min(i + chunk_sample_count, abs_start_samplenum + sample_count); - // Report this chunk as already decoded so that annotations don't - // appear in an area that we claim to not having been been decoded yet { lock_guard lock(output_mutex_); - segments_.at(current_segment_id_).samples_decoded = chunk_end; + // Update the sample count showing the samples including currently processed ones + segments_.at(current_segment_id_).samples_decoded_incl = chunk_end; } int64_t data_size = (chunk_end - i) * unit_size; @@ -939,6 +942,12 @@ void DecodeSignal::decode_data( delete[] chunk; + { + lock_guard lock(output_mutex_); + // Now that all samples are processed, the exclusive sample count catches up + segments_.at(current_segment_id_).samples_decoded_excl = chunk_end; + } + // Notify the frontend that we processed some data and // possibly have new annotations as well new_annotations(); diff --git a/pv/data/decodesignal.hpp b/pv/data/decodesignal.hpp index 4a1e7f00..9bbdd2c4 100644 --- a/pv/data/decodesignal.hpp +++ b/pv/data/decodesignal.hpp @@ -76,7 +76,7 @@ struct DecodeSegment map annotation_rows; pv::util::Timestamp start_time; double samplerate; - int64_t samples_decoded; + int64_t samples_decoded_incl, samples_decoded_excl; }; class DecodeSignal : public SignalBase @@ -120,7 +120,16 @@ public: */ int64_t get_working_sample_count(uint32_t segment_id) const; - int64_t get_decoded_sample_count(uint32_t segment_id) const; + /** + * Returns the number of processed samples. Newly generated annotations will + * have sample numbers greater than this. + * + * If include_processing is true, this number will include the ones being + * currently processed (in case the decoder stack is running). In this case, + * newly generated annotations will have sample numbers smaller than this. + */ + int64_t get_decoded_sample_count(uint32_t segment_id, + bool include_processing) const; vector visible_rows() const; diff --git a/pv/views/trace/decodetrace.cpp b/pv/views/trace/decodetrace.cpp index f68ded99..a65b4d97 100644 --- a/pv/views/trace/decodetrace.cpp +++ b/pv/views/trace/decodetrace.cpp @@ -176,8 +176,13 @@ void DecodeTrace::paint_mid(QPainter &p, ViewItemPaintParams &pp) // Iterate through the rows int y = get_visual_y(); - pair sample_range = get_sample_range( - pp.left(), pp.right()); + pair sample_range = get_sample_range(pp.left(), pp.right()); + + // Just because the view says we see a certain sample range it + // doesn't mean we have this many decoded samples, too, so crop + // the range to what has been decoded already + sample_range.second = min((int64_t)sample_range.second, + decode_signal_->get_decoded_sample_count(current_segment_, false)); const vector rows = decode_signal_->visible_rows(); @@ -580,7 +585,7 @@ void DecodeTrace::draw_unresolved_period(QPainter &p, int h, int left, int right if (sample_count == 0) return; - const int64_t samples_decoded = decode_signal_->get_decoded_sample_count(current_segment_); + const int64_t samples_decoded = decode_signal_->get_decoded_sample_count(current_segment_, true); if (sample_count == samples_decoded) return;