From: Joel Holdsworth Date: Mon, 26 Aug 2013 16:16:27 +0000 (+0100) Subject: Integrated decode X-Git-Url: http://git.code-monkey.de/?p=pulseview.git;a=commitdiff_plain;h=e0fc58100fbcd6c3bfd5aecb213d7541a3436622 Integrated decode --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d268e7..4d1e919 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,12 +146,14 @@ set(pulseview_SOURCES set(pulseview_HEADERS pv/mainwindow.h pv/sigsession.h + pv/data/decoder.h pv/dialogs/about.h pv/dialogs/connect.h pv/dialogs/deviceoptions.h pv/toolbars/contextbar.h pv/toolbars/samplingbar.h pv/view/cursor.h + pv/view/decodesignal.h pv/view/header.h pv/view/logicsignal.h pv/view/marginwidget.h diff --git a/pv/data/decoder.cpp b/pv/data/decoder.cpp index e1be16e..2848d16 100644 --- a/pv/data/decoder.cpp +++ b/pv/data/decoder.cpp @@ -20,9 +20,14 @@ #include +#include + #include "decoder.h" -#include +#include +#include +#include +#include using namespace boost; using namespace std; @@ -30,6 +35,10 @@ using namespace std; namespace pv { namespace data { +const double Decoder::DecodeMargin = 1.0; +const double Decoder::DecodeThreshold = 0.2; +const int64_t Decoder::DecodeChunkLength = 4096; + Decoder::Decoder(const srd_decoder *const dec, std::map > probes) : @@ -38,6 +47,7 @@ Decoder::Decoder(const srd_decoder *const dec, _decoder_inst(NULL) { init_decoder(); + begin_decode(); } Decoder::~Decoder() @@ -51,13 +61,33 @@ const srd_decoder* Decoder::get_decoder() const return _decoder; } +const vector< shared_ptr > + Decoder::annotations() const +{ + lock_guard lock(_annotations_mutex); + return _annotations; +} + void Decoder::begin_decode() { _decode_thread.interrupt(); _decode_thread.join(); + if (_probes.empty()) + return; + + // We get the logic data of the first probe in the list. + // This works because we are currently assuming all + // LogicSignals have the same data/snapshot + shared_ptr sig = (*_probes.begin()).second; + assert(sig); + const pv::view::LogicSignal *const l = + dynamic_cast(sig.get()); + assert(l); + shared_ptr data = l->data(); + _decode_thread = boost::thread(&Decoder::decode_proc, this, - shared_ptr()); + data); } void Decoder::clear_snapshots() @@ -66,9 +96,26 @@ void Decoder::clear_snapshots() void Decoder::init_decoder() { + if (!_probes.empty()) + { + shared_ptr logic_signal = + dynamic_pointer_cast( + (*_probes.begin()).second); + if (logic_signal) { + shared_ptr data( + logic_signal->data()); + if (data) { + _samplerate = data->get_samplerate(); + _start_time = data->get_start_time(); + } + } + } + _decoder_inst = srd_inst_new(_decoder->id, NULL); assert(_decoder_inst); + _decoder_inst->data_samplerate = _samplerate; + GHashTable *probes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); @@ -88,7 +135,56 @@ void Decoder::init_decoder() void Decoder::decode_proc(shared_ptr data) { - (void)data; + uint8_t chunk[DecodeChunkLength]; + + assert(data); + + _annotations.clear(); + + const deque< shared_ptr > &snapshots = + data->get_snapshots(); + if (snapshots.empty()) + return; + + const shared_ptr &snapshot = + snapshots.front(); + const int64_t sample_count = snapshot->get_sample_count() - 1; + double samplerate = data->get_samplerate(); + + // Show sample rate as 1Hz when it is unknown + if (samplerate == 0.0) + samplerate = 1.0; + + srd_session_start(_probes.size(), snapshot->unit_size(), samplerate); + + srd_pd_output_callback_add(SRD_OUTPUT_ANN, + Decoder::annotation_callback, this); + + for (int64_t i = 0; + !this_thread::interruption_requested() && i < sample_count; + i += DecodeChunkLength) + { + const int64_t chunk_end = min( + i + DecodeChunkLength, sample_count); + snapshot->get_samples(chunk, i, chunk_end); + + if (srd_session_send(i, chunk, chunk_end - i) != SRD_OK) + break; + } +} + +void Decoder::annotation_callback(srd_proto_data *pdata, void *decoder) +{ + using namespace pv::view::decode; + + assert(pdata); + assert(decoder); + + Decoder *const d = (Decoder*)decoder; + + shared_ptr a(new Annotation(pdata)); + lock_guard lock(d->_annotations_mutex); + d->_annotations.push_back(a); } } // namespace data diff --git a/pv/data/decoder.h b/pv/data/decoder.h index dcf12fe..4cae427 100644 --- a/pv/data/decoder.h +++ b/pv/data/decoder.h @@ -28,6 +28,8 @@ #include #include +#include + struct srd_decoder; struct srd_decoder_inst; struct srd_probe; @@ -36,14 +38,26 @@ namespace pv { namespace view { class Signal; + +namespace decode { +class Annotation; +} + } namespace data { class Logic; -class Decoder : public SignalData +class Decoder : public QObject, public SignalData { + Q_OBJECT + +private: + static const double DecodeMargin; + static const double DecodeThreshold; + static const int64_t DecodeChunkLength; + public: Decoder(const srd_decoder *const decoder, std::map > + annotations() const; void clear_snapshots(); private: + void begin_decode(); + void init_decoder(); void decode_proc(boost::shared_ptr data); + static void annotation_callback(srd_proto_data *pdata, + void *decoder); + private: const srd_decoder *const _decoder; std::map > @@ -69,6 +89,10 @@ private: srd_decoder_inst *_decoder_inst; + mutable boost::mutex _annotations_mutex; + std::vector< boost::shared_ptr > + _annotations; + boost::thread _decode_thread; }; diff --git a/pv/data/signaldata.h b/pv/data/signaldata.h index c43b7a3..c5ed6bd 100644 --- a/pv/data/signaldata.h +++ b/pv/data/signaldata.h @@ -40,8 +40,7 @@ public: virtual void clear_snapshots() = 0; protected: - const double _start_time; - + double _start_time; double _samplerate; }; diff --git a/pv/sigsession.cpp b/pv/sigsession.cpp index cad702d..ffe37d2 100644 --- a/pv/sigsession.cpp +++ b/pv/sigsession.cpp @@ -199,6 +199,13 @@ void SigSession::add_decoder(srd_decoder *const dec, { { lock_guard lock(_signals_mutex); + + if (!_decode_traces.empty()) { + qDebug("Currently only one decode trace can be added " + "at once"); + _decode_traces.clear(); + } + shared_ptr decoder( new data::Decoder(dec, probes)); shared_ptr d( diff --git a/pv/view/decodesignal.cpp b/pv/view/decodesignal.cpp index 556631c..44144d1 100644 --- a/pv/view/decodesignal.cpp +++ b/pv/view/decodesignal.cpp @@ -25,6 +25,7 @@ extern "C" { #include "decodesignal.h" #include +#include using namespace boost; using namespace std; @@ -37,6 +38,8 @@ DecodeSignal::DecodeSignal(pv::SigSession &session, Trace(session, QString(decoder->get_decoder()->name)), _decoder(decoder) { + assert(_decoder); + _colour = Qt::red; } @@ -50,6 +53,12 @@ bool DecodeSignal::enabled() const return true; } +void DecodeSignal::set_view(pv::view::View *view) +{ + assert(view); + Trace::set_view(view); +} + void DecodeSignal::paint(QPainter &p, int left, int right) { (void)p; diff --git a/pv/view/decodesignal.h b/pv/view/decodesignal.h index 3180458..95459d6 100644 --- a/pv/view/decodesignal.h +++ b/pv/view/decodesignal.h @@ -35,6 +35,8 @@ namespace view { class DecodeSignal : public Trace { + Q_OBJECT + public: DecodeSignal(pv::SigSession &session, boost::shared_ptr decoder); @@ -43,6 +45,8 @@ public: bool enabled() const; + void set_view(pv::view::View *view); + /** * Paints the trace with a QPainter * @param p the QPainter to paint into. @@ -63,6 +67,8 @@ private: private: boost::shared_ptr _decoder; + + uint64_t _decode_start, _decode_end; }; } // namespace view diff --git a/pv/view/logicsignal.cpp b/pv/view/logicsignal.cpp index 3624ccf..bc4f531 100644 --- a/pv/view/logicsignal.cpp +++ b/pv/view/logicsignal.cpp @@ -118,6 +118,11 @@ void LogicSignal::init_context_bar_actions(QWidget *parent) this, SLOT(on_trigger_change())); } +boost::shared_ptr LogicSignal::data() const +{ + return _data; +} + const list LogicSignal::get_context_bar_actions() { GVariant *gvar; diff --git a/pv/view/logicsignal.h b/pv/view/logicsignal.h index b0a328c..0237875 100644 --- a/pv/view/logicsignal.h +++ b/pv/view/logicsignal.h @@ -54,6 +54,8 @@ public: void init_context_bar_actions(QWidget *parent); + boost::shared_ptr data() const; + const std::list get_context_bar_actions(); /** diff --git a/pv/view/trace.h b/pv/view/trace.h index 4d6b49b..ffd87fa 100644 --- a/pv/view/trace.h +++ b/pv/view/trace.h @@ -84,7 +84,7 @@ public: */ virtual bool enabled() const = 0; - void set_view(pv::view::View *view); + virtual void set_view(pv::view::View *view); /** * Paints the trace with a QPainter diff --git a/pv/view/view.cpp b/pv/view/view.cpp index e6ce662..54ab4ff 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -159,6 +159,7 @@ void View::set_scale_offset(double scale, double offset) update_scroll(); _ruler->update(); _viewport->update(); + scale_offset_changed(); } vector< shared_ptr > View::get_traces() const diff --git a/pv/view/view.h b/pv/view/view.h index dce8c25..25e43b8 100644 --- a/pv/view/view.h +++ b/pv/view/view.h @@ -133,6 +133,8 @@ signals: void selection_changed(); + void scale_offset_changed(); + private: void get_scroll_layout(double &length, double &offset) const;