X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=pv%2Fdata%2Fdecoder.cpp;h=a9168ae2bdd33f8ec73fc46cfbf08c04e272c512;hb=ce94e4fd5d7ab666259231d21759613f1f2b93ee;hp=65fc8fff7c858312fa77a902d8df9d33ea3acddd;hpb=b213ef0991a13af0c74ffe5c54382c5c455c5496;p=pulseview.git diff --git a/pv/data/decoder.cpp b/pv/data/decoder.cpp index 65fc8ff..a9168ae 100644 --- a/pv/data/decoder.cpp +++ b/pv/data/decoder.cpp @@ -22,6 +22,8 @@ #include +#include + #include #include "decoder.h" @@ -41,18 +43,13 @@ 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, - GHashTable *options) : +mutex Decoder::_global_decode_mutex; + +Decoder::Decoder(const srd_decoder *const dec) : _decoder(dec), - _probes(probes), - _options(options), - _session(NULL), - _decoder_inst(NULL) + _options(g_hash_table_new_full(g_str_hash, + g_str_equal, g_free, (GDestroyNotify)g_variant_unref)) { - init_decoder(); - begin_decode(); } Decoder::~Decoder() @@ -63,35 +60,80 @@ Decoder::~Decoder() g_hash_table_destroy(_options); } -const srd_decoder* Decoder::get_decoder() const +const srd_decoder* Decoder::decoder() const { return _decoder; } +const map >& +Decoder::probes() const +{ + return _probes; +} + +void Decoder::set_probes(std::map > probes) +{ + _probes = probes; + begin_decode(); +} + +const GHashTable* Decoder::options() const +{ + return _options; +} + +void Decoder::set_option(const char *id, GVariant *value) +{ + g_variant_ref(value); + g_hash_table_replace(_options, (void*)g_strdup(id), value); + begin_decode(); +} + const vector< shared_ptr > Decoder::annotations() const { - lock_guard lock(_annotations_mutex); + lock_guard lock(_mutex); return _annotations; } +QString Decoder::error_message() +{ + lock_guard lock(_mutex); + return _error_message; +} + void Decoder::begin_decode() { _decode_thread.interrupt(); _decode_thread.join(); + _annotations.clear(); + if (_probes.empty()) return; + // Get the samplerate and start time + shared_ptr logic_signal = + dynamic_pointer_cast( + (*_probes.begin()).second); + if (logic_signal) { + shared_ptr data( + logic_signal->data()); + if (data) { + _start_time = data->get_start_time(); + _samplerate = data->get_samplerate(); + if (_samplerate == 0.0) + _samplerate = 1.0; + } + } + // 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; + 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(); + shared_ptr data = sig->data(); _decode_thread = boost::thread(&Decoder::decode_proc, this, data); @@ -101,38 +143,45 @@ void Decoder::clear_snapshots() { } -void Decoder::init_decoder() +void Decoder::decode_proc(shared_ptr data) { - 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 *session; + uint8_t chunk[DecodeChunkLength]; - srd_session_new(&_session); - assert(_session); + assert(data); - _decoder_inst = srd_inst_new(_session, _decoder->id, _options); - if(!_decoder_inst) { - qDebug() << "Failed to initialise decoder"; + const deque< shared_ptr > &snapshots = + data->get_snapshots(); + if (snapshots.empty()) return; - } - _decoder_inst->data_samplerate = _samplerate; + const shared_ptr &snapshot = + snapshots.front(); + const int64_t sample_count = snapshot->get_sample_count() - 1; + + // Create the session + srd_session_new(&session); + assert(session); + + srd_session_metadata_set(session, SRD_CONF_SAMPLERATE, + g_variant_new_uint64((uint64_t)_samplerate)); + + srd_pd_output_callback_add(session, SRD_OUTPUT_ANN, + Decoder::annotation_callback, this); + + // Create the decoder instance + srd_decoder_inst *const decoder_inst = srd_inst_new( + session, _decoder->id, _options); + if(!decoder_inst) { + _error_message = tr("Failed to initialise decoder"); + return; + } - GHashTable *probes = g_hash_table_new_full(g_str_hash, + // Setup the probes + GHashTable *const probes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); - for(map >:: + for(map >:: const_iterator i = _probes.begin(); i != _probes.end(); i++) { @@ -143,55 +192,30 @@ void Decoder::init_decoder() g_hash_table_insert(probes, (*i).first->id, gvar); } - srd_inst_probe_set_all(_decoder_inst, probes); -} + srd_inst_probe_set_all(decoder_inst, probes); -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); + // Start the session + srd_session_start(session); for (int64_t i = 0; !this_thread::interruption_requested() && i < sample_count; i += DecodeChunkLength) { + lock_guard decode_lock(_global_decode_mutex); + 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) + if (srd_session_send(session, i, i + sample_count, + chunk, chunk_end - i) != SRD_OK) { + _error_message = tr("Failed to initialise decoder"); break; + } } + + // Destroy the session + srd_session_destroy(session); } void Decoder::annotation_callback(srd_proto_data *pdata, void *decoder) @@ -204,7 +228,7 @@ void Decoder::annotation_callback(srd_proto_data *pdata, void *decoder) Decoder *const d = (Decoder*)decoder; shared_ptr a(new Annotation(pdata)); - lock_guard lock(d->_annotations_mutex); + lock_guard lock(d->_mutex); d->_annotations.push_back(a); d->new_decode_data();