X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fdata%2Fdecoder.cpp;h=5907f649e95db58eb3c1af35763613c03505a1ca;hp=65854ee056b9384c1c0a7a774de78ee9fdb3f1b3;hb=9d20a7415bfe41d8985fb026ef0ba164de08c313;hpb=e332f6d399ecba201389c1e048239a7fe0cc87d5 diff --git a/pv/data/decoder.cpp b/pv/data/decoder.cpp index 65854ee0..5907f649 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,14 +35,30 @@ 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) : + boost::shared_ptr > probes, + GHashTable *options) : _decoder(dec), _probes(probes), + _options(options), + _session(NULL), _decoder_inst(NULL) { init_decoder(); + begin_decode(); +} + +Decoder::~Decoder() +{ + _decode_thread.interrupt(); + _decode_thread.join(); + + g_hash_table_destroy(_options); } const srd_decoder* Decoder::get_decoder() const @@ -45,10 +66,66 @@ 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, + data); +} + +void Decoder::clear_snapshots() +{ +} + void Decoder::init_decoder() { - _decoder_inst = srd_inst_new(_decoder->id, NULL); - assert(_decoder_inst); + 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(); + } + } + } + + srd_session_new(&_session); + assert(_session); + + _decoder_inst = srd_inst_new(_session, _decoder->id, _options); + if(!_decoder_inst) { + qDebug() << "Failed to initialise decoder"; + return; + } + + _decoder_inst->data_samplerate = _samplerate; GHashTable *probes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); @@ -67,8 +144,68 @@ void Decoder::init_decoder() srd_inst_probe_set_all(_decoder_inst, probes); } -void Decoder::clear_snapshots() +void Decoder::decode_proc(shared_ptr 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_config_set(_session, SRD_CONF_NUM_PROBES, + g_variant_new_uint64(_probes.size())); + srd_session_config_set(_session, SRD_CONF_UNITSIZE, + g_variant_new_uint64(snapshot->unit_size())); + srd_session_config_set(_session, SRD_CONF_SAMPLERATE, + g_variant_new_uint64((uint64_t)samplerate)); + + srd_session_start(_session); + + srd_pd_output_callback_add(_session, 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(_session, 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); + + d->new_decode_data(); } } // namespace data