X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=pv%2Fdata%2Fdecodesignal.cpp;h=339c85dd01dd0305879bce1dc88d3fde6d8ec6e3;hb=a3ebd5561086f4fef6570b3ab5be0a5592724731;hp=a7bcee59c78185c9cd0d0540ac299ed4143505d4;hpb=a8a9222df63fef3805dd423aebae0b33f4a9ec6c;p=pulseview.git diff --git a/pv/data/decodesignal.cpp b/pv/data/decodesignal.cpp index a7bcee59..339c85dd 100644 --- a/pv/data/decodesignal.cpp +++ b/pv/data/decodesignal.cpp @@ -221,13 +221,6 @@ void DecodeSignal::begin_decode() } } - // TODO Currently we assume all channels have the same sample rate - auto any_channel = find_if(channels_.begin(), channels_.end(), - [](data::DecodeChannel ch) { return ch.assigned_signal; }); - shared_ptr first_segment = - any_channel->assigned_signal->logic_data()->logic_segments().front(); - samplerate_ = first_segment->samplerate(); - // Free the logic data and its segment(s) if it needs to be updated if (logic_mux_data_invalid_) logic_mux_data_.reset(); @@ -240,12 +233,6 @@ void DecodeSignal::begin_decode() logic_mux_data_->push_segment(segment_); } - // Update the samplerate and start time - start_time_ = segment_->start_time(); - samplerate_ = segment_->samplerate(); - if (samplerate_ == 0.0) - samplerate_ = 1.0; - // 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); @@ -626,6 +613,37 @@ void DecodeSignal::logic_mux_proc() decode_input_cond_.notify_one(); } +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; + + auto any_channel = find_if(channels_.begin(), channels_.end(), + [](data::DecodeChannel ch) { return ch.assigned_signal; }); + + shared_ptr logic_data = + any_channel->assigned_signal->logic_data(); + + do { + if (!logic_data->logic_segments().empty()) { + shared_ptr first_segment = + any_channel->assigned_signal->logic_data()->logic_segments().front(); + start_time_ = first_segment->start_time(); + samplerate_ = first_segment->samplerate(); + if (samplerate_ > 0) + samplerate_valid = true; + } + + // Wait until input data is available or an interrupt was requested + unique_lock 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) { @@ -647,6 +665,7 @@ void DecodeSignal::decode_data( delete[] chunk; break; } + delete[] chunk; { @@ -658,6 +677,11 @@ void DecodeSignal::decode_data( void DecodeSignal::decode_proc() { + query_input_metadata(); + + if (decode_interrupt_) + return; + start_srd_session(); uint64_t sample_count; @@ -683,7 +707,7 @@ void DecodeSignal::decode_proc() // Make sure all annotations are known to the frontend new_annotations(); - // Wait for new input data or an interrupt request + // Wait for new input data or an interrupt was requested unique_lock input_wait_lock(input_mutex_); decode_input_cond_.wait(input_wait_lock); } @@ -692,37 +716,38 @@ void DecodeSignal::decode_proc() void DecodeSignal::start_srd_session() { - if (!srd_session_) { - // Create the session - srd_session_new(&srd_session_); - assert(srd_session_); + if (srd_session_) + stop_srd_session(); - // Create the decoders - srd_decoder_inst *prev_di = nullptr; - for (const shared_ptr &dec : stack_) { - srd_decoder_inst *const di = dec->create_decoder_inst(srd_session_); + // Create the session + srd_session_new(&srd_session_); + assert(srd_session_); - if (!di) { - error_message_ = tr("Failed to create decoder instance"); - srd_session_destroy(srd_session_); - return; - } - - if (prev_di) - srd_inst_stack(srd_session_, prev_di, di); + // Create the decoders + srd_decoder_inst *prev_di = nullptr; + for (const shared_ptr &dec : stack_) { + srd_decoder_inst *const di = dec->create_decoder_inst(srd_session_); - prev_di = di; + if (!di) { + error_message_ = tr("Failed to create decoder instance"); + srd_session_destroy(srd_session_); + return; } - // Start the session - srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE, - g_variant_new_uint64(samplerate_)); - - srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_ANN, - DecodeSignal::annotation_callback, this); + if (prev_di) + srd_inst_stack(srd_session_, prev_di, di); - srd_session_start(srd_session_); + prev_di = di; } + + // Start the session + srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE, + g_variant_new_uint64(samplerate_)); + + srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_ANN, + DecodeSignal::annotation_callback, this); + + srd_session_start(srd_session_); } void DecodeSignal::stop_srd_session()