Index: /branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpStreamProcessor.cpp =================================================================== --- /branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpStreamProcessor.cpp (revision 705) +++ /branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpStreamProcessor.cpp (revision 707) @@ -31,13 +31,11 @@ // in ticks -#define TRANSMIT_TRANSFER_DELAY 9000U -// the number of cycles to send a packet in advance of it's timestamp -#define TRANSMIT_ADVANCE_CYCLES 4U +// as per AMDTP2.1: +// 354.17us + 125us @ 24.576ticks/usec = 11776.08192 ticks +#define DEFAULT_TRANSFER_DELAY (11776U) + +#define TRANSMIT_TRANSFER_DELAY DEFAULT_TRANSFER_DELAY namespace Streaming { - -IMPL_DEBUG_MODULE( AmdtpTransmitStreamProcessor, AmdtpTransmitStreamProcessor, DEBUG_LEVEL_VERBOSE ); -IMPL_DEBUG_MODULE( AmdtpReceiveStreamProcessor, AmdtpReceiveStreamProcessor, DEBUG_LEVEL_VERBOSE ); - /* transmit */ @@ -45,11 +43,5 @@ : TransmitStreamProcessor(port, framerate), m_dimension(dimension) , m_last_timestamp(0), m_dbc(0), m_ringbuffer_size_frames(0) -{ - -} - -AmdtpTransmitStreamProcessor::~AmdtpTransmitStreamProcessor() { - -} +{} /** @@ -66,11 +58,5 @@ return false; } - return true; -} - -void AmdtpTransmitStreamProcessor::setVerboseLevel(int l) { - setDebugLevel(l); - TransmitStreamProcessor::setVerboseLevel(l); } @@ -79,21 +65,18 @@ unsigned char *tag, unsigned char *sy, int cycle, unsigned int dropped, unsigned int max_length) { - struct iec61883_packet *packet = (struct iec61883_packet *) data; - + if (cycle<0) { debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,"Xmit handler for cycle %d, (running=%d)\n", cycle, m_running); - *tag = 0; *sy = 0; *length=0; return RAW1394_ISO_OK; - - } - + } + debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,"Xmit handler for cycle %d, (running=%d)\n", cycle, m_running); - + m_last_cycle=cycle; @@ -139,4 +122,7 @@ cycle, now_cycles); } + + // keep track of the lag + m_PacketStat.mark(cycle_diff); #endif @@ -150,5 +136,4 @@ } - uint64_t ts_head; signed int fc; uint64_t presentation_time; @@ -156,6 +141,23 @@ int cycles_until_presentation; - const int min_cycles_beforehand = 2; // FIXME: should become a define - const int max_cycles_beforehand = 15; // FIXME: should become a define + uint64_t transmit_at_time; + unsigned int transmit_at_cycle; + int cycles_until_transmit; + + // FIXME: should become a define + // the absolute minimum number of cycles we want to transmit + // a packet ahead of the presentation time. The nominal time + // the packet is transmitted ahead of the presentation time is + // given by TRANSMIT_TRANSFER_DELAY (in ticks), but in case we + // are too late for that, this constant defines how late we can + // be. + const int min_cycles_before_presentation = 1; + // FIXME: should become a define + // the absolute maximum number of cycles we want to transmit + // a packet ahead of the ideal transmit time. The nominal time + // the packet is transmitted ahead of the presentation time is + // given by TRANSMIT_TRANSFER_DELAY (in ticks), but we can send + // packets early if we want to. (not completely according to spec) + const int max_cycles_to_transmit_early = 1; if( !m_running || !m_data_buffer->isEnabled() ) { @@ -174,8 +176,11 @@ ffado_timestamp_t ts_head_tmp; m_data_buffer->getBufferHeadTimestamp(&ts_head_tmp, &fc); // thread safe - ts_head=(uint64_t)ts_head_tmp; - - // first calculate the presentation time of the samples - presentation_time = addTicks(ts_head, TRANSMIT_TRANSFER_DELAY); + + // the timestamp gives us the time at which we want the sample block + // to be output by the device + presentation_time=(uint64_t)ts_head_tmp; + + // now we calculate the time when we have to transmit the sample block + transmit_at_time = substractTicks(presentation_time, TRANSMIT_TRANSFER_DELAY); // calculate the cycle this block should be presented in @@ -184,8 +189,16 @@ presentation_cycle = (unsigned int)(TICKS_TO_CYCLES( presentation_time )); + // calculate the cycle this block should be transmitted in + transmit_at_cycle = (unsigned int)(TICKS_TO_CYCLES( transmit_at_time )); + // we can check whether this cycle is within the 'window' we have // to send this packet. // first calculate the number of cycles left before presentation time cycles_until_presentation = diffCycles( presentation_cycle, cycle ); + + // we can check whether this cycle is within the 'window' we have + // to send this packet. + // first calculate the number of cycles left before presentation time + cycles_until_transmit = diffCycles( transmit_at_cycle, cycle ); // two different options: @@ -196,21 +209,34 @@ // => determine whether we have to send them in this packet if (fc < (signed int)m_syt_interval) { + m_PacketStat.signal(0); // not enough frames in the buffer, debugOutput(DEBUG_LEVEL_VERBOSE, - "Insufficient frames: CY=%04u, PTC=%04u, CUP=%04d\n", - cycle, presentation_cycle, cycles_until_presentation); + "Insufficient frames: N=%02d, CY=%04u, TC=%04u, CUT=%04d\n", + fc, cycle, transmit_at_cycle, cycles_until_transmit); // we can still postpone the queueing of the packets // if we are far enough ahead of the presentation time - if( cycles_until_presentation <= min_cycles_beforehand ) { - // we have an invalid timestamp or we are too late + if( cycles_until_presentation <= min_cycles_before_presentation ) { + m_PacketStat.signal(1); + // we are too late // meaning that we in some sort of xrun state // signal xrun situation ??HERE?? m_xruns++; + // we send an empty packet on this cycle + goto send_empty_packet; // UGLY but effective } else { + m_PacketStat.signal(2); // there is still time left to send the packet + // we want the system to give this packet another go +// goto try_packet_again; // UGLY but effective + // unfortunatly the try_again doesn't work very well, + // so we'll have to either usleep(one cycle) and goto try_block_of_frames + + // or just fill this with an empty packet + // if we have to do this too often, the presentation time will + // get too close and we're in trouble + goto send_empty_packet; // UGLY but effective } - // in any case we send an empty packet on this cycle - goto send_empty_packet; // UGLY but effective } else { + m_PacketStat.signal(3); // there are enough frames, so check the time they are intended for // all frames have a certain 'time window' in which they can be sent @@ -229,36 +255,59 @@ // get next block of frames and repeat - if (cycles_until_presentation <= min_cycles_beforehand) { + if (cycles_until_transmit <= max_cycles_to_transmit_early) { + m_PacketStat.signal(4); + // it's time send the packet + goto send_packet; // UGLY but effective + } else if (cycles_until_transmit < 0) { // we are too late debugOutput(DEBUG_LEVEL_VERBOSE, - "Too late: CY=%04u, PTC=%04u, CUP=%04d, TSP=%011llu (%04u)\n", + "Too late: CY=%04u, TC=%04u, CUT=%04d, TSP=%011llu (%04u)\n", cycle, - presentation_cycle, cycles_until_presentation, + transmit_at_cycle, cycles_until_transmit, presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time)); - // remove the samples - m_data_buffer->dropFrames(m_syt_interval); - - // signal some xrun situation ??HERE?? - m_xruns++; - - // try a new block of frames - goto try_block_of_frames; // UGLY but effective - } else if (cycles_until_presentation >= max_cycles_beforehand) { + + // however, if we can send this sufficiently before the presentation + // time, it could be harmless. + // NOTE: dangerous since the device has no way of reporting that it didn't get + // this packet on time. + if ( cycles_until_presentation <= min_cycles_before_presentation ) { + m_PacketStat.signal(5); + // we are not that late and can still try to transmit the packet + goto send_packet; // UGLY but effective + } else { // definitely too late + m_PacketStat.signal(6); + // remove the samples + m_data_buffer->dropFrames(m_syt_interval); + // signal some xrun situation ??HERE?? + m_xruns++; + // try a new block of frames + goto try_block_of_frames; // UGLY but effective + } + } else { + m_PacketStat.signal(7); debugOutput(DEBUG_LEVEL_VERY_VERBOSE, - "Too early: CY=%04u, PTC=%04u, CUP=%04d, TSP=%011llu (%04u)\n", + "Too early: CY=%04u, TC=%04u, CUT=%04d, TST=%011llu (%04u), TSP=%011llu (%04u)\n", cycle, - presentation_cycle, cycles_until_presentation, + transmit_at_cycle, cycles_until_transmit, + transmit_at_time, (unsigned int)TICKS_TO_CYCLES(transmit_at_time), presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time)); + #ifdef DEBUG + if (cycles_until_transmit > max_cycles_to_transmit_early + 1) { + debugOutput(DEBUG_LEVEL_VERBOSE, + "Way too early: CY=%04u, TC=%04u, CUT=%04d, TST=%011llu (%04u), TSP=%011llu (%04u)\n", + cycle, + transmit_at_cycle, cycles_until_transmit, + transmit_at_time, (unsigned int)TICKS_TO_CYCLES(transmit_at_time), + presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time)); + } + #endif // we are too early, send only an empty packet goto send_empty_packet; // UGLY but effective - } else { - // send the packet - goto send_packet; // UGLY but effective } } - - debugError("Should never reach this code!\n"); + + debugFatal("Should never reach this code!\n"); return RAW1394_ISO_ERROR; - + send_empty_packet: debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT NONE: CY=%04u, TSP=%011llu (%04u)\n", @@ -279,13 +328,22 @@ } - debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT DATA: CY=%04u, TSH=%011llu (%04u), TSP=%011llu (%04u)\n", + debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT DATA: CY=%04u, TST=%011llu (%04u), TSP=%011llu (%04u)\n", cycle, - ts_head, (unsigned int)TICKS_TO_CYCLES(ts_head), + transmit_at_time, (unsigned int)TICKS_TO_CYCLES(transmit_at_time), presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time)); return RAW1394_ISO_OK; } + +// the ISO AGAIN does not work very well... +// try_packet_again: +// +// debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT RETRY: CY=%04u, TSP=%011llu (%04u)\n", +// cycle, +// presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time)); +// return RAW1394_ISO_AGAIN; + // else: - debugError("This is impossible, since we checked the buffer size before!\n"); + debugFatal("This is impossible, since we checked the buffer size before!\n"); return RAW1394_ISO_ERROR; } @@ -549,5 +607,4 @@ bool AmdtpTransmitStreamProcessor::prepareForStart() { - return true; } @@ -589,5 +646,4 @@ bool AmdtpTransmitStreamProcessor::putFrames(unsigned int nbframes, int64_t ts) { m_PeriodStat.mark(m_data_buffer->getBufferFill()); - debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "AmdtpTransmitStreamProcessor::putFrames(%d, %llu)\n", nbframes, ts); @@ -601,4 +657,5 @@ bool AmdtpTransmitStreamProcessor::putFramesDry(unsigned int nbframes, int64_t ts) { + m_PeriodStat.mark(m_data_buffer->getBufferFill()); debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "AmdtpTransmitStreamProcessor::putFramesDry(%d, %llu)\n", nbframes, ts); @@ -844,11 +901,6 @@ AmdtpReceiveStreamProcessor::AmdtpReceiveStreamProcessor(int port, int framerate, int dimension) - : ReceiveStreamProcessor(port, framerate), m_dimension(dimension), m_last_timestamp(0), m_last_timestamp2(0) { - -} - -AmdtpReceiveStreamProcessor::~AmdtpReceiveStreamProcessor() { - -} + : ReceiveStreamProcessor(port, framerate), m_dimension(dimension), m_last_timestamp(0), m_last_timestamp2(0) +{} bool AmdtpReceiveStreamProcessor::init() { @@ -861,5 +913,4 @@ return false; } - return true; } @@ -882,5 +933,5 @@ debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"ch%2u: CY=%4u, SYT=%08X (%4ucy + %04uticks) (running=%d)\n", - channel, cycle,ntohs(packet->syt), + channel, cycle, ntohs(packet->syt), CYCLE_TIMER_GET_CYCLES(ntohs(packet->syt)), CYCLE_TIMER_GET_OFFSET(ntohs(packet->syt)), m_running); @@ -934,6 +985,6 @@ #ifdef DEBUG_OFF if((cycle % 1000) == 0) { + uint32_t now=m_handler->getCycleTimer(); uint32_t syt = (uint32_t)ntohs(packet->syt); - uint32_t now=m_handler->getCycleTimer(); uint32_t now_ticks=CYCLE_TIMER_TO_TICKS(now); @@ -952,4 +1003,11 @@ #endif + #ifdef DEBUG + // keep track of the lag + uint32_t now=m_handler->getCycleTimer(); + int32_t diff = diffCycles( cycle, ((int)CYCLE_TIMER_GET_CYCLES(now)) ); + m_PacketStat.mark(diff); + #endif + //=> process the packet // add the data payload to the ringbuffer @@ -987,9 +1045,4 @@ void AmdtpReceiveStreamProcessor::dumpInfo() { StreamProcessor::dumpInfo(); -} - -void AmdtpReceiveStreamProcessor::setVerboseLevel(int l) { - setDebugLevel(l); - ReceiveStreamProcessor::setVerboseLevel(l); } @@ -1170,4 +1223,5 @@ bool AmdtpReceiveStreamProcessor::getFrames(unsigned int nbframes, int64_t ts) { + m_PeriodStat.mark(m_data_buffer->getBufferFill()); // ask the buffer to process nbframes of frames @@ -1180,4 +1234,5 @@ bool AmdtpReceiveStreamProcessor::getFramesDry(unsigned int nbframes, int64_t ts) { + m_PeriodStat.mark(m_data_buffer->getBufferFill()); int frames_to_ditch=(int)(nbframes); debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "stream (%p): dry run %d frames (@ ts=%lld)\n", Index: /branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpStreamProcessor.h =================================================================== --- /branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpStreamProcessor.h (revision 705) +++ /branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpStreamProcessor.h (revision 707) @@ -79,6 +79,5 @@ */ AmdtpTransmitStreamProcessor(int port, int framerate, int dimension); - - virtual ~AmdtpTransmitStreamProcessor(); + virtual ~AmdtpTransmitStreamProcessor() {}; enum raw1394_iso_disposition @@ -111,6 +110,4 @@ int getMinimalSyncDelay(); - - void setVerboseLevel(int l); protected: @@ -150,7 +147,4 @@ unsigned int m_ringbuffer_size_frames; - - DECLARE_DEBUG_MODULE; - }; /*! @@ -174,6 +168,5 @@ */ AmdtpReceiveStreamProcessor(int port, int framerate, int dimension); - - virtual ~AmdtpReceiveStreamProcessor(); + virtual ~AmdtpReceiveStreamProcessor() {}; enum raw1394_iso_disposition putPacket(unsigned char *data, unsigned int length, @@ -207,6 +200,4 @@ int getMinimalSyncDelay(); - void setVerboseLevel(int l); - protected: @@ -224,7 +215,4 @@ uint64_t m_last_timestamp2; /// last timestamp (in ticks) uint64_t m_last_timestamp_at_period_ticks; - - DECLARE_DEBUG_MODULE; - }; Index: /branches/ppalmers-streaming/src/libstreaming/StreamProcessorManager.cpp =================================================================== --- /branches/ppalmers-streaming/src/libstreaming/StreamProcessorManager.cpp (revision 705) +++ /branches/ppalmers-streaming/src/libstreaming/StreamProcessorManager.cpp (revision 707) @@ -41,5 +41,5 @@ namespace Streaming { -IMPL_DEBUG_MODULE( StreamProcessorManager, StreamProcessorManager, DEBUG_LEVEL_NORMAL ); +IMPL_DEBUG_MODULE( StreamProcessorManager, StreamProcessorManager, DEBUG_LEVEL_VERBOSE ); StreamProcessorManager::StreamProcessorManager(unsigned int period, unsigned int nb_buffers) @@ -391,5 +391,9 @@ } - debugOutput( DEBUG_LEVEL_VERBOSE, " sync at TS=%011llu...\n", m_time_of_transfer); + debugOutput( DEBUG_LEVEL_VERBOSE, " sync at TS=%011llu (%03us %04uc %04ut)...\n", + m_time_of_transfer, + (unsigned int)TICKS_TO_SECS(m_time_of_transfer), + (unsigned int)TICKS_TO_CYCLES(m_time_of_transfer), + (unsigned int)TICKS_TO_OFFSET(m_time_of_transfer)); // FIXME: xruns can screw up the framecounter accounting. do something more sane here resetXrunCounters(); @@ -450,7 +454,8 @@ while(nb_dryrun_cycles--) { waitForPeriod(); + m_TransmitProcessors.at(0)->m_PacketStat.dumpInfo(); no_xrun = dryRun(); // dry run both receive and xmit - if (no_xrun) { + if (!no_xrun) { debugOutput( DEBUG_LEVEL_VERBOSE, " This dry-run was not xrun free...\n" ); resetXrunCounters(); @@ -826,4 +831,6 @@ debugOutput( DEBUG_LEVEL_VERBOSE, "Handling Xrun ...\n"); + dumpInfo(); + /* * Reset means: @@ -892,4 +899,6 @@ } + if(xrun_occurred) break; + // check if we were waked up too soon time_till_next_period=m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); @@ -941,5 +950,5 @@ // if this is true, a xrun will occur - xrun_occurred |= !((*it)->canClientTransferFrames(m_period)); + xrun_occurred |= !((*it)->canClientTransferFrames(m_period)) && (*it)->isEnabled(); #ifdef DEBUG @@ -948,5 +957,5 @@ (*it)->dumpInfo(); } - if (!((*it)->canClientTransferFrames(m_period))) { + if (!((*it)->canClientTransferFrames(m_period)) && (*it)->isEnabled()) { debugWarning("Xrun on RECV SP %p due to buffer xrun\n",*it); (*it)->dumpInfo(); @@ -962,5 +971,5 @@ // if this is true, a xrun will occur - xrun_occurred |= !((*it)->canClientTransferFrames(m_period)); + xrun_occurred |= !((*it)->canClientTransferFrames(m_period)) && (*it)->isEnabled(); #ifdef DEBUG @@ -968,5 +977,5 @@ debugWarning("Xrun on XMIT SP %p due to ISO xrun\n",*it); } - if (!((*it)->canClientTransferFrames(m_period))) { + if (!((*it)->canClientTransferFrames(m_period)) && (*it)->isEnabled()) { debugWarning("Xrun on XMIT SP %p due to buffer xrun\n",*it); } @@ -990,9 +999,8 @@ debugOutput( DEBUG_LEVEL_VERBOSE, "Transferring period...\n"); - - if (!transfer(StreamProcessor::E_Receive)) return false; - if (!transfer(StreamProcessor::E_Transmit)) return false; - - return true; + bool retval=true; + retval &= dryRun(StreamProcessor::E_Receive); + retval &= dryRun(StreamProcessor::E_Transmit); + return retval; } @@ -1008,9 +1016,8 @@ bool StreamProcessorManager::transfer(enum StreamProcessor::EProcessorType t) { debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); - + bool retval = true; // a static cast could make sure that there is no performance // penalty for the virtual functions (to be checked) if (t==StreamProcessor::E_Receive) { - // determine the time at which we want reception to start float rate=m_SyncSource->getTicksPerFrame(); @@ -1035,7 +1042,6 @@ debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u, %11llu) from stream processor (%p)\n", m_period, m_time_of_transfer,*it); - return false; // buffer underrun - } - + retval &= false; // buffer underrun + } } } else { @@ -1055,11 +1061,10 @@ debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)\n", m_period, transmit_timestamp, *it); - return false; // buffer overrun - } - - } - } - - return true; + retval &= false; // buffer underrun + } + + } + } + return retval; } @@ -1075,7 +1080,8 @@ bool StreamProcessorManager::dryRun() { debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Dry-running period...\n"); - if (!dryRun(StreamProcessor::E_Receive)) return false; - if (!dryRun(StreamProcessor::E_Transmit)) return false; - return true; + bool retval=true; + retval &= dryRun(StreamProcessor::E_Receive); + retval &= dryRun(StreamProcessor::E_Transmit); + return retval; } @@ -1090,10 +1096,9 @@ bool StreamProcessorManager::dryRun(enum StreamProcessor::EProcessorType t) { - debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); - + debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Dry-running period...\n"); + bool retval = true; // a static cast could make sure that there is no performance // penalty for the virtual functions (to be checked) if (t==StreamProcessor::E_Receive) { - // determine the time at which we want reception to start float rate=m_SyncSource->getTicksPerFrame(); @@ -1118,5 +1123,5 @@ debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u, %11llu) from stream processor (%p)\n", m_period, m_time_of_transfer,*it); - return false; // buffer underrun + retval &= false; // buffer underrun } @@ -1138,11 +1143,10 @@ debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)\n", m_period, transmit_timestamp, *it); - return false; // buffer overrun - } - - } - } - - return true; + retval &= false; // buffer underrun + } + + } + } + return retval; } Index: /branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.h =================================================================== --- /branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.h (revision 706) +++ /branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.h (revision 707) @@ -111,4 +111,9 @@ Util::TimestampedBuffer *m_data_buffer; + StreamStatistics m_PacketStat; + StreamStatistics m_PeriodStat; + + StreamStatistics m_WakeupStat; + protected: // SPM related void setManager(StreamProcessorManager *manager) {m_manager=manager;}; @@ -130,8 +135,4 @@ unsigned int m_cycle_to_enable_at; - StreamStatistics m_PacketStat; - StreamStatistics m_PeriodStat; - - StreamStatistics m_WakeupStat; Index: /branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.cpp =================================================================== --- /branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.cpp (revision 706) +++ /branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.cpp (revision 707) @@ -84,6 +84,5 @@ m_PeriodStat.dumpInfo(); m_PacketStat.dumpInfo(); - m_WakeupStat.dumpInfo(); - +// m_WakeupStat.dumpInfo(); } @@ -293,5 +292,4 @@ IsoStream::setVerboseLevel(l); PortManager::setVerboseLevel(l); - } @@ -334,8 +332,12 @@ bool TransmitStreamProcessor::canClientTransferFrames(unsigned int nbframes) { + bool can_transfer; // there has to be enough space to put the frames in - return m_data_buffer->getBufferSize() - m_data_buffer->getFrameCounter() > nbframes; -} - - -} + can_transfer = m_data_buffer->getBufferSize() - m_data_buffer->getFrameCounter() > nbframes; + // or the buffer is transparent + can_transfer |= m_data_buffer->isTransparent(); + return can_transfer; +} + + +} Index: /branches/ppalmers-streaming/src/libstreaming/util/IsoHandlerManager.cpp =================================================================== --- /branches/ppalmers-streaming/src/libstreaming/util/IsoHandlerManager.cpp (revision 705) +++ /branches/ppalmers-streaming/src/libstreaming/util/IsoHandlerManager.cpp (revision 707) @@ -30,5 +30,5 @@ #include -#define MINIMUM_INTERRUPTS_PER_PERIOD 2U +#define MINIMUM_INTERRUPTS_PER_PERIOD 4U #define PACKETS_PER_INTERRUPT 4U @@ -450,4 +450,5 @@ // event buffers + // FIXME: latency spoiler // every irq_interval packets an interrupt will occur. that is when // buffers get transfered, meaning that we should have at least some Index: /branches/ppalmers-streaming/src/libstreaming/util/cycletimer.h =================================================================== --- /branches/ppalmers-streaming/src/libstreaming/util/cycletimer.h (revision 705) +++ /branches/ppalmers-streaming/src/libstreaming/util/cycletimer.h (revision 707) @@ -156,4 +156,31 @@ return x; +} + +/** + * @brief Computes a difference between cycles + * + * This function computes a difference between cycles + * such that it respects wrapping (at 8000 cycles). + * + * See diffTicks + * + * @param x First cycle value + * @param y Second cycle value + * @return the difference x-y, unwrapped + */ +static inline int diffCycles(unsigned int x, unsigned int y) { + int diff = x - y; + + // the maximal difference we allow (64secs) + const int max=CYCLES_PER_SECOND/2; + + if(diff > max) { + diff -= CYCLES_PER_SECOND; + } else if (diff < -max) { + diff += CYCLES_PER_SECOND; + } + + return diff; } @@ -406,30 +433,3 @@ } -/** - * @brief Computes a difference between cycles - * - * This function computes a difference between cycles - * such that it respects wrapping (at 8000 cycles). - * - * See diffTicks - * - * @param x First cycle value - * @param y Second cycle value - * @return the difference x-y, unwrapped - */ -static inline int diffCycles(unsigned int x, unsigned int y) { - int diff = x - y; - - // the maximal difference we allow (64secs) - const int max=CYCLES_PER_SECOND/2; - - if(diff > max) { - diff -= CYCLES_PER_SECOND; - } else if (diff < -max) { - diff += CYCLES_PER_SECOND; - } - - return diff; -} - #endif // __CYCLETIMER_H__ Index: /branches/ppalmers-streaming/src/debugmodule/debugmodule.cpp =================================================================== --- /branches/ppalmers-streaming/src/debugmodule/debugmodule.cpp (revision 698) +++ /branches/ppalmers-streaming/src/debugmodule/debugmodule.cpp (revision 707) @@ -428,7 +428,8 @@ for (unsigned int i=0; i +#include "debugmodule/debugmodule.h" + +#define MAX_SIGNAL_VALUE 7 namespace Streaming { @@ -33,5 +36,5 @@ StreamStatistics(); - ~StreamStatistics(); + ~StreamStatistics() {}; void setName(std::string n) {m_name=n;}; @@ -50,6 +53,13 @@ long m_sum; + // some tools to do run statistics + // will keep a histogram of the number of times a certain value + // is added. + void signal(unsigned int val); + + unsigned int m_signalled[MAX_SIGNAL_VALUE+1]; + private: - + DECLARE_DEBUG_MODULE; };