From: Joel Holdsworth Date: Sun, 20 Oct 2013 12:18:49 +0000 (+0100) Subject: Moved all srd commands into decode thread, implemented error messages X-Git-Tag: pulseview-0.2.0~234 X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=b6b267bba9d55d23fe5c3537e4785238d4377ad7 Moved all srd commands into decode thread, implemented error messages Ported decode tests to modified interface. --- diff --git a/pv/data/decoder.cpp b/pv/data/decoder.cpp index 92314039..8a84fd4d 100644 --- a/pv/data/decoder.cpp +++ b/pv/data/decoder.cpp @@ -49,12 +49,9 @@ Decoder::Decoder(const srd_decoder *const dec, GHashTable *options) : _decoder(dec), _probes(probes), - _options(options), - _session(NULL), - _decoder_inst(NULL) + _options(options) { - if (!init_decoder()) - throw runtime_error("Failed to initialise decoder."); + init_decoder(); begin_decode(); } @@ -65,9 +62,6 @@ Decoder::~Decoder() _decode_thread.join(); g_hash_table_destroy(_options); - - if (_session) - srd_session_destroy(_session); } const srd_decoder* Decoder::get_decoder() const @@ -78,10 +72,16 @@ const srd_decoder* Decoder::get_decoder() const 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(); @@ -105,7 +105,7 @@ void Decoder::clear_snapshots() { } -bool Decoder::init_decoder() +void Decoder::init_decoder() { if (!_probes.empty()) { @@ -116,44 +116,18 @@ bool Decoder::init_decoder() shared_ptr data( logic_signal->data()); if (data) { - _samplerate = data->get_samplerate(); _start_time = data->get_start_time(); + _samplerate = data->get_samplerate(); + if (_samplerate == 0.0) + _samplerate = 1.0; } } } - - srd_session_new(&_session); - assert(_session); - - _decoder_inst = srd_inst_new(_session, _decoder->id, _options); - if(!_decoder_inst) { - qDebug() << "Failed to initialise decoder"; - return false; - } - - _decoder_inst->data_samplerate = _samplerate; - - GHashTable *probes = g_hash_table_new_full(g_str_hash, - g_str_equal, g_free, (GDestroyNotify)g_variant_unref); - - for(map >:: - const_iterator i = _probes.begin(); - i != _probes.end(); i++) - { - shared_ptr signal((*i).second); - GVariant *const gvar = g_variant_new_int32( - signal->probe()->index); - g_variant_ref_sink(gvar); - g_hash_table_insert(probes, (*i).first->id, gvar); - } - - srd_inst_probe_set_all(_decoder_inst, probes); - - return true; } void Decoder::decode_proc(shared_ptr data) { + srd_session *session; uint8_t chunk[DecodeChunkLength]; assert(data); @@ -168,24 +142,51 @@ void Decoder::decode_proc(shared_ptr data) 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; + // Create the session + srd_session_new(&session); + assert(session); - srd_session_config_set(_session, SRD_CONF_NUM_PROBES, + srd_session_config_set(session, SRD_CONF_NUM_PROBES, g_variant_new_uint64(_probes.size())); - srd_session_config_set(_session, SRD_CONF_UNITSIZE, + 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_session_config_set(session, SRD_CONF_SAMPLERATE, + g_variant_new_uint64((uint64_t)_samplerate)); - srd_pd_output_callback_add(_session, SRD_OUTPUT_ANN, + 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; + } + + decoder_inst->data_samplerate = _samplerate; + + // 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 >:: + const_iterator i = _probes.begin(); + i != _probes.end(); i++) + { + shared_ptr signal((*i).second); + GVariant *const gvar = g_variant_new_int32( + signal->probe()->index); + g_variant_ref_sink(gvar); + g_hash_table_insert(probes, (*i).first->id, gvar); + } + + srd_inst_probe_set_all(decoder_inst, probes); + + // Start the session + srd_session_start(session); + for (int64_t i = 0; !this_thread::interruption_requested() && i < sample_count; i += DecodeChunkLength) @@ -194,10 +195,15 @@ void Decoder::decode_proc(shared_ptr data) 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, 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) @@ -210,7 +216,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(); diff --git a/pv/data/decoder.h b/pv/data/decoder.h index cdeb7e7a..09002ac9 100644 --- a/pv/data/decoder.h +++ b/pv/data/decoder.h @@ -29,14 +29,17 @@ #include #include +#include #include struct srd_decoder; -struct srd_decoder_inst; struct srd_probe; struct srd_proto_data; -struct srd_session; + +namespace DecoderTest { +class TwoDecoder; +} namespace pv { @@ -75,12 +78,14 @@ public: const std::vector< boost::shared_ptr > annotations() const; + QString error_message(); + void clear_snapshots(); private: void begin_decode(); - bool init_decoder(); + void init_decoder(); void decode_proc(boost::shared_ptr data); @@ -96,14 +101,14 @@ private: _probes; GHashTable *_options; - srd_session *_session; - srd_decoder_inst *_decoder_inst; - - mutable boost::mutex _annotations_mutex; + mutable boost::mutex _mutex; std::vector< boost::shared_ptr > _annotations; + QString _error_message; boost::thread _decode_thread; + + friend class DecoderTest::TwoDecoder; }; } // namespace data diff --git a/pv/view/decodesignal.cpp b/pv/view/decodesignal.cpp index 32307e9c..88531208 100644 --- a/pv/view/decodesignal.cpp +++ b/pv/view/decodesignal.cpp @@ -67,6 +67,11 @@ bool DecodeSignal::enabled() const return true; } +const boost::shared_ptr& DecodeSignal::decoder() const +{ + return _decoder; +} + void DecodeSignal::set_view(pv::view::View *view) { assert(view); diff --git a/pv/view/decodesignal.h b/pv/view/decodesignal.h index f9113f5b..e95c9822 100644 --- a/pv/view/decodesignal.h +++ b/pv/view/decodesignal.h @@ -46,6 +46,8 @@ public: bool enabled() const; + const boost::shared_ptr& decoder() const; + void set_view(pv::view::View *view); /** diff --git a/test/data/decoder.cpp b/test/data/decoder.cpp index 641064da..4ea4b10f 100644 --- a/test/data/decoder.cpp +++ b/test/data/decoder.cpp @@ -23,9 +23,10 @@ #include +#include "../../pv/data/decoder.h" #include "../../pv/devicemanager.h" #include "../../pv/sigsession.h" -#include "../../pv/view/signal.h" +#include "../../pv/view/decodesignal.h" using namespace boost; using namespace std; @@ -34,6 +35,8 @@ BOOST_AUTO_TEST_SUITE(DecoderTest) BOOST_AUTO_TEST_CASE(TwoDecoder) { + using namespace pv; + sr_context *ctx = NULL; BOOST_REQUIRE(sr_init(&ctx) == SR_OK); @@ -52,14 +55,32 @@ BOOST_AUTO_TEST_CASE(TwoDecoder) srd_decoder *const dec = (struct srd_decoder*)l->data; BOOST_REQUIRE(dec); - map > probes; - BOOST_CHECK (ss.add_decoder(dec, probes, + map > probes; + ss.add_decoder(dec, probes, g_hash_table_new_full(g_str_hash, g_str_equal, g_free, - (GDestroyNotify)g_variant_unref))); - - BOOST_CHECK (ss.add_decoder(dec, probes, + (GDestroyNotify)g_variant_unref)); + + ss.add_decoder(dec, probes, g_hash_table_new_full(g_str_hash, g_str_equal, g_free, - (GDestroyNotify)g_variant_unref))); + (GDestroyNotify)g_variant_unref)); + + // Check the signals were created + const vector< shared_ptr > sigs = + ss.get_decode_signals(); + + shared_ptr dec0 = sigs[0]->decoder(); + BOOST_REQUIRE(dec0); + + shared_ptr dec1 = sigs[0]->decoder(); + BOOST_REQUIRE(dec1); + + // Wait for the decode threads to complete + dec0->_decode_thread.join(); + dec1->_decode_thread.join(); + + // Check there were no errors + BOOST_CHECK_EQUAL(dec0->error_message().isEmpty(), true); + BOOST_CHECK_EQUAL(dec1->error_message().isEmpty(), true); }