]> sigrok.org Git - pulseview.git/commitdiff
DecodeSignal: Restructure metadata handling
authorSoeren Apel <redacted>
Wed, 27 Dec 2017 09:31:30 +0000 (10:31 +0100)
committerSoeren Apel <redacted>
Fri, 5 Jan 2018 21:50:31 +0000 (22:50 +0100)
Instead of handling the metadata separately from the mux/decode segments,
it's much neater to handle both together. Doing this also allows us to
remove the need for query_input_metadata() since we're taking the metadata
from the muxed logic segments.

pv/data/decodesignal.cpp
pv/data/decodesignal.hpp

index c0dbb20d8c9aca5f86921459d650ae52b53b906a..1eff9119f319de72fb1bfde4d1f13ec93e7228d6 100644 (file)
@@ -236,8 +236,6 @@ void DecodeSignal::begin_decode()
                return;
        }
 
-       create_segments();
-
        // Make sure the logic output data is complete and up-to-date
        logic_mux_interrupt_ = false;
        logic_mux_thread_ = std::thread(&DecodeSignal::logic_mux_proc, this);
@@ -807,8 +805,10 @@ void DecodeSignal::logic_mux_proc()
 
        assert(logic_mux_data_);
 
-       shared_ptr<LogicSegment> output_segment = logic_mux_data_->logic_segments().front();
-       assert(output_segment);
+       // Create initial logic mux segment
+       shared_ptr<LogicSegment> output_segment =
+               make_shared<LogicSegment>(*logic_mux_data_, logic_mux_unit_size_, 0);
+       logic_mux_data_->push_segment(output_segment);
 
        output_segment->set_samplerate(get_input_samplerate(0));
 
@@ -846,14 +846,9 @@ void DecodeSignal::logic_mux_proc()
                                // Process next segment
                                segment_id++;
 
-                               try {
-                                       output_segment = logic_mux_data_->logic_segments().at(segment_id);
-                               } catch (out_of_range) {
-                                       qDebug() << "Muxer error for" << name() << ": no logic mux segment" \
-                                               << segment_id << "in logic_mux_proc(), mux segments size is" \
-                                               << logic_mux_data_->logic_segments().size();
-                                       return;
-                               }
+                               output_segment =
+                                       make_shared<LogicSegment>(*logic_mux_data_, logic_mux_unit_size_, 0);
+                               logic_mux_data_->push_segment(output_segment);
 
                                output_segment->set_samplerate(get_input_samplerate(segment_id));
 
@@ -869,55 +864,6 @@ void DecodeSignal::logic_mux_proc()
        } while (!logic_mux_interrupt_);
 }
 
-void DecodeSignal::query_input_metadata()
-{
-       // Update the samplerate and start time because we cannot start
-       // the libsrd session without the current samplerate
-
-       // TODO Currently we assume all channels have the same sample rate
-       // and start time
-       bool samplerate_valid = false;
-       data::DecodeChannel *any_channel;
-       shared_ptr<Logic> logic_data;
-
-       do {
-               any_channel = &(*find_if(channels_.begin(), channels_.end(),
-                       [](data::DecodeChannel ch) { return ch.assigned_signal; }));
-
-               logic_data = any_channel->assigned_signal->logic_data();
-
-               if (!logic_data) {
-                       // 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 (!logic_data && !decode_interrupt_);
-
-       if (decode_interrupt_)
-               return;
-
-       do {
-               if (!logic_data->logic_segments().empty()) {
-                       shared_ptr<LogicSegment> first_segment =
-                               any_channel->assigned_signal->logic_data()->logic_segments().front();
-
-                       // We only need valid metadata in the first decode segment
-                       // so that start_srd_session() can use it
-                       segments_.at(current_segment_id_).start_time = first_segment->start_time();
-                       segments_.at(current_segment_id_).samplerate = first_segment->samplerate();
-
-                       if (segments_.at(current_segment_id_).samplerate > 0)
-                               samplerate_valid = true;
-               }
-
-               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_);
-}
-
 void DecodeSignal::decode_data(
        const int64_t abs_start_samplenum, const int64_t sample_count,
        const shared_ptr<LogicSegment> input_segment)
@@ -958,20 +904,28 @@ void DecodeSignal::decode_data(
 
 void DecodeSignal::decode_proc()
 {
-       query_input_metadata();
+       current_segment_id_ = 0;
+
+       // If there is no input data available yet, wait until it is or we're interrupted
+       if (logic_mux_data_->logic_segments().size() == 0) {
+               unique_lock<mutex> input_wait_lock(input_mutex_);
+               decode_input_cond_.wait(input_wait_lock);
+       }
 
        if (decode_interrupt_)
                return;
 
-       start_srd_session();
-
-       current_segment_id_ = 0;
        shared_ptr<LogicSegment> input_segment = logic_mux_data_->logic_segments().front();
-
        assert(input_segment);
+
+       // Create the initial segment and set its sample rate so that we can pass it to SRD
+       create_decode_segment();
        segments_.at(current_segment_id_).samplerate = input_segment->samplerate();
+       segments_.at(current_segment_id_).start_time = input_segment->start_time();
 
-       uint64_t sample_count;
+       start_srd_session();
+
+       uint64_t sample_count = 0;
        uint64_t abs_start_samplenum = 0;
        do {
                // Keep processing new samples until we exhaust the input data
@@ -1000,7 +954,10 @@ void DecodeSignal::decode_proc()
                                }
                                abs_start_samplenum = 0;
 
+                               // Create the next segment and set its metadata
+                               create_decode_segment();
                                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();
@@ -1081,44 +1038,33 @@ void DecodeSignal::connect_input_notifiers()
        }
 }
 
-void DecodeSignal::create_segments()
+void DecodeSignal::create_decode_segment()
 {
-       // Make sure we have as many segments as we need
-       const uint32_t input_segment_count = get_input_segment_count();
-
-       for (uint32_t i = logic_mux_data_->logic_segments().size(); i < input_segment_count; i++) {
-               shared_ptr<LogicSegment> segment =
-                       make_shared<LogicSegment>(*logic_mux_data_, logic_mux_unit_size_, 0);
-               logic_mux_data_->push_segment(segment);
-       }
-
-       for (uint32_t i = segments_.size(); i < input_segment_count; i++) {
-               // Create annotation segment
-               segments_.emplace_back(DecodeSegment());
+       // Create annotation segment
+       segments_.emplace_back(DecodeSegment());
 
-               // Add annotation classes
-               for (const shared_ptr<decode::Decoder> &dec : stack_) {
-                       assert(dec);
-                       const srd_decoder *const decc = dec->decoder();
-                       assert(dec->decoder());
+       // Add annotation classes
+       for (const shared_ptr<decode::Decoder> &dec : stack_) {
+               assert(dec);
+               const srd_decoder *const decc = dec->decoder();
+               assert(dec->decoder());
 
-                       // Add a row for the decoder if it doesn't have a row list
-                       if (!decc->annotation_rows)
-                               (segments_.back().annotation_rows)[Row(decc)] =
-                                       decode::RowData();
+               // Add a row for the decoder if it doesn't have a row list
+               if (!decc->annotation_rows)
+                       (segments_.back().annotation_rows)[Row(decc)] =
+                               decode::RowData();
 
-                       // 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);
+               // 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);
 
-                               const Row row(decc, ann_row);
+                       const Row row(decc, ann_row);
 
-                               // Add a new empty row data object
-                               (segments_.back().annotation_rows)[row] =
-                                       decode::RowData();
-                       }
+                       // Add a new empty row data object
+                       (segments_.back().annotation_rows)[row] =
+                               decode::RowData();
                }
        }
 }
@@ -1182,8 +1128,6 @@ void DecodeSignal::on_data_cleared()
 
 void DecodeSignal::on_data_received()
 {
-       create_segments();
-
        if (!logic_mux_thread_.joinable())
                begin_decode();
        else
index 04497ec52ff766ee7acd49bf1b6ff21bf5277275..b4f9a2cb0eb3da2795a6299879466c01ac91a724 100644 (file)
@@ -149,8 +149,6 @@ private:
 
        void logic_mux_proc();
 
-       void query_input_metadata();
-
        void decode_data(const int64_t abs_start_samplenum, const int64_t sample_count,
                const shared_ptr<LogicSegment> input_segment);
 
@@ -161,7 +159,7 @@ private:
 
        void connect_input_notifiers();
 
-       void create_segments();
+       void create_decode_segment();
 
        static void annotation_callback(srd_proto_data *pdata, void *decode_signal);