]> sigrok.org Git - pulseview.git/blob - pv/data/decodesignal.cpp
e8206a088bac285077271d0d5f6db08cd442649b
[pulseview.git] / pv / data / decodesignal.cpp
1 /*
2  * This file is part of the PulseView project.
3  *
4  * Copyright (C) 2017 Soeren Apel <soeren@apelpie.net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <limits>
21
22 #include <QDebug>
23
24 #include "logic.hpp"
25 #include "logicsegment.hpp"
26 #include "decodesignal.hpp"
27 #include "signaldata.hpp"
28
29 #include <pv/binding/decoder.hpp>
30 #include <pv/data/decode/decoder.hpp>
31 #include <pv/data/decode/row.hpp>
32 #include <pv/session.hpp>
33
34 using std::lock_guard;
35 using std::make_pair;
36 using std::make_shared;
37 using std::min;
38 using std::shared_ptr;
39 using std::unique_lock;
40 using pv::data::decode::Annotation;
41 using pv::data::decode::Decoder;
42 using pv::data::decode::Row;
43
44 namespace pv {
45 namespace data {
46
47 const double DecodeSignal::DecodeMargin = 1.0;
48 const double DecodeSignal::DecodeThreshold = 0.2;
49 const int64_t DecodeSignal::DecodeChunkLength = 256 * 1024;
50
51 mutex DecodeSignal::global_srd_mutex_;
52
53
54 DecodeSignal::DecodeSignal(pv::Session &session) :
55         SignalBase(nullptr, SignalBase::DecodeChannel),
56         session_(session),
57         srd_session_(nullptr),
58         logic_mux_data_invalid_(false),
59         start_time_(0),
60         samplerate_(0),
61         samples_decoded_(0),
62         frame_complete_(false)
63 {
64         connect(&session_, SIGNAL(capture_state_changed(int)),
65                 this, SLOT(on_capture_state_changed(int)));
66
67         set_name(tr("Empty decoder signal"));
68 }
69
70 DecodeSignal::~DecodeSignal()
71 {
72         if (decode_thread_.joinable()) {
73                 decode_interrupt_ = true;
74                 decode_input_cond_.notify_one();
75                 decode_thread_.join();
76         }
77
78         if (logic_mux_thread_.joinable()) {
79                 logic_mux_interrupt_ = true;
80                 logic_mux_cond_.notify_one();
81                 logic_mux_thread_.join();
82         }
83
84         stop_srd_session();
85 }
86
87 const vector< shared_ptr<Decoder> >& DecodeSignal::decoder_stack() const
88 {
89         return stack_;
90 }
91
92 void DecodeSignal::stack_decoder(srd_decoder *decoder)
93 {
94         assert(decoder);
95         stack_.push_back(make_shared<decode::Decoder>(decoder));
96
97         // Set name if this decoder is the first in the list
98         if (stack_.size() == 1)
99                 set_name(QString::fromUtf8(decoder->name));
100
101         // Include the newly created decode channels in the channel lists
102         update_channel_list();
103
104         auto_assign_signals();
105         commit_decoder_channels();
106         begin_decode();
107 }
108
109 void DecodeSignal::remove_decoder(int index)
110 {
111         assert(index >= 0);
112         assert(index < (int)stack_.size());
113
114         // Find the decoder in the stack
115         auto iter = stack_.begin();
116         for (int i = 0; i < index; i++, iter++)
117                 assert(iter != stack_.end());
118
119         // Delete the element
120         stack_.erase(iter);
121
122         // Update channels and decoded data
123         update_channel_list();
124         begin_decode();
125 }
126
127 bool DecodeSignal::toggle_decoder_visibility(int index)
128 {
129         auto iter = stack_.cbegin();
130         for (int i = 0; i < index; i++, iter++)
131                 assert(iter != stack_.end());
132
133         shared_ptr<Decoder> dec = *iter;
134
135         // Toggle decoder visibility
136         bool state = false;
137         if (dec) {
138                 state = !dec->shown();
139                 dec->show(state);
140         }
141
142         return state;
143 }
144
145 void DecodeSignal::reset_decode()
146 {
147         stop_srd_session();
148
149         frame_complete_ = false;
150         samples_decoded_ = 0;
151         error_message_ = QString();
152         rows_.clear();
153         class_rows_.clear();
154 }
155
156 void DecodeSignal::begin_decode()
157 {
158         if (decode_thread_.joinable()) {
159                 decode_interrupt_ = true;
160                 decode_input_cond_.notify_one();
161                 decode_thread_.join();
162         }
163
164         if (logic_mux_thread_.joinable()) {
165                 logic_mux_interrupt_ = true;
166                 logic_mux_cond_.notify_one();
167                 logic_mux_thread_.join();
168         }
169
170         reset_decode();
171
172         if (stack_.size() == 0) {
173                 error_message_ = tr("No decoders");
174                 return;
175         }
176
177         assert(channels_.size() > 0);
178
179         if (get_assigned_signal_count() == 0) {
180                 error_message_ = tr("There are no channels assigned to this decoder");
181                 return;
182         }
183
184         // Make sure that all assigned channels still provide logic data
185         // (can happen when a converted signal was assigned but the
186         // conversion removed in the meanwhile)
187         for (data::DecodeChannel &ch : channels_)
188                 if (ch.assigned_signal && !(ch.assigned_signal->logic_data() != nullptr))
189                         ch.assigned_signal = nullptr;
190
191         // Check that all decoders have the required channels
192         for (const shared_ptr<decode::Decoder> &dec : stack_)
193                 if (!dec->have_required_channels()) {
194                         error_message_ = tr("One or more required channels "
195                                 "have not been specified");
196                         return;
197                 }
198
199         // Add annotation classes
200         for (const shared_ptr<decode::Decoder> &dec : stack_) {
201                 assert(dec);
202                 const srd_decoder *const decc = dec->decoder();
203                 assert(dec->decoder());
204
205                 // Add a row for the decoder if it doesn't have a row list
206                 if (!decc->annotation_rows)
207                         rows_[Row(decc)] = decode::RowData();
208
209                 // Add the decoder rows
210                 for (const GSList *l = decc->annotation_rows; l; l = l->next) {
211                         const srd_decoder_annotation_row *const ann_row =
212                                 (srd_decoder_annotation_row *)l->data;
213                         assert(ann_row);
214
215                         const Row row(decc, ann_row);
216
217                         // Add a new empty row data object
218                         rows_[row] = decode::RowData();
219
220                         // Map out all the classes
221                         for (const GSList *ll = ann_row->ann_classes;
222                                 ll; ll = ll->next)
223                                 class_rows_[make_pair(decc,
224                                         GPOINTER_TO_INT(ll->data))] = row;
225                 }
226         }
227
228         // Free the logic data and its segment(s) if it needs to be updated
229         if (logic_mux_data_invalid_)
230                 logic_mux_data_.reset();
231
232         if (!logic_mux_data_) {
233                 const int64_t ch_count = get_assigned_signal_count();
234                 const int64_t unit_size = (ch_count + 7) / 8;
235                 logic_mux_data_ = make_shared<Logic>(ch_count);
236                 segment_ = make_shared<LogicSegment>(*logic_mux_data_, unit_size, samplerate_);
237                 logic_mux_data_->push_segment(segment_);
238         }
239
240         // Make sure the logic output data is complete and up-to-date
241         logic_mux_interrupt_ = false;
242         logic_mux_thread_ = std::thread(&DecodeSignal::logic_mux_proc, this);
243
244         // Decode the muxed logic data
245         decode_interrupt_ = false;
246         decode_thread_ = std::thread(&DecodeSignal::decode_proc, this);
247
248         // Receive notifications when new sample data is available
249         connect_input_notifiers();
250 }
251
252 QString DecodeSignal::error_message() const
253 {
254         lock_guard<mutex> lock(output_mutex_);
255         return error_message_;
256 }
257
258 const vector<data::DecodeChannel> DecodeSignal::get_channels() const
259 {
260         return channels_;
261 }
262
263 void DecodeSignal::auto_assign_signals()
264 {
265         bool new_assignment = false;
266
267         // Try to auto-select channels that don't have signals assigned yet
268         for (data::DecodeChannel &ch : channels_) {
269                 if (ch.assigned_signal)
270                         continue;
271
272                 for (shared_ptr<data::SignalBase> s : session_.signalbases()) {
273                         const QString ch_name = ch.name.toLower();
274                         const QString s_name = s->name().toLower();
275
276                         if (s->logic_data() &&
277                                 ((ch_name.contains(s_name)) || (s_name.contains(ch_name)))) {
278                                 ch.assigned_signal = s.get();
279                                 new_assignment = true;
280                         }
281                 }
282         }
283
284         if (new_assignment) {
285                 logic_mux_data_invalid_ = true;
286                 commit_decoder_channels();
287                 channels_updated();
288         }
289 }
290
291 void DecodeSignal::assign_signal(const uint16_t channel_id, const SignalBase *signal)
292 {
293         for (data::DecodeChannel &ch : channels_)
294                 if (ch.id == channel_id) {
295                         ch.assigned_signal = signal;
296                         logic_mux_data_invalid_ = true;
297                 }
298
299         commit_decoder_channels();
300         channels_updated();
301         begin_decode();
302 }
303
304 int DecodeSignal::get_assigned_signal_count() const
305 {
306         // Count all channels that have a signal assigned to them
307         return count_if(channels_.begin(), channels_.end(),
308                 [](data::DecodeChannel ch) { return ch.assigned_signal; });
309 }
310
311 void DecodeSignal::set_initial_pin_state(const uint16_t channel_id, const int init_state)
312 {
313         for (data::DecodeChannel &ch : channels_)
314                 if (ch.id == channel_id)
315                         ch.initial_pin_state = init_state;
316
317         channels_updated();
318
319         begin_decode();
320 }
321
322 double DecodeSignal::samplerate() const
323 {
324         return samplerate_;
325 }
326
327 const pv::util::Timestamp& DecodeSignal::start_time() const
328 {
329         return start_time_;
330 }
331
332 int64_t DecodeSignal::get_working_sample_count() const
333 {
334         // The working sample count is the highest sample number for
335         // which all used signals have data available, so go through
336         // all channels and use the lowest overall sample count of the
337         // current segment
338
339         // TODO Currently, we assume only a single segment exists
340
341         int64_t count = std::numeric_limits<int64_t>::max();
342         bool no_signals_assigned = true;
343
344         for (const data::DecodeChannel &ch : channels_)
345                 if (ch.assigned_signal) {
346                         no_signals_assigned = false;
347
348                         const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
349                         if (!logic_data || logic_data->logic_segments().empty())
350                                 return 0;
351
352                         const shared_ptr<LogicSegment> segment = logic_data->logic_segments().front();
353                         count = min(count, (int64_t)segment->get_sample_count());
354                 }
355
356         return (no_signals_assigned ? 0 : count);
357 }
358
359 int64_t DecodeSignal::get_decoded_sample_count() const
360 {
361         lock_guard<mutex> decode_lock(output_mutex_);
362         return samples_decoded_;
363 }
364
365 vector<Row> DecodeSignal::visible_rows() const
366 {
367         lock_guard<mutex> lock(output_mutex_);
368
369         vector<Row> rows;
370
371         for (const shared_ptr<decode::Decoder> &dec : stack_) {
372                 assert(dec);
373                 if (!dec->shown())
374                         continue;
375
376                 const srd_decoder *const decc = dec->decoder();
377                 assert(dec->decoder());
378
379                 // Add a row for the decoder if it doesn't have a row list
380                 if (!decc->annotation_rows)
381                         rows.emplace_back(decc);
382
383                 // Add the decoder rows
384                 for (const GSList *l = decc->annotation_rows; l; l = l->next) {
385                         const srd_decoder_annotation_row *const ann_row =
386                                 (srd_decoder_annotation_row *)l->data;
387                         assert(ann_row);
388                         rows.emplace_back(decc, ann_row);
389                 }
390         }
391
392         return rows;
393 }
394
395 void DecodeSignal::get_annotation_subset(
396         vector<pv::data::decode::Annotation> &dest,
397         const decode::Row &row, uint64_t start_sample,
398         uint64_t end_sample) const
399 {
400         lock_guard<mutex> lock(output_mutex_);
401
402         const auto iter = rows_.find(row);
403         if (iter != rows_.end())
404                 (*iter).second.get_annotation_subset(dest,
405                         start_sample, end_sample);
406 }
407
408 void DecodeSignal::save_settings(QSettings &settings) const
409 {
410         SignalBase::save_settings(settings);
411
412         // TODO Save decoder stack, channel mapping and decoder options
413 }
414
415 void DecodeSignal::restore_settings(QSettings &settings)
416 {
417         SignalBase::restore_settings(settings);
418
419         // TODO Restore decoder stack, channel mapping and decoder options
420 }
421
422 void DecodeSignal::update_channel_list()
423 {
424         vector<data::DecodeChannel> prev_channels = channels_;
425         channels_.clear();
426
427         uint16_t id = 0;
428
429         // Copy existing entries, create new as needed
430         for (shared_ptr<Decoder> decoder : stack_) {
431                 const srd_decoder* srd_d = decoder->decoder();
432                 const GSList *l;
433
434                 // Mandatory channels
435                 for (l = srd_d->channels; l; l = l->next) {
436                         const struct srd_channel *const pdch = (struct srd_channel *)l->data;
437                         bool ch_added = false;
438
439                         // Copy but update ID if this channel was in the list before
440                         for (data::DecodeChannel &ch : prev_channels)
441                                 if (ch.pdch_ == pdch) {
442                                         ch.id = id++;
443                                         channels_.push_back(ch);
444                                         ch_added = true;
445                                         break;
446                                 }
447
448                         if (!ch_added) {
449                                 // Create new entry without a mapped signal
450                                 data::DecodeChannel ch = {id++, false, nullptr,
451                                         QString::fromUtf8(pdch->name), QString::fromUtf8(pdch->desc),
452                                         SRD_INITIAL_PIN_SAME_AS_SAMPLE0, decoder, pdch};
453                                 channels_.push_back(ch);
454                         }
455                 }
456
457                 // Optional channels
458                 for (l = srd_d->opt_channels; l; l = l->next) {
459                         const struct srd_channel *const pdch = (struct srd_channel *)l->data;
460                         bool ch_added = false;
461
462                         // Copy but update ID if this channel was in the list before
463                         for (data::DecodeChannel &ch : prev_channels)
464                                 if (ch.pdch_ == pdch) {
465                                         ch.id = id++;
466                                         channels_.push_back(ch);
467                                         ch_added = true;
468                                         break;
469                                 }
470
471                         if (!ch_added) {
472                                 // Create new entry without a mapped signal
473                                 data::DecodeChannel ch = {id++, true, nullptr,
474                                         QString::fromUtf8(pdch->name), QString::fromUtf8(pdch->desc),
475                                         SRD_INITIAL_PIN_SAME_AS_SAMPLE0, decoder, pdch};
476                                 channels_.push_back(ch);
477                         }
478                 }
479         }
480
481         // Invalidate the logic output data if the channel assignment changed
482         if (prev_channels.size() != channels_.size()) {
483                 // The number of channels changed, there's definitely a difference
484                 logic_mux_data_invalid_ = true;
485         } else {
486                 // Same number but assignment may still differ, so compare all channels
487                 for (size_t i = 0; i < channels_.size(); i++) {
488                         const data::DecodeChannel &p_ch = prev_channels[i];
489                         const data::DecodeChannel &ch = channels_[i];
490
491                         if ((p_ch.pdch_ != ch.pdch_) ||
492                                 (p_ch.assigned_signal != ch.assigned_signal)) {
493                                 logic_mux_data_invalid_ = true;
494                                 break;
495                         }
496                 }
497
498         }
499
500         channels_updated();
501 }
502
503 void DecodeSignal::commit_decoder_channels()
504 {
505         // Submit channel list to every decoder, containing only the relevant channels
506         for (shared_ptr<decode::Decoder> dec : stack_) {
507                 vector<data::DecodeChannel*> channel_list;
508
509                 for (data::DecodeChannel &ch : channels_)
510                         if (ch.decoder_ == dec)
511                                 channel_list.push_back(&ch);
512
513                 dec->set_channels(channel_list);
514         }
515 }
516
517 void DecodeSignal::mux_logic_samples(const int64_t start, const int64_t end)
518 {
519         // Enforce end to be greater than start
520         if (end <= start)
521                 return;
522
523         // Fetch all segments and their data
524         // TODO Currently, we assume only a single segment exists
525         vector<shared_ptr<LogicSegment> > segments;
526         vector<const uint8_t*> signal_data;
527         vector<uint8_t> signal_in_bytepos;
528         vector<uint8_t> signal_in_bitpos;
529
530         for (data::DecodeChannel &ch : channels_)
531                 if (ch.assigned_signal) {
532                         const shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
533                         const shared_ptr<LogicSegment> segment = logic_data->logic_segments().front();
534                         segments.push_back(segment);
535                         signal_data.push_back(segment->get_samples(start, end));
536
537                         const int bitpos = ch.assigned_signal->logic_bit_index();
538                         signal_in_bytepos.push_back(bitpos / 8);
539                         signal_in_bitpos.push_back(bitpos % 8);
540                 }
541
542         // Perform the muxing of signal data into the output data
543         uint8_t* output = new uint8_t[(end - start) * segment_->unit_size()];
544         unsigned int signal_count = signal_data.size();
545
546         for (int64_t sample_cnt = 0; sample_cnt < (end - start); sample_cnt++) {
547                 int bitpos = 0;
548                 uint8_t bytepos = 0;
549
550                 const int out_sample_pos = sample_cnt * segment_->unit_size();
551                 for (unsigned int i = 0; i < segment_->unit_size(); i++)
552                         output[out_sample_pos + i] = 0;
553
554                 for (unsigned int i = 0; i < signal_count; i++) {
555                         const int in_sample_pos = sample_cnt * segments[i]->unit_size();
556                         const uint8_t in_sample = 1 &
557                                 ((signal_data[i][in_sample_pos + signal_in_bytepos[i]]) >> (signal_in_bitpos[i]));
558
559                         const uint8_t out_sample = output[out_sample_pos + bytepos];
560
561                         output[out_sample_pos + bytepos] = out_sample | (in_sample << bitpos);
562
563                         bitpos++;
564                         if (bitpos > 7) {
565                                 bitpos = 0;
566                                 bytepos++;
567                         }
568                 }
569         }
570
571         segment_->append_payload(output, (end - start) * segment_->unit_size());
572         delete[] output;
573
574         for (const uint8_t* data : signal_data)
575                 delete[] data;
576 }
577
578 void DecodeSignal::logic_mux_proc()
579 {
580         do {
581                 const uint64_t input_sample_count = get_working_sample_count();
582                 const uint64_t output_sample_count = segment_->get_sample_count();
583
584                 const uint64_t samples_to_process =
585                         (input_sample_count > output_sample_count) ?
586                         (input_sample_count - output_sample_count) : 0;
587
588                 // Process the samples if necessary...
589                 if (samples_to_process > 0) {
590                         const uint64_t unit_size = segment_->unit_size();
591                         const uint64_t chunk_sample_count = DecodeChunkLength / unit_size;
592
593                         uint64_t processed_samples = 0;
594                         do {
595                                 const uint64_t start_sample = output_sample_count + processed_samples;
596                                 const uint64_t sample_count =
597                                         min(samples_to_process - processed_samples,     chunk_sample_count);
598
599                                 mux_logic_samples(start_sample, start_sample + sample_count);
600                                 processed_samples += sample_count;
601
602                                 // ...and process the newly muxed logic data
603                                 decode_input_cond_.notify_one();
604                         } while (processed_samples < samples_to_process);
605                 }
606
607                 if (samples_to_process == 0) {
608                         // Wait for more input
609                         unique_lock<mutex> logic_mux_lock(logic_mux_mutex_);
610                         logic_mux_cond_.wait(logic_mux_lock);
611                 }
612         } while (!logic_mux_interrupt_);
613
614         // No more input data and session is stopped, let the decode thread
615         // process any pending data, terminate and release the global SRD mutex
616         // in order to let other decoders run
617         decode_input_cond_.notify_one();
618 }
619
620 void DecodeSignal::query_input_metadata()
621 {
622         // Update the samplerate and start time because we cannot start
623         // the libsrd session without the current samplerate
624
625         // TODO Currently we assume all channels have the same sample rate
626         // and start time
627         bool samplerate_valid = false;
628
629         auto any_channel = find_if(channels_.begin(), channels_.end(),
630                 [](data::DecodeChannel ch) { return ch.assigned_signal; });
631
632         shared_ptr<Logic> logic_data =
633                 any_channel->assigned_signal->logic_data();
634
635         do {
636                 if (!logic_data->logic_segments().empty()) {
637                         shared_ptr<LogicSegment> first_segment =
638                                 any_channel->assigned_signal->logic_data()->logic_segments().front();
639                         start_time_ = first_segment->start_time();
640                         samplerate_ = first_segment->samplerate();
641                         if (samplerate_ > 0)
642                                 samplerate_valid = true;
643                 }
644
645                 if (!samplerate_valid) {
646                         // Wait until input data is available or an interrupt was requested
647                         unique_lock<mutex> input_wait_lock(input_mutex_);
648                         decode_input_cond_.wait(input_wait_lock);
649                 }
650         } while (!samplerate_valid && !decode_interrupt_);
651 }
652
653 void DecodeSignal::decode_data(
654         const int64_t abs_start_samplenum, const int64_t sample_count)
655 {
656         const int64_t unit_size = segment_->unit_size();
657         const int64_t chunk_sample_count = DecodeChunkLength / unit_size;
658
659         for (int64_t i = abs_start_samplenum;
660                 !decode_interrupt_ && (i < (abs_start_samplenum + sample_count));
661                 i += chunk_sample_count) {
662
663                 const int64_t chunk_end = min(i + chunk_sample_count,
664                         abs_start_samplenum + sample_count);
665
666                 const uint8_t* chunk = segment_->get_samples(i, chunk_end);
667
668                 if (srd_session_send(srd_session_, i, chunk_end, chunk,
669                                 (chunk_end - i) * unit_size, unit_size) != SRD_OK) {
670                         error_message_ = tr("Decoder reported an error");
671                         delete[] chunk;
672                         break;
673                 }
674
675                 delete[] chunk;
676
677                 // Notify the frontend that we processed some data and
678                 // possibly have new annotations as well
679                 new_annotations();
680
681                 {
682                         lock_guard<mutex> lock(output_mutex_);
683                         samples_decoded_ = chunk_end;
684                 }
685         }
686 }
687
688 void DecodeSignal::decode_proc()
689 {
690         query_input_metadata();
691
692         if (decode_interrupt_)
693                 return;
694
695         start_srd_session();
696
697         uint64_t sample_count;
698         uint64_t abs_start_samplenum = 0;
699         do {
700                 // Keep processing new samples until we exhaust the input data
701                 do {
702                         // Prevent any other decode threads from accessing libsigrokdecode
703                         lock_guard<mutex> srd_lock(global_srd_mutex_);
704
705                         {
706                                 lock_guard<mutex> input_lock(input_mutex_);
707                                 sample_count = segment_->get_sample_count() - abs_start_samplenum;
708                         }
709
710                         if (sample_count > 0) {
711                                 decode_data(abs_start_samplenum, sample_count);
712                                 abs_start_samplenum += sample_count;
713                         }
714                 } while (error_message_.isEmpty() && (sample_count > 0));
715
716                 if (error_message_.isEmpty()) {
717                         // Wait for new input data or an interrupt was requested
718                         unique_lock<mutex> input_wait_lock(input_mutex_);
719                         decode_input_cond_.wait(input_wait_lock);
720                 }
721         } while (error_message_.isEmpty() && !decode_interrupt_);
722 }
723
724 void DecodeSignal::start_srd_session()
725 {
726         if (srd_session_)
727                 stop_srd_session();
728
729         // Create the session
730         srd_session_new(&srd_session_);
731         assert(srd_session_);
732
733         // Create the decoders
734         srd_decoder_inst *prev_di = nullptr;
735         for (const shared_ptr<decode::Decoder> &dec : stack_) {
736                 srd_decoder_inst *const di = dec->create_decoder_inst(srd_session_);
737
738                 if (!di) {
739                         error_message_ = tr("Failed to create decoder instance");
740                         srd_session_destroy(srd_session_);
741                         return;
742                 }
743
744                 if (prev_di)
745                         srd_inst_stack(srd_session_, prev_di, di);
746
747                 prev_di = di;
748         }
749
750         // Start the session
751         srd_session_metadata_set(srd_session_, SRD_CONF_SAMPLERATE,
752                 g_variant_new_uint64(samplerate_));
753
754         srd_pd_output_callback_add(srd_session_, SRD_OUTPUT_ANN,
755                 DecodeSignal::annotation_callback, this);
756
757         srd_session_start(srd_session_);
758 }
759
760 void DecodeSignal::stop_srd_session()
761 {
762         if (srd_session_) {
763                 // Destroy the session
764                 srd_session_destroy(srd_session_);
765                 srd_session_ = nullptr;
766         }
767 }
768
769 void DecodeSignal::connect_input_notifiers()
770 {
771         // Disconnect the notification slot from the previous set of signals
772         disconnect(this, SLOT(on_data_received()));
773
774         // Connect the currently used signals to our slot
775         for (data::DecodeChannel &ch : channels_) {
776                 if (!ch.assigned_signal)
777                         continue;
778
779                 shared_ptr<Logic> logic_data = ch.assigned_signal->logic_data();
780                 connect(logic_data.get(), SIGNAL(samples_added(QObject*, uint64_t, uint64_t)),
781                         this, SLOT(on_data_received()));
782         }
783 }
784
785 void DecodeSignal::annotation_callback(srd_proto_data *pdata, void *decode_signal)
786 {
787         assert(pdata);
788         assert(decoder);
789
790         DecodeSignal *const ds = (DecodeSignal*)decode_signal;
791         assert(ds);
792
793         lock_guard<mutex> lock(ds->output_mutex_);
794
795         const decode::Annotation a(pdata);
796
797         // Find the row
798         assert(pdata->pdo);
799         assert(pdata->pdo->di);
800         const srd_decoder *const decc = pdata->pdo->di->decoder;
801         assert(decc);
802
803         auto row_iter = ds->rows_.end();
804
805         // Try looking up the sub-row of this class
806         const auto r = ds->class_rows_.find(make_pair(decc, a.format()));
807         if (r != ds->class_rows_.end())
808                 row_iter = ds->rows_.find((*r).second);
809         else {
810                 // Failing that, use the decoder as a key
811                 row_iter = ds->rows_.find(Row(decc));
812         }
813
814         assert(row_iter != ds->rows_.end());
815         if (row_iter == ds->rows_.end()) {
816                 qDebug() << "Unexpected annotation: decoder = " << decc <<
817                         ", format = " << a.format();
818                 assert(false);
819                 return;
820         }
821
822         // Add the annotation
823         (*row_iter).second.push_annotation(a);
824 }
825
826 void DecodeSignal::on_capture_state_changed(int state)
827 {
828         // If a new acquisition was started, we need to start decoding from scratch
829         if (state == Session::Running)
830                 begin_decode();
831 }
832
833 void DecodeSignal::on_data_received()
834 {
835         logic_mux_cond_.notify_one();
836 }
837
838 } // namespace data
839 } // namespace pv