Changeset 1348

Show
Ignore:
Timestamp:
09/24/08 09:45:50 (15 years ago)
Author:
ppalmers
Message:

merge 2.0 branch changes to trunk. svn merge -r 1337:HEAD svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/config.h.in

    r1336 r1348  
    6464#define MAX_XMIT_NB_BUFFERS                                200 
    6565 
     66// should be PAGE_SIZE (4096) for unpatched kernels 
     67#define RAW1394_RCV_MIN_BUF_STRIDE                        4096 
     68 
    6669#define ISOHANDLER_FLUSH_BEFORE_ITERATE                      0 
    6770 
     
    9497// time to a later time instant also causes the xmit buffer fill to be 
    9598// lower on average. 
    96 #define STREAMPROCESSORMANAGER_SIGNAL_DELAY_TICKS           (3072*6) 
     99#define STREAMPROCESSORMANAGER_SIGNAL_DELAY_TICKS           (3072*0) 
     100 
     101// causes the waitForPeriod() call to wait until sufficient 
     102// data is present in the buffer such that a transfer() will 
     103// succeed. Normally we wait for the period of time that theoretically 
     104// would mean that his is true. However sometimes the kernel hasn't 
     105// flushed everything to userspace (or the card hasn't IRQ'd). 
     106// the side-effect of this is some jitter in the return timing 
     107// whenever this occurs. 
     108#define STREAMPROCESSORMANAGER_ALLOW_DELAYED_PERIOD_SIGNAL         1 
    97109 
    98110// startup control 
  • trunk/libffado/src/libieee1394/CycleTimerHelper.cpp

    r1336 r1348  
    654654} 
    655655 
     656uint64_t 
     657CycleTimerHelper::getSystemTimeForCycleTimerTicks(uint32_t ticks) 
     658{ 
     659    uint64_t retval; 
     660    struct compute_vars *my_vars; 
     661 
     662    // get pointer and copy the contents 
     663    // no locking should be needed since we have more than one 
     664    // of these vars available, and our use will always be finished before 
     665    // m_current_shadow_idx changes since this thread's priority should 
     666    // be higher than the one of the writer thread. Even if not, we only have to ensure 
     667    // that the used dataset is consistent. We can use an older dataset if it's consistent 
     668    // since it will also provide a fairly decent extrapolation. 
     669    my_vars = m_shadow_vars + m_current_shadow_idx; 
     670 
     671    // the number of ticks the request is ahead of the current CTR position 
     672    int64_t ticks_diff = diffTicks(ticks, my_vars->ticks); 
     673    // to how much time does this correspond? 
     674    double x_step_in_usec = ((double)ticks_diff) / my_vars->rate; 
     675    int64_t x_step_in_usec_int = (int64_t)x_step_in_usec; 
     676    retval = my_vars->usecs + x_step_in_usec_int; 
     677 
     678    return retval; 
     679} 
     680 
     681uint64_t 
     682CycleTimerHelper::getSystemTimeForCycleTimer(uint32_t ctr) 
     683{ 
     684    uint32_t ticks = CYCLE_TIMER_TO_TICKS(ctr); 
     685    return getSystemTimeForCycleTimerTicks(ticks); 
     686} 
     687 
    656688#else 
    657689 
     
    685717CycleTimerHelper::getCycleTimerTicks(uint64_t now) 
    686718{ 
    687     debugWarning("not implemented!\n"); 
    688     return getCycleTimerTicks(); 
     719    debugWarning("untested code\n"); 
     720    #warning Untested code 
     721    uint32_t cycle_timer; 
     722    uint64_t local_time; 
     723    readCycleTimerWithRetry(&cycle_timer, &local_time, 10); 
     724    int64_t ticks = CYCLE_TIMER_TO_TICKS(cycle_timer); 
     725 
     726    int delta_t = now - local_time; // how far ahead is the request? 
     727    ticks += delta_t * getRate(); // add ticks 
     728    if (ticks >= TICKS_PER_SECOND * 128) ticks -= TICKS_PER_SECOND * 128; 
     729    else if (ticks < 0) ticks += TICKS_PER_SECOND * 128; 
     730    return ticks; 
    689731} 
    690732 
     
    701743CycleTimerHelper::getCycleTimer(uint64_t now) 
    702744{ 
     745    return TICKS_TO_CYCLE_TIMER(getCycleTimerTicks(now)); 
     746} 
     747 
     748uint64_t 
     749CycleTimerHelper::getSystemTimeForCycleTimerTicks(uint32_t ticks) 
     750{ 
    703751    debugWarning("not implemented!\n"); 
    704     return getCycleTimer(); 
     752    return 0; 
     753
     754 
     755uint64_t 
     756CycleTimerHelper::getSystemTimeForCycleTimer(uint32_t ctr) 
     757
     758    uint32_t ticks = CYCLE_TIMER_TO_TICKS(ctr); 
     759    return getSystemTimeForCycleTimerTicks(ticks); 
    705760} 
    706761 
  • trunk/libffado/src/libieee1394/CycleTimerHelper.h

    r1080 r1348  
    9898    uint32_t getCycleTimer(uint64_t now); 
    9999 
     100    /** 
     101     * @brief get the system time for a specific cycle timer value (in ticks) 
     102     * @note thread safe 
     103     */ 
     104    uint64_t getSystemTimeForCycleTimerTicks(uint32_t ticks); 
     105 
     106    /** 
     107     * @brief get the system time for a specific cycle timer value (in CTR format) 
     108     * @note thread safe 
     109     */ 
     110    uint64_t getSystemTimeForCycleTimer(uint32_t ctr); 
     111 
    100112    float getRate(); 
    101113    float getNominalRate(); 
  • trunk/libffado/src/libieee1394/ieee1394service.cpp

    r1336 r1348  
    401401} 
    402402 
     403uint64_t 
     404Ieee1394Service::getSystemTimeForCycleTimerTicks(uint32_t ticks) { 
     405    return m_pCTRHelper->getSystemTimeForCycleTimerTicks(ticks); 
     406} 
     407 
     408uint64_t 
     409Ieee1394Service::getSystemTimeForCycleTimer(uint32_t ctr) { 
     410    return m_pCTRHelper->getSystemTimeForCycleTimer(ctr); 
     411} 
     412 
    403413bool 
    404414Ieee1394Service::readCycleTimerReg(uint32_t *cycle_timer, uint64_t *local_time) 
  • trunk/libffado/src/libieee1394/ieee1394service.h

    r1336 r1348  
    134134     */ 
    135135    uint32_t getCycleTimer(uint64_t t); 
     136 
     137    /** 
     138     * @brief get the system time for a specific cycle timer value (in ticks) 
     139     * @note thread safe 
     140     */ 
     141    uint64_t getSystemTimeForCycleTimerTicks(uint32_t ticks); 
     142 
     143    /** 
     144     * @brief get the system time for a specific cycle timer value (in CTR format) 
     145     * @note thread safe 
     146     */ 
     147    uint64_t getSystemTimeForCycleTimer(uint32_t ctr); 
    136148 
    137149    /** 
  • trunk/libffado/src/libieee1394/IsoHandler.cpp

    r1336 r1348  
    475475    // leave the offset field (for now?) 
    476476 
    477     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     477    debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 
    478478                "received packet: length=%d, channel=%d, cycle=%d, at %08X\n", 
    479479                length, channel, cycle, pkt_ctr); 
     
    566566        m_last_packet_handled_at = pkt_ctr; 
    567567    } 
    568     debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     568    debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 
    569569                "sending packet: length=%d, cycle=%d, at %08X\n", 
    570570                *length, cycle, pkt_ctr); 
     
    670670    dumpInfo(); 
    671671    if (getType() == eHT_Receive) { 
    672         if(m_irq_interval > 1) { 
    673             if(raw1394_iso_recv_init(m_handle, 
    674                                     iso_receive_handler, 
    675                                     m_buf_packets, 
    676                                     m_max_packet_size, 
    677                                     m_Client->getChannel(), 
    678                                     RAW1394_DMA_BUFFERFILL, 
    679 //                                     RAW1394_DMA_PACKET_PER_BUFFER, 
    680                                     m_irq_interval)) { 
    681                 debugFatal("Could not do receive initialisation (DMA_BUFFERFILL)!\n" ); 
    682                 debugFatal("  %s\n",strerror(errno)); 
    683                 return false; 
    684             } 
    685         } else { 
    686             if(raw1394_iso_recv_init(m_handle, 
    687                                     iso_receive_handler, 
    688                                     m_buf_packets, 
    689                                     m_max_packet_size, 
    690                                     m_Client->getChannel(), 
    691                                     RAW1394_DMA_PACKET_PER_BUFFER, 
    692                                     m_irq_interval)) { 
    693                 debugFatal("Could not do receive initialisation (PACKET_PER_BUFFER)!\n" ); 
    694                 debugFatal("  %s\n",strerror(errno)); 
    695                 return false; 
    696             } 
     672        if(raw1394_iso_recv_init(m_handle, 
     673                                iso_receive_handler, 
     674                                m_buf_packets, 
     675                                m_max_packet_size, 
     676                                m_Client->getChannel(), 
     677                                RAW1394_DMA_PACKET_PER_BUFFER, 
     678                                m_irq_interval)) { 
     679            debugFatal("Could not do receive initialisation (DMA_BUFFERFILL)!\n" ); 
     680            debugFatal("  %s\n",strerror(errno)); 
     681            return false; 
    697682        } 
    698683        return true; 
  • trunk/libffado/src/libieee1394/IsoHandler.h

    r1336 r1348  
    119119    unsigned int getMaxPacketSize() { return m_max_packet_size;}; 
    120120    unsigned int getNbBuffers() { return m_buf_packets;}; 
    121     int getPacketLatency() { return m_irq_interval;}; 
     121    int getIrqInterval() { return m_irq_interval;}; 
    122122 
    123123    unsigned int getPreBuffers() {return m_prebuffers;}; 
  • trunk/libffado/src/libieee1394/IsoHandlerManager.cpp

    r1336 r1348  
    353353        #ifdef DEBUG 
    354354        if(m_poll_fds_shadow[i].revents) { 
    355             debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     355            debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
    356356                        "(%p, %s) received events: %08X for (%d/%d, %p, %s)\n", 
    357357                        this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"), 
     
    761761        // setup the optimal parameters for the raw1394 ISO buffering 
    762762        unsigned int packets_per_period = stream->getPacketsPerPeriod(); 
    763         unsigned int max_packet_size = stream->getMaxPacketSize(); 
    764         unsigned int page_size = getpagesize() - 2; // for one reason or another this is necessary 
     763        unsigned int max_packet_size = stream->getMaxPacketSize() + 8; // bufferfill takes another 8 bytes for headers 
     764        unsigned int page_size = getpagesize(); 
    765765 
    766766        // Ensure we don't request a packet size bigger than the 
    767767        // kernel-enforced maximum which is currently 1 page. 
     768        // NOTE: PP: this is not really true AFAICT 
    768769        if (max_packet_size > page_size) { 
    769770            debugError("max packet size (%u) > page size (%u)\n", max_packet_size, page_size); 
     
    771772        } 
    772773 
    773         unsigned int irq_interval = packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 
     774        // the interrupt/wakeup interval prediction of raw1394 is a mess... 
     775        int irq_interval = (packets_per_period-1) / MINIMUM_INTERRUPTS_PER_PERIOD; 
    774776        if(irq_interval <= 0) irq_interval=1; 
    775          
     777 
    776778        // the receive buffer size doesn't matter for the latency, 
    777779        // but it has a minimal value in order for libraw to operate correctly (300) 
     
    977979    { 
    978980        if((*it)->isStreamRegistered(stream)) { 
    979             return (*it)->getPacketLatency(); 
     981            return (*it)->getIrqInterval(); 
    980982        } 
    981983    } 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp

    r1254 r1348  
    3434#include "libutil/ByteSwap.h" 
    3535#include <assert.h> 
     36#include "libutil/SystemTimeSource.h" 
    3637 
    3738namespace Streaming { 
     
    6667} 
    6768 
     69unsigned int 
     70AmdtpReceiveStreamProcessor::getAveragePacketSize() 
     71{ 
     72    // in one second we have 8000 packets 
     73    // containing FRAMERATE frames of m_dimension quadlets 
     74    // so 8000 packet headers + FRAMERATE*m_dimension quadlets 
     75    unsigned int one_second = 8000 * 2 * sizeof(quadlet_t) + m_StreamProcessorManager.getNominalRate() * m_dimension * sizeof(quadlet_t); 
     76    return one_second / 8000; 
     77} 
     78 
    6879bool AmdtpReceiveStreamProcessor::prepareChild() { 
    6980    debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this); 
     
    144155    // later than expected (the real receive time) 
    145156    #ifdef DEBUG 
     157    static int64_t last_t = Util::SystemTimeSource::getCurrentTime(); 
     158    int64_t now_t = Util::SystemTimeSource::getCurrentTime(); 
    146159    if(isRunning()) { 
    147160        debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 
    148161                           "STMP: %lluticks | syt_interval=%d, tpf=%f\n", 
    149162                           m_last_timestamp, m_syt_interval, getTicksPerFrame()); 
    150     } 
     163/*        debugOutput(DEBUG_LEVEL_NORMAL, 
     164                           "STMP: %12llu ticks | delta_t: %5lld | bufferfill: %5d\n", 
     165                           m_last_timestamp, now_t-last_t, m_data_buffer->getBufferFill());*/ 
     166    } 
     167    last_t = now_t; 
    151168 
    152169    // check whether nevents is a multiple of 8. 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h

    r1035 r1348  
    9090    virtual unsigned int getMaxPacketSize()  
    9191                    {return 4 * (2 + getSytInterval() * m_dimension);}; 
     92    virtual unsigned int getAveragePacketSize(); 
    9293    virtual unsigned int getEventsPerFrame()  
    9394                    { return m_dimension; }; 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r1336 r1348  
    406406    } 
    407407} 
     408 
     409unsigned int 
     410AmdtpTransmitStreamProcessor::getAveragePacketSize() 
     411{ 
     412    // in one second we have 8000 packets 
     413    // containing FRAMERATE frames of m_dimension quadlets 
     414    // so 8000 packet headers + FRAMERATE*m_dimension quadlets 
     415    unsigned int one_second = 8000 * 2 * sizeof(quadlet_t) + m_StreamProcessorManager.getNominalRate() * m_dimension * sizeof(quadlet_t); 
     416    return one_second / 8000; 
     417} 
     418 
    408419unsigned int 
    409420AmdtpTransmitStreamProcessor::getFDF() { 
  • trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h

    r1347 r1348  
    105105    virtual unsigned int getMaxPacketSize() 
    106106                    {return 4 * (2 + getSytInterval() * m_dimension);}; 
     107    virtual unsigned int getAveragePacketSize(); 
    107108    virtual unsigned int getEventsPerFrame() 
    108109                    { return m_dimension; }; 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp

    r1336 r1348  
    146146StreamProcessor::getNominalPacketsNeeded(unsigned int nframes) 
    147147{ 
    148     unsigned int nominal_frames_per_second  
     148    unsigned int nominal_frames_per_second 
    149149                    = m_StreamProcessorManager.getNominalRate(); 
    150150    uint64_t nominal_ticks_per_frame = TICKS_PER_SECOND / nominal_frames_per_second; 
    151151    uint64_t nominal_ticks = nominal_ticks_per_frame * nframes; 
    152     uint64_t nominal_packets = nominal_ticks / TICKS_PER_CYCLE; 
     152    // ensure proper ceiling 
     153    uint64_t nominal_packets = (nominal_ticks+TICKS_PER_CYCLE-1) / TICKS_PER_CYCLE; 
    153154    return nominal_packets; 
    154155} 
     
    219220    debugOutput(DEBUG_LEVEL_VERBOSE, "Setting SP %p SyncDelay to %u ticks, %u frames\n", this, d, frames); 
    220221    #endif 
    221     m_sync_delay = d; // FIXME: sync delay not necessary anymore 
     222    m_sync_delay = d; 
     223
     224 
     225unsigned int 
     226StreamProcessor::getSyncDelayFrames() { 
     227    unsigned int frames = (unsigned int)((float)m_sync_delay / getTicksPerFrame()); 
     228    return frames; 
    222229} 
    223230 
     
    508515            unsigned int bufferfill = m_data_buffer->getBufferFill(); 
    509516            if(bufferfill >= periodsize) { 
    510                 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "signal activity, %d>%d\n", bufferfill, periodsize); 
    511                 SIGNAL_ACTIVITY_SPM; 
    512                 return RAW1394_ISO_DEFER; 
     517                debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "signal activity, %d>%d\n",  
     518                                                        bufferfill, periodsize); 
     519                //SIGNAL_ACTIVITY_SPM; 
     520                return RAW1394_ISO_DEFER; // FIXME: might not be needed 
    513521            } 
    514522            return RAW1394_ISO_OK; 
     
    15091517            if (getType() == ePT_Transmit) { 
    15101518                ringbuffer_size_frames = m_StreamProcessorManager.getNbBuffers() * m_StreamProcessorManager.getPeriodSize(); 
     1519 
     1520                // add sync delay 
     1521                int syncdelay_in_frames = m_StreamProcessorManager.getSyncSource().getSyncDelayFrames(); 
     1522                ringbuffer_size_frames += syncdelay_in_frames; 
     1523 
    15111524                debugOutput(DEBUG_LEVEL_VERBOSE, "Prefill transmit SP %p with %u frames\n", this, ringbuffer_size_frames); 
    15121525                // prefill the buffer 
  • trunk/libffado/src/libstreaming/generic/StreamProcessor.h

    r1336 r1348  
    290290    virtual unsigned int getPacketsPerPeriod(); 
    291291    virtual unsigned int getMaxPacketSize() = 0; 
     292    virtual unsigned int getAveragePacketSize() = 0; 
    292293private: 
    293294    int m_channel; 
     
    376377         * Returns the sync delay. This is the time a syncsource 
    377378         * delays a period signal, e.g. to cope with buffering. 
    378          * @return the sync delay 
     379         * @return the sync delay (in ticks) 
    379380         */ 
    380381        unsigned int getSyncDelay() {return m_sync_delay;}; 
     382        unsigned int getSyncDelayFrames(); 
    381383        /** 
    382384         * sets the sync delay 
  • trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.cpp

    r1254 r1348  
    9696 
    9797unsigned int 
     98MotuReceiveStreamProcessor::getAveragePacketSize() 
     99{ 
     100    // in one second we have 8000 packets 
     101    // containing FRAMERATE frames 
     102    // so on average bytes/packet: (8000 packet headers + FRAMERATE * frame_size) / 8000 
     103    #warning FIXME 
     104    int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 
     105    return framerate<=48000?616:(framerate<=96000?1032:1160); 
     106} 
     107 
     108unsigned int 
    98109MotuReceiveStreamProcessor::getNominalFramesPerPacket() { 
    99110    int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 
  • trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.h

    r1035 r1348  
    152152                {return m_event_size;}; 
    153153    virtual unsigned int getMaxPacketSize(); 
     154    virtual unsigned int getAveragePacketSize(); 
    154155    virtual unsigned int getEventsPerFrame()  
    155156                    { return 1; }; // FIXME: check 
  • trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp

    r1254 r1348  
    9191 
    9292unsigned int 
     93MotuTransmitStreamProcessor::getAveragePacketSize() 
     94{ 
     95    // in one second we have 8000 packets 
     96    // containing FRAMERATE frames 
     97    // so on average bytes/packet: (8000 packet headers + FRAMERATE * frame_size) / 8000 
     98    #warning FIXME 
     99    int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 
     100    return framerate<=48000?616:(framerate<=96000?1032:1160); 
     101} 
     102 
     103unsigned int 
    93104MotuTransmitStreamProcessor::getNominalFramesPerPacket() { 
    94105    int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 
  • trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.h

    r1034 r1348  
    7676                {return m_event_size;}; 
    7777    virtual unsigned int getMaxPacketSize(); 
     78    virtual unsigned int getAveragePacketSize(); 
    7879    virtual unsigned int getEventsPerFrame()  
    7980                    { return 1; }; // FIXME: check 
  • trunk/libffado/src/libstreaming/StreamProcessorManager.cpp

    r1336 r1348  
    462462    // lower on average. 
    463463    max_of_min_delay += STREAMPROCESSORMANAGER_SIGNAL_DELAY_TICKS; 
    464     debugOutput( DEBUG_LEVEL_VERBOSE, " sync delay = %d ticks (%03us %04uc %04ut)...\n",  
    465         max_of_min_delay, 
    466         (unsigned int)TICKS_TO_SECS(max_of_min_delay), 
    467         (unsigned int)TICKS_TO_CYCLES(max_of_min_delay), 
    468         (unsigned int)TICKS_TO_OFFSET(max_of_min_delay)); 
     464 
    469465    m_SyncSource->setSyncDelay(max_of_min_delay); 
     466    unsigned int syncdelay = m_SyncSource->getSyncDelay(); 
     467    debugOutput( DEBUG_LEVEL_VERBOSE, " sync delay = %d => %d ticks (%03us %04uc %04ut)...\n",  
     468        max_of_min_delay, syncdelay, 
     469        (unsigned int)TICKS_TO_SECS(syncdelay), 
     470        (unsigned int)TICKS_TO_CYCLES(syncdelay), 
     471        (unsigned int)TICKS_TO_OFFSET(syncdelay)); 
    470472 
    471473    //STEP X: when we implement such a function, we can wait for a signal from the devices that they 
     
    477479    // DLL to have a decent sync (FIXME: does the DLL get updated when dry-running)? 
    478480    debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for sync...\n"); 
    479      
     481 
    480482    unsigned int nb_sync_runs = (STREAMPROCESSORMANAGER_SYNC_WAIT_TIME_MSEC * getNominalRate()); 
    481483    nb_sync_runs /= 1000; 
     
    600602    float rate = m_SyncSource->getTicksPerFrame(); 
    601603    int64_t delay_in_ticks=(int64_t)(((float)((m_nb_buffers-1) * m_period)) * rate); 
     604    // also add the sync delay 
     605    delay_in_ticks += m_SyncSource->getSyncDelay(); 
    602606    debugOutput( DEBUG_LEVEL_VERBOSE, "  initial time of transfer %010lld, rate %f...\n", 
    603607                m_time_of_transfer, rate); 
     
    930934    bool xrun_occurred = false; 
    931935    bool in_error = false; 
    932     bool period_not_ready = true; 
    933936 
    934937    // grab the wait lock 
    935938    // this ensures that bus reset handling doesn't interfere 
    936939    Util::MutexLockHelper lock(*m_WaitLock); 
    937  
     940    debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
     941                        "waiting for period (%d frames in buffer)...\n", 
     942                        m_SyncSource->getBufferFill()); 
     943    uint64_t ticks_at_period = m_SyncSource->getTimeAtPeriod(); 
     944    uint64_t ticks_at_period_margin = ticks_at_period + m_SyncSource->getSyncDelay(); 
     945    uint64_t pred_system_time_at_xfer = m_SyncSource->getParent().get1394Service().getSystemTimeForCycleTimerTicks(ticks_at_period_margin); 
     946 
     947    #ifdef DEBUG 
     948    int64_t now = Util::SystemTimeSource::getCurrentTime(); 
     949    debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "pred: %lld, now: %lld, wait: %lld\n", pred_system_time_at_xfer, now, pred_system_time_at_xfer-now ); 
     950    #endif 
     951 
     952    // wait until it's time to transfer 
     953    Util::SystemTimeSource::SleepUsecAbsolute(pred_system_time_at_xfer); 
     954 
     955    #ifdef DEBUG 
     956    now = Util::SystemTimeSource::getCurrentTime(); 
     957    debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "pred: %lld now: %lld, excess: %lld\n", pred_system_time_at_xfer, now, now-pred_system_time_at_xfer ); 
     958    #endif 
     959 
     960    // the period should be ready now 
     961 
     962    #if STREAMPROCESSORMANAGER_ALLOW_DELAYED_PERIOD_SIGNAL 
     963    // HACK: we force wait until every SP is ready. this is needed 
     964    // since the raw1394 interface provides no control over interrupts 
     965    // resulting in very bad predictability on when the data is present. 
     966    bool period_not_ready = true; 
    938967    while(period_not_ready) { 
    939         debugOutputExtreme(DEBUG_LEVEL_VERBOSE,  
    940                            "waiting for period (%d frames in buffer)...\n", 
    941                            m_SyncSource->getBufferFill()); 
    942  
    943         // wait for something to happen 
    944         switch(waitForActivity()) { 
    945             case eAR_Error: 
    946                 debugError("Error while waiting for activity\n"); 
    947                 m_shutdown_needed = true; 
    948                 return false; 
    949             case eAR_Interrupted: 
    950                 // FIXME: what to do here? 
    951                 debugWarning("Interrupted while waiting for activity\n"); 
    952                 break; 
    953             case eAR_Timeout: 
    954                 debugWarning("Timeout while waiting for activity\n"); 
    955                 // ignore this since it can also be due to some other hardware 
    956                 // or high-prio software that preempts us. hence only an xrun should 
    957                 // be generated (if necessary) 
    958             case eAR_Activity: 
    959                 // do nothing 
    960                 break; 
    961         } 
    962         debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "got activity...\n"); 
    963  
    964         // HACK: this should be solved more elegantly 
    965968        period_not_ready = false; 
    966969        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     
    980983            } 
    981984        } 
    982         debugOutputExtreme(DEBUG_LEVEL_VERBOSE, " period not ready? %d...\n", period_not_ready); 
     985 
     986        if (period_not_ready) { 
     987            debugOutput(DEBUG_LEVEL_VERBOSE, " wait extended since period not ready...\n"); 
     988            Util::SystemTimeSource::SleepUsecRelative(125); // one cycle 
     989        } 
    983990 
    984991        // check for underruns/errors on the ISO side, 
     
    10001007        if(xrun_occurred | in_error | m_shutdown_needed) break; 
    10011008    } 
     1009    #else 
     1010    // check for underruns/errors on the ISO side, 
     1011    // those should make us bail out of the wait loop 
     1012    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     1013        it != m_ReceiveProcessors.end(); 
     1014        ++it ) { 
     1015        // xrun on data buffer side 
     1016        if (!(*it)->canConsumePeriod()) { 
     1017            xrun_occurred = true; 
     1018        } 
     1019        // a xrun has occurred on the Iso side 
     1020        xrun_occurred |= (*it)->xrunOccurred(); 
     1021        in_error |= (*it)->inError(); 
     1022    } 
     1023    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     1024        it != m_TransmitProcessors.end(); 
     1025        ++it ) { 
     1026        // xrun on data buffer side 
     1027        if (!(*it)->canProducePeriod()) { 
     1028            xrun_occurred = true; 
     1029        } 
     1030        // a xrun has occurred on the Iso side 
     1031        xrun_occurred |= (*it)->xrunOccurred(); 
     1032        in_error |= (*it)->inError(); 
     1033    } 
     1034    #endif 
    10021035 
    10031036    if(xrun_occurred) { 
     
    10321065    #endif 
    10331066 
    1034     debugOutputExtreme( DEBUG_LEVEL_VERBOSE, 
     1067    debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
    10351068                        "transfer period %d at %llu ticks...\n", 
    10361069                        m_nbperiods, m_time_of_transfer); 
     
    10381071    // this is to notify the client of the delay that we introduced by waiting 
    10391072    m_delayed_usecs = - m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); 
    1040     debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE, 
     1073    debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 
    10411074                        "delayed for %d usecs...\n", 
    10421075                        m_delayed_usecs); 
     
    11461179        // the data we are putting into the buffer is intended to be transmitted 
    11471180        // one ringbuffer size after it has been received 
    1148         int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks); 
     1181 
     1182        // we also add one syncdelay as a safety margin, since that's the amount of time we can get 
     1183        // postponed. 
     1184        int syncdelay = m_SyncSource->getSyncDelay(); 
     1185        int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks + syncdelay); 
    11491186 
    11501187        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     
    12221259        // the data we are putting into the buffer is intended to be transmitted 
    12231260        // one ringbuffer size after it has been received 
    1224         int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks); 
     1261        // we also add one syncdelay as a safety margin, since that's the amount of time we can get 
     1262        // postponed. 
     1263        int syncdelay = m_SyncSource->getSyncDelay(); 
     1264        int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks + syncdelay); 
    12251265 
    12261266        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();