diff options
author | Josh Blum <josh@joshknows.com> | 2011-11-07 18:47:29 -0800 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-11-07 18:47:29 -0800 |
commit | e219ad10a6e86cd4edc748f2218e01a9890e108c (patch) | |
tree | 372f2e426781de9885889bec6aa98697006268ec /host/lib/transport/super_send_packet_handler.hpp | |
parent | 8ff8f206d317e8d9c026fef9228a80edc241f9d4 (diff) | |
parent | 11f1390bbde65c60f45962acb128cac1ce21e474 (diff) | |
download | uhd-e219ad10a6e86cd4edc748f2218e01a9890e108c.tar.gz uhd-e219ad10a6e86cd4edc748f2218e01a9890e108c.tar.bz2 uhd-e219ad10a6e86cd4edc748f2218e01a9890e108c.zip |
Merge branch 'uhd_next'
Diffstat (limited to 'host/lib/transport/super_send_packet_handler.hpp')
-rw-r--r-- | host/lib/transport/super_send_packet_handler.hpp | 165 |
1 files changed, 77 insertions, 88 deletions
diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp index a99adcb5f..c3ffcc861 100644 --- a/host/lib/transport/super_send_packet_handler.hpp +++ b/host/lib/transport/super_send_packet_handler.hpp @@ -21,16 +21,13 @@ #include <uhd/config.hpp> #include <uhd/exception.hpp> #include <uhd/convert.hpp> -#include <uhd/device.hpp> +#include <uhd/stream.hpp> #include <uhd/utils/msg.hpp> #include <uhd/utils/byteswap.hpp> -#include <uhd/types/io_type.hpp> -#include <uhd/types/otw_type.hpp> #include <uhd/types/metadata.hpp> #include <uhd/transport/vrt_if_packet.hpp> #include <uhd/transport/zero_copy.hpp> #include <boost/thread/thread_time.hpp> -#include <boost/thread/mutex.hpp> #include <boost/foreach.hpp> #include <boost/function.hpp> #include <iostream> @@ -100,24 +97,12 @@ public: _props.at(xport_chan).get_buff = get_buff; } - /*! - * Setup the conversion functions (homogeneous across transports). - * Here, we load a table of converters for all possible io types. - * This makes the converter look-up an O(1) operation. - * \param otw_type the channel data type - * \param width the streams per channel (usually 1) - */ - void set_converter(const uhd::otw_type_t &otw_type, const size_t width = 1){ - _io_buffs.resize(width); - _converters.resize(128); - for (size_t io_type = 0; io_type < _converters.size(); io_type++){ - try{ - _converters[io_type] = uhd::convert::get_converter_cpu_to_otw( - io_type_t::tid_t(io_type), otw_type, 1, width - ); - }catch(const uhd::value_error &){} //we expect this, not all io_types valid... - } - _bytes_per_item = otw_type.get_sample_size(); + //! Set the conversion routine for all channels + void set_converter(const uhd::convert::id_type &id){ + _io_buffs.resize(id.num_inputs); + _converter = uhd::convert::get_converter(id); + _bytes_per_otw_item = uhd::convert::get_bytes_per_item(id.output_format); + _bytes_per_cpu_item = uhd::convert::get_bytes_per_item(id.input_format); } /*! @@ -129,11 +114,6 @@ public: _max_samples_per_packet = num_samps; } - //! Get a scoped lock object for this instance - boost::mutex::scoped_lock get_scoped_lock(void){ - return boost::mutex::scoped_lock(_mutex); - } - //! Set the scale factor used in float conversion void set_scale_factor(const double scale_factor){ _scale_factor = scale_factor; @@ -145,15 +125,11 @@ public: * Dispatch into combinations of single packet send calls. ******************************************************************/ UHD_INLINE size_t send( - const uhd::device::send_buffs_type &buffs, + const uhd::tx_streamer::buffs_type &buffs, const size_t nsamps_per_buff, const uhd::tx_metadata_t &metadata, - const uhd::io_type_t &io_type, - uhd::device::send_mode_t send_mode, - double timeout + const double timeout ){ - boost::mutex::scoped_lock lock(_mutex); - //translate the metadata to vrt if packet info vrt::if_packet_info_t if_packet_info; if_packet_info.has_sid = false; @@ -166,74 +142,56 @@ public: if_packet_info.sob = metadata.start_of_burst; if_packet_info.eob = metadata.end_of_burst; - if (nsamps_per_buff <= _max_samples_per_packet) send_mode = uhd::device::SEND_MODE_ONE_PACKET; - switch(send_mode){ - - //////////////////////////////////////////////////////////////// - case uhd::device::SEND_MODE_ONE_PACKET:{ - //////////////////////////////////////////////////////////////// + if (nsamps_per_buff <= _max_samples_per_packet){ //TODO remove this code when sample counts of zero are supported by hardware #ifndef SSPH_DONT_PAD_TO_ONE if (nsamps_per_buff == 0) return send_one_packet( - _zero_buffs, 1, if_packet_info, io_type, timeout + _zero_buffs, 1, if_packet_info, timeout ) & 0x0; #endif - return send_one_packet( - buffs, - std::min(nsamps_per_buff, _max_samples_per_packet), - if_packet_info, io_type, timeout - ); + return send_one_packet(buffs, nsamps_per_buff, if_packet_info, timeout); } + size_t total_num_samps_sent = 0; - //////////////////////////////////////////////////////////////// - case uhd::device::SEND_MODE_FULL_BUFF:{ - //////////////////////////////////////////////////////////////// - size_t total_num_samps_sent = 0; + //false until final fragment + if_packet_info.eob = false; - //false until final fragment - if_packet_info.eob = false; + const size_t num_fragments = (nsamps_per_buff-1)/_max_samples_per_packet; + const size_t final_length = ((nsamps_per_buff-1)%_max_samples_per_packet)+1; - const size_t num_fragments = (nsamps_per_buff-1)/_max_samples_per_packet; - const size_t final_length = ((nsamps_per_buff-1)%_max_samples_per_packet)+1; + //loop through the following fragment indexes + for (size_t i = 0; i < num_fragments; i++){ - //loop through the following fragment indexes - for (size_t i = 0; i < num_fragments; i++){ - - //send a fragment with the helper function - const size_t num_samps_sent = send_one_packet( - buffs, _max_samples_per_packet, - if_packet_info, io_type, timeout, - total_num_samps_sent*io_type.size - ); - total_num_samps_sent += num_samps_sent; - if (num_samps_sent == 0) return total_num_samps_sent; - - //setup metadata for the next fragment - const time_spec_t time_spec = metadata.time_spec + time_spec_t(0, total_num_samps_sent, _samp_rate); - if_packet_info.tsi = boost::uint32_t(time_spec.get_full_secs()); - if_packet_info.tsf = boost::uint64_t(time_spec.get_tick_count(_tick_rate)); - if_packet_info.sob = false; + //send a fragment with the helper function + const size_t num_samps_sent = send_one_packet( + buffs, _max_samples_per_packet, + if_packet_info, timeout, + total_num_samps_sent*_bytes_per_cpu_item + ); + total_num_samps_sent += num_samps_sent; + if (num_samps_sent == 0) return total_num_samps_sent; - } + //setup metadata for the next fragment + const time_spec_t time_spec = metadata.time_spec + time_spec_t(0, total_num_samps_sent, _samp_rate); + if_packet_info.tsi = boost::uint32_t(time_spec.get_full_secs()); + if_packet_info.tsf = boost::uint64_t(time_spec.get_tick_count(_tick_rate)); + if_packet_info.sob = false; - //send the final fragment with the helper function - if_packet_info.eob = metadata.end_of_burst; - return total_num_samps_sent + send_one_packet( - buffs, final_length, - if_packet_info, io_type, timeout, - total_num_samps_sent*io_type.size - ); } - default: throw uhd::value_error("unknown send mode"); - }//switch(send_mode) + //send the final fragment with the helper function + if_packet_info.eob = metadata.end_of_burst; + return total_num_samps_sent + send_one_packet( + buffs, final_length, + if_packet_info, timeout, + total_num_samps_sent*_bytes_per_cpu_item + ); } private: - boost::mutex _mutex; vrt_packer_type _vrt_packer; size_t _header_offset_words32; double _tick_rate, _samp_rate; @@ -242,8 +200,9 @@ private: }; std::vector<xport_chan_props_type> _props; std::vector<const void *> _io_buffs; //used in conversion - size_t _bytes_per_item; //used in conversion - std::vector<uhd::convert::function_type> _converters; //used in conversion + size_t _bytes_per_otw_item; //used in conversion + size_t _bytes_per_cpu_item; //used in conversion + uhd::convert::function_type _converter; //used in conversion size_t _max_samples_per_packet; std::vector<const void *> _zero_buffs; size_t _next_packet_seq; @@ -253,15 +212,15 @@ private: * Send a single packet: ******************************************************************/ UHD_INLINE size_t send_one_packet( - const uhd::device::send_buffs_type &buffs, + const uhd::tx_streamer::buffs_type &buffs, const size_t nsamps_per_buff, vrt::if_packet_info_t &if_packet_info, - const uhd::io_type_t &io_type, - double timeout, + const double timeout, const size_t buffer_offset_bytes = 0 ){ //load the rest of the if_packet_info in here - if_packet_info.num_payload_words32 = (nsamps_per_buff*_io_buffs.size()*_bytes_per_item)/sizeof(boost::uint32_t); + if_packet_info.num_payload_bytes = nsamps_per_buff*_io_buffs.size()*_bytes_per_otw_item; + if_packet_info.num_payload_words32 = (if_packet_info.num_payload_bytes + 3/*round up*/)/sizeof(boost::uint32_t); if_packet_info.packet_count = _next_packet_seq; size_t buff_index = 0; @@ -280,7 +239,9 @@ private: otw_mem += if_packet_info.num_header_words32; //copy-convert the samples into the send buffer - _converters[io_type.tid](_io_buffs, otw_mem, nsamps_per_buff, _scale_factor); + if (nsamps_per_buff != 0) _converter( + _io_buffs, otw_mem, nsamps_per_buff, _scale_factor + ); //commit the samples to the zero-copy interface size_t num_bytes_total = (_header_offset_words32+if_packet_info.num_packet_words32)*sizeof(boost::uint32_t); @@ -292,6 +253,34 @@ private: } }; +class send_packet_streamer : public send_packet_handler, public tx_streamer{ +public: + send_packet_streamer(const size_t max_num_samps){ + _max_num_samps = max_num_samps; + this->set_max_samples_per_packet(_max_num_samps); + } + + size_t get_num_channels(void) const{ + return this->size(); + } + + size_t get_max_num_samps(void) const{ + return _max_num_samps; + } + + size_t send( + const tx_streamer::buffs_type &buffs, + const size_t nsamps_per_buff, + const uhd::tx_metadata_t &metadata, + const double timeout + ){ + return send_packet_handler::send(buffs, nsamps_per_buff, metadata, timeout); + } + +private: + size_t _max_num_samps; +}; + }}} //namespace #endif /* INCLUDED_LIBUHD_TRANSPORT_SUPER_SEND_PACKET_HANDLER_HPP */ |